em-http-request 1.0.0.beta.3 → 1.0.0.beta.4

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.

data/spec/multi_spec.rb CHANGED
@@ -3,39 +3,94 @@ require 'stallion'
3
3
 
4
4
  describe EventMachine::MultiRequest do
5
5
 
6
+ let(:multi) { EventMachine::MultiRequest.new }
7
+ let(:url) { 'http://127.0.0.1:8090/' }
8
+
6
9
  it "should submit multiple requests in parallel and return once all of them are complete" do
7
10
  EventMachine.run {
11
+ multi.add :a, EventMachine::HttpRequest.new(url).get
12
+ multi.add :b, EventMachine::HttpRequest.new(url).post
13
+ multi.add :c, EventMachine::HttpRequest.new(url).head
14
+ multi.add :d, EventMachine::HttpRequest.new(url).delete
15
+ multi.add :e, EventMachine::HttpRequest.new(url).put
8
16
 
9
- # create an instance of multi-request handler, and the requests themselves
10
- multi = EventMachine::MultiRequest.new
11
-
12
- # add multiple requests to the multi-handler
13
- multi.add(EventMachine::HttpRequest.new('http://127.0.0.1:8090/').get(:query => {:q => 'test'}))
14
- multi.add(EventMachine::HttpRequest.new('http://127.0.0.1:8090/').get)
15
-
16
- multi.callback {
17
- multi.responses[:succeeded].size.should == 2
18
- multi.responses[:succeeded][0].response.should match(/test|Hello/)
19
- multi.responses[:succeeded][1].response.should match(/test|Hello/)
17
+ multi.callback {
18
+ multi.responses[:callback].size.should == 5
19
+ multi.responses[:callback].each { |name, response|
20
+ [ :a, :b, :c, :d, :e ].should include(name)
21
+ response.response_header.status.should == 200
22
+ }
23
+ multi.responses[:errback].size.should == 0
20
24
 
21
25
  EventMachine.stop
22
26
  }
23
27
  }
24
28
  end
25
29
 
26
- it "should accept multiple open connections and return once all of them are complete" do
27
- EventMachine.run {
28
- http1 = EventMachine::HttpRequest.new('http://127.0.0.1:8090/').get(:query => {:q => 'test'})
29
- http2 = EventMachine::HttpRequest.new('http://127.0.0.1:8090/').get
30
+ describe "#requests" do
31
+ it "should return the added requests" do
32
+ request1 = stub('request1', :callback => nil, :errback => nil)
33
+ request2 = stub('request2', :callback => nil, :errback => nil)
34
+
35
+ multi.add :a, request1
36
+ multi.add :b, request2
37
+
38
+ multi.requests.should == [ request1, request2 ]
39
+ end
40
+ end
41
+
42
+ describe "#responses" do
43
+ it "should have an empty :callback hash" do
44
+ multi.responses[:callback].should be_a(Hash)
45
+ multi.responses[:callback].size.should == 0
46
+ end
47
+
48
+ it "should have an empty :errback hash" do
49
+ multi.responses[:errback].should be_a(Hash)
50
+ multi.responses[:errback].size.should == 0
51
+ end
52
+
53
+ it "should provide access to the requests by name" do
54
+ EventMachine.run {
55
+ request1 = EventMachine::HttpRequest.new(url).get
56
+ request2 = EventMachine::HttpRequest.new(url).post
57
+ multi.add :a, request1
58
+ multi.add :b, request2
30
59
 
31
- multi = EventMachine::MultiRequest.new([http1, http2]) do
32
- multi.responses[:succeeded].size.should == 2
33
- multi.responses[:succeeded][0].response.should match(/test|Hello/)
34
- multi.responses[:succeeded][1].response.should match(/test|Hello/)
60
+ multi.callback {
61
+ multi.responses[:callback][:a].should equal(request1)
62
+ multi.responses[:callback][:b].should equal(request2)
63
+
64
+ EventMachine.stop
65
+ }
66
+ }
67
+ end
68
+ end
69
+
70
+ describe "#finished?" do
71
+ it "should be true when no requests have been added" do
72
+ multi.should be_finished
73
+ end
74
+
75
+ it "should be false while the requests are not finished" do
76
+ EventMachine.run {
77
+ multi.add :a, EventMachine::HttpRequest.new(url).get
78
+ multi.should_not be_finished
35
79
 
36
80
  EventMachine.stop
37
- end
38
- }
81
+ }
82
+ end
83
+
84
+ it "should be finished when all requests are finished" do
85
+ EventMachine.run {
86
+ multi.add :a, EventMachine::HttpRequest.new(url).get
87
+ multi.callback {
88
+ multi.should be_finished
89
+
90
+ EventMachine.stop
91
+ }
92
+ }
93
+ end
39
94
  end
40
95
 
41
- end
96
+ end
@@ -27,7 +27,7 @@ requires_connection do
27
27
  pipe2.callback {
28
28
  processed += 1
29
29
  pipe2.response_header.status.should == 200
30
- pipe2.response.should match('biography')
30
+ pipe2.response.should match(/ilya/i)
31
31
  stop.call
32
32
  }
33
33
 
@@ -1,5 +1,27 @@
1
1
  require 'helper'
2
2
 
3
+ class RedirectMiddleware
4
+ attr_reader :call_count
5
+
6
+ def initialize
7
+ @call_count = 0
8
+ end
9
+
10
+ def request(c, h, r)
11
+ @call_count += 1
12
+ [h.merge({'EM-Middleware' => @call_count.to_s}), r]
13
+ end
14
+ end
15
+
16
+ class PickyRedirectMiddleware < RedirectMiddleware
17
+ def response(r)
18
+ if r.redirect? && r.response_header['LOCATION'][-1] == '3'
19
+ # set redirects to 0 to avoid further processing
20
+ r.req.redirects = 0
21
+ end
22
+ end
23
+ end
24
+
3
25
  describe EventMachine::HttpRequest do
4
26
 
5
27
  it "should follow location redirects" do
@@ -111,4 +133,68 @@ describe EventMachine::HttpRequest do
111
133
  }
