fog-internet-archive 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +53 -0
  3. data/.travis.yml +16 -0
  4. data/Gemfile +3 -0
  5. data/README.md +6 -0
  6. data/Rakefile +19 -0
  7. data/fog-internet-archive.gemspec +32 -0
  8. data/lib/fog/bin/internet_archive.rb +32 -0
  9. data/lib/fog/internet_archive.rb +1 -0
  10. data/lib/fog/internet_archive/core.rb +291 -0
  11. data/lib/fog/internet_archive/models/storage/directories.rb +39 -0
  12. data/lib/fog/internet_archive/models/storage/directory.rb +105 -0
  13. data/lib/fog/internet_archive/models/storage/file.rb +254 -0
  14. data/lib/fog/internet_archive/models/storage/files.rb +119 -0
  15. data/lib/fog/internet_archive/models/storage/ia_attributes.rb +36 -0
  16. data/lib/fog/internet_archive/parsers/storage/access_control_list.rb +42 -0
  17. data/lib/fog/internet_archive/parsers/storage/complete_multipart_upload.rb +20 -0
  18. data/lib/fog/internet_archive/parsers/storage/copy_object.rb +18 -0
  19. data/lib/fog/internet_archive/parsers/storage/cors_configuration.rb +38 -0
  20. data/lib/fog/internet_archive/parsers/storage/delete_multiple_objects.rb +45 -0
  21. data/lib/fog/internet_archive/parsers/storage/get_bucket.rb +58 -0
  22. data/lib/fog/internet_archive/parsers/storage/get_bucket_lifecycle.rb +64 -0
  23. data/lib/fog/internet_archive/parsers/storage/get_bucket_location.rb +16 -0
  24. data/lib/fog/internet_archive/parsers/storage/get_bucket_logging.rb +36 -0
  25. data/lib/fog/internet_archive/parsers/storage/get_bucket_website.rb +22 -0
  26. data/lib/fog/internet_archive/parsers/storage/get_request_payment.rb +16 -0
  27. data/lib/fog/internet_archive/parsers/storage/get_service.rb +28 -0
  28. data/lib/fog/internet_archive/parsers/storage/initiate_multipart_upload.rb +20 -0
  29. data/lib/fog/internet_archive/parsers/storage/list_multipart_uploads.rb +52 -0
  30. data/lib/fog/internet_archive/parsers/storage/list_parts.rb +36 -0
  31. data/lib/fog/internet_archive/requests/storage/abort_multipart_upload.rb +27 -0
  32. data/lib/fog/internet_archive/requests/storage/acl_utils.rb +60 -0
  33. data/lib/fog/internet_archive/requests/storage/complete_multipart_upload.rb +46 -0
  34. data/lib/fog/internet_archive/requests/storage/copy_object.rb +77 -0
  35. data/lib/fog/internet_archive/requests/storage/cors_utils.rb +39 -0
  36. data/lib/fog/internet_archive/requests/storage/delete_bucket.rb +42 -0
  37. data/lib/fog/internet_archive/requests/storage/delete_bucket_cors.rb +26 -0
  38. data/lib/fog/internet_archive/requests/storage/delete_bucket_lifecycle.rb +26 -0
  39. data/lib/fog/internet_archive/requests/storage/delete_bucket_policy.rb +26 -0
  40. data/lib/fog/internet_archive/requests/storage/delete_bucket_website.rb +26 -0
  41. data/lib/fog/internet_archive/requests/storage/delete_multiple_objects.rb +88 -0
  42. data/lib/fog/internet_archive/requests/storage/delete_object.rb +46 -0
  43. data/lib/fog/internet_archive/requests/storage/get_bucket.rb +108 -0
  44. data/lib/fog/internet_archive/requests/storage/get_bucket_acl.rb +65 -0
  45. data/lib/fog/internet_archive/requests/storage/get_bucket_cors.rb +61 -0
  46. data/lib/fog/internet_archive/requests/storage/get_bucket_lifecycle.rb +35 -0
  47. data/lib/fog/internet_archive/requests/storage/get_bucket_location.rb +54 -0
  48. data/lib/fog/internet_archive/requests/storage/get_bucket_logging.rb +45 -0
  49. data/lib/fog/internet_archive/requests/storage/get_bucket_policy.rb +31 -0
  50. data/lib/fog/internet_archive/requests/storage/get_bucket_website.rb +38 -0
  51. data/lib/fog/internet_archive/requests/storage/get_object.rb +163 -0
  52. data/lib/fog/internet_archive/requests/storage/get_object_acl.rb +72 -0
  53. data/lib/fog/internet_archive/requests/storage/get_object_http_url.rb +48 -0
  54. data/lib/fog/internet_archive/requests/storage/get_object_https_url.rb +30 -0
  55. data/lib/fog/internet_archive/requests/storage/get_object_torrent.rb +45 -0
  56. data/lib/fog/internet_archive/requests/storage/get_object_url.rb +49 -0
  57. data/lib/fog/internet_archive/requests/storage/get_request_payment.rb +45 -0
  58. data/lib/fog/internet_archive/requests/storage/get_service.rb +50 -0
  59. data/lib/fog/internet_archive/requests/storage/head_object.rb +57 -0
  60. data/lib/fog/internet_archive/requests/storage/initiate_multipart_upload.rb +42 -0
  61. data/lib/fog/internet_archive/requests/storage/list_multipart_uploads.rb +52 -0
  62. data/lib/fog/internet_archive/requests/storage/list_parts.rb +53 -0
  63. data/lib/fog/internet_archive/requests/storage/post_object_hidden_fields.rb +36 -0
  64. data/lib/fog/internet_archive/requests/storage/put_bucket.rb +70 -0
  65. data/lib/fog/internet_archive/requests/storage/put_bucket_acl.rb +69 -0
  66. data/lib/fog/internet_archive/requests/storage/put_bucket_cors.rb +47 -0
  67. data/lib/fog/internet_archive/requests/storage/put_bucket_lifecycle.rb +76 -0
  68. data/lib/fog/internet_archive/requests/storage/put_bucket_logging.rb +79 -0
  69. data/lib/fog/internet_archive/requests/storage/put_bucket_policy.rb +25 -0
  70. data/lib/fog/internet_archive/requests/storage/put_bucket_website.rb +59 -0
  71. data/lib/fog/internet_archive/requests/storage/put_object.rb +94 -0
  72. data/lib/fog/internet_archive/requests/storage/put_object_acl.rb +73 -0
  73. data/lib/fog/internet_archive/requests/storage/put_object_url.rb +43 -0
  74. data/lib/fog/internet_archive/requests/storage/put_request_payment.rb +45 -0
  75. data/lib/fog/internet_archive/requests/storage/sync_clock.rb +24 -0
  76. data/lib/fog/internet_archive/requests/storage/upload_part.rb +39 -0
  77. data/lib/fog/internet_archive/signaturev4.rb +71 -0
  78. data/lib/fog/internet_archive/storage.rb +381 -0
  79. data/lib/fog/internet_archive/version.rb +5 -0
  80. data/tasks/bundler.rake +3 -0
  81. data/tasks/console.rake +17 -0
  82. data/tasks/lint.rake +3 -0
  83. data/tasks/test.rake +7 -0
  84. data/tests/helper.rb +36 -0
  85. data/tests/helpers/collection_helper.rb +88 -0
  86. data/tests/helpers/formats_helper.rb +98 -0
  87. data/tests/helpers/formats_helper_tests.rb +106 -0
  88. data/tests/helpers/mock_helper.rb +13 -0
  89. data/tests/helpers/model_helper.rb +29 -0
  90. data/tests/helpers/responds_to_helper.rb +11 -0
  91. data/tests/helpers/schema_validator_tests.rb +101 -0
  92. data/tests/helpers/succeeds_helper.rb +9 -0
  93. data/tests/internet_archive/models/storage/directory_tests.rb +42 -0
  94. data/tests/internet_archive/models/storage/file_tests.rb +61 -0
  95. data/tests/internet_archive/models/storage/files_tests.rb +60 -0
  96. data/tests/internet_archive/models/storage/url_tests.rb +28 -0
  97. data/tests/internet_archive/requests/storage/acl_utils_tests.rb +209 -0
  98. data/tests/internet_archive/requests/storage/bucket_tests.rb +324 -0
  99. data/tests/internet_archive/requests/storage/cors_utils_tests.rb +108 -0
  100. data/tests/internet_archive/requests/storage/multipart_upload_tests.rb +132 -0
  101. data/tests/internet_archive/requests/storage/object_tests.rb +166 -0
  102. data/tests/internet_archive/signaturev4_tests.rb +41 -0
  103. data/tests/internet_archive/signed_params_tests.rb +5 -0
  104. data/tests/lorem.txt +1 -0
  105. metadata +322 -0
