rs-httpclient 3.0.0.beta1

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 (78) 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/cookie.rb +1 -0
  7. data/lib/http-access2/http.rb +1 -0
  8. data/lib/http-access2.rb +55 -0
  9. data/lib/httpclient/auth.rb +924 -0
  10. data/lib/httpclient/cacert.pem +3252 -0
  11. data/lib/httpclient/cacert1024.pem +3866 -0
  12. data/lib/httpclient/connection.rb +88 -0
  13. data/lib/httpclient/cookie.rb +220 -0
  14. data/lib/httpclient/http.rb +1082 -0
  15. data/lib/httpclient/include_client.rb +85 -0
  16. data/lib/httpclient/jruby_ssl_socket.rb +594 -0
  17. data/lib/httpclient/session.rb +960 -0
  18. data/lib/httpclient/ssl_config.rb +452 -0
  19. data/lib/httpclient/ssl_socket.rb +150 -0
  20. data/lib/httpclient/timeout.rb +140 -0
  21. data/lib/httpclient/util.rb +222 -0
  22. data/lib/httpclient/version.rb +3 -0
  23. data/lib/httpclient/webagent-cookie.rb +459 -0
  24. data/lib/httpclient.rb +1331 -0
  25. data/lib/jsonclient.rb +66 -0
  26. data/lib/oauthclient.rb +111 -0
  27. data/sample/async.rb +8 -0
  28. data/sample/auth.rb +11 -0
  29. data/sample/cookie.rb +18 -0
  30. data/sample/dav.rb +103 -0
  31. data/sample/generate_test_keys.rb +99 -0
  32. data/sample/howto.rb +49 -0
  33. data/sample/jsonclient.rb +67 -0
  34. data/sample/oauth_buzz.rb +57 -0
  35. data/sample/oauth_friendfeed.rb +59 -0
  36. data/sample/oauth_twitter.rb +61 -0
  37. data/sample/ssl/0cert.pem +22 -0
  38. data/sample/ssl/0key.pem +30 -0
  39. data/sample/ssl/1000cert.pem +19 -0
  40. data/sample/ssl/1000key.pem +18 -0
  41. data/sample/ssl/htdocs/index.html +10 -0
  42. data/sample/ssl/ssl_client.rb +22 -0
  43. data/sample/ssl/webrick_httpsd.rb +29 -0
  44. data/sample/stream.rb +21 -0
  45. data/sample/thread.rb +27 -0
  46. data/sample/wcat.rb +21 -0
  47. data/test/ca-chain.pem +40 -0
  48. data/test/ca.cert +20 -0
  49. data/test/ca.key +27 -0
  50. data/test/ca.srl +1 -0
  51. data/test/client-pass.key +30 -0
  52. data/test/client.cert +20 -0
  53. data/test/client.key +27 -0
  54. data/test/fixtures/verify.alt.cert +20 -0
  55. data/test/fixtures/verify.foo.cert +20 -0
  56. data/test/fixtures/verify.key +27 -0
  57. data/test/fixtures/verify.localhost.cert +20 -0
  58. data/test/helper.rb +129 -0
  59. data/test/htdigest +1 -0
  60. data/test/htpasswd +2 -0
  61. data/test/jruby_ssl_socket/test_pemutils.rb +32 -0
  62. data/test/runner.rb +2 -0
  63. data/test/server.cert +20 -0
  64. data/test/server.key +27 -0
  65. data/test/sslsvr.rb +65 -0
  66. data/test/subca.cert +20 -0
  67. data/test/subca.key +27 -0
  68. data/test/subca.srl +1 -0
  69. data/test/test_auth.rb +496 -0
  70. data/test/test_cookie.rb +309 -0
  71. data/test/test_hexdump.rb +13 -0
  72. data/test/test_http-access2.rb +516 -0
  73. data/test/test_httpclient.rb +2144 -0
  74. data/test/test_include_client.rb +52 -0
  75. data/test/test_jsonclient.rb +98 -0
  76. data/test/test_ssl.rb +522 -0
  77. data/test/test_webagent-cookie.rb +465 -0
  78. metadata +130 -0