112
134
  end
113
135
 
136
+ it "should capture and pass cookies on redirect and pass_cookies by default" do
137
+ EventMachine.run {
138
+ http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/redirect/multiple-with-cookie').get :redirects => 2, :head => {'cookie' => 'id=2;'}
139
+ http.errback { failed(http) }
140
+ http.callback {
141
+ http.response_header.status.should == 200
142
+ http.response_header["CONTENT_ENCODING"].should == "gzip"
143
+ http.response.should == "compressed"
144
+ http.last_effective_url.to_s.should == 'http://127.0.0.1:8090/gzip'
145
+ http.redirects.should == 2
146
+ http.cookies.should include("id=2;")
147
+ http.cookies.should include("another_id=1; expires=Tue, 09-Aug-2011 17:53:39 GMT; path=/;")
148
+
149
+ EM.stop
150
+ }
151
+ }
152
+ end
153
+
154
+ it "should capture and not pass cookies on redirect if passing is disabled via pass_cookies" do
155
+ EventMachine.run {
156
+ http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/redirect/multiple-with-cookie').get :redirects => 2, :pass_cookies => false, :head => {'cookie' => 'id=2;'}
157
+ http.errback { failed(http) }
158
+ http.callback {
159
+ http.response_header.status.should == 200
160
+ http.response_header["CONTENT_ENCODING"].should == "gzip"
161
+ http.response.should == "compressed"
162
+ http.last_effective_url.to_s.should == 'http://127.0.0.1:8090/gzip'
163
+ http.redirects.should == 2
164
+ 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=/;")
166
+
167
+ EM.stop
168
+ }
169
+ }
170
+ end
171
+
172
+ it "should call middleware each time it redirects" do
173
+ EventMachine.run {
174
+ conn = EventMachine::HttpRequest.new('http://127.0.0.1:8090/redirect/middleware_redirects_1')
175
+ conn.use RedirectMiddleware
176
+ http = conn.get :redirects => 3
177
+ http.errback { failed(http) }
178
+ http.callback {
179
+ http.response_header.status.should == 200
180
+ http.response_header['EM_MIDDLEWARE'].to_i.should == 3
181
+ EM.stop
182
+ }
183
+ }
184
+ end
185
+
186
+ it "should call middleware which may reject a redirection" do
187
+ EventMachine.run {
188
+ conn = EventMachine::HttpRequest.new('http://127.0.0.1:8090/redirect/middleware_redirects_1')
189
+ conn.use PickyRedirectMiddleware
190
+ http = conn.get :redirects => 3
191
+ http.errback { failed(http) }
192
+ http.callback {
193
+ http.response_header.status.should == 301
194
+ http.last_effective_url.to_s.should == 'http://127.0.0.1:8090/redirect/middleware_redirects_2'
195
+ EM.stop
196
+ }
197
+ }
198
+ end
199
+
114
200
  end
@@ -1,24 +1,24 @@
1
1
  require 'helper'
2
2
 
3
3
  requires_connection do
4
+ requires_port(8080) do
5
+ describe EventMachine::HttpRequest do
4
6
 
5
- describe EventMachine::HttpRequest do
7
+ # ssh -D 8080 igvita
8
+ let(:proxy) { {:proxy => { :host => '127.0.0.1', :port => 8080, :type => :socks5 }} }
6
9
 
