Updating dependencies.
[arvados.git] / lib / google / api_client / reference.rb
index 4c67bca1ebf32e2ed758b03a0f181707ca7813d4..f95761fcaa852dfaf7464465af12d219d575c3ac 100644 (file)
@@ -13,7 +13,7 @@
 # limitations under the License.
 
 
-gem 'faraday', '~> 0.7.0'
+gem 'faraday', '~> 0.8.1'
 require 'faraday'
 require 'faraday/utils'
 require 'multi_json'
@@ -21,10 +21,13 @@ require 'addressable/uri'
 require 'stringio'
 require 'google/api_client/discovery'
 
+# TODO - needs some serious cleanup
 
 module Google
   class APIClient
     class Reference
+      
+      MULTIPART_BOUNDARY = "-----------RubyApiMultipartPost".freeze
       def initialize(options={})
         # We only need this to do lookups on method ID String values
         # It's optional, but method ID lookups will fail if the client is
@@ -33,26 +36,59 @@ module Google
         @version = options[:version] || 'v1'
 
         self.connection = options[:connection] || Faraday.default_connection
+        self.authorization = options[:authorization]
         self.api_method = options[:api_method]
         self.parameters = options[:parameters] || {}
         # These parameters are handled differently because they're not
         # parameters to the API method, but rather to the API system.
         self.parameters['key'] ||= options[:key] if options[:key]
         self.parameters['userIp'] ||= options[:user_ip] if options[:user_ip]
-        self.headers = options[:headers] || []
-        if options[:body]
+        self.headers = options[:headers] || {}
+        if options[:media]
+          self.media = options[:media]
+          upload_type = parameters['uploadType'] || parameters['upload_type'] 
+          case upload_type
+          when "media"
+            if options[:body] || options[:body_object] 
+              raise ArgumentError, "Can not specify body & body object for simple uploads"
+            end
+            self.headers['Content-Type'] ||= self.media.content_type
+            self.body = self.media
+          when "multipart"
+            unless options[:body_object] 
+              raise ArgumentError, "Multipart requested but no body object"              
+            end
+            # This is all a bit of a hack due to signet requiring body to be a string
+            # Ideally, update signet to delay serialization so we can just pass
+            # streams all the way down through to the HTTP lib
+            metadata = StringIO.new(serialize_body(options[:body_object]))
+            env = {
+              :request_headers => {'Content-Type' => "multipart/related;boundary=#{MULTIPART_BOUNDARY}"},
+              :request => { :boundary => MULTIPART_BOUNDARY }
+            }
+            multipart = Faraday::Request::Multipart.new
+            self.body = multipart.create_multipart(env, [
+              [nil,Faraday::UploadIO.new(metadata, 'application/json', 'file.json')], 
+              [nil, self.media]])
+            self.headers.update(env[:request_headers])
+          when "resumable"
+            file_length = self.media.length
+            self.headers['X-Upload-Content-Type'] = self.media.content_type
+            self.headers['X-Upload-Content-Length'] = file_length.to_s
+            if options[:body_object]
+              self.headers['Content-Type'] ||= 'application/json'
+              self.body = serialize_body(options[:body_object]) 
+            else
+              self.body = ''
+            end
+          else
+            raise ArgumentError, "Invalid uploadType for media"
+          end 
+        elsif options[:body]
           self.body = options[:body]
         elsif options[:body_object]
-          if options[:body_object].respond_to?(:to_json)
-            serialized_body = options[:body_object].to_json
-          elsif options[:body_object].respond_to?(:to_hash)
-            serialized_body = MultiJson.encode(options[:body_object].to_hash)
-          else
-            raise TypeError,
-              'Could not convert body object to JSON.' +
-              'Must respond to :to_json or :to_hash.'
-          end
-          self.body = serialized_body
+          self.headers['Content-Type'] ||= 'application/json'
+          self.body = serialize_body(options[:body_object])
         else
           self.body = ''
         end
@@ -65,7 +101,30 @@ module Google
           end
         end
       end
-
+      
+      def serialize_body(body)
+        return body.to_json if body.respond_to?(:to_json)
+        return MultiJson.dump(options[:body_object].to_hash) if body.respond_to?(:to_hash)
+        raise TypeError, 'Could not convert body object to JSON.' +
+                         'Must respond to :to_json or :to_hash.'
+      end
+      
+      def media
+        return @media
+      end
+      
+      def media=(media)
+        @media = (media)
+      end
+      
+      def authorization
+        return @authorization
+      end
+      
+      def authorization=(new_authorization)
+        @authorization = new_authorization
+      end
+      
       def connection
         return @connection
       end
@@ -132,18 +191,20 @@ module Google
       def body=(new_body)
         if new_body.respond_to?(:to_str)
           @body = new_body.to_str
+        elsif new_body.respond_to?(:read)
+          @body = new_body.read()
         elsif new_body.respond_to?(:inject)
           @body = (new_body.inject(StringIO.new) do |accu, chunk|
             accu.write(chunk)
             accu
           end).string
         else
-          raise TypeError, "Expected body to be String or Enumerable chunks."
+          raise TypeError, "Expected body to be String, IO, or Enumerable chunks."
         end
       end
 
       def headers
-        return @headers ||= []
+        return @headers ||= {}
       end
 
       def headers=(new_headers)
@@ -205,6 +266,7 @@ module Google
         options[:headers] = self.headers
         options[:body] = self.body
         options[:connection] = self.connection
+        options[:authorization] = self.authorization unless self.authorization.nil?
         return options
       end
     end