httpclient 2.1.5 → 2.8.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.
Files changed (71) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +85 -0
  3. data/bin/httpclient +77 -0
  4. data/bin/jsonclient +85 -0
  5. data/lib/hexdump.rb +50 -0
  6. data/lib/http-access2.rb +6 -4
  7. data/lib/httpclient/auth.rb +575 -173
  8. data/lib/httpclient/cacert.pem +3952 -0
  9. data/lib/httpclient/cacert1024.pem +3866 -0
  10. data/lib/httpclient/connection.rb +6 -2
  11. data/lib/httpclient/cookie.rb +162 -504
  12. data/lib/httpclient/http.rb +334 -119
  13. data/lib/httpclient/include_client.rb +85 -0
  14. data/lib/httpclient/jruby_ssl_socket.rb +588 -0
  15. data/lib/httpclient/session.rb +385 -288
  16. data/lib/httpclient/ssl_config.rb +195 -155
  17. data/lib/httpclient/ssl_socket.rb +150 -0
  18. data/lib/httpclient/timeout.rb +14 -10
  19. data/lib/httpclient/util.rb +142 -6
  20. data/lib/httpclient/version.rb +3 -0
  21. data/lib/httpclient/webagent-cookie.rb +459 -0
  22. data/lib/httpclient.rb +509 -202
  23. data/lib/jsonclient.rb +63 -0
  24. data/lib/oauthclient.rb +111 -0
  25. data/sample/async.rb +8 -0
  26. data/sample/auth.rb +11 -0
  27. data/sample/cookie.rb +18 -0
  28. data/sample/dav.rb +103 -0
  29. data/sample/howto.rb +49 -0
  30. data/sample/jsonclient.rb +67 -0
  31. data/sample/oauth_buzz.rb +57 -0
  32. data/sample/oauth_friendfeed.rb +59 -0
  33. data/sample/oauth_twitter.rb +61 -0
  34. data/sample/ssl/0cert.pem +22 -0
  35. data/sample/ssl/0key.pem +30 -0
  36. data/sample/ssl/1000cert.pem +19 -0
  37. data/sample/ssl/1000key.pem +18 -0
  38. data/sample/ssl/htdocs/index.html +10 -0
  39. data/sample/ssl/ssl_client.rb +22 -0
  40. data/sample/ssl/webrick_httpsd.rb +29 -0
  41. data/sample/stream.rb +21 -0
  42. data/sample/thread.rb +27 -0
  43. data/sample/wcat.rb +21 -0
  44. data/test/ca-chain.pem +44 -0
  45. data/test/ca.cert +23 -0
  46. data/test/client-pass.key +18 -0
  47. data/test/client.cert +19 -0
  48. data/test/client.key +15 -0
  49. data/test/helper.rb +131 -0
  50. data/test/htdigest +1 -0
  51. data/test/htpasswd +2 -0
  52. data/test/jruby_ssl_socket/test_pemutils.rb +32 -0
  53. data/test/runner.rb +2 -0
  54. data/test/server.cert +19 -0
  55. data/test/server.key +15 -0
  56. data/test/sslsvr.rb +65 -0
  57. data/test/subca.cert +21 -0
  58. data/test/test_auth.rb +492 -0
  59. data/test/test_cookie.rb +309 -0
  60. data/test/test_hexdump.rb +14 -0
  61. data/test/test_http-access2.rb +508 -0
  62. data/test/test_httpclient.rb +2145 -0
  63. data/test/test_include_client.rb +52 -0
  64. data/test/test_jsonclient.rb +80 -0
  65. data/test/test_ssl.rb +559 -0
  66. data/test/test_webagent-cookie.rb +465 -0
  67. metadata +85 -44
  68. data/lib/httpclient/auth.rb.orig +0 -513
  69. data/lib/httpclient/cacert.p7s +0 -1579
  70. data/lib/httpclient.rb.orig +0 -1020
  71. data/lib/tags +0 -908
