Skip to content
This repository
Newer
Older
100644 959 lines (829 sloc) 23.621 kb
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
1 # HTTPClient - HTTP client library.
5fb44368 » nahi
2009-01-08 * Security fix introduced at 2.1.3.
2 # Copyright (C) 2000-2009 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
c6d461b8 » nahi
2008-12-28 * added RDoc for httpclient/connection.rb. see #162.
3 #
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
4 # This program is copyrighted free software by NAKAMURA, Hiroshi. You can
5 # redistribute it and/or modify it under the same terms of Ruby's license;
6 # either the dual license version in 2003, or any later version.
7
8 # httpclient/session.rb is based on http-access.rb in http-access/0.0.4.
9 # Some part of code in http-access.rb was recycled in httpclient.rb.
10 # Those part is copyrighted by Maehashi-san.
11
12
13 require 'socket'
14 require 'thread'
15 require 'stringio'
95964f13 »
2010-12-12 Added transparent_gzip_decompression property. closes #42.
16 require 'zlib'
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
17
12581c4c » nahi
2008-12-12 * added original timeout.rb. see #191.
18 require 'httpclient/timeout'
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
19 require 'httpclient/ssl_config'
20 require 'httpclient/http'
21
22
23 class HTTPClient
24
25
288f58b7 » nahi
2008-12-29 * added RDocs for util, http, auth, ssl_config and timeout. closes #162
26 # Represents a Site: protocol scheme, host String and port Number.
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
27 class Site
288f58b7 » nahi
2008-12-29 * added RDocs for util, http, auth, ssl_config and timeout. closes #162
28 # Protocol scheme.
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
29 attr_accessor :scheme
288f58b7 » nahi
2008-12-29 * added RDocs for util, http, auth, ssl_config and timeout. closes #162
30 # Host String.
c9b5f3e1 »
2011-02-18 Rename 'local_bind' to 'socket_local'
31 attr_accessor :host
288f58b7 » nahi
2008-12-29 * added RDocs for util, http, auth, ssl_config and timeout. closes #162
32 # Port number.
c9b5f3e1 »
2011-02-18 Rename 'local_bind' to 'socket_local'
33 attr_accessor :port
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
34
288f58b7 » nahi
2008-12-29 * added RDocs for util, http, auth, ssl_config and timeout. closes #162
35 # Creates a new Site based on the given URI.
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
36 def initialize(uri = nil)
37 if uri
38 @scheme = uri.scheme
39 @host = uri.host
40 @port = uri.port.to_i
41 else
42 @scheme = 'tcp'
43 @host = '0.0.0.0'
44 @port = 0
45 end
46 end
47
288f58b7 » nahi
2008-12-29 * added RDocs for util, http, auth, ssl_config and timeout. closes #162
48 # Returns address String.
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
49 def addr
50 "#{@scheme}://#{@host}:#{@port.to_s}"
51 end
52
288f58b7 » nahi
2008-12-29 * added RDocs for util, http, auth, ssl_config and timeout. closes #162
53 # Returns true is scheme, host and port are '=='
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
54 def ==(rhs)
17cbbf98 » nahi
2008-12-15 * refactoring around proxy handling. reduces created Objects. see #191.
55 (@scheme == rhs.scheme) and (@host == rhs.host) and (@port == rhs.port)
4fc7a2bd » nahi
2008-12-12 * added tests for coverage. closes #189.
56 end
57
288f58b7 » nahi
2008-12-29 * added RDocs for util, http, auth, ssl_config and timeout. closes #162
58 # Same as ==.
4fc7a2bd » nahi
2008-12-12 * added tests for coverage. closes #189.
59 def eql?(rhs)
60 self == rhs
61 end
62
288f58b7 » nahi
2008-12-29 * added RDocs for util, http, auth, ssl_config and timeout. closes #162
63 def hash # :nodoc:
4fc7a2bd » nahi
2008-12-12 * added tests for coverage. closes #189.
64 [@scheme, @host, @port].hash
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
65 end
66
288f58b7 » nahi
2008-12-29 * added RDocs for util, http, auth, ssl_config and timeout. closes #162
67 def to_s # :nodoc:
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
68 addr
69 end
17cbbf98 » nahi
2008-12-15 * refactoring around proxy handling. reduces created Objects. see #191.
70
288f58b7 » nahi
2008-12-29 * added RDocs for util, http, auth, ssl_config and timeout. closes #162
71 # Returns true if scheme, host and port of the given URI matches with this.
17cbbf98 » nahi
2008-12-15 * refactoring around proxy handling. reduces created Objects. see #191.
72 def match(uri)
73 (@scheme == uri.scheme) and (@host == uri.host) and (@port == uri.port.to_i)
74 end
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
75
288f58b7 » nahi
2008-12-29 * added RDocs for util, http, auth, ssl_config and timeout. closes #162
76 def inspect # :nodoc:
77 sprintf("#<%s:0x%x %s>", self.class.name, __id__, addr)
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
78 end
d64b7bd2 »
2011-03-23 Use @socket_local iif user specified it.
79
80 EMPTY = Site.new.freeze
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
81 end
82
83
288f58b7 » nahi
2008-12-29 * added RDocs for util, http, auth, ssl_config and timeout. closes #162
84 # Manages sessions for a HTTPClient instance.
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
85 class SessionManager
288f58b7 » nahi
2008-12-29 * added RDocs for util, http, auth, ssl_config and timeout. closes #162
86 # Name of this client. Used for 'User-Agent' header in HTTP request.
87 attr_accessor :agent_name
88 # Owner of this client. Used for 'From' header in HTTP request.
89 attr_accessor :from
90
91 # Requested protocol version
92 attr_accessor :protocol_version
93 # Chunk size for chunked request
94 attr_accessor :chunk_size
95 # Device for dumping log for debugging
96 attr_accessor :debug_dev
97 # Boolean value for Socket#sync
98 attr_accessor :socket_sync
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
99
100 attr_accessor :connect_timeout
288f58b7 » nahi
2008-12-29 * added RDocs for util, http, auth, ssl_config and timeout. closes #162
101 # Maximum retry count. 0 for infinite.
102 attr_accessor :connect_retry
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
103 attr_accessor :send_timeout
104 attr_accessor :receive_timeout
105 attr_accessor :read_block_size
3f2a9965 » nahi
2008-12-19 * tested proxy + SSL against squid.
106 attr_accessor :protocol_retry_count
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
107
c9b5f3e1 »
2011-02-18 Rename 'local_bind' to 'socket_local'
108 # Local address to bind local side of the socket to
109 attr_accessor :socket_local
02975550 » icblenke
2009-11-03 Adding local_sockaddr
110
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
111 attr_accessor :ssl_config
112
113 attr_reader :test_loopback_http_response
114
95964f13 »
2010-12-12 Added transparent_gzip_decompression property. closes #42.
115 attr_accessor :transparent_gzip_decompression
116
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
117 def initialize(client)
118 @client = client
33b4eaba » nahi
2009-02-07 * let SessionManager inherit proxy and debug_dev setting from client…
119 @proxy = client.proxy
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
120
121 @agent_name = nil
122 @from = nil
123
124 @protocol_version = nil
33b4eaba » nahi
2009-02-07 * let SessionManager inherit proxy and debug_dev setting from client…
125 @debug_dev = client.debug_dev
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
126 @socket_sync = true
127 @chunk_size = 4096
128
129 @connect_timeout = 60
130 @connect_retry = 1
131 @send_timeout = 120
132 @receive_timeout = 60 # For each read_block_size bytes
7a3a73f9 » nahi
2008-12-12 * changed read buf size: 8k -> 16k. just follows net/http. see #191.
133 @read_block_size = 1024 * 16 # follows net/http change in 1.8.7
3f2a9965 » nahi
2008-12-19 * tested proxy + SSL against squid.
134 @protocol_retry_count = 5
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
135
136 @ssl_config = nil
137 @test_loopback_http_response = []
138
95964f13 »
2010-12-12 Added transparent_gzip_decompression property. closes #42.
139 @transparent_gzip_decompression = false
c9b5f3e1 »
2011-02-18 Rename 'local_bind' to 'socket_local'
140 @socket_local = Site.new
02975550 » icblenke
2009-11-03 Adding local_sockaddr
141
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
142 @sess_pool = []
143 @sess_pool_mutex = Mutex.new
144 end
145
17cbbf98 » nahi
2008-12-15 * refactoring around proxy handling. reduces created Objects. see #191.
146 def proxy=(proxy)
147 if proxy.nil?
148 @proxy = nil
149 else
150 @proxy = Site.new(proxy)
151 end
152 end
153
154 def query(req, via_proxy)
3050bdef »
2011-04-03 Add shortcut methods.
155 req.http_body.chunk_size = @chunk_size
17cbbf98 » nahi
2008-12-15 * refactoring around proxy handling. reduces created Objects. see #191.
156 sess = open(req.header.request_uri, via_proxy)
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
157 begin
158 sess.query(req)
159 rescue
160 sess.close
161 raise
162 end
163 sess
164 end
165
166 def reset(uri)
167 site = Site.new(uri)
168 close(site)
169 end
170
171 def reset_all
172 close_all
173 end
174
175 def keep(sess)
176 add_cached_session(sess)
177 end
178
a620b5f5 »
2010-12-15 Invalidate pooled sessions for the same destination when we got a Kee…
179 def invalidate(site)
180 @sess_pool_mutex.synchronize do
181 @sess_pool.each do |sess|
182 if sess.dest == site
183 sess.invalidate
184 end
185 end
186 end
187 end
188
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
189 private
190
17cbbf98 » nahi
2008-12-15 * refactoring around proxy handling. reduces created Objects. see #191.
191 def open(uri, via_proxy = false)
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
192 sess = nil
17cbbf98 » nahi
2008-12-15 * refactoring around proxy handling. reduces created Objects. see #191.
193 if cached = get_cached_session(uri)
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
194 sess = cached
195 else
17cbbf98 » nahi
2008-12-15 * refactoring around proxy handling. reduces created Objects. see #191.
196 sess = Session.new(@client, Site.new(uri), @agent_name, @from)
197 sess.proxy = via_proxy ? @proxy : nil
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
198 sess.socket_sync = @socket_sync
199 sess.requested_version = @protocol_version if @protocol_version
200 sess.connect_timeout = @connect_timeout
201 sess.connect_retry = @connect_retry
202 sess.send_timeout = @send_timeout
203 sess.receive_timeout = @receive_timeout
204 sess.read_block_size = @read_block_size
3f2a9965 » nahi
2008-12-19 * tested proxy + SSL against squid.
205 sess.protocol_retry_count = @protocol_retry_count
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
206 sess.ssl_config = @ssl_config
207 sess.debug_dev = @debug_dev
c9b5f3e1 »
2011-02-18 Rename 'local_bind' to 'socket_local'
208 sess.socket_local = @socket_local
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
209 sess.test_loopback_http_response = @test_loopback_http_response
95964f13 »
2010-12-12 Added transparent_gzip_decompression property. closes #42.
210 sess.transparent_gzip_decompression = @transparent_gzip_decompression
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
211 end
212 sess
213 end
214
215 def close_all
e3c1331f » nahi
2008-12-25 * a few performance improvements. see #191.
216 @sess_pool_mutex.synchronize do
217 @sess_pool.each do |sess|
218 sess.close
219 end
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
220 end
221 @sess_pool.clear
222 end
223
9ada5374 »
2010-12-20 Make Keep-Alive test use threads properly.
224 # This method might not work as you expected...
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
225 def close(dest)
226 if cached = get_cached_session(dest)
227 cached.close
228 true
229 else
230 false
231 end
232 end
233
17cbbf98 » nahi
2008-12-15 * refactoring around proxy handling. reduces created Objects. see #191.
234 def get_cached_session(uri)
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
235 cached = nil
236 @sess_pool_mutex.synchronize do
237 new_pool = []
238 @sess_pool.each do |s|
a620b5f5 »
2010-12-15 Invalidate pooled sessions for the same destination when we got a Kee…
239 if s.invalidated?
240 s.close # close & remove from the pool
241 elsif !cached && s.dest.match(uri)
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
242 cached = s
243 else
244 new_pool << s
245 end
246 end
247 @sess_pool = new_pool
248 end
249 cached
250 end
251
252 def add_cached_session(sess)
253 @sess_pool_mutex.synchronize do
254 @sess_pool << sess
255 end
256 end
257 end
258
259
288f58b7 » nahi
2008-12-29 * added RDocs for util, http, auth, ssl_config and timeout. closes #162
260 # Wraps up OpenSSL::SSL::SSLSocket and offers debugging features.
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
261 class SSLSocketWrap
262 def initialize(socket, context, debug_dev = nil)
263 unless SSLEnabled
e3ae9e21 » nahi
2008-12-12 * version: 2.1.2 -> 2.1.3-SNAPSHOT
264 raise ConfigurationError.new('Ruby/OpenSSL module is required')
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
265 end
266 @context = context
267 @socket = socket
4fc7a2bd » nahi
2008-12-12 * added tests for coverage. closes #189.
268 @ssl_socket = create_openssl_socket(@socket)
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
269 @debug_dev = debug_dev
270 end
271
a65bbbd4 »
2011-01-11 Added SNI support. see #49.
272 def ssl_connect(hostname = nil)
273 if hostname && @ssl_socket.respond_to?(:hostname=)
274 @ssl_socket.hostname = hostname
275 end
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
276 @ssl_socket.connect
277 end
278
279 def post_connection_check(host)
280 verify_mode = @context.verify_mode || OpenSSL::SSL::VERIFY_NONE
281 if verify_mode == OpenSSL::SSL::VERIFY_NONE
282 return
283 elsif @ssl_socket.peer_cert.nil? and
284 check_mask(verify_mode, OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT)
e3ae9e21 » nahi
2008-12-12 * version: 2.1.2 -> 2.1.3-SNAPSHOT
285 raise OpenSSL::SSL::SSLError.new('no peer cert')
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
286 end
287 hostname = host.host
288 if @ssl_socket.respond_to?(:post_connection_check) and RUBY_VERSION > "1.8.4"
289 @ssl_socket.post_connection_check(hostname)
290 else
291 @context.post_connection_check(@ssl_socket.peer_cert, hostname)
292 end
293 end
294
295 def peer_cert
296 @ssl_socket.peer_cert
297 end
298
299 def close
300 @ssl_socket.close
301 @socket.close
302 end
303
304 def closed?
305 @socket.closed?
306 end
307
308 def eof?
309 @ssl_socket.eof?
310 end
311
312 def gets(*args)
313 str = @ssl_socket.gets(*args)
a176e7b4 » nahi
2008-12-22 * check test coverage on lib/httpclient/session.rb. see #189.
314 debug(str)
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
315 str
316 end
317
318 def read(*args)
319 str = @ssl_socket.read(*args)
a176e7b4 » nahi
2008-12-22 * check test coverage on lib/httpclient/session.rb. see #189.
320 debug(str)
321 str
322 end
323
324 def readpartial(*args)
325 str = @ssl_socket.readpartial(*args)
326 debug(str)
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
327 str
328 end
329
330 def <<(str)
331 rv = @ssl_socket.write(str)
a176e7b4 » nahi
2008-12-22 * check test coverage on lib/httpclient/session.rb. see #189.
332 debug(str)
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
333 rv
334 end
335
336 def flush
337 @ssl_socket.flush
338 end
339
340 def sync
341 @ssl_socket.sync
342 end
343
344 def sync=(sync)
345 @ssl_socket.sync = sync
346 end
347
348 private
349
350 def check_mask(value, mask)
351 value & mask == mask
352 end
353
4fc7a2bd » nahi
2008-12-12 * added tests for coverage. closes #189.
354 def create_openssl_socket(socket)
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
355 ssl_socket = nil
356 if OpenSSL::SSL.const_defined?("SSLContext")
357 ctx = OpenSSL::SSL::SSLContext.new
358 @context.set_context(ctx)
359 ssl_socket = OpenSSL::SSL::SSLSocket.new(socket, ctx)
360 else
361 ssl_socket = OpenSSL::SSL::SSLSocket.new(socket)
362 @context.set_context(ssl_socket)
363 end
364 ssl_socket
365 end
a176e7b4 » nahi
2008-12-22 * check test coverage on lib/httpclient/session.rb. see #189.
366
367 def debug(str)
368 @debug_dev << str if @debug_dev && str
369 end
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
370 end
371
372
288f58b7 » nahi
2008-12-29 * added RDocs for util, http, auth, ssl_config and timeout. closes #162
373 # Wraps up a Socket for method interception.
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
374 module SocketWrap
375 def initialize(socket, *args)
376 super(*args)
377 @socket = socket
378 end
379
380 def close
381 @socket.close
382 end
383
384 def closed?
385 @socket.closed?
386 end
387
388 def eof?
389 @socket.eof?
390 end
391
392 def gets(*args)
393 @socket.gets(*args)
394 end
395
396 def read(*args)
397 @socket.read(*args)
398 end
399
a176e7b4 » nahi
2008-12-22 * check test coverage on lib/httpclient/session.rb. see #189.
400 def readpartial(*args)
401 # StringIO doesn't support :readpartial
402 if @socket.respond_to?(:readpartial)
403 @socket.readpartial(*args)
404 else
405 @socket.read(*args)
406 end
407 end
408
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
409 def <<(str)
410 @socket << str
411 end
412
413 def flush
414 @socket.flush
415 end
416
417 def sync
418 @socket.sync
419 end
420
421 def sync=(sync)
422 @socket.sync = sync
423 end
424 end
425
426
288f58b7 » nahi
2008-12-29 * added RDocs for util, http, auth, ssl_config and timeout. closes #162
427 # Module for intercepting Socket methods and dumps in/out to given debugging
428 # device. debug_dev must respond to <<.
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
429 module DebugSocket
430 extend SocketWrap
431
432 def debug_dev=(debug_dev)
433 @debug_dev = debug_dev
434 end
435
436 def close
437 super
438 debug("! CONNECTION CLOSED\n")
439 end
440
441 def gets(*args)
442 str = super
443 debug(str)
444 str
445 end
446
447 def read(*args)
448 str = super
449 debug(str)
450 str
451 end
452
a176e7b4 » nahi
2008-12-22 * check test coverage on lib/httpclient/session.rb. see #189.
453 def readpartial(*args)
454 str = super
455 debug(str)
456 str
457 end
458
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
459 def <<(str)
460 super
461 debug(str)
462 end
463
464 private
465
466 def debug(str)
cfc2abca » chetan
2010-09-07 when debugging, don't dump binary data; display message instead
467 if str && @debug_dev
d5f00101 »
2010-12-12 Additional change for the previous commit; do hexdump if a content lo…
468 if str.index("\0")
469 require 'hexdump'
470 str.force_encoding('BINARY') if str.respond_to?(:force_encoding)
471 @debug_dev << HexDump.encode(str).join("\n")
cfc2abca » chetan
2010-09-07 when debugging, don't dump binary data; display message instead
472 else
473 @debug_dev << str
474 end
475 end
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
476 end
477 end
478
479
288f58b7 » nahi
2008-12-29 * added RDocs for util, http, auth, ssl_config and timeout. closes #162
480 # Dummy Socket for emulating loopback test.
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
481 class LoopBackSocket
482 include SocketWrap
483
484 def initialize(host, port, response)
350acc3f » nahi
2009-05-13 * applied a patch from user. IO#readpartial does not clear the secon…
485 super(response.is_a?(StringIO) ? response : StringIO.new(response))
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
486 @host = host
487 @port = port
488 end
489
490 def <<(str)
491 # ignored
492 end
493 end
494
495
288f58b7 » nahi
2008-12-29 * added RDocs for util, http, auth, ssl_config and timeout. closes #162
496 # Manages a HTTP session with a Site.
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
497 class Session
7936c390 » nahi
2008-12-12 * do not override original timeout. just use it in HTTPClient::Sessi…
498 include HTTPClient::Timeout
9a079a1a »
2010-12-12 Use absolute URI iif via proxy AND not HTTPS. closes #41.
499 include Util
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
500
288f58b7 » nahi
2008-12-29 * added RDocs for util, http, auth, ssl_config and timeout. closes #162
501 # Destination site
502 attr_reader :dest
503 # Proxy site
504 attr_accessor :proxy
505 # Boolean value for Socket#sync
506 attr_accessor :socket_sync
507 # Requested protocol version
508 attr_accessor :requested_version
509 # Device for dumping log for debugging
510 attr_accessor :debug_dev
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
511
512 attr_accessor :connect_timeout
513 attr_accessor :connect_retry
514 attr_accessor :send_timeout
515 attr_accessor :receive_timeout
516 attr_accessor :read_block_size
3f2a9965 » nahi
2008-12-19 * tested proxy + SSL against squid.
517 attr_accessor :protocol_retry_count
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
518
c9b5f3e1 »
2011-02-18 Rename 'local_bind' to 'socket_local'
519 attr_accessor :socket_local
02975550 » icblenke
2009-11-03 Adding local_sockaddr
520
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
521 attr_accessor :ssl_config
522 attr_reader :ssl_peer_cert
523 attr_accessor :test_loopback_http_response
524
95964f13 »
2010-12-12 Added transparent_gzip_decompression property. closes #42.
525 attr_accessor :transparent_gzip_decompression
526
2253f959 » nahi
2008-12-19 * test coverage checked. see #189.
527 def initialize(client, dest, agent_name, from)
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
528 @client = client
529 @dest = dest
a620b5f5 »
2010-12-15 Invalidate pooled sessions for the same destination when we got a Kee…
530 @invalidated = false
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
531 @proxy = nil
532 @socket_sync = true
533 @requested_version = nil
534
535 @debug_dev = nil
536
537 @connect_timeout = nil
538 @connect_retry = 1
539 @send_timeout = nil
540 @receive_timeout = nil
541 @read_block_size = nil
3f2a9965 » nahi
2008-12-19 * tested proxy + SSL against squid.
542 @protocol_retry_count = 5
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
543
544 @ssl_config = nil
545 @ssl_peer_cert = nil
546
547 @test_loopback_http_response = nil
c9b5f3e1 »
2011-02-18 Rename 'local_bind' to 'socket_local'
548 @socket_local = Site::EMPTY
02975550 » icblenke
2009-11-03 Adding local_sockaddr
549
2253f959 » nahi
2008-12-19 * test coverage checked. see #189.
550 @agent_name = agent_name
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
551 @from = from
552 @state = :INIT
553
554 @requests = []
555
556 @status = nil
557 @reason = nil
558 @headers = []
559
560 @socket = nil
a176e7b4 » nahi
2008-12-22 * check test coverage on lib/httpclient/session.rb. see #189.
561 @readbuf = nil
95964f13 »
2010-12-12 Added transparent_gzip_decompression property. closes #42.
562
563 @transparent_gzip_decompression = false
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
564 end
565
566 # Send a request to the server
567 def query(req)
4fc7a2bd » nahi
2008-12-12 * added tests for coverage. closes #189.
568 connect if @state == :INIT
9a079a1a »
2010-12-12 Use absolute URI iif via proxy AND not HTTPS. closes #41.
569 # Use absolute URI (not absolute path) iif via proxy AND not HTTPS.
570 req.header.request_absolute_uri = !@proxy.nil? and !https?(@dest)
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
571 begin
e77f3e06 » nahi
2008-12-18 * easier file upload: add Content-Type: multipart/form-data when the…
572 timeout(@send_timeout, SendTimeoutError) do
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
573 set_header(req)
574 req.dump(@socket)
575 # flush the IO stream as IO::sync mode is false
576 @socket.flush unless @socket_sync
577 end
2cd33855 »
2011-03-22 rescue IOError for rather old JRuby versions.
578 rescue Errno::ECONNABORTED, Errno::ECONNRESET, Errno::EPIPE, IOError
3ec4757f »
2010-04-02 JRuby exception support: see #25.
579 # JRuby can raise IOError instead of ECONNRESET for now
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
580 close
a620b5f5 »
2010-12-15 Invalidate pooled sessions for the same destination when we got a Kee…
581 raise KeepAliveDisconnected.new(self)
2253f959 » nahi
2008-12-19 * test coverage checked. see #189.
582 rescue HTTPClient::TimeoutError
583 close
584 raise
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
585 rescue
a620b5f5 »
2010-12-15 Invalidate pooled sessions for the same destination when we got a Kee…
586 close
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
587 if SSLEnabled and $!.is_a?(OpenSSL::SSL::SSLError)
a620b5f5 »
2010-12-15 Invalidate pooled sessions for the same destination when we got a Kee…
588 raise KeepAliveDisconnected.new(self)
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
589 else
590 raise
591 end
592 end
593
594 @state = :META if @state == :WAIT
595 @next_connection = nil
596 @requests.push(req)
597 end
598
599 def close
600 if !@socket.nil? and !@socket.closed?
601 # @socket.flush may block when it the socket is already closed by
602 # foreign host and the client runs under MT-condition.
603 @socket.close
604 end
605 @state = :INIT
606 end
607
608 def closed?
609 @state == :INIT
610 end
611
a620b5f5 »
2010-12-15 Invalidate pooled sessions for the same destination when we got a Kee…
612 def invalidate
613 @invalidated = true
614 end
615
616 def invalidated?
617 @invalidated
618 end
619
a176e7b4 » nahi
2008-12-22 * check test coverage on lib/httpclient/session.rb. see #189.
620 def get_header
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
621 begin
622 if @state != :META
288f58b7 » nahi
2008-12-29 * added RDocs for util, http, auth, ssl_config and timeout. closes #162
623 raise RuntimeError.new("get_status must be called at the beginning of a session")
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
624 end
a176e7b4 » nahi
2008-12-22 * check test coverage on lib/httpclient/session.rb. see #189.
625 read_header
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
626 rescue
627 close
628 raise
629 end
a176e7b4 » nahi
2008-12-22 * check test coverage on lib/httpclient/session.rb. see #189.
630 [@version, @status, @reason, @headers]
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
631 end
632
633 def eof?
634 if !@content_length.nil?
635 @content_length == 0
636 else
637 @socket.closed? or @socket.eof?
638 end
639 end
640
a176e7b4 » nahi
2008-12-22 * check test coverage on lib/httpclient/session.rb. see #189.
641 def get_body(&block)
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
642 begin
4fc7a2bd » nahi
2008-12-12 * added tests for coverage. closes #189.
643 read_header if @state == :META
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
644 return nil if @state != :DATA
95964f13 »
2010-12-12 Added transparent_gzip_decompression property. closes #42.
645 if @gzipped and @transparent_gzip_decompression
646 # zlib itself has a functionality to decompress gzip stream.
647 # - zlib 1.2.5 Manual
648 # http://www.zlib.net/manual.html#Advanced
649 # > windowBits can also be greater than 15 for optional gzip decoding. Add 32 to
650 # > windowBits to enable zlib and gzip decoding with automatic header detection,
651 # > or add 16 to decode only the gzip format
652 inflate_stream = Zlib::Inflate.new(Zlib::MAX_WBITS + 32)
653 original_block = block
654 block = Proc.new { |buf|
655 original_block.call(inflate_stream.inflate(buf))
656 }
657 end
a176e7b4 » nahi
2008-12-22 * check test coverage on lib/httpclient/session.rb. see #189.
658 if @chunked
659 read_body_chunked(&block)
660 elsif @content_length
661 read_body_length(&block)
662 else
663 read_body_rest(&block)
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
664 end
665 rescue
666 close
667 raise
668 end
669 if eof?
670 if @next_connection
671 @state = :WAIT
672 else
673 close
674 end
675 end
e77f3e06 » nahi
2008-12-18 * easier file upload: add Content-Type: multipart/form-data when the…
676 nil
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
677 end
678
679 private
680
681 def set_header(req)
b4523c39 » nahi
2008-12-15 * performance improvements especially on HTTP::Message. see #191.
682 if @requested_version
683 if /^(?:HTTP\/|)(\d+.\d+)$/ =~ @requested_version
19499386 »
2010-12-12 Do not depend on Float#to_s behavior. closes #36.
684 req.http_version = $1
b4523c39 » nahi
2008-12-15 * performance improvements especially on HTTP::Message. see #191.
685 end
686 end
2253f959 » nahi
2008-12-19 * test coverage checked. see #189.
687 if @agent_name
688 req.header.set('User-Agent', "#{@agent_name} #{LIB_NAME}")
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
689 end
690 if @from
691 req.header.set('From', @from)
692 end
95964f13 »
2010-12-12 Added transparent_gzip_decompression property. closes #42.
693 if @transparent_gzip_decompression
694 req.header.set('Accept-Encoding', 'gzip,deflate')
695 end
c6d461b8 » nahi
2008-12-28 * added RDoc for httpclient/connection.rb. see #162.
696 req.header.set('Date', Time.now.httpdate)
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
697 end
698
699 # Connect to the server
700 def connect
701 site = @proxy || @dest
702 retry_number = 0
703 begin
e77f3e06 » nahi
2008-12-18 * easier file upload: add Content-Type: multipart/form-data when the…
704 timeout(@connect_timeout, ConnectTimeoutError) do
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
705 @socket = create_socket(site)
9a079a1a »
2010-12-12 Use absolute URI iif via proxy AND not HTTPS. closes #41.
706 if https?(@dest)
ac0fa203 » nahi
2008-12-19 * added a test for CONNECT proxy auth.
707 if @socket.is_a?(LoopBackSocket)
708 connect_ssl_proxy(@socket, URI.parse(@dest.to_s)) if @proxy
709 else
710 @socket = create_ssl_socket(@socket)
711 connect_ssl_proxy(@socket, URI.parse(@dest.to_s)) if @proxy
a65bbbd4 »
2011-01-11 Added SNI support. see #49.
712 @socket.ssl_connect(@dest.host)
ac0fa203 » nahi
2008-12-19 * added a test for CONNECT proxy auth.
713 @socket.post_connection_check(@dest)
714 @ssl_peer_cert = @socket.peer_cert
715 end
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
716 end
90174d93 » nahi
2008-12-29 * spell check.
717 # Use Ruby internal buffering instead of passing data immediately
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
718 # to the underlying layer
90174d93 » nahi
2008-12-29 * spell check.
719 # => we need to to call explicitly flush on the socket
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
720 @socket.sync = @socket_sync
721 end
722 rescue RetryableResponse
723 retry_number += 1
724 if retry_number < @protocol_retry_count
725 retry
726 end
e77f3e06 » nahi
2008-12-18 * easier file upload: add Content-Type: multipart/form-data when the…
727 raise BadResponseError.new("connect to the server failed with status #{@status} #{@reason}")
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
728 rescue TimeoutError
729 if @connect_retry == 0
730 retry
731 else
732 retry_number += 1
733 retry if retry_number < @connect_retry
734 end
735 close
736 raise
737 end
738 @state = :WAIT
739 end
740
741 def create_socket(site)
742 socket = nil
743 begin
744 @debug_dev << "! CONNECT TO #{site.host}:#{site.port}\n" if @debug_dev
745 if str = @test_loopback_http_response.shift
746 socket = LoopBackSocket.new(site.host, site.port, str)
d64b7bd2 »
2011-03-23 Use @socket_local iif user specified it.
747 elsif @socket_local == Site::EMPTY
748 socket = TCPSocket.new(site.host, site.port)
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
749 else
c9b5f3e1 »
2011-02-18 Rename 'local_bind' to 'socket_local'
750 socket = TCPSocket.new(site.host, site.port, @socket_local.host, @socket_local.port)
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
751 end
752 if @debug_dev
753 @debug_dev << "! CONNECTION ESTABLISHED\n"
754 socket.extend(DebugSocket)
755 socket.debug_dev = @debug_dev
756 end
757 rescue SystemCallError => e
758 e.message << " (#{site})"
759 raise
760 rescue SocketError => e
761 e.message << " (#{site})"
762 raise
763 end
764 socket
765 end
766
767 # wrap socket with OpenSSL.
768 def create_ssl_socket(raw_socket)
288f58b7 » nahi
2008-12-29 * added RDocs for util, http, auth, ssl_config and timeout. closes #162
769 SSLSocketWrap.new(raw_socket, @ssl_config, @debug_dev)
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
770 end
771
772 def connect_ssl_proxy(socket, uri)
288f58b7 » nahi
2008-12-29 * added RDocs for util, http, auth, ssl_config and timeout. closes #162
773 req = HTTP::Message.new_connect_request(uri)
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
774 @client.request_filter.each do |filter|
775 filter.filter_request(req)
776 end
777 set_header(req)
778 req.dump(@socket)
779 @socket.flush unless @socket_sync
780 res = HTTP::Message.new_response('')
a176e7b4 » nahi
2008-12-22 * check test coverage on lib/httpclient/session.rb. see #189.
781 parse_header
19499386 »
2010-12-12 Do not depend on Float#to_s behavior. closes #36.
782 res.http_version, res.status, res.reason = @version, @status, @reason
17cbbf98 » nahi
2008-12-15 * refactoring around proxy handling. reduces created Objects. see #191.
783 @headers.each do |key, value|
784 res.header.set(key, value)
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
785 end
786 commands = @client.request_filter.collect { |filter|
787 filter.filter_response(req, res)
788 }
789 if commands.find { |command| command == :retry }
790 raise RetryableResponse.new
791 end
792 unless @status == 200
e77f3e06 » nahi
2008-12-18 * easier file upload: add Content-Type: multipart/form-data when the…
793 raise BadResponseError.new("connect to ssl proxy failed with status #{@status} #{@reason}", res)
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
794 end
795 end
796
797 # Read status block.
798 def read_header
2a71767d » nahi
2009-02-04 * when we hit some site through http-proxy we get a response without…
799 @content_length = nil
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
800 @chunked = false
95964f13 »
2010-12-12 Added transparent_gzip_decompression property. closes #42.
801 @gzipped = false
17cbbf98 » nahi
2008-12-15 * refactoring around proxy handling. reduces created Objects. see #191.
802 @chunk_length = 0
a176e7b4 » nahi
2008-12-22 * check test coverage on lib/httpclient/session.rb. see #189.
803 parse_header
d24ab1dd »
2009-11-02 do not try to read when a response code is 1XX, 204 or 304. closes #10.
804 # Header of the request has been parsed.
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
805 @state = :DATA
806 req = @requests.shift
d24ab1dd »
2009-11-02 do not try to read when a response code is 1XX, 204 or 304. closes #10.
807 if req.header.request_method == 'HEAD' or no_message_body?(@status)
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
808 @content_length = 0
809 if @next_connection
810 @state = :WAIT
811 else
812 close
813 end
814 end
815 @next_connection = false unless @content_length
816 end
817
818 StatusParseRegexp = %r(\AHTTP/(\d+\.\d+)\s+(\d\d\d)\s*([^\r\n]+)?\r?\n\z)
a176e7b4 » nahi
2008-12-22 * check test coverage on lib/httpclient/session.rb. see #189.
819 def parse_header
2253f959 » nahi
2008-12-19 * test coverage checked. see #189.
820 timeout(@receive_timeout, ReceiveTimeoutError) do
3ec4757f »
2010-04-02 JRuby exception support: see #25.
821 initial_line = nil
2253f959 » nahi
2008-12-19 * test coverage checked. see #189.
822 begin
a176e7b4 » nahi
2008-12-22 * check test coverage on lib/httpclient/session.rb. see #189.
823 initial_line = @socket.gets("\n")
2253f959 » nahi
2008-12-19 * test coverage checked. see #189.
824 if initial_line.nil?
3ec4757f »
2010-04-02 JRuby exception support: see #25.
825 close
a620b5f5 »
2010-12-15 Invalidate pooled sessions for the same destination when we got a Kee…
826 raise KeepAliveDisconnected.new(self)
2253f959 » nahi
2008-12-19 * test coverage checked. see #189.
827 end
3ec4757f »
2010-04-02 JRuby exception support: see #25.
828 rescue Errno::ECONNABORTED, Errno::ECONNRESET, Errno::EPIPE, IOError
829 # JRuby can raise IOError instead of ECONNRESET for now
830 close
a620b5f5 »
2010-12-15 Invalidate pooled sessions for the same destination when we got a Kee…
831 raise KeepAliveDisconnected.new(self)
3ec4757f »
2010-04-02 JRuby exception support: see #25.
832 end
833 begin
2253f959 » nahi
2008-12-19 * test coverage checked. see #189.
834 if StatusParseRegexp !~ initial_line
835 @version = '0.9'
836 @status = nil
837 @reason = nil
838 @next_connection = false
a176e7b4 » nahi
2008-12-22 * check test coverage on lib/httpclient/session.rb. see #189.
839 @content_length = nil
2253f959 » nahi
2008-12-19 * test coverage checked. see #189.
840 @readbuf = initial_line
841 break
842 end
843 @version, @status, @reason = $1, $2.to_i, $3
19499386 »
2010-12-12 Do not depend on Float#to_s behavior. closes #36.
844 @next_connection = HTTP::Message.keep_alive_enabled?(@version)
2253f959 » nahi
2008-12-19 * test coverage checked. see #189.
845 @headers = []
846 while true
a176e7b4 » nahi
2008-12-22 * check test coverage on lib/httpclient/session.rb. see #189.
847 line = @socket.gets("\n")
2253f959 » nahi
2008-12-19 * test coverage checked. see #189.
848 unless line
849 raise BadResponseError.new('unexpected EOF')
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
850 end
2253f959 » nahi
2008-12-19 * test coverage checked. see #189.
851 line.chomp!
852 break if line.empty?
7968719b »
2009-10-30 multiline response message header support.
853 if line[0] == ?\ or line[0] == ?\t
854 last = @headers.last[1]
855 last << ' ' unless last.empty?
856 last << line.strip
857 else
858 key, value = line.strip.split(/\s*:\s*/, 2)
859 parse_keepalive_header(key, value)
860 @headers << [key, value]
861 end
2253f959 » nahi
2008-12-19 * test coverage checked. see #189.
862 end
863 end while (@version == '1.1' && @status == 100)
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
864 end
865 end
866
d24ab1dd »
2009-11-02 do not try to read when a response code is 1XX, 204 or 304. closes #10.
867 def no_message_body?(status)
868 !status.nil? && # HTTP/0.9
869 ((status >= 100 && status < 200) || status == 204 || status == 304)
870 end
871
e3c1331f » nahi
2008-12-25 * a few performance improvements. see #191.
872 def parse_keepalive_header(key, value)
873 key = key.downcase
874 if key == 'content-length'
875 @content_length = value.to_i
95964f13 »
2010-12-12 Added transparent_gzip_decompression property. closes #42.
876 elsif key == 'content-encoding' and ( value.downcase == 'gzip' or
877 value.downcase == 'x-gzip' or value.downcase == 'deflate' )
878 @gzipped = true
e3c1331f » nahi
2008-12-25 * a few performance improvements. see #191.
879 elsif key == 'transfer-encoding' and value.downcase == 'chunked'
17cbbf98 » nahi
2008-12-15 * refactoring around proxy handling. reduces created Objects. see #191.
880 @chunked = true
881 @chunk_length = 0
e77f3e06 » nahi
2008-12-18 * easier file upload: add Content-Type: multipart/form-data when the…
882 @content_length = nil
e3c1331f » nahi
2008-12-25 * a few performance improvements. see #191.
883 elsif key == 'connection' or key == 'proxy-connection'
884 if value.downcase == 'keep-alive'
17cbbf98 » nahi
2008-12-15 * refactoring around proxy handling. reduces created Objects. see #191.
885 @next_connection = true
e3c1331f » nahi
2008-12-25 * a few performance improvements. see #191.
886 else
17cbbf98 » nahi
2008-12-15 * refactoring around proxy handling. reduces created Objects. see #191.
887 @next_connection = false
888 end
889 end
890 end
891
a176e7b4 » nahi
2008-12-22 * check test coverage on lib/httpclient/session.rb. see #189.
892 def read_body_length(&block)
893 return nil if @content_length == 0
894 buf = ''
895 while true
896 maxbytes = @read_block_size
897 maxbytes = @content_length if maxbytes > @content_length
898 timeout(@receive_timeout, ReceiveTimeoutError) do
350acc3f » nahi
2009-05-13 * applied a patch from user. IO#readpartial does not clear the secon…
899 begin
900 @socket.readpartial(maxbytes, buf)
901 rescue EOFError
902 buf = nil
903 end
a176e7b4 » nahi
2008-12-22 * check test coverage on lib/httpclient/session.rb. see #189.
904 end
261b2806 »
2009-12-03 define String#bytesize and use it for 1.9 compatibility. closes #23.
905 if buf && buf.bytesize > 0
906 @content_length -= buf.bytesize
a176e7b4 » nahi
2008-12-22 * check test coverage on lib/httpclient/session.rb. see #189.
907 yield buf
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
908 else
a176e7b4 » nahi
2008-12-22 * check test coverage on lib/httpclient/session.rb. see #189.
909 @content_length = 0
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
910 end
a176e7b4 » nahi
2008-12-22 * check test coverage on lib/httpclient/session.rb. see #189.
911 return if @content_length == 0
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
912 end
913 end
914
915 RS = "\r\n"
a176e7b4 » nahi
2008-12-22 * check test coverage on lib/httpclient/session.rb. see #189.
916 def read_body_chunked(&block)
917 buf = ''
918 while true
919 len = @socket.gets(RS)
920 @chunk_length = len.hex
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
921 if @chunk_length == 0
922 @content_length = 0
923 @socket.gets(RS)
a176e7b4 » nahi
2008-12-22 * check test coverage on lib/httpclient/session.rb. see #189.
924 return
925 end
926 timeout(@receive_timeout, ReceiveTimeoutError) do
927 @socket.read(@chunk_length + 2, buf)
928 end
929 unless buf.empty?
930 yield buf.slice(0, @chunk_length)
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
931 end
932 end
933 end
934
a176e7b4 » nahi
2008-12-22 * check test coverage on lib/httpclient/session.rb. see #189.
935 def read_body_rest
261b2806 »
2009-12-03 define String#bytesize and use it for 1.9 compatibility. closes #23.
936 if @readbuf and @readbuf.bytesize > 0
a176e7b4 » nahi
2008-12-22 * check test coverage on lib/httpclient/session.rb. see #189.
937 yield @readbuf
938 @readbuf = nil
939 end
940 buf = ''
941 while true
942 timeout(@receive_timeout, ReceiveTimeoutError) do
350acc3f » nahi
2009-05-13 * applied a patch from user. IO#readpartial does not clear the secon…
943 begin
944 @socket.readpartial(@read_block_size, buf)
945 rescue EOFError
946 buf = nil
947 end
a176e7b4 » nahi
2008-12-22 * check test coverage on lib/httpclient/session.rb. see #189.
948 end
261b2806 »
2009-12-03 define String#bytesize and use it for 1.9 compatibility. closes #23.
949 if buf && buf.bytesize > 0
a176e7b4 » nahi
2008-12-22 * check test coverage on lib/httpclient/session.rb. see #189.
950 yield buf
951 else
952 return
66269246 » nahi
2008-12-12 * split httpclient.rb into several files at httpclient/*.rb. see #162.
953 end
954 end
955 end
956 end
957
958
959 end
Something went wrong with that request. Please try again.