Module: S3Multipart::TransferHelpers

Included in:
Upload
Defined in:
lib/s3_multipart/transfer_helpers.rb

Overview

Collection of methods to be mixed in to the Upload class.

Handle all communication with Amazon S3 servers

Instance Method Summary collapse

Instance Method Details

#complete(options) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/s3_multipart/transfer_helpers.rb', line 38

def complete(options)
  options[:content_type] = "application/xml"

  url = URI.escape("/#{options[:object_name]}?uploadId=#{options[:upload_id]}")

  body = format_part_list_in_xml(options)
  headers = { content_type: options[:content_type],
              content_length: options[:content_length] }

  headers[:authorization], headers[:date] = sign_request verb: 'POST', url: url, content_type: options[:content_type]

  response = Http.post url, {headers: headers, body: body}
  parsed_response_body = XmlSimple.xml_in(response.body)  

  begin
    return { location: parsed_response_body["Location"][0] }
  rescue NoMethodError
    return { error: "Upload does not exist"} if parsed_response_body["Message"].first.match("The specified upload does not exist. The upload ID may be invalid, or the upload may have been aborted or completed.")
  end
end

#initiate(options) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/s3_multipart/transfer_helpers.rb', line 7

def initiate(options)
  url = "/#{unique_name(options)}?uploads"

  headers = {content_type: options[:content_type]}
  headers.merge!(options[:headers]) if options.key?(:headers)
  headers[:authorization], headers[:date] = sign_request verb: 'POST',
                                                         url: url,
                                                         content_type: options[:content_type],
                                                         headers: options[:headers]

  response = Http.post url, headers: headers
  parsed_response_body = XmlSimple.xml_in(response.body)  

  { "key"  => parsed_response_body["Key"][0],
    "upload_id"   => parsed_response_body["UploadId"][0],
    "name" => options[:object_name] }
end

#sign_batch(options) ⇒ Object



25
26
27
28
29
# File 'lib/s3_multipart/transfer_helpers.rb', line 25

def sign_batch(options)
  parts = options[:content_lengths].to_s.split('-').each_with_index.map do |len, i|
    sign_part(options.merge!({content_length: len, part_number: i+1}))
  end
end

#sign_part(options) ⇒ Object



31
32
33
34
35
36
# File 'lib/s3_multipart/transfer_helpers.rb', line 31

def sign_part(options)
  url = "/#{options[:object_name]}?partNumber=#{options[:part_number]}&uploadId=#{options[:upload_id]}"
  authorization, date = sign_request verb: 'PUT', url: URI.escape(url), content_length: options[:content_length]

  { authorization: authorization, date: date }
end

#sign_request(options) ⇒ Object



59
60
61
62
# File 'lib/s3_multipart/transfer_helpers.rb', line 59

def sign_request(options)
  time = Time.now.utc.strftime("%a, %d %b %Y %T %Z")
  [calculate_authorization_hash(time, options), time]
end

#unique_name(options) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/s3_multipart/transfer_helpers.rb', line 64

def unique_name(options)
  url = [UUID.generate, options[:object_name]].join("/")
  controller = S3Multipart::Uploader.deserialize(options[:uploader])

  if controller.mount_point && defined?(CarrierWaveDirect)
    uploader = controller.model.to_s.classify.constantize.new.send(controller.mount_point)

    if uploader.class.ancestors.include?(CarrierWaveDirect::Uploader)
      url = uploader.key.sub(/#{Regexp.escape(CarrierWaveDirect::Uploader::FILENAME_WILDCARD)}\z/, options[:object_name])
    end
  end

  URI.escape(url)
end