em-http-request 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of em-http-request might be problematic. Click here for more details.

@@ -1,3 +1,5 @@
1
+ # -*- encoding: utf-8 -*-
2
+
1
3
  require 'helper'
2
4
 
3
5
  describe EventMachine::HttpEncoding do
@@ -13,7 +15,8 @@ describe EventMachine::HttpEncoding do
13
15
 
14
16
  it "should transform a very complex hash into HTTP POST Params" do
15
17
  params = form_encode_body({:a => "a", :b => [{:c => "c", :d => "d"}, {:e => "e", :f => "f"}]})
16
- params.should == "a=a&b[0][c]=c&b[0][d]=d&b[1][e]=e&b[1][f]=f"
18
+ # 1.8.7 does not have ordered hashes.
19
+ params.split(/&/).sort.join('&').should == "a=a&b[0][c]=c&b[0][d]=d&b[1][e]=e&b[1][f]=f"
17
20
  end
18
21
 
19
22
  it "should escape values" do
@@ -31,10 +34,16 @@ describe EventMachine::HttpEncoding do
31
34
  params.should == "bad%26str[key%26key][0]=bad%2B%26stuff&bad%26str[key%26key][1]=%5Btest%5D"
32
35
  end
33
36
 
37
+ it "should not issue warnings on non-ASCII encodings" do
38
+ # I don't know how to check for ruby warnings.
39
+ params = escape('valö')
40
+ params = escape('valö'.encode('ISO-8859-15'))
41
+ end
42
+
34
43
  # xit "should be fast on long string escapes" do
35
44
  # s = Time.now
36
45
  # 5000.times { |n| form_encode_body({:a => "{a:'b', d:'f', g:['a','b']}"*50}) }
37
46
  # (Time.now - s).should satisfy { |t| t < 1.5 }
38
47
  # end
39
48
 
