class Google::Apis::Core::ResumableUploadCommand

Implementation of the resumable upload protocol

Constants

BYTES_RECEIVED_HEADER
QUERY_COMMAND
RESUMABLE
START_COMMAND
STATUS_ACTIVE
STATUS_CANCELLED
STATUS_FINAL
UPLOAD_COMMAND
UPLOAD_COMMAND_HEADER
UPLOAD_OFFSET_HEADER
UPLOAD_STATUS_HEADER
UPLOAD_URL_HEADER

Public Instance Methods

execute_once(client, &block) click to toggle source

Execute the upload request once. This will typically perform two HTTP requests – one to initiate or query for the status of the upload, the second to send the (remaining) content.

@private @param [Hurley::Client] client

HTTP client

@yield [result, err] Result or error if block supplied @return [Object] @raise [Google::Apis::ServerError] An error occurred on the server and the request can be retried @raise [Google::Apis::ClientError] The request is invalid and should not be retried without modification @raise [Google::Apis::AuthorizationError] Authorization is required

# File lib/google/apis/core/upload.rb, line 262
def execute_once(client, &block)
  case @state
  when :start
    response = send_start_command(client)
    result = process_response(response.status_code, response.header, response.body)
  when :active
    response = send_query_command(client)
    result = process_response(response.status_code, response.header, response.body)
  when :cancelled, :final
    error(@last_error, rethrow: true, &block)
  end
  if @state == :active
    response = send_upload_command(client)
    result = process_response(response.status_code, response.header, response.body)
  end

  success(result, &block) if @state == :final
rescue => e
  # Some APIs like Youtube generate non-retriable 401 errors and mark
  # the upload as finalized. Save the error just in case we get
  # retried.
  @last_error = e
  error(e, rethrow: true, &block)
end
prepare!() click to toggle source

Reset upload to initial state.

@return [void] @raise [Google::Apis::ClientError] if upload source is invalid

# File lib/google/apis/core/upload.rb, line 165
def prepare!
  @state = :start
  @upload_url = nil
  @offset = 0
  super
end
process_response(status, header, body) click to toggle source

Check the to see if the upload is complete or needs to be resumed.

@param [Fixnum] status

HTTP status code of response

@param [Hurley::Header] header

Response headers

@param [String, read] body

Response body

@return [Object]

Response object

@raise [Google::Apis::ServerError] An error occurred on the server and the request can be retried @raise [Google::Apis::ClientError] The request is invalid and should not be retried without modification @raise [Google::Apis::AuthorizationError] Authorization is required

Calls superclass method
# File lib/google/apis/core/upload.rb, line 185
def process_response(status, header, body)
  @offset = Integer(header[BYTES_RECEIVED_HEADER]) if header.key?(BYTES_RECEIVED_HEADER)
  @upload_url = header[UPLOAD_URL_HEADER] if header.key?(UPLOAD_URL_HEADER)
  upload_status = header[UPLOAD_STATUS_HEADER]
  logger.debug { sprintf('Upload status %s', upload_status) }
  if upload_status == STATUS_ACTIVE
    @state = :active
  elsif upload_status == STATUS_FINAL
    @state = :final
  elsif upload_status == STATUS_CANCELLED
    @state = :cancelled
    fail Google::Apis::ClientError, body
  end
  super(status, header, body)
end
send_query_command(client) click to toggle source

Query for the status of an incomplete upload

@param [Hurley::Client] client

HTTP client

@return [Hurley::Response] @raise [Google::Apis::ServerError] Unable to send the request

# File lib/google/apis/core/upload.rb, line 226
def send_query_command(client)
  logger.debug { sprintf('Sending upload query command to %s', @upload_url) }
  client.post(@upload_url, nil) do |req|
    apply_request_options(req)
    req.header[UPLOAD_COMMAND_HEADER] = QUERY_COMMAND
  end
end
send_start_command(client) click to toggle source

Send the start command to initiate the upload

@param [Hurley::Client] client

HTTP client

@return [Hurley::Response] @raise [Google::Apis::ServerError] Unable to send the request

# File lib/google/apis/core/upload.rb, line 207
def send_start_command(client)
  logger.debug { sprintf('Sending upload start command to %s', url) }
  client.send(method, url, body) do |req|
    apply_request_options(req)
    req.header[UPLOAD_PROTOCOL_HEADER] = RESUMABLE
    req.header[UPLOAD_COMMAND_HEADER] = START_COMMAND
    req.header[UPLOAD_CONTENT_LENGTH] = upload_io.length.to_s
    req.header[UPLOAD_CONTENT_TYPE_HEADER] = upload_io.content_type
  end
rescue => e
  raise Google::Apis::ServerError, e.message
end
send_upload_command(client) click to toggle source

Send the actual content

@param [Hurley::Client] client

HTTP client

@return [Hurley::Response] @raise [Google::Apis::ServerError] Unable to send the request

# File lib/google/apis/core/upload.rb, line 240
def send_upload_command(client)
  logger.debug { sprintf('Sending upload command to %s', @upload_url) }
  content = upload_io
  content.pos = @offset
  client.post(@upload_url, content) do |req|
    apply_request_options(req)
    req.header[UPLOAD_COMMAND_HEADER] = UPLOAD_COMMAND
    req.header[UPLOAD_OFFSET_HEADER] = @offset.to_s
  end
end