7
- # ssh -D 8080 igvita
8
- let(:proxy) { {:proxy => { :host => '127.0.0.1', :port => 8080, :type => :socks5 }} }
10
+ it "should use SOCKS5 proxy" do
11
+ EventMachine.run {
12
+ http = EventMachine::HttpRequest.new('http://jsonip.com/', proxy).get
9
13
 
10
- it "should use SOCKS5 proxy" do
11
- EventMachine.run {
12
- http = EventMachine::HttpRequest.new('http://whatismyip.everdot.org/', proxy).get
13
-
14
- http.errback { failed(http) }
15
- http.callback {
16
- http.response_header.status.should == 200
17
- http.response.should match('72.52.131')
18
- EventMachine.stop
14
+ http.errback { failed(http) }
15
+ http.callback {
16
+ http.response_header.status.should == 200
17
+ http.response.should match('72.52.131')
18
+ EventMachine.stop
19
+ }
19
20
  }
20
- }
21
+ end
21
22
  end
22
23
  end
23
-
24
24
  end
data/spec/stallion.rb CHANGED
@@ -113,11 +113,21 @@ Stallion.saddle :spec do |stable|
113
113
  sleep(10)
114
114
  stable.response.write 'timeout'
115
115
 
116
+ elsif stable.request.path_info == '/cookie_parrot'
117
+ stable.response.status = 200
118
+ stable.response["Set-Cookie"] = stable.request.env['HTTP_COOKIE']
119
+
116
120
  elsif stable.request.path_info == '/redirect'
117
121
  stable.response.status = 301
118
122
  stable.response["Location"] = "/gzip"
119
123
  stable.response.write 'redirect'
120
124
 
125
+ elsif stable.request.path_info == '/redirect/multiple-with-cookie'
126
+ stable.response.status = 301
127
+ stable.response["Set-Cookie"] = "another_id=1; expires=Tue, 09-Aug-2011 17:53:39 GMT; path=/;"
128
+ stable.response["Location"] = "/redirect"
129
+ stable.response.write 'redirect'
130
+
121
131
  elsif stable.request.path_info == '/redirect/bad'
122
132
  stable.response.status = 301
123
133
  stable.response["Location"] = "http://127.0.0.1:8090"
@@ -126,6 +136,20 @@ Stallion.saddle :spec do |stable|
126
136
  stable.response.status = 301
127
137
  stable.response["Location"] = "/"
128
138
 
139
+ elsif stable.request.path_info == '/redirect/middleware_redirects_1'
140
+ stable.response.status = 301
141
+ stable.response["EM-Middleware"] = stable.request.env["HTTP_EM_MIDDLEWARE"]
142
+ stable.response["Location"] = "/redirect/middleware_redirects_2"
143
+
144
+ elsif stable.request.path_info == '/redirect/middleware_redirects_2'
145
+ stable.response.status = 301
146
+ stable.response["EM-Middleware"] = stable.request.env["HTTP_EM_MIDDLEWARE"]
147
+ stable.response["Location"] = "/redirect/middleware_redirects_3"
148
+
149
+ elsif stable.request.path_info == '/redirect/middleware_redirects_3'
150
+ stable.response.status = 200
151
+ stable.response["EM-Middleware"] = stable.request.env["HTTP_EM_MIDDLEWARE"]
152
+
129
153
  elsif stable.request.path_info == '/redirect/nohost'
130
154
  stable.response.status = 301
131
155
  stable.response["Location"] = "http:/"
@@ -144,9 +168,16 @@ Stallion.saddle :spec do |stable|
144
168
  stable.response["Content-Encoding"] = "gzip"
145
169
 
146
170
  elsif stable.request.path_info == '/deflate'
147
- stable.response.write Zlib::Deflate.deflate("compressed")
171
+ deflater = Zlib::Deflate.new(
172
+ Zlib::DEFAULT_COMPRESSION,
173
+ -Zlib::MAX_WBITS, # drop the zlib header which causes both Safari and IE to choke
174
+ Zlib::DEF_MEM_LEVEL,
175
+ Zlib::DEFAULT_STRATEGY
176
+ )
177
+ deflater.deflate("compressed")
178
+ stable.response.write deflater.finish
148
179
  stable.response["Content-Encoding"] = "deflate"
149
-
180
+
150
181
  elsif stable.request.env["HTTP_IF_NONE_MATCH"]
151
182
  stable.response.status = 304
152
183
 
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: em-http-request
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease: 6
5
- version: 1.0.0.beta.3
5
+ version: 1.0.0.beta.4
6
6
  platform: ruby
7
7
  authors:
8
8
  - Ilya Grigorik
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-03-12 00:00:00 -05:00
13
+ date: 2011-05-27 00:00:00 -07:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -21,7 +21,7 @@ dependencies:
21
21
  requirements:
22
22
  - - ">="
23
23
  - !ruby/object:Gem::Version
24
- version: "0"
24
+ version: 1.0.0.beta.3
25
25
  type: :runtime
26
26
  version_requirements: *id001
27
27
  - !ruby/object:Gem::Dependency
@@ -102,16 +102,27 @@ dependencies:
102
102
  type: :development
103
103
  version_requirements: *id008
104
104
  - !ruby/object:Gem::Dependency
105
- name: mongrel
105
+ name: cookiejar
106
106
  prerelease: false
107
107
  requirement: &id009 !ruby/object:Gem::Requirement
108
+ none: false
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: "0"
113
+ type: :development
114
+ version_requirements: *id009
115
+ - !ruby/object:Gem::Dependency
116
+ name: mongrel
117
+ prerelease: false
118
+ requirement: &id010 !ruby/object:Gem::Requirement
108
119
  none: false
109
120
  requirements:
110
121
  - - ~>
111
122
  - !ruby/object:Gem::Version
112
123
  version: 1.2.0.pre2
113
124
  type: :development
114
- version_requirements: *id009
125
+ version_requirements: *id010
115
126
  description: EventMachine based, async HTTP Request client
116
127
  email:
117
128
  - ilya@igvita.com
@@ -122,13 +133,20 @@ extensions: []
122
133
  extra_rdoc_files: []
123
134
 
124
135
  files:
136
+ - .gemtest
125
137
  - .gitignore
126
138
  - .rspec
127
139
  - Changelog.md
128
140
  - Gemfile
129
141
  - README.md
130
142
  - Rakefile
143
+ - benchmarks/clients.rb
144
+ - benchmarks/em-excon.rb
145
+ - benchmarks/em-profile.gif
146
+ - benchmarks/em-profile.txt
147
+ - benchmarks/server.rb
131
148
  - em-http-request.gemspec
149
+ - examples/.gitignore
132
150
  - examples/fetch.rb
133
151
  - examples/fibered-http.rb
134
152
  - examples/oauth-tweet.rb
@@ -138,10 +156,14 @@ files:
138
156
  - lib/em-http/client.rb
139
157
  - lib/em-http/core_ext/bytesize.rb
140
158
  - lib/em-http/decoders.rb
159
+ - lib/em-http/http_client_options.rb
141
160
  - lib/em-http/http_connection.rb
161
+ - lib/em-http/http_connection_options.rb
142
162
  - lib/em-http/http_encoding.rb
143
163
  - lib/em-http/http_header.rb
144
- - lib/em-http/http_options.rb
164
+ - lib/em-http/middleware/cookie_jar.rb
165
+ - lib/em-http/middleware/json_response.rb
166
+ - lib/em-http/middleware/oauth.rb
145
167
  - lib/em-http/multi.rb
146
168
  - lib/em-http/request.rb
147
169
  - lib/em-http/version.rb
@@ -1,53 +0,0 @@
1
- class HttpOptions
2
- attr_reader :uri, :method, :host, :port, :options
3
-
4
- def initialize(uri, options, method = :none)
5
- @options = options
6
- @method = method.to_s.upcase
7
-
8
- set_uri(uri)
9
-
10
- @options[:keepalive] ||= false # default to single request per connection
11
- @options[:redirects] ||= 0 # default number of redirects to follow
12
- @options[:followed] ||= 0 # keep track of number of followed requests
13
-
14
- @options[:connect_timeout] ||= 5 # default connection setup timeout
15
- @options[:inactivity_timeout] ||= 10 # default connection inactivity (post-setup) timeout
16
- end
17
-
18
- def proxy
19
- @options[:proxy]
20
- end
21
-
22
- def follow_redirect?
23
- @options[:followed] < @options[:redirects]
24
- end
25
-
26
- def set_uri(uri)
27
- uri = uri.kind_of?(Addressable::URI) ? uri : Addressable::URI::parse(uri.to_s)
28
-
29
- uri.path = '/' if uri.path.empty?
30
- if path = @options.delete(:path)
31
- uri.path = path
32
- end
33
-
34
- @uri = uri
35
-
36
- # Make sure the ports are set as Addressable::URI doesn't
37
- # set the port if it isn't there
38
- if @uri.scheme == "https"
39
- @uri.port ||= 443
40
- else
41
- @uri.port ||= 80
42
- end
43
-
44
- if proxy = @options[:proxy]
45
- @host = proxy[:host]
46
- @port = proxy[:port]
47
- else
48
- @host = @uri.host
49
- @port = @uri.port
50
- end
51
-
52
- end
53
- end