only upload media if there is one
[arvados.git] / lib / google / api_client / request.rb
index 9a084c31a4e3ecf9f4b7f88af088a517e4544315..78ec87793368db05b3e81bed2588f9f44d6292eb 100644 (file)
@@ -13,7 +13,7 @@
 # limitations under the License.
 
 require 'faraday'
-require 'faraday/utils'
+require 'faraday/request/multipart'
 require 'multi_json'
 require 'compat/multi_json'
 require 'addressable/uri'
@@ -71,8 +71,10 @@ module Google
       # @option options [String, Symbol] :http_method
       #   HTTP method when requesting a URI
       def initialize(options={})
-        @parameters = Hash[options[:parameters] || {}]
+        @parameters = Faraday::Utils::ParamsHash.new
         @headers = Faraday::Utils::Headers.new
+
+        self.parameters.merge!(options[:parameters]) unless options[:parameters].nil?
         self.headers.merge!(options[:headers]) unless options[:headers].nil?
         self.api_method = options[:api_method]
         self.authenticated = options[:authenticated]
@@ -150,10 +152,13 @@ module Google
       #
       # @param [Faraday::Connection] connection
       #   the connection to transmit with
+      # @param [TrueValue,FalseValue] is_retry
+      #   True if request has been previous sent
       #
       # @return [Google::APIClient::Result]
       #   result of API request
-      def send(connection)
+      def send(connection, is_retry = false)
+        self.body.rewind if is_retry && self.body.respond_to?(:rewind)          
         env = self.to_env(connection)
         logger.debug  { "#{self.class} Sending API request #{env[:method]} #{env[:url].to_s} #{env[:request_headers]}" }
         http_response = connection.app.call(env)
@@ -163,8 +168,8 @@ module Google
 
         # Resumamble slightly different than other upload protocols in that it requires at least
         # 2 requests.
-        if self.upload_type == 'resumable'
-          upload =  result.resumable_upload
+        if result.status == 200 && self.upload_type == 'resumable' && self.media
+          upload = result.resumable_upload
           unless upload.complete?
             logger.debug { "#{self.class} Sending upload body" }
             result = upload.send(connection)
@@ -181,14 +186,15 @@ module Google
       # @return [Array<(Symbol, Addressable::URI, Hash, [#read,#to_str])>]
       def to_http_request
         request = (
-          if self.uri
+          if self.api_method
+            self.api_method.generate_request(self.parameters, self.body, self.headers)
+          elsif self.uri
             unless self.parameters.empty?
               self.uri.query = Addressable::URI.form_encode(self.parameters)
             end
             [self.http_method, self.uri.to_s, self.headers, self.body]
-          else
-            self.api_method.generate_request(self.parameters, self.body, self.headers)
           end)
+        return request
       end
 
       ##
@@ -227,7 +233,7 @@ module Google
       def to_env(connection)
         method, uri, headers, body = self.to_http_request
         http_request = connection.build_request(method) do |req|
-          req.url(uri)
+          req.url(uri.to_s)
           req.headers.update(headers)
           req.body = body
         end
@@ -281,6 +287,7 @@ module Google
             raise ArgumentError, "Can not specify body & body object for simple uploads"
           end
           self.headers['Content-Type'] ||= self.media.content_type
+          self.headers['Content-Length'] ||= self.media.length.to_s
           self.body = self.media
         when "multipart"
           unless options[:body_object]
@@ -313,10 +320,10 @@ module Google
       # @param [String] boundary
       #   Boundary for separating each part of the message
       def build_multipart(parts, mime_type = 'multipart/related', boundary = MULTIPART_BOUNDARY)
-        env = {
-          :request_headers => {'Content-Type' => "#{mime_type};boundary=#{boundary}"},
-          :request => { :boundary => boundary }
-        }
+        env = Faraday::Env.new
+        env.request = Faraday::RequestOptions.new
+        env.request.boundary = boundary
+        env.request_headers = {'Content-Type' => "#{mime_type};boundary=#{boundary}"}
         multipart = Faraday::Request::Multipart.new
         self.body = multipart.create_multipart(env, parts.map {|part| [nil, part]})
         self.headers.update(env[:request_headers])