httpclient 2.1.5 → 2.8.3

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