135 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Ruby
		
	
	
	
			
		
		
	
	
			135 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Ruby
		
	
	
	
# Copyright 2015 Google Inc.
 | 
						|
#
 | 
						|
# Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
# you may not use this file except in compliance with the License.
 | 
						|
# You may obtain a copy of the License at
 | 
						|
#
 | 
						|
#      http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
#
 | 
						|
# Unless required by applicable law or agreed to in writing, software
 | 
						|
# distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
# See the License for the specific language governing permissions and
 | 
						|
# limitations under the License.
 | 
						|
 | 
						|
 | 
						|
module Google
 | 
						|
  module Apis
 | 
						|
    module Core
 | 
						|
      # Part of a multipart request for holding JSON data
 | 
						|
      #
 | 
						|
      # @private
 | 
						|
      class JsonPart
 | 
						|
 | 
						|
        # @param [String] value
 | 
						|
        #   JSON content
 | 
						|
        # @param [Hash] header
 | 
						|
        #   Additional headers
 | 
						|
        def initialize(value, header = {})
 | 
						|
          @value = value
 | 
						|
          @header = header
 | 
						|
        end
 | 
						|
 | 
						|
        def to_io(boundary)
 | 
						|
          part = ''
 | 
						|
          part << "--#{boundary}\r\n"
 | 
						|
          part << "Content-Type: application/json\r\n"
 | 
						|
          @header.each do |(k, v)|
 | 
						|
            part << "#{k}: #{v}\r\n"
 | 
						|
          end
 | 
						|
          part << "\r\n"
 | 
						|
          part << "#{@value}\r\n"
 | 
						|
          StringIO.new(part)
 | 
						|
        end
 | 
						|
 | 
						|
      end
 | 
						|
 | 
						|
      # Part of a multipart request for holding arbitrary content.
 | 
						|
      #
 | 
						|
      # @private
 | 
						|
      class FilePart
 | 
						|
        # @param [IO] io
 | 
						|
        #   IO stream
 | 
						|
        # @param [Hash] header
 | 
						|
        #   Additional headers
 | 
						|
        def initialize(io, header = {})
 | 
						|
          @io = io
 | 
						|
          @header = header
 | 
						|
          @length = io.respond_to?(:size) ? io.size : nil
 | 
						|
        end
 | 
						|
 | 
						|
        def to_io(boundary)
 | 
						|
          head = ''
 | 
						|
          head << "--#{boundary}\r\n"
 | 
						|
          @header.each do |(k, v)|
 | 
						|
            head << "#{k}: #{v}\r\n"
 | 
						|
          end
 | 
						|
          head << "Content-Length: #{@length}\r\n" unless @length.nil?
 | 
						|
          head << "Content-Transfer-Encoding: binary\r\n"
 | 
						|
          head << "\r\n"
 | 
						|
          Google::Apis::Core::CompositeIO.new(StringIO.new(head), @io, StringIO.new("\r\n"))
 | 
						|
        end
 | 
						|
      end
 | 
						|
 | 
						|
      # Helper for building multipart requests
 | 
						|
      class Multipart
 | 
						|
        MULTIPART_RELATED = 'multipart/related'
 | 
						|
 | 
						|
        # @return [String]
 | 
						|
        #  Content type header
 | 
						|
        attr_reader :content_type
 | 
						|
 | 
						|
        # @param [String] content_type
 | 
						|
        #  Content type for the multipart request
 | 
						|
        # @param [String] boundary
 | 
						|
        #  Part delimiter
 | 
						|
 | 
						|
        def initialize(content_type: MULTIPART_RELATED, boundary: nil)
 | 
						|
          @parts = []
 | 
						|
          @boundary = boundary || Digest::SHA1.hexdigest(SecureRandom.random_bytes(8))
 | 
						|
          @content_type = "#{content_type}; boundary=#{@boundary}"
 | 
						|
        end
 | 
						|
 | 
						|
        # Append JSON data part
 | 
						|
        #
 | 
						|
        # @param [String] body
 | 
						|
        #   JSON text
 | 
						|
        # @param [String] content_id
 | 
						|
        #   Optional unique ID of this part
 | 
						|
        # @return [self]
 | 
						|
        def add_json(body, content_id: nil)
 | 
						|
          header = {}
 | 
						|
          header['Content-ID'] = content_id unless content_id.nil?
 | 
						|
          @parts << Google::Apis::Core::JsonPart.new(body, header).to_io(@boundary)
 | 
						|
          self
 | 
						|
        end
 | 
						|
 | 
						|
        # Append arbitrary data as a part
 | 
						|
        #
 | 
						|
        # @param [IO] upload_io
 | 
						|
        #   IO stream
 | 
						|
        # @param [String] content_id
 | 
						|
        #   Optional unique ID of this part
 | 
						|
        # @return [self]
 | 
						|
        def add_upload(upload_io, content_type: nil, content_id: nil)
 | 
						|
          header = {
 | 
						|
              'Content-Type' => content_type || 'application/octet-stream'
 | 
						|
          }
 | 
						|
          header['Content-Id'] = content_id unless content_id.nil?
 | 
						|
          @parts << Google::Apis::Core::FilePart.new(upload_io,
 | 
						|
                                                     header).to_io(@boundary)
 | 
						|
          self
 | 
						|
        end
 | 
						|
 | 
						|
        # Assemble the multipart requests
 | 
						|
        #
 | 
						|
        # @return [IO]
 | 
						|
        #  IO stream
 | 
						|
        def assemble
 | 
						|
          @parts <<  StringIO.new("--#{@boundary}--\r\n\r\n")
 | 
						|
          Google::Apis::Core::CompositeIO.new(*@parts)
 | 
						|
        end
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
end |