aws-sdk 1.6.2 → 1.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/aws/core.rb +13 -2
- data/lib/aws/core/autoloader.rb +1 -1
- data/lib/aws/core/client.rb +69 -30
- data/lib/aws/core/configuration.rb +12 -1
- data/lib/aws/core/http/handler.rb +28 -16
- data/lib/aws/core/http/net_http_handler.rb +31 -11
- data/lib/aws/core/http/request.rb +52 -16
- data/lib/aws/core/http/response.rb +20 -16
- data/lib/aws/core/indifferent_hash.rb +14 -14
- data/lib/aws/core/query_client.rb +1 -0
- data/lib/aws/core/response.rb +32 -14
- data/lib/aws/core/signature/version_2.rb +1 -0
- data/lib/aws/core/signature/version_4.rb +16 -16
- data/lib/aws/dynamo_db/client.rb +2 -2
- data/lib/aws/dynamo_db/request.rb +0 -6
- data/lib/aws/ec2/security_group/ip_permission.rb +4 -1
- data/lib/aws/rails.rb +10 -10
- data/lib/aws/s3.rb +44 -29
- data/lib/aws/s3/bucket.rb +171 -6
- data/lib/aws/s3/cipher_io.rb +119 -0
- data/lib/aws/s3/client.rb +75 -45
- data/lib/aws/s3/config.rb +6 -0
- data/lib/aws/s3/data_options.rb +136 -49
- data/lib/aws/s3/encryption_utils.rb +144 -0
- data/lib/aws/s3/errors.rb +14 -0
- data/lib/aws/s3/multipart_upload.rb +7 -4
- data/lib/aws/s3/object_collection.rb +2 -2
- data/lib/aws/s3/policy.rb +1 -1
- data/lib/aws/s3/request.rb +21 -33
- data/lib/aws/s3/s3_object.rb +797 -237
- data/lib/aws/simple_email_service/request.rb +0 -2
- data/lib/aws/simple_workflow/request.rb +0 -3
- data/lib/net/http/connection_pool.rb +63 -75
- data/lib/net/http/connection_pool/connection.rb +69 -15
- data/lib/net/http/connection_pool/session.rb +39 -6
- metadata +4 -2
@@ -16,18 +16,19 @@ require 'net/http/connection_pool/connection'
|
|
16
16
|
require 'thread'
|
17
17
|
require 'logger'
|
18
18
|
|
19
|
+
# A wrapper around Net::HTTP that provides a manged pool of persistant HTTP
|
20
|
+
# connections.
|
21
|
+
#
|
22
|
+
# pool = Net::HTTP::ConnectionPool.new
|
23
|
+
# connection = pool.connection_for('domain.com')
|
24
|
+
# connection.request(Net::HTTP::Get.new('/')) do |resp|
|
25
|
+
# # Connection#request yields Net::HTTPResponse objects
|
26
|
+
# puts resp.body
|
27
|
+
# end
|
28
|
+
#
|
19
29
|
# @private
|
20
30
|
class Net::HTTP::ConnectionPool
|
21
31
|
|
22
|
-
SOCKET_ERRORS = [
|
23
|
-
EOFError,
|
24
|
-
IOError,
|
25
|
-
Errno::ECONNABORTED,
|
26
|
-
Errno::ECONNRESET,
|
27
|
-
Errno::EPIPE,
|
28
|
-
Errno::EINVAL
|
29
|
-
]
|
30
|
-
|
31
32
|
# @param [Hash] options
|
32
33
|
#
|
33
34
|
# @option options [Numeric] :http_idle_timeout (60) The number of seconds a
|
@@ -42,10 +43,10 @@ class Net::HTTP::ConnectionPool
|
|
42
43
|
#
|
43
44
|
# @option options [Logger] :logger (Logger.new($stdout)) Where debug out
|
44
45
|
# is sent (wire traces).
|
45
|
-
#
|
46
|
+
#
|
46
47
|
def initialize options = {}
|
47
|
-
@pool = []
|
48
48
|
@pool_mutex = Mutex.new
|
49
|
+
@pool = []
|
49
50
|
@open_timeout = options[:http_open_timeout] || 15
|
50
51
|
@idle_timeout = options[:http_idle_timeout] || 60
|
51
52
|
@http_wire_trace = !!options[:http_wire_trace]
|
@@ -56,7 +57,7 @@ class Net::HTTP::ConnectionPool
|
|
56
57
|
end
|
57
58
|
end
|
58
59
|
|
59
|
-
# @return [Integer]
|
60
|
+
# @return [Integer]
|
60
61
|
attr_reader :idle_timeout
|
61
62
|
|
62
63
|
# @return [Integer]
|
@@ -76,20 +77,18 @@ class Net::HTTP::ConnectionPool
|
|
76
77
|
# Requests a connection object from the connection pool.
|
77
78
|
#
|
78
79
|
# connection = pool.connection_for('domain.com')
|
79
|
-
# connection.request(Net::HTTP::Get.new('/index.html'))
|
80
|
-
# connection.request(Net::HTTP::Get.new('/about.html'))
|
80
|
+
# connection.request(Net::HTTP::Get.new('/index.html')) {|resp|}
|
81
|
+
# connection.request(Net::HTTP::Get.new('/about.html')) {|resp|}
|
81
82
|
#
|
82
83
|
# # same thing in block form
|
83
84
|
# pool.connection_for('domain.com') do |connection|
|
84
|
-
# connection.request(Net::HTTP::Get.new('/index.html'))
|
85
|
-
# connection.request(Net::HTTP::Get.new('/about.html'))
|
85
|
+
# connection.request(Net::HTTP::Get.new('/index.html')) {|resp|}
|
86
|
+
# connection.request(Net::HTTP::Get.new('/about.html')) {|resp|}
|
86
87
|
# end
|
87
88
|
#
|
88
89
|
# Because the pool manages HTTP sessions you do not have to
|
89
90
|
# worry about closing a connection or returning a connection
|
90
|
-
# to the pool.
|
91
|
-
# object, a HTTP session received from the pool and returned after
|
92
|
-
# the request is complete.
|
91
|
+
# to the pool.
|
93
92
|
#
|
94
93
|
# @param [String] host
|
95
94
|
#
|
@@ -102,12 +101,12 @@ class Net::HTTP::ConnectionPool
|
|
102
101
|
# SSL. Defaults to +false+, unless +:port+ is 443, then it defaults
|
103
102
|
# to +true+.
|
104
103
|
#
|
105
|
-
# @option options [Boolean] :ssl_verify_peer (true) If true, ssl
|
104
|
+
# @option options [Boolean] :ssl_verify_peer (true) If true, ssl
|
106
105
|
# connections should verify peer certificates. This should only ever be
|
107
106
|
# set false false for debugging purposes.
|
108
107
|
#
|
109
108
|
# @option options [String] :ssl_ca_file Full path to the SSL certificate
|
110
|
-
# authority bundle file that should be used when verifying peer
|
109
|
+
# authority bundle file that should be used when verifying peer
|
111
110
|
# certificates. If you do not pass +:ssl_ca_file+ or +:ssl_ca_path+
|
112
111
|
# the the system default will be used if available.
|
113
112
|
#
|
@@ -117,7 +116,7 @@ class Net::HTTP::ConnectionPool
|
|
117
116
|
# the the system default will be used if available.
|
118
117
|
#
|
119
118
|
# @option options [URI::HTTP,String] :proxy_uri (nil) A URI string or
|
120
|
-
# URI::HTTP object to use as a proxy. You should not provide
|
119
|
+
# URI::HTTP object to use as a proxy. You should not provide
|
121
120
|
# +:proxy_uri+ with any other proxy options.
|
122
121
|
#
|
123
122
|
# :proxy_uri => 'http://user:pass@host.com:80'
|
@@ -142,54 +141,19 @@ class Net::HTTP::ConnectionPool
|
|
142
141
|
connection
|
143
142
|
end
|
144
143
|
|
145
|
-
# @private
|
146
|
-
def request connection, *request_args, &block
|
147
|
-
|
148
|
-
session = nil
|
149
|
-
response = nil
|
150
|
-
retried = false
|
151
|
-
|
152
|
-
begin
|
153
|
-
|
154
|
-
session = session_for(connection, retried)
|
155
|
-
session.http_session.read_timeout = connection.read_timeout
|
156
|
-
response = session.request(*request_args, &block)
|
157
|
-
|
158
|
-
rescue Exception => error
|
159
|
-
|
160
|
-
# close the http session to prevent the connection from being
|
161
|
-
# left open and risk the other side sending data
|
162
|
-
session.finish if session
|
163
|
-
|
164
|
-
# retry socket errors once on a new session
|
165
|
-
if SOCKET_ERRORS.include?(error.class) and !retried
|
166
|
-
retried = true
|
167
|
-
retry
|
168
|
-
end
|
169
|
-
|
170
|
-
raise error
|
171
|
-
|
172
|
-
else
|
173
|
-
@pool_mutex.synchronize { @pool << session }
|
174
|
-
end
|
175
|
-
|
176
|
-
response
|
177
|
-
|
178
|
-
end
|
179
|
-
|
180
144
|
# Returns the number of sessions currently in the pool, not counting those
|
181
145
|
# currently in use.
|
182
146
|
def size
|
183
|
-
@pool_mutex.synchronize { @pool.size }
|
147
|
+
@pool_mutex.synchronize { @pool.size }
|
184
148
|
end
|
185
149
|
|
186
|
-
# Removes stale http sessions from the pool (that have exceeded
|
150
|
+
# Removes stale http sessions from the pool (that have exceeded
|
187
151
|
# the idle timeout).
|
188
152
|
def clean!
|
189
153
|
@pool_mutex.synchronize { _clean }
|
190
154
|
end
|
191
155
|
|
192
|
-
# Closes and removes removes all sessions from the pool.
|
156
|
+
# Closes and removes removes all sessions from the pool.
|
193
157
|
# If empty! is called while there are outstanding requests they may
|
194
158
|
# get checked back into the pool, leaving the pool in a non-empty state.
|
195
159
|
def empty!
|
@@ -199,33 +163,57 @@ class Net::HTTP::ConnectionPool
|
|
199
163
|
end
|
200
164
|
end
|
201
165
|
|
202
|
-
#
|
203
|
-
|
204
|
-
|
166
|
+
# Makes a single HTTP request. See {Connection#request} for more information
|
167
|
+
# on making an HTTP request.
|
168
|
+
# @return [nil]
|
169
|
+
# @private
|
170
|
+
def request connection, *args, &block
|
171
|
+
session_for(connection) do |session|
|
172
|
+
session.read_timeout = connection.read_timeout
|
173
|
+
session.request(*args, &block)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
protected
|
178
|
+
|
179
|
+
# Yields an open http session for the given connection.
|
180
|
+
def session_for connection, &block
|
205
181
|
|
206
182
|
session = nil
|
207
183
|
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
end
|
184
|
+
# search the pool for an idle session that can be used
|
185
|
+
@pool_mutex.synchronize do
|
186
|
+
_clean # removes stale sessions
|
187
|
+
session = @pool.find{|idle_session| idle_session.key == connection.key }
|
188
|
+
@pool.delete(session) if session
|
214
189
|
end
|
215
190
|
|
216
|
-
|
217
|
-
|
218
|
-
session =
|
191
|
+
begin
|
192
|
+
# opens a new HTTP session if no suitable idle session was found
|
193
|
+
session = _create_session(connection) unless session
|
194
|
+
yield(session)
|
195
|
+
rescue Exception => error
|
196
|
+
session.finish if session
|
197
|
+
raise error
|
198
|
+
else
|
199
|
+
# only check the session back into the pool if no errors were raised
|
200
|
+
@pool_mutex.synchronize { @pool << session }
|
219
201
|
end
|
220
202
|
|
221
|
-
|
203
|
+
nil
|
204
|
+
|
205
|
+
end
|
206
|
+
|
207
|
+
def _create_session connection
|
208
|
+
Session.start(connection,
|
209
|
+
:open_timeout => open_timeout,
|
210
|
+
:debug_logger => log_wire_trace? ? logger : nil)
|
222
211
|
end
|
223
212
|
|
224
|
-
private
|
225
213
|
def _clean
|
226
214
|
now = Time.now
|
227
215
|
@pool.delete_if do |idle_session|
|
228
|
-
if
|
216
|
+
if
|
229
217
|
idle_session.last_used_at.nil? or
|
230
218
|
now - idle_session.last_used_at > idle_timeout
|
231
219
|
then
|
@@ -15,17 +15,34 @@ require 'uri'
|
|
15
15
|
|
16
16
|
class Net::HTTP::ConnectionPool
|
17
17
|
|
18
|
-
#
|
18
|
+
# Represents a HTTP connection. Call {#request} on a connection like
|
19
|
+
# you would with a Net::HTTPSession object.
|
19
20
|
#
|
20
|
-
#
|
21
|
-
#
|
21
|
+
# == Getting a Connection object
|
22
|
+
#
|
23
|
+
# To get a connection object, you start with a connection pool:
|
24
|
+
#
|
25
|
+
# pool = Net::HTTP::ConnectionPool.new
|
26
|
+
# connection = pool.connection_for('domain.com')
|
27
|
+
#
|
28
|
+
# {ConnectionPool#connection_for} accepts a number of options to control
|
29
|
+
# the connection settings (SSL, proxy, timeouts, etc).
|
30
|
+
#
|
31
|
+
# == Making Requests
|
32
|
+
#
|
33
|
+
# Given a connection object, you call #request. {Connection#request}
|
34
|
+
# yields Net::HTTPResponse objects (when given a block). You should
|
35
|
+
# read the response (via #body or #read_body) before the end of the
|
36
|
+
# block.
|
37
|
+
#
|
38
|
+
# connection.request(Net::HTTP::Get.new('/')) do |resp|
|
39
|
+
# puts resp.body
|
40
|
+
# end
|
22
41
|
#
|
23
42
|
class Connection
|
24
43
|
|
25
|
-
#
|
26
|
-
# @
|
27
|
-
# @option (see ConnectionPool#connection_for)
|
28
|
-
# @return [Connection]
|
44
|
+
# Use {ConnectionPool#connection_for} to construct {Connection} objects.
|
45
|
+
# @private
|
29
46
|
def initialize pool, host, options = {}
|
30
47
|
|
31
48
|
@pool = pool
|
@@ -96,35 +113,72 @@ class Net::HTTP::ConnectionPool
|
|
96
113
|
# @return [Numeric,nil]
|
97
114
|
attr_accessor :read_timeout
|
98
115
|
|
99
|
-
# @return [Boolean] Returns true if this connection requires SSL.
|
116
|
+
# @return [Boolean] Returns +true+ if this connection requires SSL.
|
100
117
|
def ssl?
|
101
118
|
@ssl
|
102
119
|
end
|
103
120
|
|
104
|
-
# @return [Boolean] Returns true if ssl connections should verify the
|
121
|
+
# @return [Boolean] Returns +true+ if ssl connections should verify the
|
105
122
|
# peer certificate.
|
106
123
|
def ssl_verify_peer?
|
107
124
|
@ssl_verify_peer
|
108
125
|
end
|
109
126
|
|
110
|
-
# @return [Boolean] Returns true if this connection proxies requests.
|
127
|
+
# @return [Boolean] Returns +true+ if this connection proxies requests.
|
111
128
|
def proxy?
|
112
129
|
!!proxy_address
|
113
130
|
end
|
114
131
|
|
115
|
-
# Makes a HTTP request.
|
116
|
-
#
|
117
|
-
#
|
132
|
+
# Makes a single HTTP request. The Net::HTTPResponse is yielded to the
|
133
|
+
# given block.
|
134
|
+
#
|
135
|
+
# pool = Net::HTTP::ConnectionPool.new
|
136
|
+
# connection = pool.connection_for('www.google.com')
|
137
|
+
#
|
138
|
+
# connection.request(Net::HTTP::Get.new('/')) do |response|
|
139
|
+
# # yeilds a Net::HTTPResponse object
|
140
|
+
# puts "STATUS CODE: #{response.code}"
|
141
|
+
# puts "HEADERS: #{response.to_hash.inspect}"
|
142
|
+
# puts "BODY:\n#{response.body}"
|
143
|
+
# end
|
144
|
+
#
|
145
|
+
# If you want to read the HTTP response body in chunks (useful for
|
146
|
+
# large responses you do not want to load into memory), you should
|
147
|
+
# pass a block to the #read_body method of the yielded response.
|
148
|
+
#
|
149
|
+
# File.open('output.txt', 'w') do |file|
|
150
|
+
# connection.request(Net::HTTP::Get.new('/')) do |response|
|
151
|
+
# response.read_body do |chunk|
|
152
|
+
# file.write(chunk)
|
153
|
+
# end
|
154
|
+
# end
|
155
|
+
# end
|
156
|
+
#
|
157
|
+
# If you omit the block when calling #request, you will not be able
|
158
|
+
# to read the response. This method never returns the
|
159
|
+
# Net::HTTPResponse generated.
|
160
|
+
#
|
161
|
+
# This method passes *args to Net::HTTPSession#request. See the
|
162
|
+
# Ruby standard lib documentation for more documentation about
|
163
|
+
# accepted arguments.
|
164
|
+
#
|
165
|
+
# @note You should read the yielded response object before the end
|
166
|
+
# of the passed block. Do no save a reference to yielded response
|
167
|
+
# objects.
|
168
|
+
#
|
169
|
+
# @yield [response]
|
170
|
+
# @yieldparam [Net::HTTPResponse] response
|
171
|
+
# @return [nil]
|
118
172
|
def request *args, &block
|
119
173
|
pool.request(self, *args, &block)
|
120
174
|
end
|
121
175
|
|
122
176
|
# @return [String] Returns a key that can be used to group connections
|
123
|
-
# that
|
177
|
+
# that may share the same HTTP sessions.
|
124
178
|
def key
|
125
179
|
@key ||= begin
|
126
180
|
%w(
|
127
|
-
host port
|
181
|
+
host port
|
128
182
|
ssl ssl_verify_peer ssl_ca_file ssl_ca_path
|
129
183
|
proxy_address proxy_port proxy_user proxy_password
|
130
184
|
).map{|part| send(part).to_s }.join(":")
|
@@ -17,9 +17,13 @@ require 'openssl'
|
|
17
17
|
|
18
18
|
class Net::HTTP::ConnectionPool
|
19
19
|
|
20
|
+
# Used by Net::HTTP::ConnectionPool to wrap Net::HTTP::Session objects.
|
21
|
+
# Users should never need to interact with these session wrappers.
|
20
22
|
# @private
|
21
23
|
class Session
|
22
24
|
|
25
|
+
# @param [Net::HTTPSession] http_session
|
26
|
+
# @param [String] key
|
23
27
|
def initialize http_session, key
|
24
28
|
@http_session = http_session
|
25
29
|
@key = key
|
@@ -27,20 +31,42 @@ class Net::HTTP::ConnectionPool
|
|
27
31
|
@last_used_at = nil
|
28
32
|
end
|
29
33
|
|
34
|
+
# @return [Net::HTTPSession]
|
30
35
|
attr_reader :http_session
|
31
36
|
|
37
|
+
# @return [String]
|
32
38
|
attr_reader :key
|
33
39
|
|
40
|
+
# @return [Time]
|
34
41
|
attr_reader :created_at
|
35
42
|
|
43
|
+
# @return [Time]
|
36
44
|
attr_reader :last_used_at
|
37
45
|
|
46
|
+
# @param [Integer] timeout Number of seconds before Net::HTTP should
|
47
|
+
# timeout while waiting to read a response.
|
48
|
+
def read_timeout= timeout
|
49
|
+
http_session.read_timeout = timeout
|
50
|
+
end
|
51
|
+
|
52
|
+
# Makes a HTTP request. See Net::HTTPSession#request documentation
|
53
|
+
# from the Ruby standard library for information about argments.
|
54
|
+
#
|
55
|
+
# connection.request(Net::HTTP::Get.new('/')) do |response|
|
56
|
+
# # Parse the response (status, headers and body) here.
|
57
|
+
# # You should be done with the response by the end of the block.
|
58
|
+
# end
|
59
|
+
#
|
60
|
+
# @yield [response]
|
61
|
+
# @yieldparam [Net::HTTPResponse] response
|
62
|
+
# @return [nil]
|
38
63
|
def request *args, &block
|
39
|
-
|
64
|
+
http_session.request(*args, &block)
|
40
65
|
@last_used_at = Time.now
|
41
|
-
|
66
|
+
nil
|
42
67
|
end
|
43
68
|
|
69
|
+
# Attempts to cleanly close the HTTP session.
|
44
70
|
# @return [nil]
|
45
71
|
def finish
|
46
72
|
begin
|
@@ -52,7 +78,15 @@ class Net::HTTP::ConnectionPool
|
|
52
78
|
|
53
79
|
class << self
|
54
80
|
|
55
|
-
|
81
|
+
# Starts a new HTTP session and returns it wrapped in a {Session} object.
|
82
|
+
# @param [Connection] connection
|
83
|
+
# @param [Hash] options
|
84
|
+
# @option options [Integer] :open_timeout (15) The number of seconds to
|
85
|
+
# wait while trying to open the HTTP session before timeing out.
|
86
|
+
# @option options [Logger] :debug_logger HTTP wire traces are logged
|
87
|
+
# here when specified.
|
88
|
+
# @return [Session]
|
89
|
+
def start connection, options = {}
|
56
90
|
|
57
91
|
http_args = []
|
58
92
|
http_args << connection.host
|
@@ -65,8 +99,8 @@ class Net::HTTP::ConnectionPool
|
|
65
99
|
end
|
66
100
|
|
67
101
|
http = Net::HTTP.new(*http_args)
|
68
|
-
http.set_debug_output(debug_logger)
|
69
|
-
http.open_timeout = open_timeout
|
102
|
+
http.set_debug_output(options[:debug_logger]) if options[:debug_logger]
|
103
|
+
http.open_timeout = options[:open_timeout] || 15
|
70
104
|
|
71
105
|
if connection.ssl?
|
72
106
|
http.use_ssl = true
|
@@ -88,6 +122,5 @@ class Net::HTTP::ConnectionPool
|
|
88
122
|
end
|
89
123
|
|
90
124
|
end
|
91
|
-
|
92
125
|
end
|
93
126
|
end
|