40
- end
49
+ end
@@ -1,127 +1,128 @@
1
- require 'helper'
2
-
3
- requires_connection do
4
-
5
- describe EventMachine::HttpRequest do
6
-
7
- it "should follow redirects on HEAD method (external)" do
8
- EventMachine.run {
9
- http = EventMachine::HttpRequest.new('http://www.google.com/').head :redirects => 1
10
- http.errback { failed(http) }
11
- http.callback {
12
- http.response_header.status.should == 200
13
- EM.stop
14
- }
15
- }
16
- end
17
-
18
- it "should follow redirect to https and initiate the handshake" do
19
- EventMachine.run {
20
- http = EventMachine::HttpRequest.new('http://analytics.postrank.com/').get :redirects => 5
21
-
22
- http.errback { failed(http) }
23
- http.callback {
24
- http.response_header.status.should == 200
25
- EventMachine.stop
26
- }
27
- }
28
- end
29
-
30
- it "should perform a streaming GET" do
31
- EventMachine.run {
32
-
33
- # digg.com uses chunked encoding
34
- http = EventMachine::HttpRequest.new('http://digg.com/news').get
35
-
36
- http.errback { failed(http) }
37
- http.callback {
38
- http.response_header.status.should == 200
39
- EventMachine.stop
40
- }
41
- }
42
- end
43
-
44
- it "should handle a 100 continue" do
45
- EventMachine.run {
46
- # 8.2.3 Use of the 100 (Continue) Status - http://www.ietf.org/rfc/rfc2616.txt
47
- #
48
- # An origin server SHOULD NOT send a 100 (Continue) response if
49
- # the request message does not include an Expect request-header
50
- # field with the "100-continue" expectation, and MUST NOT send a
51
- # 100 (Continue) response if such a request comes from an HTTP/1.0
52
- # (or earlier) client. There is an exception to this rule: for
53
- # compatibility with RFC 2068, a server MAY send a 100 (Continue)
54
- # status in response to an HTTP/1.1 PUT or POST request that does
55
- # not include an Expect request-header field with the "100-
56
- # continue" expectation. This exception, the purpose of which is
57
- # to minimize any client processing delays associated with an
58
- # undeclared wait for 100 (Continue) status, applies only to
59
- # HTTP/1.1 requests, and not to requests with any other HTTP-
60
- # version value.
61
- #
62
- # 10.1.1: 100 Continue - http://www.ietf.org/rfc/rfc2068.txt
63
- # The client may continue with its request. This interim response is
64
- # used to inform the client that the initial part of the request has
65
- # been received and has not yet been rejected by the server. The client
66
- # SHOULD continue by sending the remainder of the request or, if the
67
- # request has already been completed, ignore this response. The server
68
- # MUST send a final response after the request has been completed.
69
-
70
- url = 'http://ws.serviceobjects.com/lv/LeadValidation.asmx/ValidateLead_V2'
71
- http = EventMachine::HttpRequest.new(url).post :body => {:name => :test}
72
-
73
- http.errback { failed(http) }
74
- http.callback {
75
- http.response_header.status.should == 500
76
- http.response.should match('Missing')
77
- EventMachine.stop
78
- }
79
- }
80
- end
81
-
82
- it "should detect deflate encoding" do
83
- EventMachine.run {
84
-
85
- options = {:head => {"accept-encoding" => "deflate"}, :redirects => 5}
86
- http = EventMachine::HttpRequest.new('http://www.msn.com').get options
87
-
88
- http.errback { failed(http) }
89
- http.callback {
90
- http.response_header.status.should == 200
91
- http.response_header["CONTENT_ENCODING"].should == "deflate"
92
-
93
- EventMachine.stop
94
- }
95
- }
96
- end
97
-
98
- context "keepalive" do
99
- it "should default to non-keepalive" do
100
- EventMachine.run {
101
- headers = {'If-Modified-Since' => 'Thu, 05 Aug 2010 22:54:44 GMT'}
102
- http = EventMachine::HttpRequest.new('http://www.google.com/images/logos/ps_logo2.png').get :head => headers
103
-
104
- http.errback { fail }
105
- start = Time.now.to_i
106
- http.callback {
107
- (Time.now.to_i - start).should be_within(2).of(0)
108
- EventMachine.stop
109
- }
110
- }
111
- end
112
-
113
- it "should work with keep-alive servers" do
114
- EventMachine.run {
115
- http = EventMachine::HttpRequest.new('http://mexicodiario.com/touch.public.json.php').get :keepalive => true
116
-
117
- http.errback { failed(http) }
118
- http.callback {
119
- http.response_header.status.should == 200
120
- EventMachine.stop
121
- }
122
- }
123
- end
124
- end
125
-
126
- end
127
- end
1
+ require 'helper'
2
+
3
+ requires_connection do
4
+
5
+ describe EventMachine::HttpRequest do
6
+
7
+ it "should follow redirects on HEAD method (external)" do
8
+ EventMachine.run {
9
+ http = EventMachine::HttpRequest.new('http://www.google.com/').head :redirects => 1
10
+ http.errback { failed(http) }
11
+ http.callback {
12
+ http.response_header.status.should == 200
13
+ EM.stop
14
+ }
15
+ }
16
+ end
17
+
18
+ it "should follow redirect to https and initiate the handshake" do
19
+ EventMachine.run {
20
+ http = EventMachine::HttpRequest.new('http://analytics.postrank.com/').get :redirects => 5
21
+
22
+ http.errback { failed(http) }
23
+ http.callback {
24
+ http.response_header.status.should == 200
25
+ EventMachine.stop
26
+ }
27
+ }
28
+ end
29
+
30
+ it "should perform a streaming GET" do
31
+ EventMachine.run {
32
+
33
+ # digg.com uses chunked encoding
34
+ http = EventMachine::HttpRequest.new('http://digg.com/news').get
35
+
36
+ http.errback { failed(http) }
37
+ http.callback {
38
+ http.response_header.status.should == 200
39
+ EventMachine.stop
40
+ }
41
+ }
42
+ end
43
+
44
+ it "should handle a 100 continue" do
45
+ EventMachine.run {
46
+ # 8.2.3 Use of the 100 (Continue) Status - http://www.ietf.org/rfc/rfc2616.txt
47
+ #
48
+ # An origin server SHOULD NOT send a 100 (Continue) response if
49
+ # the request message does not include an Expect request-header
50
+ # field with the "100-continue" expectation, and MUST NOT send a
51
+ # 100 (Continue) response if such a request comes from an HTTP/1.0
52
+ # (or earlier) client. There is an exception to this rule: for
53
+ # compatibility with RFC 2068, a server MAY send a 100 (Continue)
54
+ # status in response to an HTTP/1.1 PUT or POST request that does
55
+ # not include an Expect request-header field with the "100-
56
+ # continue" expectation. This exception, the purpose of which is
57
+ # to minimize any client processing delays associated with an
58
+ # undeclared wait for 100 (Continue) status, applies only to
59
+ # HTTP/1.1 requests, and not to requests with any other HTTP-
60
+ # version value.
61
+ #
62
+ # 10.1.1: 100 Continue - http://www.ietf.org/rfc/rfc2068.txt
63
+ # The client may continue with its request. This interim response is
64
+ # used to inform the client that the initial part of the request has
65
+ # been received and has not yet been rejected by the server. The client
66
+ # SHOULD continue by sending the remainder of the request or, if the
67
+ # request has already been completed, ignore this response. The server
68
+ # MUST send a final response after the request has been completed.
69
+
70
+ url = 'http://ws.serviceobjects.com/lv/LeadValidation.asmx/ValidateLead_V2'
71
+ http = EventMachine::HttpRequest.new(url).post :body => {:name => :test}
72
+
73
+ http.errback { failed(http) }
74
+ http.callback {
75
+ http.response_header.status.should == 500
76
+ http.response.should match('Missing')
77
+ EventMachine.stop
78
+ }
79
+ }
80
+ end
81
+
82
+ it "should detect deflate encoding" do
83
+ pending "need an endpoint which supports deflate.. MSN is no longer"
84
+ EventMachine.run {
85
+
86
+ options = {:head => {"accept-encoding" => "deflate"}, :redirects => 5}
87
+ http = EventMachine::HttpRequest.new('http://www.msn.com').get options
88
+
89
+ http.errback { failed(http) }
90
+ http.callback {
91
+ http.response_header.status.should == 200
92
+ http.response_header["CONTENT_ENCODING"].should == "deflate"
93
+
94
+ EventMachine.stop
95
+ }
96
+ }
97
+ end
98
+
99
+ context "keepalive" do
100
+ it "should default to non-keepalive" do
101
+ EventMachine.run {
102
+ headers = {'If-Modified-Since' => 'Thu, 05 Aug 2010 22:54:44 GMT'}
103
+ http = EventMachine::HttpRequest.new('http://www.google.com/images/logos/ps_logo2.png').get :head => headers
104
+
105
+ http.errback { fail }
106
+ start = Time.now.to_i
107
+ http.callback {
108
+ (Time.now.to_i - start).should be_within(2).of(0)
109
+ EventMachine.stop
110
+ }
111
+ }
112
+ end
113
+
114
+ it "should work with keep-alive servers" do
115
+ EventMachine.run {
116
+ http = EventMachine::HttpRequest.new('http://mexicodiario.com/touch.public.json.php').get :keepalive => true
117
+
118
+ http.errback { failed(http) }
119
+ http.callback {
120
+ http.response_header.status.should == 200
121
+ EventMachine.stop
122
+ }
123
+ }
124
+ end
125
+ end
126
+
127
+ end
128
+ end
@@ -13,7 +13,7 @@ def failed(http = nil)
13
13
  end
