em-http-request 1.0.3 → 1.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.
Potentially problematic release.
This version of em-http-request might be problematic. Click here for more details.
- data/Changelog.md +4 -0
- data/README.md +2 -2
- data/em-http-request.gemspec +4 -4
- data/examples/digest_auth/client.rb +25 -0
- data/examples/digest_auth/server.rb +28 -0
- data/examples/fibered-http.rb +1 -1
- data/lib/em-http/client.rb +13 -6
- data/lib/em-http/decoders.rb +138 -29
- data/lib/em-http/http_client_options.rb +6 -5
- data/lib/em-http/http_connection.rb +9 -4
- data/lib/em-http/http_connection_options.rb +13 -2
- data/lib/em-http/http_header.rb +21 -1
- data/lib/em-http/middleware/digest_auth.rb +112 -0
- data/lib/em-http/middleware/oauth2.rb +28 -0
- data/lib/em-http/request.rb +1 -0
- data/lib/em-http/version.rb +1 -1
- data/spec/client_spec.rb +62 -7
- data/spec/digest_auth_spec.rb +48 -0
- data/spec/external_spec.rb +2 -2
- data/spec/fixtures/gzip-sample.gz +0 -0
- data/spec/gzip_spec.rb +68 -0
- data/spec/helper.rb +1 -0
- data/spec/middleware/oauth2_spec.rb +15 -0
- data/spec/pipelining_spec.rb +2 -2
- data/spec/redirect_spec.rb +66 -12
- data/spec/socksify_proxy_spec.rb +36 -0
- data/spec/stallion.rb +7 -0
- metadata +20 -10
data/spec/helper.rb
CHANGED
@@ -0,0 +1,15 @@
|
|
1
|
+
describe EventMachine::Middleware::OAuth2 do
|
2
|
+
it "should add an access token to a URI with no query parameters" do
|
3
|
+
middleware = EventMachine::Middleware::OAuth2.new(:access_token => "fedcba9876543210")
|
4
|
+
uri = Addressable::URI.parse("https://graph.facebook.com/me")
|
5
|
+
middleware.update_uri! uri
|
6
|
+
uri.to_s.should == "https://graph.facebook.com/me?access_token=fedcba9876543210"
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should add an access token to a URI with query parameters" do
|
10
|
+
middleware = EventMachine::Middleware::OAuth2.new(:access_token => "fedcba9876543210")
|
11
|
+
uri = Addressable::URI.parse("https://graph.facebook.com/me?fields=photo")
|
12
|
+
middleware.update_uri! uri
|
13
|
+
uri.to_s.should == "https://graph.facebook.com/me?fields=photo&access_token=fedcba9876543210"
|
14
|
+
end
|
15
|
+
end
|
data/spec/pipelining_spec.rb
CHANGED
@@ -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(/
|
30
|
+
pipe2.response.should match(/html/i)
|
31
31
|
stop.call
|
32
32
|
}
|
33
33
|
|
@@ -63,4 +63,4 @@ requires_connection do
|
|
63
63
|
end
|
64
64
|
end
|
65
65
|
|
66
|
-
end
|
66
|
+
end
|
data/spec/redirect_spec.rb
CHANGED
@@ -40,21 +40,33 @@ describe EventMachine::HttpRequest do
|
|
40
40
|
}
|
41
41
|
end
|
42
42
|
|
43
|
+
it "should not follow redirects on created" do
|
44
|
+
EventMachine.run {
|
45
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/redirect/created').get :redirects => 1
|
46
|
+
http.errback { failed(http) }
|
47
|
+
http.callback {
|
48
|
+
http.response_header.status.should == 201
|
49
|
+
http.response.should match(/Hello/)
|
50
|
+
EM.stop
|
51
|
+
}
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
43
55
|
it "should not forward cookies across domains with http redirect" do
|
44
56
|
|
45
57
|
expires = (Date.today + 2).strftime('%a, %d %b %Y %T GMT')
|
46
58
|
response =<<-HTTP.gsub(/^ +/, '')
|
47
59
|
HTTP/1.1 301 MOVED PERMANENTLY
|
48
|
-
Location: http://localhost:
|
60
|
+
Location: http://localhost:8071/
|
49
61
|
Set-Cookie: foo=bar; expires=#{expires}; path=/; HttpOnly
|
50
62
|
|
51
63
|
HTTP
|
52
64
|
|
53
65
|
EventMachine.run do
|
54
|
-
@stub = StubServer.new(:host => '127.0.0.1', :port =>
|
55
|
-
@echo = StubServer.new(:host => 'localhost', :port =>
|
66
|
+
@stub = StubServer.new(:host => '127.0.0.1', :port => 8070, :response => response)
|
67
|
+
@echo = StubServer.new(:host => 'localhost', :port => 8071, :echo => true)
|
56
68
|
|
57
|
-
http = EventMachine::HttpRequest.new('http://127.0.0.1:
|
69
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8070/').get :redirects => 1
|
58
70
|
|
59
71
|
http.errback { failed(http) }
|
60
72
|
http.callback do
|
@@ -71,16 +83,43 @@ describe EventMachine::HttpRequest do
|
|
71
83
|
expires = (Date.today + 2).strftime('%a, %d %b %Y %T GMT')
|
72
84
|
response =<<-HTTP.gsub(/^ +/, '')
|
73
85
|
HTTP/1.1 301 MOVED PERMANENTLY
|
74
|
-
Location: http://127.0.0.1:
|
86
|
+
Location: http://127.0.0.1:8071/
|
75
87
|
Set-Cookie: foo=bar; expires=#{expires}; path=/; HttpOnly
|
76
88
|
|
77
89
|
HTTP
|
78
90
|
|
79
91
|
EventMachine.run do
|
80
|
-
@stub = StubServer.new(:host => '127.0.0.1', :port =>
|
81
|
-
@echo = StubServer.new(:host => '127.0.0.1', :port =>
|
92
|
+
@stub = StubServer.new(:host => '127.0.0.1', :port => 8070, :response => response)
|
93
|
+
@echo = StubServer.new(:host => '127.0.0.1', :port => 8071, :echo => true)
|
82
94
|
|
83
|
-
http = EventMachine::HttpRequest.new('http://127.0.0.1:
|
95
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8070/').get :redirects => 1
|
96
|
+
|
97
|
+
http.errback { failed(http) }
|
98
|
+
http.callback do
|
99
|
+
http.response.should match(/Cookie/)
|
100
|
+
@stub.stop
|
101
|
+
@echo.stop
|
102
|
+
EM.stop
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
it "should normalize path and forward valid cookies across domains" do
|
109
|
+
|
110
|
+
expires = (Date.today + 2).strftime('%a, %d %b %Y %T GMT')
|
111
|
+
response =<<-HTTP.gsub(/^ +/, '')
|
112
|
+
HTTP/1.1 301 MOVED PERMANENTLY
|
113
|
+
Location: http://127.0.0.1:8071?omg=ponies
|
114
|
+
Set-Cookie: foo=bar; expires=#{expires}; path=/; HttpOnly
|
115
|
+
|
116
|
+
HTTP
|
117
|
+
|
118
|
+
EventMachine.run do
|
119
|
+
@stub = StubServer.new(:host => '127.0.0.1', :port => 8070, :response => response)
|
120
|
+
@echo = StubServer.new(:host => '127.0.0.1', :port => 8071, :echo => true)
|
121
|
+
|
122
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8070/').get :redirects => 1
|
84
123
|
|
85
124
|
http.errback { failed(http) }
|
86
125
|
http.callback do
|
@@ -94,9 +133,10 @@ describe EventMachine::HttpRequest do
|
|
94
133
|
|
95
134
|
it "should redirect with missing content-length" do
|
96
135
|
EventMachine.run {
|
97
|
-
|
136
|
+
response = "HTTP/1.0 301 MOVED PERMANENTLY\r\nlocation: http://127.0.0.1:8090/redirect\r\n\r\n"
|
137
|
+
@stub = StubServer.new(:host => '127.0.0.1', :port => 8070, :response => response)
|
98
138
|
|
99
|
-
http = EventMachine::HttpRequest.new('http://127.0.0.1:
|
139
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8070/').get :redirects => 3
|
100
140
|
http.errback { failed(http) }
|
101
141
|
|
102
142
|
http.callback {
|
@@ -106,7 +146,7 @@ describe EventMachine::HttpRequest do
|
|
106
146
|
http.last_effective_url.to_s.should == 'http://127.0.0.1:8090/gzip'
|
107
147
|
http.redirects.should == 3
|
108
148
|
|
109
|
-
@
|
149
|
+
@stub.stop
|
110
150
|
EM.stop
|
111
151
|
}
|
112
152
|
}
|
@@ -153,7 +193,7 @@ describe EventMachine::HttpRequest do
|
|
153
193
|
|
154
194
|
it "should not invoke redirect logic on failed(http) connections" do
|
155
195
|
EventMachine.run {
|
156
|
-
http = EventMachine::HttpRequest.new('http://127.0.0.1:
|
196
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8070/', :connect_timeout => 0.1).get :redirects => 5
|
157
197
|
http.callback { failed(http) }
|
158
198
|
http.errback {
|
159
199
|
http.redirects.should == 0
|
@@ -236,6 +276,20 @@ describe EventMachine::HttpRequest do
|
|
236
276
|
}
|
237
277
|
end
|
238
278
|
|
279
|
+
it "should follow location redirects with path" do
|
280
|
+
EventMachine.run {
|
281
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/redirect').get :path => '/redirect', :redirects => 1
|
282
|
+
http.errback { failed(http) }
|
283
|
+
http.callback {
|
284
|
+
http.last_effective_url.to_s.should == 'http://127.0.0.1:8090/gzip'
|
285
|
+
http.response_header.status.should == 200
|
286
|
+
http.redirects.should == 1
|
287
|
+
|
288
|
+
EM.stop
|
289
|
+
}
|
290
|
+
}
|
291
|
+
end
|
292
|
+
|
239
293
|
it "should call middleware each time it redirects" do
|
240
294
|
EventMachine.run {
|
241
295
|
conn = EventMachine::HttpRequest.new('http://127.0.0.1:8090/redirect/middleware_redirects_1')
|
data/spec/socksify_proxy_spec.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
3
|
requires_connection do
|
4
|
+
|
4
5
|
requires_port(8080) do
|
5
6
|
describe EventMachine::HttpRequest do
|
6
7
|
|
@@ -21,4 +22,39 @@ requires_connection do
|
|
21
22
|
end
|
22
23
|
end
|
23
24
|
end
|
25
|
+
|
26
|
+
requires_port(8081) do
|
27
|
+
describe EventMachine::HttpRequest do
|
28
|
+
|
29
|
+
# brew install tinyproxy
|
30
|
+
let(:http_proxy) { {:proxy => { :host => '127.0.0.1', :port => 8081 }} }
|
31
|
+
|
32
|
+
it "should use HTTP proxy by default" do
|
33
|
+
EventMachine.run {
|
34
|
+
http = EventMachine::HttpRequest.new('http://jsonip.com/', http_proxy).get
|
35
|
+
|
36
|
+
http.errback { failed(http) }
|
37
|
+
http.callback {
|
38
|
+
http.response_header.status.should == 200
|
39
|
+
http.response.should match(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/)
|
40
|
+
EventMachine.stop
|
41
|
+
}
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should auto CONNECT via HTTP proxy for HTTPS requests" do
|
46
|
+
EventMachine.run {
|
47
|
+
http = EventMachine::HttpRequest.new('https://ipjson.herokuapp.com/', http_proxy).get
|
48
|
+
|
49
|
+
http.errback { failed(http) }
|
50
|
+
http.callback {
|
51
|
+
http.response_header.status.should == 200
|
52
|
+
http.response.should match(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/)
|
53
|
+
EventMachine.stop
|
54
|
+
}
|
55
|
+
}
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
24
60
|
end
|
data/spec/stallion.rb
CHANGED
@@ -140,6 +140,11 @@ Stallion.saddle :spec do |stable|
|
|
140
140
|
stable.response["Location"] = "/gzip"
|
141
141
|
stable.response.write 'redirect'
|
142
142
|
|
143
|
+
elsif stable.request.path_info == '/redirect/created'
|
144
|
+
stable.response.status = 201
|
145
|
+
stable.response["Location"] = "/"
|
146
|
+
stable.response.write 'Hello, World!'
|
147
|
+
|
143
148
|
elsif stable.request.path_info == '/redirect/multiple-with-cookie'
|
144
149
|
stable.response.status = 301
|
145
150
|
stable.response["Set-Cookie"] = "another_id=1; expires=Sat, 09 Aug 2031 17:53:39 GMT; path=/;"
|
@@ -223,6 +228,8 @@ Stallion.saddle :spec do |stable|
|
|
223
228
|
elsif stable.request.path_info == '/relative-location'
|
224
229
|
stable.response.status = 301
|
225
230
|
stable.response["Location"] = '/forwarded'
|
231
|
+
elsif stable.request.path_info == '/echo-user-agent'
|
232
|
+
stable.response.write stable.request.env["HTTP_USER_AGENT"].inspect
|
226
233
|
|
227
234
|
elsif
|
228
235
|
stable.response.write 'Hello, World!'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: em-http-request
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-06-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: eventmachine
|
@@ -18,7 +18,7 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 1.0.
|
21
|
+
version: 1.0.3
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -26,7 +26,7 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ! '>='
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: 1.0.
|
29
|
+
version: 1.0.3
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
name: addressable
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
@@ -34,7 +34,7 @@ dependencies:
|
|
34
34
|
requirements:
|
35
35
|
- - ! '>='
|
36
36
|
- !ruby/object:Gem::Version
|
37
|
-
version: 2.
|
37
|
+
version: 2.3.4
|
38
38
|
type: :runtime
|
39
39
|
prerelease: false
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -42,7 +42,7 @@ dependencies:
|
|
42
42
|
requirements:
|
43
43
|
- - ! '>='
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version: 2.
|
45
|
+
version: 2.3.4
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
47
|
name: http_parser.rb
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
@@ -50,7 +50,7 @@ dependencies:
|
|
50
50
|
requirements:
|
51
51
|
- - ! '>='
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: 0.
|
53
|
+
version: 0.6.0.beta.2
|
54
54
|
type: :runtime
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -58,7 +58,7 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - ! '>='
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0.
|
61
|
+
version: 0.6.0.beta.2
|
62
62
|
- !ruby/object:Gem::Dependency
|
63
63
|
name: em-socksify
|
64
64
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,7 +66,7 @@ dependencies:
|
|
66
66
|
requirements:
|
67
67
|
- - ! '>='
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version: '0'
|
69
|
+
version: '0.3'
|
70
70
|
type: :runtime
|
71
71
|
prerelease: false
|
72
72
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -74,7 +74,7 @@ dependencies:
|
|
74
74
|
requirements:
|
75
75
|
- - ! '>='
|
76
76
|
- !ruby/object:Gem::Version
|
77
|
-
version: '0'
|
77
|
+
version: '0.3'
|
78
78
|
- !ruby/object:Gem::Dependency
|
79
79
|
name: cookiejar
|
80
80
|
requirement: !ruby/object:Gem::Requirement
|
@@ -192,6 +192,8 @@ files:
|
|
192
192
|
- benchmarks/server.rb
|
193
193
|
- em-http-request.gemspec
|
194
194
|
- examples/.gitignore
|
195
|
+
- examples/digest_auth/client.rb
|
196
|
+
- examples/digest_auth/server.rb
|
195
197
|
- examples/fetch.rb
|
196
198
|
- examples/fibered-http.rb
|
197
199
|
- examples/multi.rb
|
@@ -208,20 +210,25 @@ files:
|
|
208
210
|
- lib/em-http/http_encoding.rb
|
209
211
|
- lib/em-http/http_header.rb
|
210
212
|
- lib/em-http/http_status_codes.rb
|
213
|
+
- lib/em-http/middleware/digest_auth.rb
|
211
214
|
- lib/em-http/middleware/json_response.rb
|
212
215
|
- lib/em-http/middleware/oauth.rb
|
216
|
+
- lib/em-http/middleware/oauth2.rb
|
213
217
|
- lib/em-http/multi.rb
|
214
218
|
- lib/em-http/request.rb
|
215
219
|
- lib/em-http/version.rb
|
216
220
|
- spec/client_fiber_spec.rb
|
217
221
|
- spec/client_spec.rb
|
222
|
+
- spec/digest_auth_spec.rb
|
218
223
|
- spec/dns_spec.rb
|
219
224
|
- spec/encoding_spec.rb
|
220
225
|
- spec/external_spec.rb
|
221
226
|
- spec/fixtures/google.ca
|
222
227
|
- spec/fixtures/gzip-sample.gz
|
228
|
+
- spec/gzip_spec.rb
|
223
229
|
- spec/helper.rb
|
224
230
|
- spec/http_proxy_spec.rb
|
231
|
+
- spec/middleware/oauth2_spec.rb
|
225
232
|
- spec/middleware_spec.rb
|
226
233
|
- spec/multi_spec.rb
|
227
234
|
- spec/pipelining_spec.rb
|
@@ -257,13 +264,16 @@ summary: EventMachine based, async HTTP Request client
|
|
257
264
|
test_files:
|
258
265
|
- spec/client_fiber_spec.rb
|
259
266
|
- spec/client_spec.rb
|
267
|
+
- spec/digest_auth_spec.rb
|
260
268
|
- spec/dns_spec.rb
|
261
269
|
- spec/encoding_spec.rb
|
262
270
|
- spec/external_spec.rb
|
263
271
|
- spec/fixtures/google.ca
|
264
272
|
- spec/fixtures/gzip-sample.gz
|
273
|
+
- spec/gzip_spec.rb
|
265
274
|
- spec/helper.rb
|
266
275
|
- spec/http_proxy_spec.rb
|
276
|
+
- spec/middleware/oauth2_spec.rb
|
267
277
|
- spec/middleware_spec.rb
|
268
278
|
- spec/multi_spec.rb
|
269
279
|
- spec/pipelining_spec.rb
|