@@ -0,0 +1,516 @@
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.truncate(0)
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 = "".dup
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 = "".dup
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 = "".dup
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 = "".dup
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 = "".dup
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 = "".dup
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 = "".dup
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 = "".dup
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.truncate(0)
134
+ @client.proxy = nil
135
+ assert_equal(200, @client.head(serverurl).status)
136
+ assert(@proxyio.string.empty?)
137
+ #
138
+ @proxyio.truncate(0)
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.truncate(0)
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.truncate(0)
158
+ @client.proxy = nil
159
+ assert_equal(200, @client.head(serverurl).status)
160
+ assert(/accept/ !~ @proxyio.string)
161
+ #
162
+ @proxyio.truncate(0)
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.truncate(0)
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.truncate(0)
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.truncate(0)
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.truncate(0)
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 = "".dup
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 = "".dup
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
+ client = HTTPClient.new
335
+ assert_equal(60, client.connect_timeout)
336
+ assert_equal(120, client.send_timeout)
337
+ assert_equal(60, client.receive_timeout)
338
+ #
339
+ client.connect_timeout = 1
340
+ client.send_timeout = 2
341
+ client.receive_timeout = 3
342
+ assert_equal(1, client.connect_timeout)
343
+ assert_equal(2, client.send_timeout)
344
+ assert_equal(3, client.receive_timeout)
345
+ end
346
+
347
+ def test_connect_timeout
348
+ # ToDo
349
+ end
350
+
351
+ def test_send_timeout
352
+ # ToDo
353
+ end
354
+
355
+ def test_receive_timeout
356
+ # this test takes 2 sec
357
+ assert_equal('hello', @client.get_content(serverurl + 'sleep?sec=2'))
358
+ @client.reset_all
359
+ @client.receive_timeout = 1
360
+ assert_equal('hello', @client.get_content(serverurl + 'sleep?sec=0'))
361
+ assert_raise(HTTPClient::ReceiveTimeoutError) do
362
+ @client.get_content(serverurl + 'sleep?sec=2')
363
+ end
364
+ @client.reset_all
365
+ @client.receive_timeout = 3
366
+ assert_equal('hello', @client.get_content(serverurl + 'sleep?sec=2'))
367
+ end
368
+
369
+ def test_cookies
370
+ cookiefile = Tempfile.new('test_cookies_file')
371
+ # from [ruby-talk:164079]
372
+ File.open(cookiefile.path, "wb") do |f|
373
+ f << "http://rubyforge.org//account/login.php session_ser LjEwMy45Ni40Ni0q%2A-fa0537de8cc31 2131676286 .rubyforge.org / 13\n"
374
+ end
375
+ cm = WebAgent::CookieManager::new(cookiefile.path)
376
+ cm.load_cookies
377
+ assert_equal(1, cm.cookies.size)
378
+ end
379
+
380
+ private
381
+
382
+ def check_query_get(query)
383
+ WEBrick::HTTPUtils.parse_query(
384
+ @client.get(serverurl + 'servlet', query).header["x-query"][0]
385
+ )
386
+ end
387
+
388
+ def check_query_post(query)
389
+ WEBrick::HTTPUtils.parse_query(
390
+ @client.post(serverurl + 'servlet', query).header["x-query"][0]
391
+ )
392
+ end
393
+
394
+ def setup_server
395
+ @server = WEBrick::HTTPServer.new(
396
+ :BindAddress => "localhost",
397
+ :Logger => @logger,
398
+ :Port => 0,
399
+ :AccessLog => [],
400
+ :DocumentRoot => File.dirname(File.expand_path(__FILE__))
401
+ )
402
+ @serverport = @server.config[:Port]
403
+ [:hello, :sleep, :redirect1, :redirect2, :redirect3, :redirect_self, :relative_redirect].each do |sym|
404
+ @server.mount(
405
+ "/#{sym}",
406
+ WEBrick::HTTPServlet::ProcHandler.new(method("do_#{sym}").to_proc)
407
+ )
408
+ end
409
+ @server.mount('/servlet', TestServlet.new(@server))
410
+ @server_thread = start_server_thread(@server)
411
+ end
412
+
413
+ def escape_noproxy
414
+ backup = HTTPAccess2::Client::NO_PROXY_HOSTS.dup
415
+ HTTPAccess2::Client::NO_PROXY_HOSTS.clear
416
+ yield
417
+ ensure
418
+ HTTPAccess2::Client::NO_PROXY_HOSTS.replace(backup)
419
+ end
420
+
421
+ def do_hello(req, res)
422
+ res['content-type'] = 'text/html'
423
+ res.body = "hello"
424
+ end
425
+
426
+ def do_sleep(req, res)
427
+ sec = req.query['sec'].to_i
428
+ sleep sec
429
+ res['content-type'] = 'text/html'
430
+ res.body = "hello"
431
+ end
432
+
433
+ def do_redirect1(req, res)
434
+ res.set_redirect(WEBrick::HTTPStatus::MovedPermanently, serverurl + "hello")
435
+ end
436
+
437
+ def do_redirect2(req, res)
438
+ res.set_redirect(WEBrick::HTTPStatus::TemporaryRedirect, serverurl + "redirect3")
439
+ end
440
+
441
+ def do_redirect3(req, res)
442
+ res.set_redirect(WEBrick::HTTPStatus::Found, serverurl + "hello")
443
+ end
444
+
445
+ def do_redirect_self(req, res)
446
+ res.set_redirect(WEBrick::HTTPStatus::Found, serverurl + "redirect_self")
447
+ end
448
+
449
+ def do_relative_redirect(req, res)
450
+ res.set_redirect(WEBrick::HTTPStatus::Found, "hello")
451
+ end
452
+
453
+ class TestServlet < WEBrick::HTTPServlet::AbstractServlet
454
+ def get_instance(*arg)
455
+ self
456
+ end
457
+
458
+ def do_HEAD(req, res)
459
+ res["x-head"] = 'head' # use this for test purpose only.
460
+ res["x-query"] = query_response(req)
461
+ end
462
+
463
+ def do_GET(req, res)
464
+ res.body = 'get'
465
+ res["x-query"] = query_response(req)
466
+ end
467
+
468
+ def do_POST(req, res)
469
+ res.body = 'post'
470
+ res["x-query"] = body_response(req)
471
+ end
472
+
473
+ def do_PUT(req, res)
474
+ res.body = 'put'
475
+ end
476
+
477
+ def do_DELETE(req, res)
478
+ res.body = 'delete'
479
+ end
480
+
481
+ def do_OPTIONS(req, res)
482
+ # check RFC for legal response.
483
+ res.body = 'options'
484
+ end
485
+
486
+ def do_TRACE(req, res)
487
+ # client SHOULD reflect the message received back to the client as the
488
+ # entity-body of a 200 (OK) response. [RFC2616]
489
+ res.body = 'trace'
490
+ res["x-query"] = query_response(req)
491
+ end
492
+
493
+ private
494
+
495
+ def query_response(req)
496
+ query_escape(WEBrick::HTTPUtils.parse_query(req.query_string))
497
+ end
498
+
499
+ def body_response(req)
500
+ query_escape(WEBrick::HTTPUtils.parse_query(req.body))
501
+ end
502
+
503
+ def query_escape(query)
504
+ escaped = []
505
+ query.collect do |k, v|
506
+ v.to_ary.each do |ve|
507
+ escaped << CGI.escape(k) + '=' + CGI.escape(ve)
508
+ end
509
+ end
510
+ escaped.join('&')
511
+ end
512
+ end
513
+ end
514
+
515
+
516
+ end