14
14
 
15
15
  def requires_connection(&blk)
16
- blk.call if system('ping -t1 -c1 google.com &> /dev/null')
16
+ blk.call if system('ping -t1 -c1 google.com 2>&1 > /dev/null')
17
17
  end
18
18
 
19
19
  def requires_port(port, &blk)
@@ -26,4 +26,4 @@ def requires_port(port, &blk)
26
26
  end
27
27
 
28
28
  blk.call if port_open
29
- end
29
+ end
@@ -27,6 +27,14 @@ describe EventMachine::MultiRequest do
27
27
  }
28
28
  end
29
29
 
30
+ it "should require unique keys for each deferrable" do
31
+ lambda do
32
+ multi.add :df1, EM::DefaultDeferrable.new
33
+ multi.add :df1, EM::DefaultDeferrable.new
34
+ end.should raise_error("Duplicate Multi key")
35
+ end
36
+
37
+
30
38
  describe "#requests" do
31
39
  it "should return the added requests" do
32
40
  request1 = stub('request1', :callback => nil, :errback => nil)
@@ -35,7 +43,7 @@ describe EventMachine::MultiRequest do
35
43
  multi.add :a, request1
36
44
  multi.add :b, request2
37
45
 
38
- multi.requests.should == [ request1, request2 ]
46
+ multi.requests.should == {:a => request1, :b => request2}
39
47
  end