@@ -0,0 +1,508 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'http-access2'
3
+ require File.expand_path('helper', File.dirname(__FILE__))
4
+ require 'tempfile'
5
+
6
+
7
+ module HTTPAccess2
8
+
9
+
10
+ class TestClient < Test::Unit::TestCase
11
+ include Helper
12
+ include HTTPClient::Util
13
+
14
+ def setup
15
+ super
16
+ setup_server
17
+ setup_client
18
+ end
19
+
20
+ def teardown
21
+ super
22
+ end
23
+
24
+ def test_initialize
25
+ setup_proxyserver
26
+ escape_noproxy do
27
+ @proxyio.string = ""
28
+ @client = HTTPAccess2::Client.new(proxyurl)
29
+ assert_equal(urify(proxyurl), @client.proxy)
30
+ assert_equal(200, @client.head(serverurl).status)
31
+ assert(!@proxyio.string.empty?)
32
+ end
33
+ end
34
+
35
+ def test_agent_name
36
+ @client = HTTPAccess2::Client.new(nil, "agent_name_foo")
37
+ str = ""
38
+ @client.debug_dev = str
39
+ @client.get(serverurl)
40
+ lines = str.split(/(?:\r?\n)+/)
41
+ assert_equal("= Request", lines[0])
42
+ assert_match(/^User-Agent: agent_name_foo/, lines[4])
43
+ end
44
+
45
+ def test_from
46
+ @client = HTTPAccess2::Client.new(nil, nil, "from_bar")
47
+ str = ""
48
+ @client.debug_dev = str
49
+ @client.get(serverurl)
50
+ lines = str.split(/(?:\r?\n)+/)
51
+ assert_equal("= Request", lines[0])
52
+ assert_match(/^From: from_bar/, lines[5])
53
+ end
54
+
55
+ def test_debug_dev
56
+ str = ""
57
+ @client.debug_dev = str
58
+ assert(str.empty?)
59
+ @client.get(serverurl)
60
+ assert(!str.empty?)
61
+ end
62
+
63
+ def _test_protocol_version_http09
64
+ @client.protocol_version = 'HTTP/0.9'
65
+ str = ""
66
+ @client.debug_dev = str
67
+ @client.get(serverurl + 'hello')
68
+ lines = str.split(/(?:\r?\n)+/)
69
+ assert_equal("= Request", lines[0])
70
+ assert_equal("! CONNECTION ESTABLISHED", lines[2])
71
+ assert_equal("GET /hello HTTP/0.9", lines[3])
72
+ assert_equal("Connection: close", lines[5])
73
+ assert_equal("= Response", lines[6])
74
+ assert_match(/^hello/, lines[7])
75
+ end
76
+
77
+ def test_protocol_version_http10
78
+ @client.protocol_version = 'HTTP/1.0'
79
+ str = ""
80
+ @client.debug_dev = str
81
+ @client.get(serverurl + 'hello')
82
+ lines = str.split(/(?:\r?\n)+/)
83
+ assert_equal("= Request", lines[0])
84
+ assert_equal("! CONNECTION ESTABLISHED", lines[2])
85
+ assert_equal("GET /hello HTTP/1.0", lines[3])
86
+ assert_equal("Connection: close", lines[7])
87
+ assert_equal("= Response", lines[8])
88
+ end
89
+
90
+ def test_protocol_version_http11
91
+ str = ""
92
+ @client.debug_dev = str
93
+ @client.get(serverurl)
94
+ lines = str.split(/(?:\r?\n)+/)
95
+ assert_equal("= Request", lines[0])
96
+ assert_equal("! CONNECTION ESTABLISHED", lines[2])
97
+ assert_equal("GET / HTTP/1.1", lines[3])
98
+ assert_equal("Host: localhost:#{serverport}", lines[7])
99
+ @client.protocol_version = 'HTTP/1.1'
100
+ str = ""
101
+ @client.debug_dev = str
102
+ @client.get(serverurl)
103
+ lines = str.split(/(?:\r?\n)+/)
104
+ assert_equal("= Request", lines[0])
105
+ assert_equal("! CONNECTION ESTABLISHED", lines[2])
106
+ assert_equal("GET / HTTP/1.1", lines[3])
107
+ @client.protocol_version = 'HTTP/1.0'
108
+ str = ""
109
+ @client.debug_dev = str
110
+ @client.get(serverurl)
111
+ lines = str.split(/(?:\r?\n)+/)
112
+ assert_equal("= Request", lines[0])
113
+ assert_equal("! CONNECTION ESTABLISHED", lines[2])
114
+ assert_equal("GET / HTTP/1.0", lines[3])
115
+ end
116
+
117
+ def test_proxy
118
+ setup_proxyserver
119
+ escape_noproxy do
120
+ begin
121
+ @client.proxy = "http://あ"
122
+ rescue => e
123
+ assert_match(/InvalidURIError/, e.class.to_s)
124
+ end
125
+ @client.proxy = ""
126
+ assert_nil(@client.proxy)
127
+ @client.proxy = "http://foo:1234"
128
+ assert_equal(urify("http://foo:1234"), @client.proxy)
129
+ uri = urify("http://bar:2345")
130
+ @client.proxy = uri
131
+ assert_equal(uri, @client.proxy)
132
+ #
133
+ @proxyio.string = ""
134
+ @client.proxy = nil
135
+ assert_equal(200, @client.head(serverurl).status)
136
+ assert(@proxyio.string.empty?)
137
+ #
138
+ @proxyio.string = ""
139
+ @client.proxy = proxyurl
140
+ assert_equal(200, @client.head(serverurl).status)
141
+ assert(!@proxyio.string.empty?)
142
+ end
143
+ end
144
+
145
+ def test_noproxy_for_localhost
146
+ @proxyio.string = ""
147
+ @client.proxy = proxyurl
148
+ assert_equal(200, @client.head(serverurl).status)
149
+ assert(@proxyio.string.empty?)
150
+ end
151
+
152
+ def test_no_proxy
153
+ setup_proxyserver
154
+ escape_noproxy do
155
+ # proxy is not set.
156
+ @client.no_proxy = 'localhost'
157
+ @proxyio.string = ""
158
+ @client.proxy = nil
159
+ assert_equal(200, @client.head(serverurl).status)
160
+ assert(/accept/ !~ @proxyio.string)
161
+ #
162
+ @proxyio.string = ""
163
+ @client.proxy = proxyurl
164
+ assert_equal(200, @client.head(serverurl).status)
165
+ assert(/accept/ !~ @proxyio.string)
166
+ #
167
+ @client.no_proxy = 'foobar'
168
+ @proxyio.string = ""
169
+ @client.proxy = proxyurl
170
+ assert_equal(200, @client.head(serverurl).status)
171
+ assert(/accept/ =~ @proxyio.string)
172
+ #
173
+ @client.no_proxy = 'foobar,localhost:baz'
174
+ @proxyio.string = ""
175
+ @client.proxy = proxyurl
176
+ assert_equal(200, @client.head(serverurl).status)
177
+ assert(/accept/ !~ @proxyio.string)
178
+ #
179
+ @client.no_proxy = 'foobar,localhost:443'
180
+ @proxyio.string = ""
181
+ @client.proxy = proxyurl
182
+ assert_equal(200, @client.head(serverurl).status)
183
+ assert(/accept/ =~ @proxyio.string)
184
+ #
185
+ @client.no_proxy = "foobar,localhost:443:localhost:#{serverport},baz"
186
+ @proxyio.string = ""
187
+ @client.proxy = proxyurl
188
+ assert_equal(200, @client.head(serverurl).status)
189
+ assert(/accept/ !~ @proxyio.string)
190
+ end
191
+ end
192
+
193
+ def test_get_content
194
+ assert_equal('hello', @client.get_content(serverurl + 'hello'))
195
+ assert_equal('hello', @client.get_content(serverurl + 'redirect1'))
196
+ assert_equal('hello', @client.get_content(serverurl + 'redirect2'))
197
+ assert_raises(HTTPClient::Session::BadResponse) do
198
+ @client.get_content(serverurl + 'notfound')
199
+ end
200
+ assert_raises(HTTPClient::Session::BadResponse) do
201
+ @client.get_content(serverurl + 'redirect_self')
202
+ end
203
+ called = false
204
+ @client.redirect_uri_callback = lambda { |uri, res|
205
+ newuri = res.header['location'][0]
206
+ called = true
207
+ newuri
208
+ }
209
+ assert_equal('hello', @client.get_content(serverurl + 'relative_redirect'))
210
+ assert(called)
211
+ end
212
+
213
+ def test_post_content
214
+ assert_equal('hello', @client.post_content(serverurl + 'hello'))
215
+ assert_equal('hello', @client.post_content(serverurl + 'redirect1'))
216
+ assert_equal('hello', @client.post_content(serverurl + 'redirect2'))
217
+ assert_raises(HTTPClient::Session::BadResponse) do
218
+ @client.post_content(serverurl + 'notfound')
219
+ end
220
+ assert_raises(HTTPClient::Session::BadResponse) do
221
+ @client.post_content(serverurl + 'redirect_self')
222
+ end
223
+ called = false
224
+ @client.redirect_uri_callback = lambda { |uri, res|
225
+ newuri = res.header['location'][0]
226
+ called = true
227
+ newuri
228
+ }
229
+ assert_equal('hello', @client.post_content(serverurl + 'relative_redirect'))
230
+ assert(called)
231
+ end
232
+
233
+ def test_head
234
+ assert_equal("head", @client.head(serverurl + 'servlet').header["x-head"][0])
235
+ param = {'1'=>'2', '3'=>'4'}
236
+ res = @client.head(serverurl + 'servlet', param)
237
+ assert_equal(param, params(res.header["x-query"][0]))
238
+ end
239
+
240
+ def test_get
241
+ assert_equal("get", @client.get(serverurl + 'servlet').content)
242
+ param = {'1'=>'2', '3'=>'4'}
243
+ res = @client.get(serverurl + 'servlet', param)
244
+ assert_equal(param, params(res.header["x-query"][0]))
245
+ end
246
+
247
+ def test_post
248
+ assert_equal("post", @client.post(serverurl + 'servlet', '').content)
249
+ param = {'1'=>'2', '3'=>'4'}
250
+ res = @client.get(serverurl + 'servlet', param)
251
+ assert_equal(param, params(res.header["x-query"][0]))
252
+ end
253
+
254
+ def test_put
255
+ assert_equal("put", @client.put(serverurl + 'servlet').content)
256
+ param = {'1'=>'2', '3'=>'4'}
257
+ res = @client.get(serverurl + 'servlet', param)
258
+ assert_equal(param, params(res.header["x-query"][0]))
259
+ end
260
+
261
+ def test_delete
262
+ assert_equal("delete", @client.delete(serverurl + 'servlet').content)
263
+ param = {'1'=>'2', '3'=>'4'}
264
+ res = @client.get(serverurl + 'servlet', param)
265
+ assert_equal(param, params(res.header["x-query"][0]))
266
+ end
267
+
268
+ def test_options
269
+ assert_equal("options", @client.options(serverurl + 'servlet').content)
270
+ param = {'1'=>'2', '3'=>'4'}
271
+ res = @client.get(serverurl + 'servlet', param)
272
+ assert_equal(param, params(res.header["x-query"][0]))
273
+ end
274
+
275
+ def test_trace
276
+ assert_equal("trace", @client.trace(serverurl + 'servlet').content)
277
+ param = {'1'=>'2', '3'=>'4'}
278
+ res = @client.get(serverurl + 'servlet', param)
279
+ assert_equal(param, params(res.header["x-query"][0]))
280
+ end
281
+
282
+ def test_get_query
283
+ assert_equal({'1'=>'2'}, check_query_get({1=>2}))
284
+ assert_equal({'a'=>'A', 'B'=>'b'}, check_query_get({"a"=>"A", "B"=>"b"}))
285
+ assert_equal({'&'=>'&'}, check_query_get({"&"=>"&"}))
286
+ assert_equal({'= '=>' =+'}, check_query_get({"= "=>" =+"}))
287
+ assert_equal(
288
+ ['=', '&'].sort,
289
+ check_query_get([["=", "="], ["=", "&"]])['='].to_ary.sort
290
+ )
291
+ assert_equal({'123'=>'45'}, check_query_get('123=45'))
292
+ assert_equal({'12 3'=>'45', ' '=>' '}, check_query_get('12+3=45&+=+'))
293
+ assert_equal({}, check_query_get(''))
294
+ end
295
+
296
+ def test_post_body
297
+ assert_equal({'1'=>'2'}, check_query_post({1=>2}))
298
+ assert_equal({'a'=>'A', 'B'=>'b'}, check_query_post({"a"=>"A", "B"=>"b"}))
299
+ assert_equal({'&'=>'&'}, check_query_post({"&"=>"&"}))
300
+ assert_equal({'= '=>' =+'}, check_query_post({"= "=>" =+"}))
301
+ assert_equal(
302
+ ['=', '&'].sort,
303
+ check_query_post([["=", "="], ["=", "&"]])['='].to_ary.sort
304
+ )
305
+ assert_equal({'123'=>'45'}, check_query_post('123=45'))
306
+ assert_equal({'12 3'=>'45', ' '=>' '}, check_query_post('12+3=45&+=+'))
307
+ assert_equal({}, check_query_post(''))
308
+ #
309
+ post_body = StringIO.new("foo=bar&foo=baz")
310
+ assert_equal(
311
+ ["bar", "baz"],
312
+ check_query_post(post_body)["foo"].to_ary.sort
313
+ )
314
+ end
315
+
316
+ def test_extra_headers
317
+ str = ""
318
+ @client.debug_dev = str
319
+ @client.head(serverurl, nil, {"ABC" => "DEF"})
320
+ lines = str.split(/(?:\r?\n)+/)
321
+ assert_equal("= Request", lines[0])
322
+ assert_match("ABC: DEF", lines[4])
323
+ #
324
+ str = ""
325
+ @client.debug_dev = str
326
+ @client.get(serverurl, nil, [["ABC", "DEF"], ["ABC", "DEF"]])
327
+ lines = str.split(/(?:\r?\n)+/)
328
+ assert_equal("= Request", lines[0])
329
+ assert_match("ABC: DEF", lines[4])
330
+ assert_match("ABC: DEF", lines[5])
331
+ end
332
+
333
+ def test_timeout
334
+ assert_equal(60, @client.connect_timeout)
335
+ assert_equal(120, @client.send_timeout)
336
+ assert_equal(60, @client.receive_timeout)
337
+ end
338
+
339
+ def test_connect_timeout
340
+ # ToDo
341
+ end
342
+
343
+ def test_send_timeout
344
+ # ToDo
345
+ end
346
+
347
+ def test_receive_timeout
348
+ # this test takes 2 sec
349
+ assert_equal('hello', @client.get_content(serverurl + 'sleep?sec=2'))
350
+ @client.reset_all
351
+ @client.receive_timeout = 1
352
+ assert_equal('hello', @client.get_content(serverurl + 'sleep?sec=0'))
353
+ assert_raise(HTTPClient::ReceiveTimeoutError) do
354
+ @client.get_content(serverurl + 'sleep?sec=2')
355
+ end
356
+ @client.reset_all
357
+ @client.receive_timeout = 3
358
+ assert_equal('hello', @client.get_content(serverurl + 'sleep?sec=2'))
359
+ end
360
+
361
+ def test_cookies
362
+ cookiefile = Tempfile.new('test_cookies_file')
363
+ # from [ruby-talk:164079]
364
+ File.open(cookiefile.path, "wb") do |f|
365
+ f << "http://rubyforge.org//account/login.php session_ser LjEwMy45Ni40Ni0q%2A-fa0537de8cc31 2131676286 .rubyforge.org / 13\n"
366
+ end
367
+ cm = WebAgent::CookieManager::new(cookiefile.path)
368
+ cm.load_cookies
369
+ assert_equal(1, cm.cookies.size)
370
+ end
371
+
372
+ private
373
+
374
+ def check_query_get(query)
375
+ WEBrick::HTTPUtils.parse_query(
376
+ @client.get(serverurl + 'servlet', query).header["x-query"][0]
377
+ )
378
+ end
379
+
380
+ def check_query_post(query)
381
+ WEBrick::HTTPUtils.parse_query(
382
+ @client.post(serverurl + 'servlet', query).header["x-query"][0]
383
+ )
384
+ end
385
+
386
+ def setup_server
387
+ @server = WEBrick::HTTPServer.new(
388
+ :BindAddress => "localhost",
389
+ :Logger => @logger,
390
+ :Port => 0,
391
+ :AccessLog => [],
392
+ :DocumentRoot => File.dirname(File.expand_path(__FILE__))
393
+ )
394
+ @serverport = @server.config[:Port]
395
+ [:hello, :sleep, :redirect1, :redirect2, :redirect3, :redirect_self, :relative_redirect].each do |sym|
396
+ @server.mount(
397
+ "/#{sym}",
398
+ WEBrick::HTTPServlet::ProcHandler.new(method("do_#{sym}").to_proc)
399
+ )
400
+ end
401
+ @server.mount('/servlet', TestServlet.new(@server))
402
+ @server_thread = start_server_thread(@server)
403
+ end
404
+
405
+ def escape_noproxy
406
+ backup = HTTPAccess2::Client::NO_PROXY_HOSTS.dup
407
+ HTTPAccess2::Client::NO_PROXY_HOSTS.clear
408
+ yield
409
+ ensure
410
+ HTTPAccess2::Client::NO_PROXY_HOSTS.replace(backup)
411
+ end
412
+
413
+ def do_hello(req, res)
414
+ res['content-type'] = 'text/html'
415
+ res.body = "hello"
416
+ end
417
+
418
+ def do_sleep(req, res)
419
+ sec = req.query['sec'].to_i
420
+ sleep sec
421
+ res['content-type'] = 'text/html'
422
+ res.body = "hello"
423
+ end
424
+
425
+ def do_redirect1(req, res)
426
+ res.set_redirect(WEBrick::HTTPStatus::MovedPermanently, serverurl + "hello")
427
+ end
428
+
429
+ def do_redirect2(req, res)
430
+ res.set_redirect(WEBrick::HTTPStatus::TemporaryRedirect, serverurl + "redirect3")
431
+ end
432
+
433
+ def do_redirect3(req, res)
434
+ res.set_redirect(WEBrick::HTTPStatus::Found, serverurl + "hello")
435
+ end
436
+
437
+ def do_redirect_self(req, res)
438
+ res.set_redirect(WEBrick::HTTPStatus::Found, serverurl + "redirect_self")
439
+ end
440
+
441
+ def do_relative_redirect(req, res)
442
+ res.set_redirect(WEBrick::HTTPStatus::Found, "hello")
443
+ end
444
+
445
+ class TestServlet < WEBrick::HTTPServlet::AbstractServlet
446
+ def get_instance(*arg)
447
+ self
448
+ end
449
+
450
+ def do_HEAD(req, res)
451
+ res["x-head"] = 'head' # use this for test purpose only.
452
+ res["x-query"] = query_response(req)
453
+ end
454
+
455
+ def do_GET(req, res)
456
+ res.body = 'get'
457
+ res["x-query"] = query_response(req)
458
+ end
459
+
460
+ def do_POST(req, res)
461
+ res.body = 'post'
462
+ res["x-query"] = body_response(req)
463
+ end
464
+
465
+ def do_PUT(req, res)
466
+ res.body = 'put'
467
+ end
468
+
469
+ def do_DELETE(req, res)
470
+ res.body = 'delete'
471
+ end
472
+
473
+ def do_OPTIONS(req, res)
474
+ # check RFC for legal response.
475
+ res.body = 'options'
476
+ end
477
+
478
+ def do_TRACE(req, res)
479
+ # client SHOULD reflect the message received back to the client as the
480
+ # entity-body of a 200 (OK) response. [RFC2616]
481
+ res.body = 'trace'
482
+ res["x-query"] = query_response(req)
483
+ end
484
+
485
+ private
486
+
487
+ def query_response(req)
488
+ query_escape(WEBrick::HTTPUtils.parse_query(req.query_string))
489
+ end
490
+
491
+ def body_response(req)
492
+ query_escape(WEBrick::HTTPUtils.parse_query(req.body))
493
+ end
494
+
495
+ def query_escape(query)
496
+ escaped = []
497
+ query.collect do |k, v|
498
+ v.to_ary.each do |ve|
499
+ escaped << CGI.escape(k) + '=' + CGI.escape(ve)
500
+ end
501
+ end
502
+ escaped.join('&')
503
+ end
504
+ end
505
+ end
506
+
507
+
508
+ end