aws-sdk 1.6.2 → 1.6.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|