em-http-request 1.0.0 → 1.0.1
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.
Potentially problematic release.
This version of em-http-request might be problematic. Click here for more details.
- data/.gitignore +2 -0
- data/README.md +4 -2
- data/em-http-request.gemspec +33 -33
- data/examples/fibered-http.rb +51 -47
- data/lib/em-http/client.rb +307 -275
- data/lib/em-http/http_client_options.rb +1 -0
- data/lib/em-http/http_connection.rb +199 -194
- data/lib/em-http/http_connection_options.rb +6 -1
- data/lib/em-http/http_encoding.rb +2 -2
- data/lib/em-http/http_header.rb +4 -0
- data/lib/em-http/http_status_codes.rb +51 -37
- data/lib/em-http/multi.rb +4 -2
- data/lib/em-http/version.rb +5 -5
- data/spec/client_fiber_spec.rb +21 -0
- data/spec/client_spec.rb +734 -669
- data/spec/encoding_spec.rb +11 -2
- data/spec/external_spec.rb +128 -127
- data/spec/helper.rb +2 -2
- data/spec/multi_spec.rb +9 -1
- data/spec/pipelining_spec.rb +66 -38
- data/spec/redirect_spec.rb +55 -3
- data/spec/socksify_proxy_spec.rb +24 -24
- data/spec/stallion.rb +273 -270
- data/spec/stub_server.rb +25 -5
- metadata +34 -31
data/lib/em-http/multi.rb
CHANGED
@@ -29,12 +29,14 @@ module EventMachine
|
|
29
29
|
attr_reader :requests, :responses
|
30
30
|
|
31
31
|
def initialize
|
32
|
-
@requests =
|
32
|
+
@requests = {}
|
33
33
|
@responses = {:callback => {}, :errback => {}}
|
34
34
|
end
|
35
35
|
|
36
36
|
def add(name, conn)
|
37
|
-
@requests.
|
37
|
+
raise 'Duplicate Multi key' if @requests.key? name
|
38
|
+
|
39
|
+
@requests[name] = conn
|
38
40
|
|
39
41
|
conn.callback { @responses[:callback][name] = conn; check_progress }
|
40
42
|
conn.errback { @responses[:errback][name] = conn; check_progress }
|
data/lib/em-http/version.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
module EventMachine
|
2
|
-
class HttpRequest
|
3
|
-
VERSION = "1.0.
|
4
|
-
end
|
5
|
-
end
|
1
|
+
module EventMachine
|
2
|
+
class HttpRequest
|
3
|
+
VERSION = "1.0.1"
|
4
|
+
end
|
5
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'fiber'
|
3
|
+
|
4
|
+
describe EventMachine::HttpRequest do
|
5
|
+
context "with fibers" do
|
6
|
+
it "should be transparent to connexion errors" do
|
7
|
+
EventMachine.run do
|
8
|
+
Fiber.new do
|
9
|
+
f = Fiber.current
|
10
|
+
http = EventMachine::HttpRequest.new('http://non-existing.domain/').get
|
11
|
+
http.callback {failed(http)}
|
12
|
+
http.errback {f.resume}
|
13
|
+
Fiber.yield
|
14
|
+
EventMachine.stop
|
15
|
+
end.resume
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
|
data/spec/client_spec.rb
CHANGED
@@ -1,669 +1,734 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
describe EventMachine::HttpRequest do
|
4
|
-
|
5
|
-
def failed(http=nil)
|
6
|
-
EventMachine.stop
|
7
|
-
http ? fail(http.error) : fail
|
8
|
-
end
|
9
|
-
|
10
|
-
it "should perform successful GET" do
|
11
|
-
EventMachine.run {
|
12
|
-
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/').get
|
13
|
-
|
14
|
-
http.errback { failed(http) }
|
15
|
-
http.callback {
|
16
|
-
http.response_header.status.should == 200
|
17
|
-
http.response.should match(/Hello/)
|
18
|
-
EventMachine.stop
|
19
|
-
}
|
20
|
-
}
|
21
|
-
end
|
22
|
-
|
23
|
-
it "should perform successful GET with a URI passed as argument" do
|
24
|
-
EventMachine.run {
|
25
|
-
uri = URI.parse('http://127.0.0.1:8090/')
|
26
|
-
http = EventMachine::HttpRequest.new(uri).get
|
27
|
-
|
28
|
-
http.errback { failed(http) }
|
29
|
-
http.callback {
|
30
|
-
http.response_header.status.should == 200
|
31
|
-
http.response.should match(/Hello/)
|
32
|
-
EventMachine.stop
|
33
|
-
}
|
34
|
-
}
|
35
|
-
end
|
36
|
-
|
37
|
-
it "should succeed GET on missing path" do
|
38
|
-
EventMachine.run {
|
39
|
-
lambda {
|
40
|
-
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090').get
|
41
|
-
http.callback {
|
42
|
-
http.response.should match(/Hello/)
|
43
|
-
EventMachine.stop
|
44
|
-
}
|
45
|
-
}.should_not raise_error(ArgumentError)
|
46
|
-
|
47
|
-
}
|
48
|
-
end
|
49
|
-
|
50
|
-
it "should raise error on invalid URL" do
|
51
|
-
EventMachine.run {
|
52
|
-
lambda {
|
53
|
-
EventMachine::HttpRequest.new('random?text').get
|
54
|
-
}.should raise_error
|
55
|
-
|
56
|
-
EM.stop
|
57
|
-
}
|
58
|
-
end
|
59
|
-
|
60
|
-
it "should perform successful HEAD with a URI passed as argument" do
|
61
|
-
EventMachine.run {
|
62
|
-
uri = URI.parse('http://127.0.0.1:8090/')
|
63
|
-
http = EventMachine::HttpRequest.new(uri).head
|
64
|
-
|
65
|
-
http.errback { failed(http) }
|
66
|
-
http.callback {
|
67
|
-
http.response_header.status.should == 200
|
68
|
-
http.response.should == ""
|
69
|
-
EventMachine.stop
|
70
|
-
}
|
71
|
-
}
|
72
|
-
end
|
73
|
-
|
74
|
-
it "should perform successful DELETE with a URI passed as argument" do
|
75
|
-
EventMachine.run {
|
76
|
-
uri = URI.parse('http://127.0.0.1:8090/')
|
77
|
-
http = EventMachine::HttpRequest.new(uri).delete
|
78
|
-
|
79
|
-
http.errback { failed(http) }
|
80
|
-
http.callback {
|
81
|
-
http.response_header.status.should == 200
|
82
|
-
http.response.should == ""
|
83
|
-
EventMachine.stop
|
84
|
-
}
|
85
|
-
}
|
86
|
-
end
|
87
|
-
|
88
|
-
it "should return 404 on invalid path" do
|
89
|
-
EventMachine.run {
|
90
|
-
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/fail').get
|
91
|
-
|
92
|
-
http.errback { failed(http) }
|
93
|
-
http.callback {
|
94
|
-
http.response_header.status.should == 404
|
95
|
-
EventMachine.stop
|
96
|
-
}
|
97
|
-
}
|
98
|
-
end
|
99
|
-
|
100
|
-
it "should return HTTP reason" do
|
101
|
-
EventMachine.run {
|
102
|
-
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/fail').get
|
103
|
-
|
104
|
-
http.errback { failed(http) }
|
105
|
-
http.callback {
|
106
|
-
http.response_header.status.should == 404
|
107
|
-
http.response_header.http_reason.should == 'Not Found'
|
108
|
-
EventMachine.stop
|
109
|
-
}
|
110
|
-
}
|
111
|
-
end
|
112
|
-
|
113
|
-
it "should return HTTP reason 'unknown' on a non-standard status code" do
|
114
|
-
EventMachine.run {
|
115
|
-
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/fail_with_nonstandard_response').get
|
116
|
-
|
117
|
-
http.errback { failed(http) }
|
118
|
-
http.callback {
|
119
|
-
http.response_header.status.should == 420
|
120
|
-
http.response_header.http_reason.should == 'unknown'
|
121
|
-
EventMachine.stop
|
122
|
-
}
|
123
|
-
}
|
124
|
-
end
|
125
|
-
|
126
|
-
it "should build query parameters from Hash" do
|
127
|
-
EventMachine.run {
|
128
|
-
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/').get :query => {:q => 'test'}
|
129
|
-
|
130
|
-
http.errback { failed(http) }
|
131
|
-
http.callback {
|
132
|
-
http.response_header.status.should == 200
|
133
|
-
http.response.should match(/test/)
|
134
|
-
EventMachine.stop
|
135
|
-
}
|
136
|
-
}
|
137
|
-
end
|
138
|
-
|
139
|
-
it "should pass query parameters string" do
|
140
|
-
EventMachine.run {
|
141
|
-
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/').get :query => "q=test"
|
142
|
-
|
143
|
-
http.errback { failed(http) }
|
144
|
-
http.callback {
|
145
|
-
http.response_header.status.should == 200
|
146
|
-
http.response.should match(/test/)
|
147
|
-
EventMachine.stop
|
148
|
-
}
|
149
|
-
}
|
150
|
-
end
|
151
|
-
|
152
|
-
it "should encode an array of query parameters" do
|
153
|
-
EventMachine.run {
|
154
|
-
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/echo_query').get :query => {:hash =>['value1','value2']}
|
155
|
-
|
156
|
-
http.errback { failed(http) }
|
157
|
-
http.callback {
|
158
|
-
http.response_header.status.should == 200
|
159
|
-
http.response.should match(/hash\[\]=value1&hash\[\]=value2/)
|
160
|
-
EventMachine.stop
|
161
|
-
}
|
162
|
-
}
|
163
|
-
end
|
164
|
-
|
165
|
-
it "should perform successful PUT" do
|
166
|
-
EventMachine.run {
|
167
|
-
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/').put :body => "data"
|
168
|
-
|
169
|
-
http.errback { failed(http) }
|
170
|
-
http.callback {
|
171
|
-
http.response_header.status.should == 200
|
172
|
-
http.response.should match(/data/)
|
173
|
-
EventMachine.stop
|
174
|
-
}
|
175
|
-
}
|
176
|
-
end
|
177
|
-
|
178
|
-
it "should perform successful POST" do
|
179
|
-
EventMachine.run {
|
180
|
-
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/').post :body => "data"
|
181
|
-
|
182
|
-
http.errback { failed(http) }
|
183
|
-
http.callback {
|
184
|
-
http.response_header.status.should == 200
|
185
|
-
http.response.should match(/data/)
|
186
|
-
EventMachine.stop
|
187
|
-
}
|
188
|
-
}
|
189
|
-
end
|
190
|
-
|
191
|
-
it "should escape body on POST" do
|
192
|
-
EventMachine.run {
|
193
|
-
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/').post :body => {:stuff => 'string&string'}
|
194
|
-
|
195
|
-
http.errback { failed(http) }
|
196
|
-
http.callback {
|
197
|
-
http.response_header.status.should == 200
|
198
|
-
http.response.should == "stuff=string%26string"
|
199
|
-
EventMachine.stop
|
200
|
-
}
|
201
|
-
}
|
202
|
-
end
|
203
|
-
|
204
|
-
it "should perform successful POST with Ruby Hash/Array as params" do
|
205
|
-
EventMachine.run {
|
206
|
-
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/').post :body => {"key1" => 1, "key2" => [2,3]}
|
207
|
-
|
208
|
-
http.errback { failed(http) }
|
209
|
-
http.callback {
|
210
|
-
http.response_header.status.should == 200
|
211
|
-
|
212
|
-
http.response.should match(/key1=1&key2\[0\]=2&key2\[1\]=3/)
|
213
|
-
EventMachine.stop
|
214
|
-
}
|
215
|
-
}
|
216
|
-
end
|
217
|
-
|
218
|
-
it "should
|
219
|
-
EventMachine.run {
|
220
|
-
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/
|
221
|
-
|
222
|
-
http.errback { failed(http) }
|
223
|
-
http.callback {
|
224
|
-
http.response_header.status.should == 200
|
225
|
-
|
226
|
-
http.response.
|
227
|
-
EventMachine.stop
|
228
|
-
}
|
229
|
-
}
|
230
|
-
end
|
231
|
-
|
232
|
-
it "should perform successful
|
233
|
-
EventMachine.run {
|
234
|
-
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/').
|
235
|
-
|
236
|
-
http.errback {
|
237
|
-
http.callback {
|
238
|
-
http.response_header.status.should ==
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
http.
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
}
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
http.
|
311
|
-
|
312
|
-
http.response_header.
|
313
|
-
http.
|
314
|
-
EventMachine.stop
|
315
|
-
}
|
316
|
-
}
|
317
|
-
end
|
318
|
-
|
319
|
-
it "should
|
320
|
-
EventMachine.run {
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
http.
|
325
|
-
|
326
|
-
http.response_header.
|
327
|
-
http.response_header
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
http
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
http.
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
(
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
}
|
385
|
-
end
|
386
|
-
|
387
|
-
it "should
|
388
|
-
EventMachine.run {
|
389
|
-
|
390
|
-
|
391
|
-
http
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
http.
|
419
|
-
|
420
|
-
http.
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/echo_content_type').post
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
http.
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
http.response_header.
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
http.response_header.
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
}
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
http
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
http
|
558
|
-
|
559
|
-
http.
|
560
|
-
|
561
|
-
http.response_header.
|
562
|
-
http.
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
http.
|
574
|
-
|
575
|
-
http.response_header.
|
576
|
-
http.response_header.cookie.
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
http
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
http.
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
http
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
http.
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
http
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
http.
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
end
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe EventMachine::HttpRequest do
|
4
|
+
|
5
|
+
def failed(http=nil)
|
6
|
+
EventMachine.stop
|
7
|
+
http ? fail(http.error) : fail
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should perform successful GET" do
|
11
|
+
EventMachine.run {
|
12
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/').get
|
13
|
+
|
14
|
+
http.errback { failed(http) }
|
15
|
+
http.callback {
|
16
|
+
http.response_header.status.should == 200
|
17
|
+
http.response.should match(/Hello/)
|
18
|
+
EventMachine.stop
|
19
|
+
}
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should perform successful GET with a URI passed as argument" do
|
24
|
+
EventMachine.run {
|
25
|
+
uri = URI.parse('http://127.0.0.1:8090/')
|
26
|
+
http = EventMachine::HttpRequest.new(uri).get
|
27
|
+
|
28
|
+
http.errback { failed(http) }
|
29
|
+
http.callback {
|
30
|
+
http.response_header.status.should == 200
|
31
|
+
http.response.should match(/Hello/)
|
32
|
+
EventMachine.stop
|
33
|
+
}
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should succeed GET on missing path" do
|
38
|
+
EventMachine.run {
|
39
|
+
lambda {
|
40
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090').get
|
41
|
+
http.callback {
|
42
|
+
http.response.should match(/Hello/)
|
43
|
+
EventMachine.stop
|
44
|
+
}
|
45
|
+
}.should_not raise_error(ArgumentError)
|
46
|
+
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should raise error on invalid URL" do
|
51
|
+
EventMachine.run {
|
52
|
+
lambda {
|
53
|
+
EventMachine::HttpRequest.new('random?text').get
|
54
|
+
}.should raise_error
|
55
|
+
|
56
|
+
EM.stop
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should perform successful HEAD with a URI passed as argument" do
|
61
|
+
EventMachine.run {
|
62
|
+
uri = URI.parse('http://127.0.0.1:8090/')
|
63
|
+
http = EventMachine::HttpRequest.new(uri).head
|
64
|
+
|
65
|
+
http.errback { failed(http) }
|
66
|
+
http.callback {
|
67
|
+
http.response_header.status.should == 200
|
68
|
+
http.response.should == ""
|
69
|
+
EventMachine.stop
|
70
|
+
}
|
71
|
+
}
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should perform successful DELETE with a URI passed as argument" do
|
75
|
+
EventMachine.run {
|
76
|
+
uri = URI.parse('http://127.0.0.1:8090/')
|
77
|
+
http = EventMachine::HttpRequest.new(uri).delete
|
78
|
+
|
79
|
+
http.errback { failed(http) }
|
80
|
+
http.callback {
|
81
|
+
http.response_header.status.should == 200
|
82
|
+
http.response.should == ""
|
83
|
+
EventMachine.stop
|
84
|
+
}
|
85
|
+
}
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should return 404 on invalid path" do
|
89
|
+
EventMachine.run {
|
90
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/fail').get
|
91
|
+
|
92
|
+
http.errback { failed(http) }
|
93
|
+
http.callback {
|
94
|
+
http.response_header.status.should == 404
|
95
|
+
EventMachine.stop
|
96
|
+
}
|
97
|
+
}
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should return HTTP reason" do
|
101
|
+
EventMachine.run {
|
102
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/fail').get
|
103
|
+
|
104
|
+
http.errback { failed(http) }
|
105
|
+
http.callback {
|
106
|
+
http.response_header.status.should == 404
|
107
|
+
http.response_header.http_reason.should == 'Not Found'
|
108
|
+
EventMachine.stop
|
109
|
+
}
|
110
|
+
}
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should return HTTP reason 'unknown' on a non-standard status code" do
|
114
|
+
EventMachine.run {
|
115
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/fail_with_nonstandard_response').get
|
116
|
+
|
117
|
+
http.errback { failed(http) }
|
118
|
+
http.callback {
|
119
|
+
http.response_header.status.should == 420
|
120
|
+
http.response_header.http_reason.should == 'unknown'
|
121
|
+
EventMachine.stop
|
122
|
+
}
|
123
|
+
}
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should build query parameters from Hash" do
|
127
|
+
EventMachine.run {
|
128
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/').get :query => {:q => 'test'}
|
129
|
+
|
130
|
+
http.errback { failed(http) }
|
131
|
+
http.callback {
|
132
|
+
http.response_header.status.should == 200
|
133
|
+
http.response.should match(/test/)
|
134
|
+
EventMachine.stop
|
135
|
+
}
|
136
|
+
}
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should pass query parameters string" do
|
140
|
+
EventMachine.run {
|
141
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/').get :query => "q=test"
|
142
|
+
|
143
|
+
http.errback { failed(http) }
|
144
|
+
http.callback {
|
145
|
+
http.response_header.status.should == 200
|
146
|
+
http.response.should match(/test/)
|
147
|
+
EventMachine.stop
|
148
|
+
}
|
149
|
+
}
|
150
|
+
end
|
151
|
+
|
152
|
+
it "should encode an array of query parameters" do
|
153
|
+
EventMachine.run {
|
154
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/echo_query').get :query => {:hash =>['value1','value2']}
|
155
|
+
|
156
|
+
http.errback { failed(http) }
|
157
|
+
http.callback {
|
158
|
+
http.response_header.status.should == 200
|
159
|
+
http.response.should match(/hash\[\]=value1&hash\[\]=value2/)
|
160
|
+
EventMachine.stop
|
161
|
+
}
|
162
|
+
}
|
163
|
+
end
|
164
|
+
|
165
|
+
it "should perform successful PUT" do
|
166
|
+
EventMachine.run {
|
167
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/').put :body => "data"
|
168
|
+
|
169
|
+
http.errback { failed(http) }
|
170
|
+
http.callback {
|
171
|
+
http.response_header.status.should == 200
|
172
|
+
http.response.should match(/data/)
|
173
|
+
EventMachine.stop
|
174
|
+
}
|
175
|
+
}
|
176
|
+
end
|
177
|
+
|
178
|
+
it "should perform successful POST" do
|
179
|
+
EventMachine.run {
|
180
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/').post :body => "data"
|
181
|
+
|
182
|
+
http.errback { failed(http) }
|
183
|
+
http.callback {
|
184
|
+
http.response_header.status.should == 200
|
185
|
+
http.response.should match(/data/)
|
186
|
+
EventMachine.stop
|
187
|
+
}
|
188
|
+
}
|
189
|
+
end
|
190
|
+
|
191
|
+
it "should escape body on POST" do
|
192
|
+
EventMachine.run {
|
193
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/').post :body => {:stuff => 'string&string'}
|
194
|
+
|
195
|
+
http.errback { failed(http) }
|
196
|
+
http.callback {
|
197
|
+
http.response_header.status.should == 200
|
198
|
+
http.response.should == "stuff=string%26string"
|
199
|
+
EventMachine.stop
|
200
|
+
}
|
201
|
+
}
|
202
|
+
end
|
203
|
+
|
204
|
+
it "should perform successful POST with Ruby Hash/Array as params" do
|
205
|
+
EventMachine.run {
|
206
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/').post :body => {"key1" => 1, "key2" => [2,3]}
|
207
|
+
|
208
|
+
http.errback { failed(http) }
|
209
|
+
http.callback {
|
210
|
+
http.response_header.status.should == 200
|
211
|
+
|
212
|
+
http.response.should match(/key1=1&key2\[0\]=2&key2\[1\]=3/)
|
213
|
+
EventMachine.stop
|
214
|
+
}
|
215
|
+
}
|
216
|
+
end
|
217
|
+
|
218
|
+
it "should set content-length to 0 on posts with empty bodies" do
|
219
|
+
EventMachine.run {
|
220
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/echo_content_length_from_header').post
|
221
|
+
|
222
|
+
http.errback { failed(http) }
|
223
|
+
http.callback {
|
224
|
+
http.response_header.status.should == 200
|
225
|
+
|
226
|
+
http.response.strip.split(':')[1].should == '0'
|
227
|
+
EventMachine.stop
|
228
|
+
}
|
229
|
+
}
|
230
|
+
end
|
231
|
+
|
232
|
+
it "should perform successful POST with Ruby Hash/Array as params and with the correct content length" do
|
233
|
+
EventMachine.run {
|
234
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/echo_content_length').post :body => {"key1" => "data1"}
|
235
|
+
|
236
|
+
http.errback { failed(http) }
|
237
|
+
http.callback {
|
238
|
+
http.response_header.status.should == 200
|
239
|
+
|
240
|
+
http.response.to_i.should == 10
|
241
|
+
EventMachine.stop
|
242
|
+
}
|
243
|
+
}
|
244
|
+
end
|
245
|
+
|
246
|
+
it "should perform successful GET with custom header" do
|
247
|
+
EventMachine.run {
|
248
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/').get :head => {'if-none-match' => 'evar!'}
|
249
|
+
|
250
|
+
http.errback { p http; failed(http) }
|
251
|
+
http.callback {
|
252
|
+
http.response_header.status.should == 304
|
253
|
+
EventMachine.stop
|
254
|
+
}
|
255
|
+
}
|
256
|
+
end
|
257
|
+
|
258
|
+
it "should perform basic auth" do
|
259
|
+
EventMachine.run {
|
260
|
+
|
261
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/').get :head => {'authorization' => ['user', 'pass']}
|
262
|
+
|
263
|
+
http.errback { failed(http) }
|
264
|
+
http.callback {
|
265
|
+
http.response_header.status.should == 200
|
266
|
+
EventMachine.stop
|
267
|
+
}
|
268
|
+
}
|
269
|
+
end
|
270
|
+
|
271
|
+
it "should return peer's IP address" do
|
272
|
+
EventMachine.run {
|
273
|
+
|
274
|
+
conn = EventMachine::HttpRequest.new('http://127.0.0.1:8090/')
|
275
|
+
conn.peer.should be_nil
|
276
|
+
|
277
|
+
http = conn.get
|
278
|
+
http.peer.should be_nil
|
279
|
+
|
280
|
+
http.errback { failed(http) }
|
281
|
+
http.callback {
|
282
|
+
conn.peer.should == '127.0.0.1'
|
283
|
+
http.peer.should == '127.0.0.1'
|
284
|
+
|
285
|
+
EventMachine.stop
|
286
|
+
}
|
287
|
+
}
|
288
|
+
end
|
289
|
+
|
290
|
+
it "should remove all newlines from long basic auth header" do
|
291
|
+
EventMachine.run {
|
292
|
+
auth = {'authorization' => ['aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz']}
|
293
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/auth').get :head => auth
|
294
|
+
http.errback { failed(http) }
|
295
|
+
http.callback {
|
296
|
+
http.response_header.status.should == 200
|
297
|
+
http.response.should == "Basic YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhOnp6enp6enp6enp6enp6enp6enp6enp6enp6enp6eg=="
|
298
|
+
EventMachine.stop
|
299
|
+
}
|
300
|
+
}
|
301
|
+
end
|
302
|
+
|
303
|
+
it "should send proper OAuth auth header" do
|
304
|
+
EventMachine.run {
|
305
|
+
oauth_header = 'OAuth oauth_nonce="oqwgSYFUD87MHmJJDv7bQqOF2EPnVus7Wkqj5duNByU", b=c, d=e'
|
306
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/auth').get :head => {
|
307
|
+
'authorization' => oauth_header
|
308
|
+
}
|
309
|
+
|
310
|
+
http.errback { failed(http) }
|
311
|
+
http.callback {
|
312
|
+
http.response_header.status.should == 200
|
313
|
+
http.response.should == oauth_header
|
314
|
+
EventMachine.stop
|
315
|
+
}
|
316
|
+
}
|
317
|
+
end
|
318
|
+
|
319
|
+
it "should return ETag and Last-Modified headers" do
|
320
|
+
EventMachine.run {
|
321
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/echo_query').get
|
322
|
+
|
323
|
+
http.errback { failed(http) }
|
324
|
+
http.callback {
|
325
|
+
http.response_header.status.should == 200
|
326
|
+
http.response_header.etag.should match('abcdefg')
|
327
|
+
http.response_header.last_modified.should match('Fri, 13 Aug 2010 17:31:21 GMT')
|
328
|
+
EventMachine.stop
|
329
|
+
}
|
330
|
+
}
|
331
|
+
end
|
332
|
+
|
333
|
+
it "should detect deflate encoding" do
|
334
|
+
EventMachine.run {
|
335
|
+
|
336
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/deflate').get :head => {"accept-encoding" => "deflate"}
|
337
|
+
|
338
|
+
http.errback { failed(http) }
|
339
|
+
http.callback {
|
340
|
+
http.response_header.status.should == 200
|
341
|
+
http.response_header["CONTENT_ENCODING"].should == "deflate"
|
342
|
+
http.response.should == "compressed"
|
343
|
+
|
344
|
+
EventMachine.stop
|
345
|
+
}
|
346
|
+
}
|
347
|
+
end
|
348
|
+
|
349
|
+
it "should detect gzip encoding" do
|
350
|
+
EventMachine.run {
|
351
|
+
|
352
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/gzip').get :head => {
|
353
|
+
"accept-encoding" => "gzip, compressed"
|
354
|
+
}
|
355
|
+
|
356
|
+
http.errback { failed(http) }
|
357
|
+
http.callback {
|
358
|
+
http.response_header.status.should == 200
|
359
|
+
http.response_header["CONTENT_ENCODING"].should == "gzip"
|
360
|
+
http.response.should == "compressed"
|
361
|
+
|
362
|
+
EventMachine.stop
|
363
|
+
}
|
364
|
+
}
|
365
|
+
end
|
366
|
+
|
367
|
+
it "should not decode the response when configured so" do
|
368
|
+
EventMachine.run {
|
369
|
+
|
370
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/gzip').get :head => {
|
371
|
+
"accept-encoding" => "gzip, compressed"
|
372
|
+
}, :decoding => false
|
373
|
+
|
374
|
+
http.errback { failed(http) }
|
375
|
+
http.callback {
|
376
|
+
http.response_header.status.should == 200
|
377
|
+
http.response_header["CONTENT_ENCODING"].should == "gzip"
|
378
|
+
|
379
|
+
raw = http.response
|
380
|
+
Zlib::GzipReader.new(StringIO.new(raw)).read.should == "compressed"
|
381
|
+
|
382
|
+
EventMachine.stop
|
383
|
+
}
|
384
|
+
}
|
385
|
+
end
|
386
|
+
|
387
|
+
it "should timeout after 0.1 seconds of inactivity" do
|
388
|
+
EventMachine.run {
|
389
|
+
t = Time.now.to_i
|
390
|
+
EventMachine.heartbeat_interval = 0.1
|
391
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/timeout', :inactivity_timeout => 0.1).get
|
392
|
+
|
393
|
+
http.errback {
|
394
|
+
(Time.now.to_i - t).should <= 1
|
395
|
+
EventMachine.stop
|
396
|
+
}
|
397
|
+
http.callback { failed(http) }
|
398
|
+
}
|
399
|
+
end
|
400
|
+
|
401
|
+
it "should complete a Location: with a relative path" do
|
402
|
+
EventMachine.run {
|
403
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/relative-location').get
|
404
|
+
|
405
|
+
http.errback { failed(http) }
|
406
|
+
http.callback {
|
407
|
+
http.response_header['LOCATION'].should == 'http://127.0.0.1:8090/forwarded'
|
408
|
+
EventMachine.stop
|
409
|
+
}
|
410
|
+
}
|
411
|
+
end
|
412
|
+
|
413
|
+
context "body content-type encoding" do
|
414
|
+
it "should not set content type on string in body" do
|
415
|
+
EventMachine.run {
|
416
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/echo_content_type').post :body => "data"
|
417
|
+
|
418
|
+
http.errback { failed(http) }
|
419
|
+
http.callback {
|
420
|
+
http.response_header.status.should == 200
|
421
|
+
http.response.should be_empty
|
422
|
+
EventMachine.stop
|
423
|
+
}
|
424
|
+
}
|
425
|
+
end
|
426
|
+
|
427
|
+
it "should set content-type automatically when passed a ruby hash/array for body" do
|
428
|
+
EventMachine.run {
|
429
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/echo_content_type').post :body => {:a => :b}
|
430
|
+
|
431
|
+
http.errback { failed(http) }
|
432
|
+
http.callback {
|
433
|
+
http.response_header.status.should == 200
|
434
|
+
http.response.should match("application/x-www-form-urlencoded")
|
435
|
+
EventMachine.stop
|
436
|
+
}
|
437
|
+
}
|
438
|
+
end
|
439
|
+
|
440
|
+
it "should not override content-type when passing in ruby hash/array for body" do
|
441
|
+
EventMachine.run {
|
442
|
+
ct = 'text; charset=utf-8'
|
443
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/echo_content_type').post({
|
444
|
+
:body => {:a => :b}, :head => {'content-type' => ct}})
|
445
|
+
|
446
|
+
http.errback { failed(http) }
|
447
|
+
http.callback {
|
448
|
+
http.response_header.status.should == 200
|
449
|
+
http.content_charset.should == Encoding.find('utf-8') if defined? Encoding
|
450
|
+
http.response_header["CONTENT_TYPE"].should == ct
|
451
|
+
EventMachine.stop
|
452
|
+
}
|
453
|
+
}
|
454
|
+
end
|
455
|
+
|
456
|
+
it "should default to external encoding on invalid encoding" do
|
457
|
+
EventMachine.run {
|
458
|
+
ct = 'text/html; charset=utf-8lias'
|
459
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/echo_content_type').post({
|
460
|
+
:body => {:a => :b}, :head => {'content-type' => ct}})
|
461
|
+
|
462
|
+
http.errback { failed(http) }
|
463
|
+
http.callback {
|
464
|
+
http.response_header.status.should == 200
|
465
|
+
http.content_charset.should == Encoding.find('utf-8') if defined? Encoding
|
466
|
+
http.response_header["CONTENT_TYPE"].should == ct
|
467
|
+
EventMachine.stop
|
468
|
+
}
|
469
|
+
}
|
470
|
+
end
|
471
|
+
|
472
|
+
it "should processed escaped content-type" do
|
473
|
+
EventMachine.run {
|
474
|
+
ct = "text/html; charset=\"ISO-8859-4\""
|
475
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/echo_content_type').post({
|
476
|
+
:body => {:a => :b}, :head => {'content-type' => ct}})
|
477
|
+
|
478
|
+
http.errback { failed(http) }
|
479
|
+
http.callback {
|
480
|
+
http.response_header.status.should == 200
|
481
|
+
http.content_charset.should == Encoding.find('ISO-8859-4') if defined? Encoding
|
482
|
+
http.response_header["CONTENT_TYPE"].should == ct
|
483
|
+
EventMachine.stop
|
484
|
+
}
|
485
|
+
}
|
486
|
+
end
|
487
|
+
end
|
488
|
+
|
489
|
+
context "optional header callback" do
|
490
|
+
it "should optionally pass the response headers" do
|
491
|
+
EventMachine.run {
|
492
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/').get
|
493
|
+
|
494
|
+
http.errback { failed(http) }
|
495
|
+
http.headers { |hash|
|
496
|
+
hash.should be_an_kind_of Hash
|
497
|
+
hash.should include 'CONNECTION'
|
498
|
+
hash.should include 'CONTENT_LENGTH'
|
499
|
+
}
|
500
|
+
|
501
|
+
http.callback {
|
502
|
+
http.response_header.status.should == 200
|
503
|
+
http.response.should match(/Hello/)
|
504
|
+
EventMachine.stop
|
505
|
+
}
|
506
|
+
}
|
507
|
+
end
|
508
|
+
|
509
|
+
it "should allow to terminate current connection from header callback" do
|
510
|
+
EventMachine.run {
|
511
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/').get
|
512
|
+
|
513
|
+
http.callback { failed(http) }
|
514
|
+
http.headers { |hash|
|
515
|
+
hash.should be_an_kind_of Hash
|
516
|
+
hash.should include 'CONNECTION'
|
517
|
+
hash.should include 'CONTENT_LENGTH'
|
518
|
+
|
519
|
+
http.close('header callback terminated connection')
|
520
|
+
}
|
521
|
+
|
522
|
+
http.errback { |e|
|
523
|
+
http.response_header.status.should == 200
|
524
|
+
http.error.should == 'header callback terminated connection'
|
525
|
+
http.response.should == ''
|
526
|
+
EventMachine.stop
|
527
|
+
}
|
528
|
+
}
|
529
|
+
end
|
530
|
+
end
|
531
|
+
|
532
|
+
it "should optionally pass the response body progressively" do
|
533
|
+
EventMachine.run {
|
534
|
+
body = ''
|
535
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/').get
|
536
|
+
|
537
|
+
http.errback { failed(http) }
|
538
|
+
http.stream { |chunk| body += chunk }
|
539
|
+
|
540
|
+
http.callback {
|
541
|
+
http.response_header.status.should == 200
|
542
|
+
http.response.should == ''
|
543
|
+
body.should match(/Hello/)
|
544
|
+
EventMachine.stop
|
545
|
+
}
|
546
|
+
}
|
547
|
+
end
|
548
|
+
|
549
|
+
it "should optionally pass the deflate-encoded response body progressively" do
|
550
|
+
EventMachine.run {
|
551
|
+
body = ''
|
552
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/deflate').get :head => {
|
553
|
+
"accept-encoding" => "deflate, compressed"
|
554
|
+
}
|
555
|
+
|
556
|
+
http.errback { failed(http) }
|
557
|
+
http.stream { |chunk| body += chunk }
|
558
|
+
|
559
|
+
http.callback {
|
560
|
+
http.response_header.status.should == 200
|
561
|
+
http.response_header["CONTENT_ENCODING"].should == "deflate"
|
562
|
+
http.response.should == ''
|
563
|
+
body.should == "compressed"
|
564
|
+
EventMachine.stop
|
565
|
+
}
|
566
|
+
}
|
567
|
+
end
|
568
|
+
|
569
|
+
it "should accept & return cookie header to user" do
|
570
|
+
EventMachine.run {
|
571
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/set_cookie').get
|
572
|
+
|
573
|
+
http.errback { failed(http) }
|
574
|
+
http.callback {
|
575
|
+
http.response_header.status.should == 200
|
576
|
+
http.response_header.cookie.should == "id=1; expires=Sat, 09 Aug 2031 17:53:39 GMT; path=/;"
|
577
|
+
EventMachine.stop
|
578
|
+
}
|
579
|
+
}
|
580
|
+
end
|
581
|
+
|
582
|
+
it "should return array of cookies on multiple Set-Cookie headers" do
|
583
|
+
EventMachine.run {
|
584
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/set_multiple_cookies').get
|
585
|
+
|
586
|
+
http.errback { failed(http) }
|
587
|
+
http.callback {
|
588
|
+
http.response_header.status.should == 200
|
589
|
+
http.response_header.cookie.size.should == 2
|
590
|
+
http.response_header.cookie.first.should == "id=1; expires=Sat, 09 Aug 2031 17:53:39 GMT; path=/;"
|
591
|
+
http.response_header.cookie.last.should == "id=2;"
|
592
|
+
|
593
|
+
EventMachine.stop
|
594
|
+
}
|
595
|
+
}
|
596
|
+
end
|
597
|
+
|
598
|
+
it "should pass cookie header to server from string" do
|
599
|
+
EventMachine.run {
|
600
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/echo_cookie').get :head => {'cookie' => 'id=2;'}
|
601
|
+
|
602
|
+
http.errback { failed(http) }
|
603
|
+
http.callback {
|
604
|
+
http.response.should == "id=2;"
|
605
|
+
EventMachine.stop
|
606
|
+
}
|
607
|
+
}
|
608
|
+
end
|
609
|
+
|
610
|
+
it "should pass cookie header to server from Hash" do
|
611
|
+
EventMachine.run {
|
612
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/echo_cookie').get :head => {'cookie' => {'id' => 2}}
|
613
|
+
|
614
|
+
http.errback { failed(http) }
|
615
|
+
http.callback {
|
616
|
+
http.response.should == "id=2;"
|
617
|
+
EventMachine.stop
|
618
|
+
}
|
619
|
+
}
|
620
|
+
end
|
621
|
+
|
622
|
+
context "when talking to a stub HTTP/1.0 server" do
|
623
|
+
it "should get the body without Content-Length" do
|
624
|
+
|
625
|
+
EventMachine.run {
|
626
|
+
@s = StubServer.new("HTTP/1.0 200 OK\r\nConnection: close\r\n\r\nFoo")
|
627
|
+
|
628
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8081/').get
|
629
|
+
http.errback { failed(http) }
|
630
|
+
http.callback {
|
631
|
+
http.response.should match(/Foo/)
|
632
|
+
http.response_header['CONTENT_LENGTH'].should_not == 0
|
633
|
+
|
634
|
+
@s.stop
|
635
|
+
EventMachine.stop
|
636
|
+
}
|
637
|
+
}
|
638
|
+
end
|
639
|
+
|
640
|
+
it "should work with \\n instead of \\r\\n" do
|
641
|
+
EventMachine.run {
|
642
|
+
@s = StubServer.new("HTTP/1.0 200 OK\nContent-Type: text/plain\nContent-Length: 3\nConnection: close\n\nFoo")
|
643
|
+
|
644
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8081/').get
|
645
|
+
http.errback { failed(http) }
|
646
|
+
http.callback {
|
647
|
+
http.response_header.status.should == 200
|
648
|
+
http.response_header['CONTENT_TYPE'].should == 'text/plain'
|
649
|
+
http.response.should match(/Foo/)
|
650
|
+
|
651
|
+
@s.stop
|
652
|
+
EventMachine.stop
|
653
|
+
}
|
654
|
+
}
|
655
|
+
end
|
656
|
+
|
657
|
+
it "should handle invalid HTTP response" do
|
658
|
+
EventMachine.run {
|
659
|
+
@s = StubServer.new("<html></html>")
|
660
|
+
|
661
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8081/').get
|
662
|
+
http.callback { failed(http) }
|
663
|
+
http.errback {
|
664
|
+
http.error.should_not be_nil
|
665
|
+
EM.stop
|
666
|
+
}
|
667
|
+
}
|
668
|
+
end
|
669
|
+
end
|
670
|
+
|
671
|
+
it "should stream a file off disk" do
|
672
|
+
EventMachine.run {
|
673
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/').post :file => 'spec/fixtures/google.ca'
|
674
|
+
|
675
|
+
http.errback { failed(http) }
|
676
|
+
http.callback {
|
677
|
+
http.response.should match('google')
|
678
|
+
EventMachine.stop
|
679
|
+
}
|
680
|
+
}
|
681
|
+
end
|
682
|
+
|
683
|
+
it 'should handle malformed Content-Type header repetitions' do
|
684
|
+
EventMachine.run {
|
685
|
+
response =<<-HTTP.gsub(/^ +/, '').strip
|
686
|
+
HTTP/1.0 200 OK
|
687
|
+
Content-Type: text/plain; charset=iso-8859-1
|
688
|
+
Content-Type: text/plain; charset=utf-8
|
689
|
+
Content-Length: 5
|
690
|
+
Connection: close
|
691
|
+
|
692
|
+
Hello
|
693
|
+
HTTP
|
694
|
+
|
695
|
+
@s = StubServer.new(response)
|
696
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8081/').get
|
697
|
+
http.errback { failed(http) }
|
698
|
+
http.callback {
|
699
|
+
http.content_charset.should == Encoding::ISO_8859_1 if defined? Encoding
|
700
|
+
EventMachine.stop
|
701
|
+
}
|
702
|
+
}
|
703
|
+
end
|
704
|
+
|
705
|
+
it "should allow indifferent access to headers" do
|
706
|
+
EventMachine.run {
|
707
|
+
response =<<-HTTP.gsub(/^ +/, '').strip
|
708
|
+
HTTP/1.0 200 OK
|
709
|
+
Content-Type: text/plain; charset=utf-8
|
710
|
+
X-Custom-Header: foo
|
711
|
+
Content-Length: 5
|
712
|
+
Connection: close
|
713
|
+
|
714
|
+
Hello
|
715
|
+
HTTP
|
716
|
+
|
717
|
+
@s = StubServer.new(response)
|
718
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8081/').get
|
719
|
+
http.errback { failed(http) }
|
720
|
+
http.callback {
|
721
|
+
http.response_header["Content-Type"].should == "text/plain; charset=utf-8"
|
722
|
+
http.response_header["CONTENT_TYPE"].should == "text/plain; charset=utf-8"
|
723
|
+
|
724
|
+
http.response_header["Content-Length"].should == "5"
|
725
|
+
http.response_header["CONTENT_LENGTH"].should == "5"
|
726
|
+
|
727
|
+
http.response_header["X-Custom-Header"].should == "foo"
|
728
|
+
http.response_header["X_CUSTOM_HEADER"].should == "foo"
|
729
|
+
|
730
|
+
EventMachine.stop
|
731
|
+
}
|
732
|
+
}
|
733
|
+
end
|
734
|
+
end
|