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.
@@ -13,7 +13,6 @@
13
13
 
14
14
  module AWS
15
15
  class SimpleEmailService
16
-
17
16
  # @private
18
17
  class Request < Core::Http::Request
19
18
 
@@ -24,6 +23,5 @@ module AWS
24
23
  end
25
24
 
26
25
  end
27
-
28
26
  end
29
27
  end
@@ -19,9 +19,6 @@ module AWS
19
19
 
20
20
  include Core::Signature::Version3
21
21
 
22
- # @return [String,nil]
23
- attr_accessor :body
24
-
25
22
  def read_timeout
26
23
  # increase read timeout for long polling
27
24
  if headers['x-amz-target'] =~ /PollFor(Decision|Activity)Task/
@@ -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. Every time you call request on a connection
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
- # Returns a suitable session from the pool or creates a new one
203
- private
204
- def session_for connection, force_new = false
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
- unless force_new
209
- @pool_mutex.synchronize do
210
- _clean
211
- session = @pool.find{|idle_session| idle_session.key == connection.key }
212
- @pool.delete(session) if session
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
- if session.nil?
217
- logger = http_wire_trace? ? self.logger : nil
218
- session = Session.for(connection, open_timeout, logger)
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
- session
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
- # A light wrapper around Net::HTTP.
18
+ # Represents a HTTP connection. Call {#request} on a connection like
19
+ # you would with a Net::HTTPSession object.
19
20
  #
20
- # You should not need to construct connection objects yourself.
21
- # You receive them as a response to {ConnectionPool#connection_for}.
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
- # @param [ConnectionPool] pool
26
- # @param (see ConnectionPool#connection_for)
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. See Net::HTTPSession#request documentation
116
- # from the Ruby standard library for information about argments.
117
- # @return [Net::HTTPResponse]
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 connection to the same host.
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
- response = http_session.request(*args, &block)
64
+ http_session.request(*args, &block)
40
65
  @last_used_at = Time.now
41
- response
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
- def for connection, open_timeout, debug_logger = nil
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