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.

@@ -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
  }