40
48
  end
41
49
 
@@ -1,38 +1,66 @@
1
- require 'helper'
2
-
3
- requires_connection do
4
-
5
- describe EventMachine::HttpRequest do
6
-
7
- it "should perform successful pipelined GETs" do
8
- EventMachine.run do
9
-
10
- # Mongrel doesn't support pipelined requests - bah!
11
- conn = EventMachine::HttpRequest.new('http://www.igvita.com/')
12
-
13
- pipe1 = conn.get :keepalive => true
14
- pipe2 = conn.get :path => '/about/', :keepalive => true
15
-
16
- processed = 0
17
- stop = proc { EM.stop if processed == 2}
18
-
19
- pipe1.errback { failed(conn) }
20
- pipe1.callback {
21
- processed += 1
22
- pipe1.response_header.status.should == 200
23
- stop.call
24
- }
25
-
26
- pipe2.errback { p pipe2; failed(conn) }
27
- pipe2.callback {
28
- processed += 1
29
- pipe2.response_header.status.should == 200
30
- pipe2.response.should match(/ilya/i)
31
- stop.call
32
- }
33
-
34
- end
35
- end
36
- end
37
-
38
- end
1
+ require 'helper'
2
+
3
+ requires_connection do
4
+
5
+ describe EventMachine::HttpRequest do
6
+
7
+ it "should perform successful pipelined GETs" do
8
+ EventMachine.run do
9
+
10
+ # Mongrel doesn't support pipelined requests - bah!
11
+ conn = EventMachine::HttpRequest.new('http://www.igvita.com/')
12
+
13
+ pipe1 = conn.get :keepalive => true
14
+ pipe2 = conn.get :path => '/archives/', :keepalive => true
15
+
16
+ processed = 0
17
+ stop = proc { EM.stop if processed == 2}
18
+
19
+ pipe1.errback { failed(conn) }
20
+ pipe1.callback {
21
+ processed += 1
22
+ pipe1.response_header.status.should == 200
23
+ stop.call
24
+ }
25
+
26
+ pipe2.errback { failed(conn) }
27
+ pipe2.callback {
28
+ processed += 1
29
+ pipe2.response_header.status.should == 200
30
+ pipe2.response.should match(/2011/i)
31
+ stop.call
32
+ }
33
+
34
+ end
35
+ end
36
+
37
+ it "should perform successful pipelined HEAD requests" do
38
+ EventMachine.run do
39
+ conn = EventMachine::HttpRequest.new('http://www.igvita.com/')
40
+
41
+ pipe1 = conn.head :keepalive => true
42
+ pipe2 = conn.head :path => '/archives/', :keepalive => true
43
+
44
+ processed = 0
45
+ stop = proc { EM.stop if processed == 2}
46
+
47
+ pipe1.errback { failed(conn) }
48
+ pipe1.callback {
49
+ processed += 1
50
+ pipe1.response_header.status.should == 200
51
+ stop.call
52
+ }
53
+
54
+ pipe2.errback { failed(conn) }
55
+ pipe2.callback {
56
+ processed += 1
57
+ pipe2.response_header.status.should == 200
58
+ stop.call
59
+ }
60
+
61
+ end
62
+
63
+ end
64
+ end
65
+
66
+ end
@@ -15,7 +15,7 @@ end
15
15
 
