From 890aba2af07ef21f9e5b547f57e057db0daff9f7 Mon Sep 17 00:00:00 2001 From: David Chandek-Stark Date: Tue, 31 Jan 2017 15:48:43 -0500 Subject: [PATCH] Patches Rubydora::RestApiClient to not read file-like object When adding or modifying datastream content. Note: Previously, rubydora read the entire file content into a string and passed the string to rest-client, so the file remained open. Since rest-client closes the file, the changed methods alter the state of passed in file/io objects. --- Gemfile | 1 + lib/rubydora/rest_api_client.rb | 6 ++---- spec/lib/rest_api_client_spec.rb | 10 +++++----- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Gemfile b/Gemfile index f129f89..810e95d 100644 --- a/Gemfile +++ b/Gemfile @@ -4,3 +4,4 @@ gemspec gem 'jruby-openssl', :platform => :jruby gem 'activesupport', '< 5' if RUBY_VERSION < '2.2.2' +gem 'rake', '< 12' diff --git a/lib/rubydora/rest_api_client.rb b/lib/rubydora/rest_api_client.rb index 4c0aa18..de1a7e0 100644 --- a/lib/rubydora/rest_api_client.rb +++ b/lib/rubydora/rest_api_client.rb @@ -336,9 +336,8 @@ def add_datastream(options = {}) file = query_options.delete(:content) content_type = query_options.delete(:content_type) || query_options[:mimeType] || file_content_type(file) run_hook :before_add_datastream, :pid => pid, :dsid => dsid, :file => file, :options => options - str = file.respond_to?(:read) ? file.read : file file.rewind if file.respond_to?(:rewind) - ProfileParser.parse_datastream_profile(client[datastream_url(pid, dsid, query_options)].post(str, :content_type => content_type.to_s, :multipart => true)) + ProfileParser.parse_datastream_profile(client[datastream_url(pid, dsid, query_options)].post(file, :content_type => content_type.to_s, :multipart => true)) rescue Exception => exception rescue_with_handler(exception) || raise end @@ -361,9 +360,8 @@ def modify_datastream(options = {}) end run_hook :before_modify_datastream, :pid => pid, :dsid => dsid, :file => file, :content_type => content_type, :options => options - str = file.respond_to?(:read) ? file.read : file file.rewind if file.respond_to?(:rewind) - ProfileParser.parse_datastream_profile(client[datastream_url(pid, dsid, query_options)].put(str, rest_client_options)) + ProfileParser.parse_datastream_profile(client[datastream_url(pid, dsid, query_options)].put(file, rest_client_options)) rescue Exception => exception rescue_with_handler(exception) || raise diff --git a/spec/lib/rest_api_client_spec.rb b/spec/lib/rest_api_client_spec.rb index fac5edf..691c474 100644 --- a/spec/lib/rest_api_client_spec.rb +++ b/spec/lib/rest_api_client_spec.rb @@ -240,11 +240,11 @@ class MockRepository @mock_repository.add_datastream :pid => 'mypid', :dsid => 'aaa' end describe "when a file is passed" do - let!(:file) { StringIO.new('test', 'r') } # StringIO is a good stand it for a real File (it has read, rewind and close) - it "should rewind the file" do + let!(:file) { StringIO.new('test', 'r') } # StringIO is a good stand in for a real File (it has read, rewind and close) + it "closes the file" do RestClient::Request.any_instance.should_receive(:transmit) #stub transmit so that Request.execute can close the file we pass @mock_repository.add_datastream :pid => 'mypid', :dsid => 'aaa', :content=>file - lambda {file.read}.should_not raise_error + file.should be_closed end describe "and mimeType is not provided" do describe "and file responds to :content_type" do @@ -282,10 +282,10 @@ class MockRepository end describe "when a file is passed" do let!(:file) { StringIO.new('test', 'r') } # StringIO is a good stand it for a real File (it has read, rewind and close) - it "should rewind the file" do + it "closes the file" do RestClient::Request.any_instance.should_receive(:transmit) #stub transmit so that Request.execute can close the file we pass @mock_repository.modify_datastream :pid => 'mypid', :dsid => 'aaa', :content=>file - lambda {file.read}.should_not raise_error + file.should be_closed end describe "and mimeType is not provided" do describe "and file responds to :content_type" do