@@ -0,0 +1,54 @@
1
+ module Fog
2
+ module Storage
3
+ class InternetArchive
4
+ class Real
5
+ require 'fog/internet_archive/parsers/storage/get_bucket_location'
6
+
7
+ # Get location constraint for an S3 bucket
8
+ #
9
+ # @param bucket_name [String] name of bucket to get location constraint for
10
+ #
11
+ # @return [Excon::Response] response:
12
+ # * body [Hash]:
13
+ # * LocationConstraint [String] - Location constraint of the bucket
14
+ #
15
+ # @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketGETlocation.html
16
+
17
+ def get_bucket_location(bucket_name)
18
+ request({
19
+ :expects => 200,
20
+ :headers => {},
21
+ :host => "#{bucket_name}.#{@host}",
22
+ :idempotent => true,
23
+ :method => 'GET',
24
+ :parser => Fog::Parsers::Storage::InternetArchive::GetBucketLocation.new,
25
+ :query => {'location' => nil}
26
+ })
27
+ end
28
+ end
29
+
30
+ class Mock # :nodoc:all
31
+ def get_bucket_location(bucket_name)
32
+ response = Excon::Response.new
33
+ if bucket = self.data[:buckets][bucket_name]
34
+ location_constraint = case bucket['LocationConstraint']
35
+ when 'us-east-1'
36
+ nil
37
+ when 'eu-east-1'
38
+ 'EU'
39
+ else
40
+ bucket['LocationConstraint']
41
+ end
42
+
43
+ response.status = 200
44
+ response.body = {'LocationConstraint' => location_constraint }
45
+ else
46
+ response.status = 404
47
+ raise(Excon::Errors.status_error({:expects => 200}, response))
48
+ end
49
+ response
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,45 @@
1
+ module Fog
2
+ module Storage
3
+ class InternetArchive
4
+ class Real
5
+ require 'fog/internet_archive/parsers/storage/get_bucket_logging'
6
+
7
+ # Get logging status for an S3 bucket
8
+ #
9
+ # @param bucket_name [String] name of bucket to get logging status for
10
+ #
11
+ # @return [Excon::Response] response:
12
+ # * body [Hash]:
13
+ # * BucketLoggingStatus (will be empty if logging is disabled) [Hash]:
14
+ # * LoggingEnabled [Hash]:
15
+ # * TargetBucket [String] - bucket where logs are stored
16
+ # * TargetPrefix [String] - prefix logs are stored with
17
+ # * TargetGrants [Array]:
18
+ # * Grant [Hash]:
19
+ # * Grantee [Hash]:
20
+ # * DisplayName [String] - Display name of grantee
21
+ # * ID [String] - Id of grantee
22
+ # or
23
+ # * URI [String] - URI of group to grant access for
24
+ # * Permission [String] - Permission, in [FULL_CONTROL, WRITE, WRITE_ACP, READ, READ_ACP]
25
+ #
26
+ # @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketGETlogging.html
27
+
28
+ def get_bucket_logging(bucket_name)
29
+ unless bucket_name
30
+ raise ArgumentError.new('bucket_name is required')
31
+ end
32
+ request({
33
+ :expects => 200,
34
+ :headers => {},
35
+ :host => "#{bucket_name}.#{@host}",
36
+ :idempotent => true,
37
+ :method => 'GET',
38
+ :parser => Fog::Parsers::Storage::InternetArchive::GetBucketLogging.new,
39
+ :query => {'logging' => nil}
40
+ })
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,31 @@
1
+ module Fog
2
+ module Storage
3
+ class InternetArchive
4
+ class Real
5
+ # Get bucket policy for an S3 bucket
6
+ #
7
+ # @param bucket_name [String] name of bucket to get policy for
8
+ #
9
+ # @return [Excon::Response] response:
10
+ # * body [Hash] - policy document
11
+ #
12
+ # @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketGETpolicy.html
13
+
14
+ def get_bucket_policy(bucket_name)
15
+ unless bucket_name
16
+ raise ArgumentError.new('bucket_name is required')
17
+ end
18
+ response = request({
19
+ :expects => 200,
20
+ :headers => {},
21
+ :host => "#{bucket_name}.#{@host}",
22
+ :idempotent => true,
23
+ :method => 'GET',
24
+ :query => {'policy' => nil}
25
+ })
26
+ response.body = Fog::JSON.decode(response.body) unless response.body.nil?
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,38 @@
1
+ module Fog
2
+ module Storage
3
+ class InternetArchive
4
+ class Real
5
+ require 'fog/internet_archive/parsers/storage/get_bucket_website'
6
+
7
+ # Get website configuration for an S3 bucket
8
+ #
9
+ #
10
+ # @param bucket_name [String] name of bucket to get website configuration for
11
+ #
12
+ # @return [Excon::Response] response:
13
+ # * body [Hash]:
14
+ # * IndexDocument [Hash]:
15
+ # * Suffix [String] - Suffix appended when directory is requested
16
+ # * ErrorDocument [Hash]:
17
+ # * Key [String] - Object key to return for 4XX class errors
18
+ #
19
+ # @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketGETwebsite.html
20
+
21
+ def get_bucket_website(bucket_name)
22
+ unless bucket_name
23
+ raise ArgumentError.new('bucket_name is required')
24
+ end
25
+ request({
26
+ :expects => 200,
27
+ :headers => {},
28
+ :host => "#{bucket_name}.#{@host}",
29
+ :idempotent => true,
30
+ :method => 'GET',
31
+ :parser => Fog::Parsers::Storage::InternetArchive::GetBucketWebsite.new,
32
+ :query => {'website' => nil}
33
+ })
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,163 @@
1
+ module Fog
2
+ module Storage
3
+ class InternetArchive
4
+ class Real
5
+ # Get an object from S3
6
+ #
7
+ # @param bucket_name [String] Name of bucket to read from
8
+ # @param object_name [String] Name of object to read
9
+ # @param options [Hash]
10
+ # @option options If-Match [String] Returns object only if its etag matches this value, otherwise returns 412 (Precondition Failed).
11
+ # @option options If-Modified-Since [Time] Returns object only if it has been modified since this time, otherwise returns 304 (Not Modified).
12
+ # @option options If-None-Match [String] Returns object only if its etag differs from this value, otherwise returns 304 (Not Modified)
13
+ # @option options If-Unmodified-Since [Time] Returns object only if it has not been modified since this time, otherwise returns 412 (Precodition Failed).
14
+ # @option options Range [String] Range of object to download
15
+ #
16
+ # @return [Excon::Response] response:
17
+ # * body [String]- Contents of object
18
+ # * headers [Hash]:
19
+ # * Content-Length [String] - Size of object contents
20
+ # * Content-Type [String] - MIME type of object
21
+ # * ETag [String] - Etag of object
22
+ # * Last-Modified [String] - Last modified timestamp for object
23
+ #
24
+ # @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectGET.html
25
+
26
+ def get_object(bucket_name, object_name, options = {}, &block)
27
+ unless bucket_name
28
+ raise ArgumentError.new('bucket_name is required')
29
+ end
30
+ unless object_name
31
+ raise ArgumentError.new('object_name is required')
32
+ end
33
+
34
+ params = { :headers => {} }
35
+ params[:headers].merge!(options)
36
+ if options['If-Modified-Since']
37
+ params[:headers]['If-Modified-Since'] = Fog::Time.at(options['If-Modified-Since'].to_i).to_date_header
38
+ end
39
+ if options['If-Unmodified-Since']
40
+ params[:headers]['If-Unmodified-Since'] = Fog::Time.at(options['If-Unmodified-Since'].to_i).to_date_header
41
+ end
42
+
43
+ if block_given?
44
+ params[:response_block] = Proc.new
45
+ end
46
+
47
+ request(params.merge!({
48
+ :expects => [ 200, 206 ],
49
+ :host => "#{bucket_name}.#{@host}",
50
+ :idempotent => true,
51
+ :method => 'GET',
52
+ :path => CGI.escape(object_name),
53
+ }))
54
+ end
55
+ end
56
+
57
+ class Mock # :nodoc:all
58
+ def get_object(bucket_name, object_name, options = {}, &block)
59
+ unless bucket_name
60
+ raise ArgumentError.new('bucket_name is required')
61
+ end
62
+
63
+ unless object_name
64
+ raise ArgumentError.new('object_name is required')
65
+ end
66
+
67
+ response = Excon::Response.new
68
+ if (bucket = self.data[:buckets][bucket_name])
69
+ object = nil
70
+ if bucket[:objects].key?(object_name)
71
+ object = bucket[:objects][object_name].first
72
+ end
73
+
74
+ if (object && !object[:delete_marker])
75
+ if options['If-Match'] && options['If-Match'] != object['ETag']
76
+ response.status = 412
77
+ elsif options['If-Modified-Since'] && options['If-Modified-Since'] >= Time.parse(object['Last-Modified'])
78
+ response.status = 304
79
+ elsif options['If-None-Match'] && options['If-None-Match'] == object['ETag']
80
+ response.status = 304
81
+ elsif options['If-Unmodified-Since'] && options['If-Unmodified-Since'] < Time.parse(object['Last-Modified'])
82
+ response.status = 412
83
+ else
84
+ response.status = 200
85
+ for key, value in object
86
+ case key
87
+ when 'Cache-Control', 'Content-Disposition', 'Content-Encoding', 'Content-Length', 'Content-MD5', 'Content-Type', 'ETag', 'Expires', 'Last-Modified', /^x-amz-meta-/
88
+ response.headers[key] = value
89
+ end
90
+ end
91
+
92
+ body = object[:body]
93
+ if options['Range']
94
+ # since AWS S3 itself does not support multiple range headers, we will use only the first
95
+ ranges = byte_ranges(options['Range'], body.size)
96
+ unless ranges.nil? || ranges.empty?
97
+ response.status = 206
98
+ body = body[ranges.first]
99
+ end
100
+ end
101
+
102
+ unless block_given?
103
+ response.body = body
104
+ else
105
+ data = StringIO.new(body)
106
+ remaining = data.length
107
+ while remaining > 0
108
+ chunk = data.read([remaining, Excon::CHUNK_SIZE].min)
109
+ block.call(chunk)
110
+ remaining -= Excon::CHUNK_SIZE
111
+ end
112
+ end
113
+ end
114
+ else
115
+ response.status = 404
116
+ response.body = "...<Code>NoSuchKey<\/Code>..."
117
+ raise(Excon::Errors.status_error({:expects => 200}, response))
118
+ end
119
+ else
120
+ response.status = 404
121
+ response.body = "...<Code>NoSuchBucket</Code>..."
122
+ raise(Excon::Errors.status_error({:expects => 200}, response))
123
+ end
124
+ response
125
+ end
126
+
127
+ private
128
+
129
+ # === Borrowed from rack
130
+ # Parses the "Range:" header, if present, into an array of Range objects.
131
+ # Returns nil if the header is missing or syntactically invalid.
132
+ # Returns an empty array if none of the ranges are satisfiable.
133
+ def byte_ranges(http_range, size)
134
+ # See <http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35>
135
+ return nil unless http_range
136
+ ranges = []
137
+ http_range.split(/,\s*/).each do |range_spec|
138
+ matches = range_spec.match(/bytes=(\d*)-(\d*)/)
139
+ return nil unless matches
140
+ r0,r1 = matches[1], matches[2]
141
+ if r0.empty?
142
+ return nil if r1.empty?
143
+ # suffix-byte-range-spec, represents trailing suffix of file
144
+ r0 = [size - r1.to_i, 0].max
145
+ r1 = size - 1
146
+ else
147
+ r0 = r0.to_i
148
+ if r1.empty?
149
+ r1 = size - 1
150
+ else
151
+ r1 = r1.to_i
152
+ return nil if r1 < r0 # backwards range is syntactically invalid
153
+ r1 = size-1 if r1 >= size
154
+ end
155
+ end
156
+ ranges << (r0..r1) if r0 <= r1
157
+ end
158
+ ranges
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,72 @@
1
+ module Fog
2
+ module Storage
3
+ class InternetArchive
4
+ class Real
5
+ require 'fog/internet_archive/parsers/storage/access_control_list'
6
+
7
+ # Get access control list for an S3 object
8
+ #
9
+ # @param bucket_name [String] name of bucket containing object
10
+ # @param object_name [String] name of object to get access control list for
11
+ # @param options [Hash]
12
+ #
13
+ # @return [Excon::Response] response:
14
+ # * body [Hash]:
15
+ # * [AccessControlPolicy [Hash]:
16
+ # * Owner [Hash]:
17
+ # * DisplayName [String] - Display name of object owner
18
+ # * ID [String] - Id of object owner
19
+ # * AccessControlList [Array]:
20
+ # * Grant [Hash]:
21
+ # * Grantee [Hash]:
22
+ # * DisplayName [String] - Display name of grantee
23
+ # * ID [String] - Id of grantee
24
+ # or
25
+ # * URI [String] - URI of group to grant access for
26
+ # * Permission [String] - Permission, in [FULL_CONTROL, WRITE, WRITE_ACP, READ, READ_ACP]
27
+ #
28
+ # @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectGETacl.html
29
+
30
+ def get_object_acl(bucket_name, object_name, options = {})
31
+ unless bucket_name
32
+ raise ArgumentError.new('bucket_name is required')
33
+ end
34
+ unless object_name
35
+ raise ArgumentError.new('object_name is required')
36
+ end
37
+ query = {'acl' => nil}
38
+ request({
39
+ :expects => 200,
40
+ :headers => {},
41
+ :host => "#{bucket_name}.#{@host}",
42
+ :idempotent => true,
43
+ :method => 'GET',
44
+ :parser => Fog::Parsers::Storage::InternetArchive::AccessControlList.new,
45
+ :path => CGI.escape(object_name),
46
+ :query => query
47
+ })
48
+ end
49
+ end
50
+
51
+ class Mock # :nodoc:all
52
+ require 'fog/internet_archive/requests/storage/acl_utils'
53
+
54
+ def get_object_acl(bucket_name, object_name, options = {})
55
+ response = Excon::Response.new
56
+ if acl = self.data[:acls][:object][bucket_name] && self.data[:acls][:object][bucket_name][object_name]
57
+ response.status = 200
58
+ if acl.is_a?(String)
59
+ response.body = Fog::Storage::InternetArchive.acl_to_hash(acl)
60
+ else
61
+ response.body = acl
62
+ end
63
+ else
64
+ response.status = 404
65
+ raise(Excon::Errors.status_error({:expects => 200}, response))
66
+ end
67
+ response
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,48 @@
1
+ module Fog
2
+ module Storage
3
+ class InternetArchive
4
+ module GetObjectHttpUrl
5
+ def get_object_http_url(bucket_name, object_name, expires, options = {})
6
+ unless bucket_name
7
+ raise ArgumentError.new('bucket_name is required')
8
+ end
9
+ unless object_name
10
+ raise ArgumentError.new('object_name is required')
11
+ end
12
+ host, path = if bucket_name =~ /^(?:[a-z]|\d(?!\d{0,2}(?:\.\d{1,3}){3}$))(?:[a-z0-9]|\.(?![\.\-])|\-(?![\.])){1,61}[a-z0-9]$/
13
+ ["#{bucket_name}.#{@host}", object_name]
14
+ else
15
+ [@host, "#{bucket_name}/#{object_name}"]
16
+ end
17
+ http_url({
18
+ :headers => {},
19
+ :host => host,
20
+ :port => @port,
21
+ :method => 'GET',
22
+ :path => path,
23
+ :query => options[:query]
24
+ }, expires)
25
+ end
26
+ end
27
+
28
+ class Real
29
+ # Get an expiring object http url from S3
30
+ #
31
+ # @param bucket_name [String] Name of bucket containing object
32
+ # @param object_name [String] Name of object to get expiring url for
33
+ # @param expires [Time] An expiry time for this url
34
+ #
35
+ # @return [Excon::Response] response:
36
+ # * body [String] - url for object
37
+ #
38
+ # @see http://docs.amazonwebservices.com/AmazonS3/latest/dev/S3_QSAuth.html
39
+
40
+ include GetObjectHttpUrl
41
+ end
42
+
43
+ class Mock # :nodoc:all
44
+ include GetObjectHttpUrl
45
+ end
46
+ end
47
+ end
48
+ end