16
16
  class PickyRedirectMiddleware < RedirectMiddleware
17
17
  def response(r)
18
- if r.redirect? && r.response_header['LOCATION'][-1] == '3'
18
+ if r.redirect? && r.response_header['LOCATION'][-1].chr == '3'
19
19
  # set redirects to 0 to avoid further processing
20
20
  r.req.redirects = 0
21
21
  end
@@ -40,6 +40,58 @@ describe EventMachine::HttpRequest do
40
40
  }
41
41
  end
42
42
 
43
+ it "should not forward cookies across domains with http redirect" do
44
+
45
+ expires = (Date.today + 1).strftime('%a, %d %b %Y %T GMT')
46
+ response =<<-HTTP.gsub(/^ +/, '')
47
+ HTTP/1.1 301 MOVED PERMANENTLY
48
+ Location: http://localhost:8081/
49
+ Set-Cookie: foo=bar; expires=#{expires}; path=/; HttpOnly
50
+
51
+ HTTP
52
+
53
+ EventMachine.run do
54
+ @stub = StubServer.new(:host => '127.0.0.1', :port => 8080, :response => response)
55
+ @echo = StubServer.new(:host => 'localhost', :port => 8081, :echo => true)
56
+
57
+ http = EventMachine::HttpRequest.new('http://127.0.0.1:8080/').get :redirects => 1
58
+
59
+ http.errback { failed(http) }
60
+ http.callback do
61
+ http.response.should_not match(/Cookie/)
62
+ @stub.stop
63
+ @echo.stop
64
+ EM.stop
65
+ end
66
+ end
67
+ end
68
+
69
+ it "should forward valid cookies across domains with http redirect" do
70
+
71
+ expires = (Date.today + 1).strftime('%a, %d %b %Y %T GMT')
72
+ response =<<-HTTP.gsub(/^ +/, '')
73
+ HTTP/1.1 301 MOVED PERMANENTLY
74
+ Location: http://127.0.0.1:8081/
75
+ Set-Cookie: foo=bar; expires=#{expires}; path=/; HttpOnly
76
+
77
+ HTTP
78
+
79
+ EventMachine.run do
80
+ @stub = StubServer.new(:port => 8080, :response => response)
81
+ @echo = StubServer.new(:port => 8081, :echo => true)
82
+
83
+ http = EventMachine::HttpRequest.new('http://127.0.0.1:8080/').get :redirects => 1
84
+
85
+ http.errback { failed(http) }
86
+ http.callback do
87
+ http.response.should match(/Cookie/)
88
+ @stub.stop
89
+ @echo.stop
90
+ EM.stop
91
+ end
92
+ end
93
+ end
94
+
43
95
  it "should redirect with missing content-length" do
44
96
  EventMachine.run {
45
97
  @s = StubServer.new("HTTP/1.0 301 MOVED PERMANENTLY\r\nlocation: http://127.0.0.1:8090/redirect\r\n\r\n")
@@ -144,7 +196,7 @@ describe EventMachine::HttpRequest do
144
196
  http.last_effective_url.to_s.should == 'http://127.0.0.1:8090/gzip'
145
197
  http.redirects.should == 2
146
198
  http.cookies.should include("id=2;")
147
- http.cookies.should include("another_id=1; expires=Tue, 09-Aug-2011 17:53:39 GMT; path=/;")
199
+ http.cookies.should include("another_id=1")
148
200
 
149
201
  EM.stop
150
202
  }
@@ -162,7 +214,7 @@ describe EventMachine::HttpRequest do
162
214
  http.last_effective_url.to_s.should == 'http://127.0.0.1:8090/gzip'
163
215
  http.redirects.should == 2
164
216
  http.cookies.should include("id=2;")
165
- http.cookies.should_not include("another_id=1; expires=Tue, 09-Aug-2011 17:53:39 GMT; path=/;")
217
+ http.cookies.should_not include("another_id=1; expires=Sat, 09 Aug 2031 17:53:39 GMT; path=/;")
166
218
 
167
219
  EM.stop
168
220
  }