em-http-request 1.1.2 → 1.1.7
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.
- checksums.yaml +5 -5
- data/.travis.yml +7 -0
- data/README.md +5 -4
- data/em-http-request.gemspec +2 -2
- data/lib/em-http.rb +1 -0
- data/lib/em-http/client.rb +35 -12
- data/lib/em-http/decoders.rb +1 -2
- data/lib/em-http/http_client_options.rb +7 -6
- data/lib/em-http/http_connection.rb +114 -10
- data/lib/em-http/http_connection_options.rb +29 -3
- data/lib/em-http/http_encoding.rb +10 -3
- data/lib/em-http/http_header.rb +5 -5
- data/lib/em-http/middleware/json_response.rb +1 -1
- data/lib/em-http/version.rb +1 -1
- data/lib/em/io_streamer.rb +49 -0
- data/spec/client_spec.rb +114 -2
- data/spec/dns_spec.rb +2 -2
- data/spec/external_spec.rb +3 -3
- data/spec/gzip_spec.rb +23 -0
- data/spec/helper.rb +1 -0
- data/spec/http_proxy_spec.rb +241 -63
- data/spec/pipelining_spec.rb +4 -4
- data/spec/redirect_spec.rb +65 -0
- data/spec/spec_helper.rb +25 -0
- data/spec/ssl_spec.rb +52 -1
- data/spec/stallion.rb +20 -5
- data/spec/stub_server.rb +6 -3
- metadata +39 -36
@@ -46,12 +46,19 @@ module EventMachine
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
-
def encode_request(method, uri, query,
|
49
|
+
def encode_request(method, uri, query, connopts)
|
50
50
|
query = encode_query(uri, query)
|
51
51
|
|
52
52
|
# Non CONNECT proxies require that you provide the full request
|
53
53
|
# uri in request header, as opposed to a relative path.
|
54
|
-
|
54
|
+
# Don't modify the header with CONNECT proxies. It's unneeded and will
|
55
|
+
# cause 400 Bad Request errors with many standard setups.
|
56
|
+
if connopts.proxy && !connopts.connect_proxy?
|
57
|
+
query = uri.join(query)
|
58
|
+
# Drop the userinfo, it's been converted to a header and won't be
|
59
|
+
# accepted by the proxy
|
60
|
+
query.userinfo = nil
|
61
|
+
end
|
55
62
|
|
56
63
|
HTTP_REQUEST_HEADER % [method.to_s.upcase, query]
|
57
64
|
end
|
@@ -112,7 +119,7 @@ module EventMachine
|
|
112
119
|
# String - custom auth string (OAuth, etc)
|
113
120
|
def encode_auth(k,v)
|
114
121
|
if v.is_a? Array
|
115
|
-
FIELD_ENCODING % [k, ["Basic", Base64.
|
122
|
+
FIELD_ENCODING % [k, ["Basic", Base64.strict_encode64(v.join(":")).split.join].join(" ")]
|
116
123
|
else
|
117
124
|
encode_field(k,v)
|
118
125
|
end
|
data/lib/em-http/http_header.rb
CHANGED
@@ -2,13 +2,13 @@ module EventMachine
|
|
2
2
|
# A simple hash is returned for each request made by HttpClient with the
|
3
3
|
# headers that were given by the server for that request.
|
4
4
|
class HttpResponseHeader < Hash
|
5
|
-
# The reason returned in the http response ("OK"
|
5
|
+
# The reason returned in the http response (string - e.g. "OK")
|
6
6
|
attr_accessor :http_reason
|
7
7
|
|
8
|
-
# The HTTP version returned.
|
8
|
+
# The HTTP version returned (string - e.g. "1.1")
|
9
9
|
attr_accessor :http_version
|
10
10
|
|
11
|
-
# The status code (
|
11
|
+
# The status code (integer - e.g. 200)
|
12
12
|
attr_accessor :http_status
|
13
13
|
|
14
14
|
# Raw headers
|
@@ -23,9 +23,9 @@ module EventMachine
|
|
23
23
|
self[HttpClient::LAST_MODIFIED]
|
24
24
|
end
|
25
25
|
|
26
|
-
# HTTP response status
|
26
|
+
# HTTP response status
|
27
27
|
def status
|
28
|
-
|
28
|
+
Integer(http_status) rescue 0
|
29
29
|
end
|
30
30
|
|
31
31
|
# Length of content as an integer, or nil if chunked/unspecified
|
data/lib/em-http/version.rb
CHANGED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'em/streamer'
|
2
|
+
|
3
|
+
# similar to EventMachine::FileStreamer, but for any IO object
|
4
|
+
module EventMachine
|
5
|
+
class IOStreamer
|
6
|
+
include Deferrable
|
7
|
+
CHUNK_SIZE = 16384
|
8
|
+
|
9
|
+
# @param [EventMachine::Connection] connection
|
10
|
+
# @param [IO] io Data source
|
11
|
+
# @param [Integer] Data size
|
12
|
+
#
|
13
|
+
# @option opts [Boolean] :http_chunks (false) Use HTTP 1.1 style chunked-encoding semantics.
|
14
|
+
def initialize(connection, io, opts = {})
|
15
|
+
@connection = connection
|
16
|
+
@io = io
|
17
|
+
@http_chunks = opts[:http_chunks]
|
18
|
+
|
19
|
+
@buff = String.new
|
20
|
+
@io.binmode if @io.respond_to?(:binmode)
|
21
|
+
stream_one_chunk
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
# Used internally to stream one chunk at a time over multiple reactor ticks
|
27
|
+
# @private
|
28
|
+
def stream_one_chunk
|
29
|
+
loop do
|
30
|
+
if @io.eof?
|
31
|
+
@connection.send_data "0\r\n\r\n" if @http_chunks
|
32
|
+
succeed
|
33
|
+
break
|
34
|
+
end
|
35
|
+
|
36
|
+
if @connection.respond_to?(:get_outbound_data_size) && (@connection.get_outbound_data_size > FileStreamer::BackpressureLevel)
|
37
|
+
EventMachine::next_tick { stream_one_chunk }
|
38
|
+
break
|
39
|
+
end
|
40
|
+
|
41
|
+
if @io.read(CHUNK_SIZE, @buff)
|
42
|
+
@connection.send_data("#{@buff.length.to_s(16)}\r\n") if @http_chunks
|
43
|
+
@connection.send_data(@buff)
|
44
|
+
@connection.send_data("\r\n") if @http_chunks
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/spec/client_spec.rb
CHANGED
@@ -51,7 +51,7 @@ describe EventMachine::HttpRequest do
|
|
51
51
|
EventMachine.run {
|
52
52
|
lambda {
|
53
53
|
EventMachine::HttpRequest.new('random?text').get
|
54
|
-
}.should raise_error
|
54
|
+
}.should raise_error(Addressable::URI::InvalidURIError)
|
55
55
|
|
56
56
|
EM.stop
|
57
57
|
}
|
@@ -256,6 +256,19 @@ describe EventMachine::HttpRequest do
|
|
256
256
|
}
|
257
257
|
end
|
258
258
|
|
259
|
+
xit "should support expect-continue header" do
|
260
|
+
EventMachine.run {
|
261
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090').post :body => "data", :head => { 'expect' => '100-continue' }
|
262
|
+
|
263
|
+
http.errback { failed(http) }
|
264
|
+
http.callback {
|
265
|
+
http.response_header.status.should == 200
|
266
|
+
http.response.should == "data"
|
267
|
+
EventMachine.stop
|
268
|
+
}
|
269
|
+
}
|
270
|
+
end
|
271
|
+
|
259
272
|
it "should perform successful GET with custom header" do
|
260
273
|
EventMachine.run {
|
261
274
|
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/').get :head => {'if-none-match' => 'evar!'}
|
@@ -386,7 +399,7 @@ describe EventMachine::HttpRequest do
|
|
386
399
|
}
|
387
400
|
end
|
388
401
|
|
389
|
-
it "should detect gzip encoding" do
|
402
|
+
it "should auto-detect and decode gzip encoding" do
|
390
403
|
EventMachine.run {
|
391
404
|
|
392
405
|
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/gzip').get :head => {"accept-encoding" => "gzip, compressed"}
|
@@ -446,6 +459,36 @@ describe EventMachine::HttpRequest do
|
|
446
459
|
}
|
447
460
|
end
|
448
461
|
|
462
|
+
it "should default to requesting compressed response" do
|
463
|
+
EventMachine.run {
|
464
|
+
|
465
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/echo_accept_encoding').get
|
466
|
+
|
467
|
+
http.errback { failed(http) }
|
468
|
+
http.callback {
|
469
|
+
http.response_header.status.should == 200
|
470
|
+
http.response.should == "gzip, compressed"
|
471
|
+
|
472
|
+
EventMachine.stop
|
473
|
+
}
|
474
|
+
}
|
475
|
+
end
|
476
|
+
|
477
|
+
it "should default to requesting compressed response" do
|
478
|
+
EventMachine.run {
|
479
|
+
|
480
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/echo_accept_encoding').get :compressed => false
|
481
|
+
|
482
|
+
http.errback { failed(http) }
|
483
|
+
http.callback {
|
484
|
+
http.response_header.status.should == 200
|
485
|
+
http.response.should == ""
|
486
|
+
|
487
|
+
EventMachine.stop
|
488
|
+
}
|
489
|
+
}
|
490
|
+
end
|
491
|
+
|
449
492
|
it "should timeout after 0.1 seconds of inactivity" do
|
450
493
|
EventMachine.run {
|
451
494
|
t = Time.now.to_i
|
@@ -759,6 +802,28 @@ describe EventMachine::HttpRequest do
|
|
759
802
|
}
|
760
803
|
end
|
761
804
|
|
805
|
+
it "streams POST request from disk via Pathname" do
|
806
|
+
EventMachine.run {
|
807
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/').post :body => Pathname.new('spec/fixtures/google.ca')
|
808
|
+
http.errback { failed(http) }
|
809
|
+
http.callback {
|
810
|
+
http.response.should match('google')
|
811
|
+
EventMachine.stop
|
812
|
+
}
|
813
|
+
}
|
814
|
+
end
|
815
|
+
|
816
|
+
it "streams POST request from IO object" do
|
817
|
+
EventMachine.run {
|
818
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/').post :body => StringIO.new(File.read('spec/fixtures/google.ca'))
|
819
|
+
http.errback { failed(http) }
|
820
|
+
http.callback {
|
821
|
+
http.response.should match('google')
|
822
|
+
EventMachine.stop
|
823
|
+
}
|
824
|
+
}
|
825
|
+
end
|
826
|
+
|
762
827
|
it "should reconnect if connection was closed between requests" do
|
763
828
|
EventMachine.run {
|
764
829
|
conn = EM::HttpRequest.new('http://127.0.0.1:8090/')
|
@@ -848,6 +913,33 @@ describe EventMachine::HttpRequest do
|
|
848
913
|
}
|
849
914
|
end
|
850
915
|
|
916
|
+
it "should close connection on invalid HTTP response" do
|
917
|
+
EventMachine.run {
|
918
|
+
response =<<-HTTP.gsub(/^ +/, '').strip
|
919
|
+
HTTP/1.1 403 Forbidden
|
920
|
+
Content-Type: text/plain
|
921
|
+
Content-Length: 13
|
922
|
+
|
923
|
+
Access Denied
|
924
|
+
|
925
|
+
HTTP/1.1 403 Forbidden
|
926
|
+
Content-Type: text/plain
|
927
|
+
Content-Length: 13
|
928
|
+
|
929
|
+
Access Denied
|
930
|
+
HTTP
|
931
|
+
|
932
|
+
@s = StubServer.new(response)
|
933
|
+
lambda {
|
934
|
+
conn = EventMachine::HttpRequest.new('http://127.0.0.1:8081/')
|
935
|
+
req = conn.get
|
936
|
+
req.errback { failed(http) }
|
937
|
+
req.callback { EM.stop }
|
938
|
+
}.should_not raise_error
|
939
|
+
|
940
|
+
}
|
941
|
+
end
|
942
|
+
|
851
943
|
context "User-Agent" do
|
852
944
|
it 'should default to "EventMachine HttpClient"' do
|
853
945
|
EventMachine.run {
|
@@ -885,4 +977,24 @@ describe EventMachine::HttpRequest do
|
|
885
977
|
}
|
886
978
|
end
|
887
979
|
end
|
980
|
+
|
981
|
+
context "IPv6" do
|
982
|
+
it "should perform successful GET" do
|
983
|
+
EventMachine.run {
|
984
|
+
@s = StubServer.new({
|
985
|
+
response: "HTTP/1.1 200 OK\r\n\r\nHello IPv6",
|
986
|
+
port: 8091,
|
987
|
+
host: '::1',
|
988
|
+
})
|
989
|
+
http = EventMachine::HttpRequest.new('http://[::1]:8091/').get
|
990
|
+
|
991
|
+
http.errback { failed(http) }
|
992
|
+
http.callback {
|
993
|
+
http.response_header.status.should == 200
|
994
|
+
http.response.should match(/Hello IPv6/)
|
995
|
+
EventMachine.stop
|
996
|
+
}
|
997
|
+
}
|
998
|
+
end
|
999
|
+
end
|
888
1000
|
end
|
data/spec/dns_spec.rb
CHANGED
@@ -7,7 +7,7 @@ describe EventMachine::HttpRequest do
|
|
7
7
|
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/redirect/badhost', :connect_timeout => 0.1).get :redirects => 1
|
8
8
|
http.callback { failed(http) }
|
9
9
|
http.errback {
|
10
|
-
http.error.should match(
|
10
|
+
http.error.should match(/unable to resolve (server |)address/)
|
11
11
|
EventMachine.stop
|
12
12
|
}
|
13
13
|
}
|
@@ -31,7 +31,7 @@ describe EventMachine::HttpRequest do
|
|
31
31
|
http = EventMachine::HttpRequest.new('http://somethinglocal/', :connect_timeout => 0.1).get
|
32
32
|
http.callback { failed(http) }
|
33
33
|
http.errback {
|
34
|
-
http.error.should match(/unable to resolve server address/)
|
34
|
+
http.error.should match(/unable to resolve (server |)address/)
|
35
35
|
http.response_header.status.should == 0
|
36
36
|
EventMachine.stop
|
37
37
|
}
|
data/spec/external_spec.rb
CHANGED
@@ -80,11 +80,11 @@ requires_connection do
|
|
80
80
|
end
|
81
81
|
|
82
82
|
it "should detect deflate encoding" do
|
83
|
-
pending "need an endpoint which supports deflate.. MSN is no longer"
|
83
|
+
# pending "need an endpoint which supports deflate.. MSN is no longer"
|
84
84
|
EventMachine.run {
|
85
85
|
|
86
86
|
options = {:head => {"accept-encoding" => "deflate"}, :redirects => 5}
|
87
|
-
http = EventMachine::HttpRequest.new('http://www.
|
87
|
+
http = EventMachine::HttpRequest.new('http://www.libpng.org/').get options
|
88
88
|
|
89
89
|
http.errback { failed(http) }
|
90
90
|
http.callback {
|
@@ -135,7 +135,7 @@ requires_connection do
|
|
135
135
|
|
136
136
|
it "should work with keep-alive servers" do
|
137
137
|
EventMachine.run {
|
138
|
-
http = EventMachine::HttpRequest.new('
|
138
|
+
http = EventMachine::HttpRequest.new('https://github.com/igrigorik/em-http-request').get :keepalive => true
|
139
139
|
|
140
140
|
http.errback { failed(http) }
|
141
141
|
http.callback {
|
data/spec/gzip_spec.rb
CHANGED
@@ -56,6 +56,29 @@ describe EventMachine::HttpDecoders::GZip do
|
|
56
56
|
decompressed.size.should eq(32907)
|
57
57
|
end
|
58
58
|
|
59
|
+
it "should not care how many chunks the file is split up into" do
|
60
|
+
examples = [
|
61
|
+
["\x1F", "\x8B", "\b", "\x00", "\x00", "\x00", "\x00", "\x00", "\x00", "\x00", "\xF3", "\xCB", "/", "Q", "p\xCB/\xCDK\x01\x00M\x8Ct\xB1\t\x00\x00\x00"],
|
62
|
+
["\x1F", "\x8B", "\b", "\x00", "\x00", "\x00", "\x00", "\x00\x00\x00\xF3\xCB/Qp\xCB/\xCDK\x01\x00M\x8Ct\xB1\t\x00\x00\x00"]
|
63
|
+
]
|
64
|
+
|
65
|
+
examples.each do |example|
|
66
|
+
decompressed = ""
|
67
|
+
|
68
|
+
gz = EventMachine::HttpDecoders::GZip.new do |data|
|
69
|
+
decompressed << data
|
70
|
+
end
|
71
|
+
|
72
|
+
example.each do |bytes|
|
73
|
+
gz << bytes
|
74
|
+
end
|
75
|
+
|
76
|
+
gz.finalize!
|
77
|
+
|
78
|
+
decompressed.should eq("Not Found")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
59
82
|
it "should fail with a DecoderError if not a gzip file" do
|
60
83
|
not_a_gzip = ["1f8c08089668a650000"].pack("H*")
|
61
84
|
header = EventMachine::HttpDecoders::GZipHeader.new
|
data/spec/helper.rb
CHANGED
data/spec/http_proxy_spec.rb
CHANGED
@@ -1,90 +1,268 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
|
+
shared_examples "*_PROXY var (through proxy)" do
|
4
|
+
it "should use HTTP proxy" do
|
5
|
+
EventMachine.run {
|
6
|
+
http = EventMachine::HttpRequest.new("#{proxy_test_scheme}://127.0.0.1:8090/?q=test").get
|
7
|
+
|
8
|
+
http.errback { failed(http) }
|
9
|
+
http.callback {
|
10
|
+
http.response_header.status.should == 200
|
11
|
+
http.response_header.should_not include("X_PROXY_AUTH")
|
12
|
+
http.response.should match('test')
|
13
|
+
EventMachine.stop
|
14
|
+
}
|
15
|
+
}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
shared_examples "*_PROXY var (testing var)" do
|
20
|
+
subject { HttpConnectionOptions.new("#{proxy_test_scheme}://example.com", {}) }
|
21
|
+
it { expect(subject.proxy_from_env).to eq({ :host => "127.0.0.1", :port => 8083, :type => :http }) }
|
22
|
+
it { expect(subject.host).to eq "127.0.0.1" }
|
23
|
+
it { expect(subject.port).to be 8083 }
|
24
|
+
it do
|
25
|
+
case proxy_test_scheme.to_sym
|
26
|
+
when :http
|
27
|
+
expect(subject.http_proxy?).to be_truthy
|
28
|
+
when :https
|
29
|
+
expect(subject.connect_proxy?).to be_truthy
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
3
34
|
describe EventMachine::HttpRequest do
|
4
35
|
|
5
36
|
context "connections via" do
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
http.
|
16
|
-
|
17
|
-
|
18
|
-
|
37
|
+
context "without *_PROXY env" do
|
38
|
+
let(:proxy) { {:proxy => { :host => '127.0.0.1', :port => 8083 }} }
|
39
|
+
let(:authenticated_proxy) { {:proxy => { :host => '127.0.0.1', :port => 8083, :authorization => ["user", "name"] } } }
|
40
|
+
|
41
|
+
it "should use HTTP proxy" do
|
42
|
+
EventMachine.run {
|
43
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/?q=test', proxy).get
|
44
|
+
|
45
|
+
http.errback { failed(http) }
|
46
|
+
http.callback {
|
47
|
+
http.response_header.status.should == 200
|
48
|
+
http.response_header.should_not include("X_PROXY_AUTH")
|
49
|
+
http.response.should match('test')
|
50
|
+
EventMachine.stop
|
51
|
+
}
|
19
52
|
}
|
20
|
-
|
21
|
-
end
|
53
|
+
end
|
22
54
|
|
23
|
-
|
24
|
-
|
25
|
-
|
55
|
+
it "should use HTTP proxy with authentication" do
|
56
|
+
EventMachine.run {
|
57
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/proxyauth?q=test', authenticated_proxy).get
|
26
58
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
59
|
+
http.errback { failed(http) }
|
60
|
+
http.callback {
|
61
|
+
http.response_header.status.should == 200
|
62
|
+
http.response_header['X_PROXY_AUTH'].should == "Proxy-Authorization: Basic dXNlcjpuYW1l"
|
63
|
+
http.response.should match('test')
|
64
|
+
EventMachine.stop
|
65
|
+
}
|
33
66
|
}
|
34
|
-
|
35
|
-
end
|
67
|
+
end
|
36
68
|
|
37
|
-
|
38
|
-
|
69
|
+
it "should send absolute URIs to the proxy server" do
|
70
|
+
EventMachine.run {
|
39
71
|
|
40
|
-
|
72
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/?q=test', proxy).get
|
41
73
|
|
42
|
-
|
43
|
-
|
44
|
-
|
74
|
+
http.errback { failed(http) }
|
75
|
+
http.callback {
|
76
|
+
http.response_header.status.should == 200
|
45
77
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
78
|
+
# The test proxy server gives the requested uri back in this header
|
79
|
+
http.response_header['X_THE_REQUESTED_URI'].should == 'http://127.0.0.1:8090/?q=test'
|
80
|
+
http.response_header['X_THE_REQUESTED_URI'].should_not == '/?q=test'
|
81
|
+
http.response.should match('test')
|
82
|
+
EventMachine.stop
|
83
|
+
}
|
51
84
|
}
|
52
|
-
|
53
|
-
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should strip basic auth from before the host in URI sent to proxy" do
|
88
|
+
EventMachine.run {
|
54
89
|
|
55
|
-
|
56
|
-
EventMachine.run {
|
57
|
-
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/', proxy).get :query => { 'q' => 'test' }
|
90
|
+
http = EventMachine::HttpRequest.new('http://user:pass@127.0.0.1:8090/echo_authorization_header', proxy).get
|
58
91
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
92
|
+
http.errback { failed(http) }
|
93
|
+
http.callback {
|
94
|
+
http.response_header.status.should == 200
|
95
|
+
# The test proxy server gives the requested uri back in this header
|
96
|
+
http.response_header['X_THE_REQUESTED_URI'].should == 'http://127.0.0.1:8090/echo_authorization_header'
|
97
|
+
# Ensure the basic auth was converted to a header correctly
|
98
|
+
http.response.should match('authorization:Basic dXNlcjpwYXNz')
|
99
|
+
EventMachine.stop
|
100
|
+
}
|
64
101
|
}
|
65
|
-
|
66
|
-
end
|
102
|
+
end
|
67
103
|
|
68
|
-
|
69
|
-
|
70
|
-
|
104
|
+
it "should include query parameters specified in the options" do
|
105
|
+
EventMachine.run {
|
106
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/', proxy).get :query => { 'q' => 'test' }
|
71
107
|
|
72
|
-
|
73
|
-
|
74
|
-
|
108
|
+
http.errback { failed(http) }
|
109
|
+
http.callback {
|
110
|
+
http.response_header.status.should == 200
|
111
|
+
http.response.should match('test')
|
112
|
+
EventMachine.stop
|
113
|
+
}
|
114
|
+
}
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should use HTTP proxy while redirecting" do
|
118
|
+
EventMachine.run {
|
119
|
+
http = EventMachine::HttpRequest.new('http://127.0.0.1:8090/redirect', proxy).get :redirects => 1
|
75
120
|
|
76
|
-
http.
|
77
|
-
http.
|
121
|
+
http.errback { failed(http) }
|
122
|
+
http.callback {
|
123
|
+
http.response_header.status.should == 200
|
78
124
|
|
79
|
-
|
80
|
-
|
81
|
-
http.last_effective_url.to_s.should == 'http://127.0.0.1:8090/gzip'
|
82
|
-
http.redirects.should == 1
|
125
|
+
http.response_header['X_THE_REQUESTED_URI'].should == 'http://127.0.0.1:8090/gzip'
|
126
|
+
http.response_header['X_THE_REQUESTED_URI'].should_not == '/redirect'
|
83
127
|
|
84
|
-
|
128
|
+
http.response_header["CONTENT_ENCODING"].should == "gzip"
|
129
|
+
http.response.should == "compressed"
|
130
|
+
http.last_effective_url.to_s.should == 'http://127.0.0.1:8090/gzip'
|
131
|
+
http.redirects.should == 1
|
132
|
+
|
133
|
+
EventMachine.stop
|
134
|
+
}
|
85
135
|
}
|
86
|
-
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
context "when parsing *_PROXY var (through proxy)s" do
|
140
|
+
context "with $HTTP_PROXY env" do
|
141
|
+
let(:proxy_test_scheme) { :http }
|
142
|
+
|
143
|
+
before(:all) do
|
144
|
+
PROXY_ENV_VARS.each {|k| ENV.delete k }
|
145
|
+
ENV['HTTP_PROXY'] = 'http://127.0.0.1:8083'
|
146
|
+
end
|
147
|
+
|
148
|
+
include_examples "*_PROXY var (through proxy)"
|
149
|
+
end
|
150
|
+
|
151
|
+
context "with $http_proxy env" do
|
152
|
+
let(:proxy_test_scheme) { :http }
|
153
|
+
|
154
|
+
before(:all) do
|
155
|
+
PROXY_ENV_VARS.each {|k| ENV.delete k }
|
156
|
+
ENV['http_proxy'] = 'http://127.0.0.1:8083'
|
157
|
+
end
|
158
|
+
|
159
|
+
include_examples "*_PROXY var (through proxy)"
|
160
|
+
end
|
161
|
+
|
162
|
+
## TODO: Use a Mongrel HTTP server that can handle SSL:
|
163
|
+
context "with $HTTPS_PROXY env", skip: "Mongrel isn't configured to handle HTTPS, currently" do
|
164
|
+
let(:proxy_test_scheme) { :https }
|
165
|
+
|
166
|
+
before(:all) do
|
167
|
+
PROXY_ENV_VARS.each {|k| ENV.delete k }
|
168
|
+
ENV['HTTPS_PROXY'] = 'http://127.0.0.1:8083'
|
169
|
+
end
|
170
|
+
|
171
|
+
include_examples "*_PROXY var (through proxy)"
|
172
|
+
end
|
173
|
+
|
174
|
+
## TODO: Use a Mongrel HTTP server that can handle SSL:
|
175
|
+
context "with $https_proxy env", skip: "Mongrel isn't configured to handle HTTPS, currently" do
|
176
|
+
let(:proxy_test_scheme) { :https }
|
177
|
+
|
178
|
+
before(:all) do
|
179
|
+
PROXY_ENV_VARS.each {|k| ENV.delete k }
|
180
|
+
ENV['https_proxy'] = 'http://127.0.0.1:8083'
|
181
|
+
end
|
182
|
+
|
183
|
+
include_examples "*_PROXY var (through proxy)"
|
184
|
+
end
|
185
|
+
|
186
|
+
context "with $ALL_PROXY env" do
|
187
|
+
let(:proxy_test_scheme) { :http }
|
188
|
+
|
189
|
+
before(:all) do
|
190
|
+
PROXY_ENV_VARS.each {|k| ENV.delete k }
|
191
|
+
ENV['ALL_PROXY'] = 'http://127.0.0.1:8083'
|
192
|
+
end
|
193
|
+
|
194
|
+
include_examples "*_PROXY var (through proxy)"
|
195
|
+
end
|
87
196
|
end
|
88
197
|
end
|
89
198
|
|
199
|
+
context "when parsing *_PROXY vars" do
|
200
|
+
context "without a *_PROXY var" do
|
201
|
+
before(:all) do
|
202
|
+
PROXY_ENV_VARS.each {|k| ENV.delete k }
|
203
|
+
end
|
204
|
+
|
205
|
+
subject { HttpConnectionOptions.new("http://example.com", {}) }
|
206
|
+
it { expect(subject.proxy_from_env).to be_nil }
|
207
|
+
it { expect(subject.host).to eq "example.com" }
|
208
|
+
it { expect(subject.port).to be 80 }
|
209
|
+
it { expect(subject.http_proxy?).to be_falsey }
|
210
|
+
it { expect(subject.connect_proxy?).to be_falsey }
|
211
|
+
end
|
212
|
+
|
213
|
+
context "with $HTTP_PROXY env" do
|
214
|
+
let(:proxy_test_scheme) { :http }
|
215
|
+
|
216
|
+
before(:each) do
|
217
|
+
PROXY_ENV_VARS.each {|k| ENV.delete k }
|
218
|
+
ENV['HTTP_PROXY'] = 'http://127.0.0.1:8083'
|
219
|
+
end
|
220
|
+
|
221
|
+
include_examples "*_PROXY var (testing var)"
|
222
|
+
end
|
223
|
+
|
224
|
+
context "with $http_proxy env" do
|
225
|
+
let(:proxy_test_scheme) { :http }
|
226
|
+
|
227
|
+
before(:each) do
|
228
|
+
PROXY_ENV_VARS.each {|k| ENV.delete k }
|
229
|
+
ENV['http_proxy'] = 'http://127.0.0.1:8083'
|
230
|
+
end
|
231
|
+
|
232
|
+
include_examples "*_PROXY var (testing var)"
|
233
|
+
end
|
234
|
+
|
235
|
+
context "with $HTTPS_PROXY env" do
|
236
|
+
let(:proxy_test_scheme) { :https }
|
237
|
+
|
238
|
+
before(:each) do
|
239
|
+
PROXY_ENV_VARS.each {|k| ENV.delete k }
|
240
|
+
ENV['HTTPS_PROXY'] = 'http://127.0.0.1:8083'
|
241
|
+
end
|
242
|
+
|
243
|
+
include_examples "*_PROXY var (testing var)"
|
244
|
+
end
|
245
|
+
|
246
|
+
context "with $https_proxy env" do
|
247
|
+
let(:proxy_test_scheme) { :https }
|
248
|
+
|
249
|
+
before(:each) do
|
250
|
+
PROXY_ENV_VARS.each {|k| ENV.delete k }
|
251
|
+
ENV['https_proxy'] = 'http://127.0.0.1:8083'
|
252
|
+
end
|
253
|
+
|
254
|
+
include_examples "*_PROXY var (testing var)"
|
255
|
+
end
|
256
|
+
|
257
|
+
context "with $ALL_PROXY env" do
|
258
|
+
let(:proxy_test_scheme) { :https }
|
259
|
+
|
260
|
+
before(:each) do
|
261
|
+
PROXY_ENV_VARS.each {|k| ENV.delete k }
|
262
|
+
ENV['ALL_PROXY'] = 'http://127.0.0.1:8083'
|
263
|
+
end
|
264
|
+
|
265
|
+
include_examples "*_PROXY var (testing var)"
|
266
|
+
end
|
267
|
+
end
|
90
268
|
end
|