http_tools 0.1.0
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.
- data/README.rdoc +80 -0
- data/bench/parser/request_bench.rb +59 -0
- data/bench/parser/response_bench.rb +21 -0
- data/example/http_client.rb +132 -0
- data/lib/http_tools.rb +110 -0
- data/lib/http_tools/builder.rb +49 -0
- data/lib/http_tools/encoding.rb +169 -0
- data/lib/http_tools/errors.rb +5 -0
- data/lib/http_tools/parser.rb +478 -0
- data/profile/parser/request_profile.rb +12 -0
- data/profile/parser/response_profile.rb +12 -0
- data/test/builder/request_test.rb +26 -0
- data/test/builder/response_test.rb +32 -0
- data/test/cover.rb +28 -0
- data/test/encoding/transfer_encoding_chunked_test.rb +141 -0
- data/test/encoding/url_encoding_test.rb +37 -0
- data/test/encoding/www_form_test.rb +42 -0
- data/test/parser/request_test.rb +481 -0
- data/test/parser/response_test.rb +446 -0
- data/test/runner.rb +1 -0
- metadata +89 -0
@@ -0,0 +1,446 @@
|
|
1
|
+
base = File.expand_path(File.dirname(__FILE__) + '/../../lib')
|
2
|
+
require base + '/http_tools'
|
3
|
+
require 'test/unit'
|
4
|
+
|
5
|
+
class ResponseTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
def test_version
|
8
|
+
parser = HTTPTools::Parser.new
|
9
|
+
version = nil
|
10
|
+
|
11
|
+
parser.add_listener(:version) {|v| version = v}
|
12
|
+
|
13
|
+
parser << "HTTP/1.1 "
|
14
|
+
|
15
|
+
assert_equal("1.1", version)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_ok
|
19
|
+
parser = HTTPTools::Parser.new
|
20
|
+
code, message = nil
|
21
|
+
|
22
|
+
parser.add_listener(:status) {|c, m| code, message = c, m}
|
23
|
+
|
24
|
+
parser << "HTTP/1.1 200 OK\r\n\r\n"
|
25
|
+
|
26
|
+
assert_equal(200, code)
|
27
|
+
assert_equal("OK", message)
|
28
|
+
assert(!parser.finished?, "parser should not be finished")
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_not_found
|
32
|
+
parser = HTTPTools::Parser.new
|
33
|
+
code, message = nil
|
34
|
+
|
35
|
+
parser.add_listener(:status) {|c, m| code, message = c, m}
|
36
|
+
|
37
|
+
parser << "HTTP/1.1 404 Not Found\r\n\r\n"
|
38
|
+
|
39
|
+
assert_equal(404, code)
|
40
|
+
assert_equal("Not Found", message)
|
41
|
+
assert(!parser.finished?, "parser should not be finished")
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_no_content
|
45
|
+
parser = HTTPTools::Parser.new
|
46
|
+
code, message = nil
|
47
|
+
|
48
|
+
parser.add_listener(:status) {|c, m| code, message = c, m}
|
49
|
+
|
50
|
+
parser << "HTTP/1.1 204 No Content\r\n\r\n"
|
51
|
+
|
52
|
+
assert_equal(204, code)
|
53
|
+
assert_equal("No Content", message)
|
54
|
+
assert(parser.finished?, "parser should be finished")
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_not_modified
|
58
|
+
parser = HTTPTools::Parser.new
|
59
|
+
code, message = nil
|
60
|
+
|
61
|
+
parser.add_listener(:status) {|c, m| code, message = c, m}
|
62
|
+
|
63
|
+
parser << "HTTP/1.1 304 Not Modified\r\n\r\n"
|
64
|
+
|
65
|
+
assert_equal(304, code)
|
66
|
+
assert_equal("Not Modified", message)
|
67
|
+
assert(parser.finished?, "parser should be finished")
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_force_no_body
|
71
|
+
parser = HTTPTools::Parser.new
|
72
|
+
parser.force_no_body = true
|
73
|
+
headers = nil
|
74
|
+
|
75
|
+
parser.add_listener(:headers) {|h| headers = h}
|
76
|
+
|
77
|
+
parser << "HTTP/1.1 200 OK\r\n"
|
78
|
+
parser << "Content-Length: 20\r\n"
|
79
|
+
parser << "\r\n"
|
80
|
+
|
81
|
+
assert_equal({"Content-Length" => "20"}, headers)
|
82
|
+
assert(parser.finished?, "parser should be finished")
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_apple_dot_com
|
86
|
+
parser = HTTPTools::Parser.new
|
87
|
+
code, message, headers = nil
|
88
|
+
|
89
|
+
parser.add_listener(:status) {|c, m| code, message = c, m}
|
90
|
+
parser.add_listener(:headers) {|h| headers = h}
|
91
|
+
|
92
|
+
parser << "HTTP/1.1 200 OK\r\n"
|
93
|
+
parser << "Server: Apache/2.2.11 (Unix)\r\n"
|
94
|
+
parser << "Content-Type: text/html; charset=utf-8\r\n"
|
95
|
+
parser << "Cache-Control: max-age=319\r\n"
|
96
|
+
parser << "Expires: Sun, 16 May 2010 18:15:18 GMT\r\n"
|
97
|
+
parser << "Date: Sun, 16 May 2010 18:09:59 GMT\r\n"
|
98
|
+
parser << "Connection: keep-alive\r\n"
|
99
|
+
parser << "\r\n"
|
100
|
+
|
101
|
+
assert_equal(200, code)
|
102
|
+
assert_equal("OK", message)
|
103
|
+
assert_equal({
|
104
|
+
"Server" => "Apache/2.2.11 (Unix)",
|
105
|
+
"Content-Type" => "text/html; charset=utf-8",
|
106
|
+
"Cache-Control" => "max-age=319",
|
107
|
+
"Expires" => "Sun, 16 May 2010 18:15:18 GMT",
|
108
|
+
"Date" => "Sun, 16 May 2010 18:09:59 GMT",
|
109
|
+
"Connection" => "keep-alive"}, headers)
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_stream
|
113
|
+
parser = HTTPTools::Parser.new
|
114
|
+
code, message, headers = nil
|
115
|
+
body = []
|
116
|
+
|
117
|
+
parser.add_listener(:status) {|c, m| code, message = c, m}
|
118
|
+
parser.add_listener(:headers) {|h| headers = h}
|
119
|
+
parser.add_listener(:stream) {|b| body << b}
|
120
|
+
|
121
|
+
parser << "HTTP/1.1 200 OK\r\n"
|
122
|
+
parser << "Content-Length: 20\r\n"
|
123
|
+
parser << "\r\n"
|
124
|
+
parser << "<h1>Hello"
|
125
|
+
parser << " world</h1>"
|
126
|
+
|
127
|
+
assert_equal(200, code)
|
128
|
+
assert_equal("OK", message)
|
129
|
+
assert_equal({"Content-Length" => "20"}, headers)
|
130
|
+
assert_equal(["<h1>Hello", " world</h1>"], body)
|
131
|
+
assert(parser.finished?, "parser should be finished")
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_body
|
135
|
+
parser = HTTPTools::Parser.new
|
136
|
+
code, message, headers, body = nil
|
137
|
+
|
138
|
+
parser.add_listener(:status) {|c, m| code, message = c, m}
|
139
|
+
parser.add_listener(:headers) {|h| headers = h}
|
140
|
+
parser.add_listener(:body) {|b| body = b}
|
141
|
+
|
142
|
+
parser << "HTTP/1.1 200 OK\r\n"
|
143
|
+
parser << "Content-Length: 20\r\n"
|
144
|
+
parser << "\r\n"
|
145
|
+
parser << "<h1>Hello"
|
146
|
+
parser << " world</h1>"
|
147
|
+
|
148
|
+
assert_equal(200, code)
|
149
|
+
assert_equal("OK", message)
|
150
|
+
assert_equal({"Content-Length" => "20"}, headers)
|
151
|
+
assert_equal("<h1>Hello world</h1>", body)
|
152
|
+
assert(parser.finished?, "parser should be finished")
|
153
|
+
end
|
154
|
+
|
155
|
+
def test_sub_line_chunks
|
156
|
+
parser = HTTPTools::Parser.new
|
157
|
+
code, message, headers, body = nil
|
158
|
+
|
159
|
+
parser.add_listener(:status) {|c, m| code, message = c, m}
|
160
|
+
parser.add_listener(:headers) {|h| headers = h}
|
161
|
+
parser.add_listener(:body) {|b| body = b}
|
162
|
+
|
163
|
+
parser << "HTTP/"
|
164
|
+
parser << "1."
|
165
|
+
parser << "1 "
|
166
|
+
parser << "200"
|
167
|
+
parser << " OK\r\n"
|
168
|
+
parser << "Content-"
|
169
|
+
parser << "Length: 20\r\n\r\n"
|
170
|
+
parser << "<h1>Hello"
|
171
|
+
parser << " world</h1>"
|
172
|
+
|
173
|
+
assert_equal(200, code)
|
174
|
+
assert_equal("OK", message)
|
175
|
+
assert_equal({"Content-Length" => "20"}, headers)
|
176
|
+
assert_equal("<h1>Hello world</h1>", body)
|
177
|
+
assert(parser.finished?, "parser should be finished")
|
178
|
+
end
|
179
|
+
|
180
|
+
def test_body_with_key_terminator_like_value
|
181
|
+
parser = HTTPTools::Parser.new
|
182
|
+
code, message, headers, body = nil
|
183
|
+
|
184
|
+
parser.add_listener(:status) {|c, m| code, message = c, m}
|
185
|
+
parser.add_listener(:headers) {|h| headers = h}
|
186
|
+
parser.add_listener(:body) {|b| body = b}
|
187
|
+
|
188
|
+
parser << "HTTP/1.1 200 OK\r\n"
|
189
|
+
parser << "Content-Length: 21\r\n"
|
190
|
+
parser << "\r\n<h1>Hello: world</h1>"
|
191
|
+
|
192
|
+
assert_equal(200, code)
|
193
|
+
assert_equal("OK", message)
|
194
|
+
assert_equal({"Content-Length" => "21"}, headers)
|
195
|
+
assert_equal("<h1>Hello: world</h1>", body)
|
196
|
+
assert(parser.finished?, "parser should be finished")
|
197
|
+
end
|
198
|
+
|
199
|
+
def test_lazy_server
|
200
|
+
parser = HTTPTools::Parser.new
|
201
|
+
code, message, headers, body = nil
|
202
|
+
|
203
|
+
parser.add_listener(:status) {|c, m| code, message = c, m}
|
204
|
+
parser.add_listener(:headers) {|h| headers = h}
|
205
|
+
parser.add_listener(:body) {|b| body = b}
|
206
|
+
|
207
|
+
parser << "HTTP/1.1 200 OK\n"
|
208
|
+
parser << "Content-Type: text/html; charset=utf-8\n"
|
209
|
+
parser << "Connection: close\n\n"
|
210
|
+
parser << "<h1>hello world</h1>"
|
211
|
+
parser.finish # notify parser the connection has closed
|
212
|
+
|
213
|
+
assert_equal(200, code)
|
214
|
+
assert_equal("OK", message)
|
215
|
+
assert_equal({"Content-Type" => "text/html; charset=utf-8", "Connection" => "close"}, headers)
|
216
|
+
assert_equal("<h1>hello world</h1>", body)
|
217
|
+
assert(parser.finished?, "parser should be finished")
|
218
|
+
end
|
219
|
+
|
220
|
+
def test_chunked
|
221
|
+
parser = HTTPTools::Parser.new
|
222
|
+
code, message, headers, body = nil
|
223
|
+
|
224
|
+
parser.add_listener(:status) {|c, m| code, message = c, m}
|
225
|
+
parser.add_listener(:headers) {|h| headers = h}
|
226
|
+
parser.add_listener(:body) {|b| body = b}
|
227
|
+
|
228
|
+
parser << "HTTP/1.1 200 OK\r\n"
|
229
|
+
parser << "Transfer-Encoding: chunked\r\n"
|
230
|
+
parser << "\r\n"
|
231
|
+
parser << "14\r\n"
|
232
|
+
parser << "<h1>Hello world</h1>\r\n"
|
233
|
+
parser << "0\r\n"
|
234
|
+
|
235
|
+
assert_equal(200, code)
|
236
|
+
assert_equal("OK", message)
|
237
|
+
assert_equal({"Transfer-Encoding" => "chunked"}, headers)
|
238
|
+
assert_equal("<h1>Hello world</h1>", body)
|
239
|
+
assert(parser.finished?, "parser should be finished")
|
240
|
+
end
|
241
|
+
|
242
|
+
def test_chunked_stream
|
243
|
+
parser = HTTPTools::Parser.new
|
244
|
+
code, message, headers = nil
|
245
|
+
body = []
|
246
|
+
|
247
|
+
parser.add_listener(:status) {|c, m| code, message = c, m}
|
248
|
+
parser.add_listener(:headers) {|h| headers = h}
|
249
|
+
parser.add_listener(:stream) {|b| body << b}
|
250
|
+
|
251
|
+
parser << "HTTP/1.1 200 OK\r\n"
|
252
|
+
parser << "Transfer-Encoding: chunked\r\n"
|
253
|
+
parser << "\r\n"
|
254
|
+
parser << "9\r\n<h1>Hello\r\n"
|
255
|
+
parser << "b\r\n world</h1>\r\n"
|
256
|
+
parser << "0\r\n"
|
257
|
+
|
258
|
+
assert_equal(200, code)
|
259
|
+
assert_equal("OK", message)
|
260
|
+
assert_equal({"Transfer-Encoding" => "chunked"}, headers)
|
261
|
+
assert_equal(["<h1>Hello", " world</h1>"], body)
|
262
|
+
assert(parser.finished?, "parser should be finished")
|
263
|
+
end
|
264
|
+
|
265
|
+
def test_chunked_stream_with_multiple_chunks_at_once
|
266
|
+
parser = HTTPTools::Parser.new
|
267
|
+
code, message, headers = nil
|
268
|
+
body = []
|
269
|
+
|
270
|
+
parser.add_listener(:status) {|c, m| code, message = c, m}
|
271
|
+
parser.add_listener(:headers) {|h| headers = h}
|
272
|
+
parser.add_listener(:stream) {|b| body << b}
|
273
|
+
|
274
|
+
parser << "HTTP/1.1 200 OK\r\n"
|
275
|
+
parser << "Transfer-Encoding: chunked\r\n"
|
276
|
+
parser << "\r\n"
|
277
|
+
parser << "9\r\n<h1>Hello\r\nb\r\n world</h1>\r\n"
|
278
|
+
parser << "12\r\n<p>Lorem ipsum</p>\r\n"
|
279
|
+
parser << "0\r\n"
|
280
|
+
|
281
|
+
assert_equal(200, code)
|
282
|
+
assert_equal("OK", message)
|
283
|
+
assert_equal({"Transfer-Encoding" => "chunked"}, headers)
|
284
|
+
assert_equal(["<h1>Hello world</h1>", "<p>Lorem ipsum</p>"], body)
|
285
|
+
assert(parser.finished?, "parser should be finished")
|
286
|
+
end
|
287
|
+
|
288
|
+
def test_finished
|
289
|
+
parser = HTTPTools::Parser.new
|
290
|
+
code, message, body, remainder = nil
|
291
|
+
|
292
|
+
parser.add_listener(:status) {|c, m| code, message = c, m}
|
293
|
+
parser.add_listener(:body) {|b| body = b}
|
294
|
+
parser.add_listener(:finished) {|r| remainder = r}
|
295
|
+
|
296
|
+
parser << "HTTP/1.1 200 OK\r\nContent-Length: 20\r\n\r\n"
|
297
|
+
parser << "<h1>Hello world</h1>HTTP/1.1 404 Not Found\r\n"
|
298
|
+
|
299
|
+
assert_equal(200, code)
|
300
|
+
assert_equal("OK", message)
|
301
|
+
assert_equal("<h1>Hello world</h1>", body)
|
302
|
+
assert_equal("HTTP/1.1 404 Not Found\r\n", remainder)
|
303
|
+
assert(parser.finished?, "parser should be finished")
|
304
|
+
end
|
305
|
+
|
306
|
+
def test_finished_chunked
|
307
|
+
parser = HTTPTools::Parser.new
|
308
|
+
code, message, body, remainder = nil
|
309
|
+
|
310
|
+
parser.add_listener(:status) {|c, m| code, message = c, m}
|
311
|
+
parser.add_listener(:body) {|b| body = b}
|
312
|
+
parser.add_listener(:finished) {|r| remainder = r}
|
313
|
+
|
314
|
+
parser << "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"
|
315
|
+
parser << "14\r\n<h1>Hello world</h1>\r\n0\r\nHTTP/1.1 404 Not Found\r\n"
|
316
|
+
|
317
|
+
assert_equal(200, code)
|
318
|
+
assert_equal("OK", message)
|
319
|
+
assert_equal("<h1>Hello world</h1>", body)
|
320
|
+
assert_equal("HTTP/1.1 404 Not Found\r\n", remainder)
|
321
|
+
assert(parser.finished?, "parser should be finished")
|
322
|
+
end
|
323
|
+
|
324
|
+
def test_trailer
|
325
|
+
parser = HTTPTools::Parser.new
|
326
|
+
trailer = nil
|
327
|
+
|
328
|
+
parser.add_listener(:trailer) {|t| trailer = t}
|
329
|
+
|
330
|
+
parser << "HTTP/1.1 200 OK\r\n"
|
331
|
+
parser << "Transfer-Encoding: chunked\r\nTrailer: X-Checksum\r\n\r\n"
|
332
|
+
parser << "14\r\n<h1>Hello world</h1>\r\n0\r\n"
|
333
|
+
parser << "X-Checksum: 2a2e12c8edad17de62354ea4531ac82c\r\n\r\n"
|
334
|
+
|
335
|
+
assert_equal({"X-Checksum" => "2a2e12c8edad17de62354ea4531ac82c"}, trailer)
|
336
|
+
assert(parser.finished?, "parser should be finished")
|
337
|
+
end
|
338
|
+
|
339
|
+
def test_trailer_sub_line_chunks
|
340
|
+
parser = HTTPTools::Parser.new
|
341
|
+
trailer = nil
|
342
|
+
|
343
|
+
parser.add_listener(:trailer) {|t| trailer = t}
|
344
|
+
|
345
|
+
parser << "HTTP/1.1 200 OK\r\n"
|
346
|
+
parser << "Transfer-Encoding: chunked\r\nTrailer: X-Checksum\r\n\r\n"
|
347
|
+
parser << "14\r\n<h1>Hello world</h1>\r\n0\r\nX-Chec"
|
348
|
+
parser << "ksum: 2a2e12c8eda"
|
349
|
+
parser << "d17de62354ea4531ac82c\r\n\r\n"
|
350
|
+
|
351
|
+
assert_equal({"X-Checksum" => "2a2e12c8edad17de62354ea4531ac82c"}, trailer)
|
352
|
+
assert(parser.finished?, "parser should be finished")
|
353
|
+
end
|
354
|
+
|
355
|
+
def test_force_trailer
|
356
|
+
parser = HTTPTools::Parser.new
|
357
|
+
trailer = nil
|
358
|
+
|
359
|
+
parser.add_listener(:trailer) {|t| trailer = t}
|
360
|
+
|
361
|
+
parser.force_trailer = true
|
362
|
+
|
363
|
+
parser << "HTTP/1.1 200 OK\r\n"
|
364
|
+
parser << "Transfer-Encoding: chunked\r\n\r\n"
|
365
|
+
parser << "14\r\n<h1>Hello world</h1>\r\n0\r\n"
|
366
|
+
parser << "X-Checksum: 2a2e12c8edad17de62354ea4531ac82c\r\n\r\n"
|
367
|
+
|
368
|
+
assert_equal({"X-Checksum" => "2a2e12c8edad17de62354ea4531ac82c"}, trailer)
|
369
|
+
assert(parser.finished?, "parser should be finished")
|
370
|
+
end
|
371
|
+
|
372
|
+
def test_error_on_unallowed_trailer
|
373
|
+
parser = HTTPTools::Parser.new
|
374
|
+
|
375
|
+
parser << "HTTP/1.1 200 OK\r\n"
|
376
|
+
parser << "Content-Length: 20\r\n\r\n"
|
377
|
+
parser << "<h1>Hello world</h1>"
|
378
|
+
|
379
|
+
assert_raise(HTTPTools::EndOfMessageError) do
|
380
|
+
parser << "X-Checksum: 2a2e12c8edad17de62354ea4531ac82c\r\n\r\n"
|
381
|
+
end
|
382
|
+
end
|
383
|
+
|
384
|
+
def test_error_on_unexpected_trailer
|
385
|
+
parser = HTTPTools::Parser.new
|
386
|
+
|
387
|
+
parser << "HTTP/1.1 200 OK\r\n"
|
388
|
+
parser << "Transfer-Encoding: chunked\r\n\r\n"
|
389
|
+
parser << "14\r\n<h1>Hello world</h1>\r\n0\r\n"
|
390
|
+
|
391
|
+
assert_raise(HTTPTools::EndOfMessageError) do
|
392
|
+
parser << "X-Checksum: 2a2e12c8edad17de62354ea4531ac82c\r\n\r\n"
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
def test_invalid_trailer_key
|
397
|
+
parser = HTTPTools::Parser.new
|
398
|
+
trailer = nil
|
399
|
+
|
400
|
+
parser.add_listener(:trailer) {|t| trailer = t}
|
401
|
+
|
402
|
+
parser << "HTTP/1.1 200 OK\r\n"
|
403
|
+
parser << "Transfer-Encoding: chunked\r\nTrailer: X-Checksum\r\n\r\n"
|
404
|
+
parser << "14\r\n<h1>Hello world</h1>\r\n0\r\n"
|
405
|
+
|
406
|
+
assert_raise(HTTPTools::ParseError) do
|
407
|
+
parser << "x-invalid key: value\r\n\r\n"
|
408
|
+
end
|
409
|
+
end
|
410
|
+
|
411
|
+
def test_invalid_trailer_value
|
412
|
+
parser = HTTPTools::Parser.new
|
413
|
+
trailer = nil
|
414
|
+
|
415
|
+
parser.add_listener(:trailer) {|t| trailer = t}
|
416
|
+
|
417
|
+
parser << "HTTP/1.1 200 OK\r\n"
|
418
|
+
parser << "Transfer-Encoding: chunked\r\nTrailer: X-Checksum\r\n\r\n"
|
419
|
+
parser << "14\r\n<h1>Hello world</h1>\r\n0\r\n"
|
420
|
+
|
421
|
+
assert_raise(HTTPTools::ParseError) do
|
422
|
+
parser << "x-test: inva\0lid\r\n\r\n"
|
423
|
+
end
|
424
|
+
end
|
425
|
+
|
426
|
+
def test_invalid_version
|
427
|
+
parser = HTTPTools::Parser.new
|
428
|
+
|
429
|
+
assert_raise(HTTPTools::ParseError) {parser << "HTTP/one dot one 200 OK"}
|
430
|
+
end
|
431
|
+
|
432
|
+
def test_invalid_status
|
433
|
+
parser = HTTPTools::Parser.new
|
434
|
+
|
435
|
+
assert_raise(HTTPTools::ParseError) {parser << "HTTP/1.1 0 Fail"}
|
436
|
+
end
|
437
|
+
|
438
|
+
def test_finish_early
|
439
|
+
parser = HTTPTools::Parser.new
|
440
|
+
|
441
|
+
parser << "HTTP/1.1 200 OK\r\n"
|
442
|
+
|
443
|
+
assert_raise(HTTPTools::MessageIncompleteError) {parser.finish}
|
444
|
+
end
|
445
|
+
|
446
|
+
end
|
data/test/runner.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Dir["**/*_test.rb"].each {|test| require test}
|
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: http_tools
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Matthew Sadler
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-01-09 00:00:00 +00:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: A collection of lower level utilities to aid working with HTTP, including a fast-as-possible pure Ruby HTTP parser.
|
23
|
+
email: mat@sourcetagsandcodes.com
|
24
|
+
executables: []
|
25
|
+
|
26
|
+
extensions: []
|
27
|
+
|
28
|
+
extra_rdoc_files:
|
29
|
+
- README.rdoc
|
30
|
+
files:
|
31
|
+
- lib/http_tools/builder.rb
|
32
|
+
- lib/http_tools/encoding.rb
|
33
|
+
- lib/http_tools/errors.rb
|
34
|
+
- lib/http_tools/parser.rb
|
35
|
+
- lib/http_tools.rb
|
36
|
+
- test/builder/request_test.rb
|
37
|
+
- test/builder/response_test.rb
|
38
|
+
- test/cover.rb
|
39
|
+
- test/encoding/transfer_encoding_chunked_test.rb
|
40
|
+
- test/encoding/url_encoding_test.rb
|
41
|
+
- test/encoding/www_form_test.rb
|
42
|
+
- test/parser/request_test.rb
|
43
|
+
- test/parser/response_test.rb
|
44
|
+
- test/runner.rb
|
45
|
+
- bench/parser/request_bench.rb
|
46
|
+
- bench/parser/response_bench.rb
|
47
|
+
- profile/parser/request_profile.rb
|
48
|
+
- profile/parser/response_profile.rb
|
49
|
+
- example/http_client.rb
|
50
|
+
- README.rdoc
|
51
|
+
has_rdoc: true
|
52
|
+
homepage: http://github.com/matsadler/http_tools
|
53
|
+
licenses: []
|
54
|
+
|
55
|
+
post_install_message:
|
56
|
+
rdoc_options:
|
57
|
+
- --main
|
58
|
+
- README.rdoc
|
59
|
+
- --charset
|
60
|
+
- utf-8
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
hash: 3
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
version: "0"
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
hash: 3
|
78
|
+
segments:
|
79
|
+
- 0
|
80
|
+
version: "0"
|
81
|
+
requirements: []
|
82
|
+
|
83
|
+
rubyforge_project:
|
84
|
+
rubygems_version: 1.3.7
|
85
|
+
signing_key:
|
86
|
+
specification_version: 3
|
87
|
+
summary: Pure Ruby HTTP parser and friends
|
88
|
+
test_files: []
|
89
|
+
|