httparty 0.8.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of httparty might be problematic. Click here for more details.
- data/.gitignore +1 -0
- data/.travis.yml +8 -0
- data/Gemfile +8 -1
- data/Guardfile +16 -0
- data/History +34 -0
- data/README.md +79 -0
- data/bin/httparty +10 -4
- data/cucumber.yml +1 -1
- data/examples/crack.rb +19 -0
- data/examples/headers_and_user_agents.rb +6 -0
- data/examples/nokogiri_html_parser.rb +22 -0
- data/features/steps/remote_service_steps.rb +1 -1
- data/httparty.gemspec +2 -2
- data/lib/httparty.rb +81 -30
- data/lib/httparty/connection_adapter.rb +116 -0
- data/lib/httparty/cookie_hash.rb +2 -2
- data/lib/httparty/core_extensions.rb +23 -0
- data/lib/httparty/hash_conversions.rb +1 -1
- data/lib/httparty/module_inheritable_attributes.rb +11 -1
- data/lib/httparty/net_digest_auth.rb +20 -7
- data/lib/httparty/parser.rb +10 -6
- data/lib/httparty/request.rb +34 -51
- data/lib/httparty/response.rb +17 -40
- data/lib/httparty/response/headers.rb +31 -0
- data/lib/httparty/version.rb +1 -1
- data/spec/httparty/connection_adapter_spec.rb +206 -0
- data/spec/httparty/cookie_hash_spec.rb +3 -4
- data/spec/httparty/net_digest_auth_spec.rb +33 -11
- data/spec/httparty/parser_spec.rb +16 -0
- data/spec/httparty/request_spec.rb +78 -101
- data/spec/httparty/response_spec.rb +41 -20
- data/spec/httparty/ssl_spec.rb +13 -5
- data/spec/httparty_spec.rb +84 -2
- data/spec/spec.opts +0 -1
- data/spec/spec_helper.rb +8 -0
- data/spec/support/ssl_test_helper.rb +28 -6
- data/spec/support/ssl_test_server.rb +19 -8
- data/spec/support/stub_response.rb +13 -0
- metadata +53 -61
- data/README.rdoc +0 -54
@@ -0,0 +1,31 @@
|
|
1
|
+
module HTTParty
|
2
|
+
class Response #:nodoc:
|
3
|
+
class Headers
|
4
|
+
include ::Net::HTTPHeader
|
5
|
+
|
6
|
+
def initialize(header = {})
|
7
|
+
@header = header
|
8
|
+
end
|
9
|
+
|
10
|
+
def ==(other)
|
11
|
+
@header == other
|
12
|
+
end
|
13
|
+
|
14
|
+
def inspect
|
15
|
+
@header.inspect
|
16
|
+
end
|
17
|
+
|
18
|
+
def method_missing(name, *args, &block)
|
19
|
+
if @header.respond_to?(name)
|
20
|
+
@header.send(name, *args, &block)
|
21
|
+
else
|
22
|
+
super
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def respond_to?(method)
|
27
|
+
super || @header.respond_to?(method)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/httparty/version.rb
CHANGED
@@ -0,0 +1,206 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
2
|
+
|
3
|
+
describe HTTParty::ConnectionAdapter do
|
4
|
+
|
5
|
+
describe "initialization" do
|
6
|
+
let(:uri) { URI 'http://www.google.com' }
|
7
|
+
it "takes a URI as input" do
|
8
|
+
HTTParty::ConnectionAdapter.new(uri)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "raises an ArgumentError if the uri is nil" do
|
12
|
+
expect { HTTParty::ConnectionAdapter.new(nil) }.to raise_error ArgumentError
|
13
|
+
end
|
14
|
+
|
15
|
+
it "raises an ArgumentError if the uri is a String" do
|
16
|
+
expect { HTTParty::ConnectionAdapter.new('http://www.google.com') }.to raise_error ArgumentError
|
17
|
+
end
|
18
|
+
|
19
|
+
it "sets the uri" do
|
20
|
+
adapter = HTTParty::ConnectionAdapter.new(uri)
|
21
|
+
adapter.uri.should be uri
|
22
|
+
end
|
23
|
+
|
24
|
+
it "also accepts an optional options hash" do
|
25
|
+
HTTParty::ConnectionAdapter.new(uri, {})
|
26
|
+
end
|
27
|
+
|
28
|
+
it "sets the options" do
|
29
|
+
options = {:foo => :bar}
|
30
|
+
adapter = HTTParty::ConnectionAdapter.new(uri, options)
|
31
|
+
adapter.options.should be options
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe ".call" do
|
36
|
+
it "generates an HTTParty::ConnectionAdapter instance with the given uri and options" do
|
37
|
+
HTTParty::ConnectionAdapter.should_receive(:new).with(@uri, @options).and_return(stub(:connection => nil))
|
38
|
+
HTTParty::ConnectionAdapter.call(@uri, @options)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "calls #connection on the connection adapter" do
|
42
|
+
adapter = mock('Adapter')
|
43
|
+
connection = mock('Connection')
|
44
|
+
adapter.should_receive(:connection).and_return(connection)
|
45
|
+
HTTParty::ConnectionAdapter.stub(:new => adapter)
|
46
|
+
HTTParty::ConnectionAdapter.call(@uri, @options).should be connection
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe '#connection' do
|
51
|
+
let(:uri) { URI 'http://www.google.com' }
|
52
|
+
let(:options) { Hash.new }
|
53
|
+
let(:adapter) { HTTParty::ConnectionAdapter.new(uri, options) }
|
54
|
+
|
55
|
+
describe "the resulting connection" do
|
56
|
+
subject { adapter.connection }
|
57
|
+
it { should be_an_instance_of Net::HTTP }
|
58
|
+
|
59
|
+
context "using port 80" do
|
60
|
+
let(:uri) { URI 'http://foobar.com' }
|
61
|
+
it { should_not use_ssl }
|
62
|
+
end
|
63
|
+
|
64
|
+
context "when dealing with ssl" do
|
65
|
+
let(:uri) { URI 'https://foobar.com' }
|
66
|
+
|
67
|
+
context "using port 443 for ssl" do
|
68
|
+
let(:uri) { URI 'https://api.foo.com/v1:443' }
|
69
|
+
it { should use_ssl }
|
70
|
+
end
|
71
|
+
|
72
|
+
context "https scheme with default port" do
|
73
|
+
it { should use_ssl }
|
74
|
+
end
|
75
|
+
|
76
|
+
context "https scheme with non-standard port" do
|
77
|
+
let(:uri) { URI 'https://foobar.com:123456' }
|
78
|
+
it { should use_ssl }
|
79
|
+
end
|
80
|
+
|
81
|
+
context "when ssl version is set" do
|
82
|
+
let(:options) { {:ssl_version => :TLSv1} }
|
83
|
+
|
84
|
+
it "sets ssl version" do
|
85
|
+
subject.ssl_version.should == :TLSv1
|
86
|
+
end
|
87
|
+
end if RUBY_VERSION > '1.9'
|
88
|
+
end
|
89
|
+
|
90
|
+
context "when timeout is not set" do
|
91
|
+
it "doesn't set the timeout" do
|
92
|
+
http = mock("http", :null_object => true)
|
93
|
+
http.should_not_receive(:open_timeout=)
|
94
|
+
http.should_not_receive(:read_timeout=)
|
95
|
+
Net::HTTP.stub(:new => http)
|
96
|
+
|
97
|
+
adapter.connection
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context "when setting timeout" do
|
102
|
+
context "to 5 seconds" do
|
103
|
+
let(:options) { {:timeout => 5} }
|
104
|
+
|
105
|
+
its(:open_timeout) { should == 5 }
|
106
|
+
its(:read_timeout) { should == 5 }
|
107
|
+
end
|
108
|
+
|
109
|
+
context "and timeout is a string" do
|
110
|
+
let(:options) { {:timeout => "five seconds"} }
|
111
|
+
|
112
|
+
it "doesn't set the timeout" do
|
113
|
+
http = mock("http", :null_object => true)
|
114
|
+
http.should_not_receive(:open_timeout=)
|
115
|
+
http.should_not_receive(:read_timeout=)
|
116
|
+
Net::HTTP.stub(:new => http)
|
117
|
+
|
118
|
+
adapter.connection
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
context "when debug_output" do
|
124
|
+
let(:http) { Net::HTTP.new(uri) }
|
125
|
+
before do
|
126
|
+
Net::HTTP.stub(:new => http)
|
127
|
+
end
|
128
|
+
|
129
|
+
context "is set to $stderr" do
|
130
|
+
let(:options) { {:debug_output => $stderr} }
|
131
|
+
it "has debug output set" do
|
132
|
+
http.should_receive(:set_debug_output).with($stderr)
|
133
|
+
adapter.connection
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
context "is not provided" do
|
138
|
+
it "does not set_debug_output" do
|
139
|
+
http.should_not_receive(:set_debug_output)
|
140
|
+
adapter.connection
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
context 'when providing proxy address and port' do
|
146
|
+
let(:options) { {:http_proxyaddr => '1.2.3.4', :http_proxyport => 8080} }
|
147
|
+
|
148
|
+
it { should be_a_proxy }
|
149
|
+
its(:proxy_address) { should == '1.2.3.4' }
|
150
|
+
its(:proxy_port) { should == 8080 }
|
151
|
+
|
152
|
+
context 'as well as proxy user and password' do
|
153
|
+
let(:options) do
|
154
|
+
{:http_proxyaddr => '1.2.3.4', :http_proxyport => 8080,
|
155
|
+
:http_proxyuser => 'user', :http_proxypass => 'pass'}
|
156
|
+
end
|
157
|
+
its(:proxy_user) { should == 'user' }
|
158
|
+
its(:proxy_pass) { should == 'pass' }
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
context "when providing PEM certificates" do
|
163
|
+
let(:pem) { :pem_contents }
|
164
|
+
let(:options) { {:pem => pem, :pem_password => "password"} }
|
165
|
+
|
166
|
+
context "when scheme is https" do
|
167
|
+
let(:uri) { URI 'https://google.com' }
|
168
|
+
let(:cert) { mock("OpenSSL::X509::Certificate") }
|
169
|
+
let(:key) { mock("OpenSSL::PKey::RSA") }
|
170
|
+
|
171
|
+
before do
|
172
|
+
OpenSSL::X509::Certificate.should_receive(:new).with(pem).and_return(cert)
|
173
|
+
OpenSSL::PKey::RSA.should_receive(:new).with(pem, "password").and_return(key)
|
174
|
+
end
|
175
|
+
|
176
|
+
it "uses the provided PEM certificate " do
|
177
|
+
subject.cert.should == cert
|
178
|
+
subject.key.should == key
|
179
|
+
end
|
180
|
+
|
181
|
+
it "will verify the certificate" do
|
182
|
+
subject.verify_mode.should == OpenSSL::SSL::VERIFY_PEER
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
context "when scheme is not https" do
|
187
|
+
let(:uri) { URI 'http://google.com' }
|
188
|
+
let(:http) { Net::HTTP.new(uri) }
|
189
|
+
|
190
|
+
before do
|
191
|
+
Net::HTTP.stub(:new => http)
|
192
|
+
OpenSSL::X509::Certificate.should_not_receive(:new).with(pem)
|
193
|
+
OpenSSL::PKey::RSA.should_not_receive(:new).with(pem, "password")
|
194
|
+
http.should_not_receive(:cert=)
|
195
|
+
http.should_not_receive(:key=)
|
196
|
+
end
|
197
|
+
|
198
|
+
it "has no PEM certificate " do
|
199
|
+
subject.cert.should be_nil
|
200
|
+
subject.key.should be_nil
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
@@ -6,7 +6,6 @@ describe HTTParty::CookieHash do
|
|
6
6
|
end
|
7
7
|
|
8
8
|
describe "#add_cookies" do
|
9
|
-
|
10
9
|
describe "with a hash" do
|
11
10
|
it "should add new key/value pairs to the hash" do
|
12
11
|
@cookie_hash.add_cookies(:foo => "bar")
|
@@ -29,7 +28,7 @@ describe HTTParty::CookieHash do
|
|
29
28
|
@cookie_hash[:second].should == 'two'
|
30
29
|
@cookie_hash[:third].should == nil
|
31
30
|
end
|
32
|
-
|
31
|
+
|
33
32
|
it "should overwrite any existing key" do
|
34
33
|
@cookie_hash[:foo] = 'bar'
|
35
34
|
@cookie_hash.add_cookies("foo=tar")
|
@@ -37,7 +36,7 @@ describe HTTParty::CookieHash do
|
|
37
36
|
@cookie_hash[:foo].should eql("tar")
|
38
37
|
end
|
39
38
|
end
|
40
|
-
|
39
|
+
|
41
40
|
describe 'with other class' do
|
42
41
|
it "should error" do
|
43
42
|
lambda {
|
@@ -61,7 +60,7 @@ describe HTTParty::CookieHash do
|
|
61
60
|
@s.should match(/rofl=copter/)
|
62
61
|
@s.should match(/^\w+=\w+; \w+=\w+$/)
|
63
62
|
end
|
64
|
-
|
63
|
+
|
65
64
|
it "should not include client side only cookies" do
|
66
65
|
@cookie_hash.add_cookies(:path => "/")
|
67
66
|
@s = @cookie_hash.to_cookie_string
|
@@ -14,10 +14,35 @@ describe Net::HTTPHeader::DigestAuthenticator do
|
|
14
14
|
end
|
15
15
|
|
16
16
|
|
17
|
+
context "with an opaque value in the response header" do
|
18
|
+
before do
|
19
|
+
@digest = setup_digest({
|
20
|
+
'www-authenticate' => 'Digest realm="myhost@testrealm.com", opaque="solid"'
|
21
|
+
})
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should set opaque" do
|
25
|
+
authorization_header.should include(%Q(opaque="solid"))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "without an opaque valid in the response header" do
|
30
|
+
before do
|
31
|
+
@digest = setup_digest({
|
32
|
+
'www-authenticate' => 'Digest realm="myhost@testrealm.com"'
|
33
|
+
})
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should not set opaque" do
|
37
|
+
authorization_header.should_not include(%Q(opaque=))
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
17
41
|
context "with specified quality of protection (qop)" do
|
18
42
|
before do
|
19
|
-
@digest = setup_digest({
|
20
|
-
'Digest realm="myhost@testrealm.com", nonce="NONCE", qop="auth"'
|
43
|
+
@digest = setup_digest({
|
44
|
+
'www-authenticate' => 'Digest realm="myhost@testrealm.com", nonce="NONCE", qop="auth"',
|
45
|
+
})
|
21
46
|
end
|
22
47
|
|
23
48
|
it "should set prefix" do
|
@@ -41,13 +66,11 @@ describe Net::HTTPHeader::DigestAuthenticator do
|
|
41
66
|
end
|
42
67
|
|
43
68
|
it "should set nonce-count" do
|
44
|
-
authorization_header.should include(%Q(nc="
|
69
|
+
authorization_header.should include(%Q(nc="00000001"))
|
45
70
|
end
|
46
71
|
|
47
72
|
it "should set response" do
|
48
|
-
request_digest =
|
49
|
-
"md5(md5(Mufasa:myhost@testrealm.com:Circle Of Life)" +
|
50
|
-
":NONCE:0:md5(deadbeef):auth:md5(GET:/dir/index.html))"
|
73
|
+
request_digest = "md5(md5(Mufasa:myhost@testrealm.com:Circle Of Life):NONCE:00000001:md5(deadbeef):auth:md5(GET:/dir/index.html))"
|
51
74
|
authorization_header.should include(%Q(response="#{request_digest}"))
|
52
75
|
end
|
53
76
|
end
|
@@ -55,8 +78,9 @@ describe Net::HTTPHeader::DigestAuthenticator do
|
|
55
78
|
|
56
79
|
context "with unspecified quality of protection (qop)" do
|
57
80
|
before do
|
58
|
-
@digest = setup_digest({
|
59
|
-
'Digest realm="myhost@testrealm.com", nonce="NONCE"'
|
81
|
+
@digest = setup_digest({
|
82
|
+
'www-authenticate' => 'Digest realm="myhost@testrealm.com", nonce="NONCE"',
|
83
|
+
})
|
60
84
|
end
|
61
85
|
|
62
86
|
it "should set prefix" do
|
@@ -84,9 +108,7 @@ describe Net::HTTPHeader::DigestAuthenticator do
|
|
84
108
|
end
|
85
109
|
|
86
110
|
it "should set response" do
|
87
|
-
request_digest =
|
88
|
-
"md5(md5(Mufasa:myhost@testrealm.com:Circle Of Life)" +
|
89
|
-
":NONCE:md5(GET:/dir/index.html))"
|
111
|
+
request_digest = "md5(md5(Mufasa:myhost@testrealm.com:Circle Of Life):NONCE:md5(GET:/dir/index.html))"
|
90
112
|
authorization_header.should include(%Q(response="#{request_digest}"))
|
91
113
|
end
|
92
114
|
end
|
@@ -87,6 +87,16 @@ describe HTTParty::Parser do
|
|
87
87
|
@parser.stub(:body => nil)
|
88
88
|
@parser.parse.should be_nil
|
89
89
|
end
|
90
|
+
|
91
|
+
it "returns nil for a 'null' body" do
|
92
|
+
@parser.stub(:body => "null")
|
93
|
+
@parser.parse.should be_nil
|
94
|
+
end
|
95
|
+
|
96
|
+
it "returns nil for a body with spaces only" do
|
97
|
+
@parser.stub(:body => " ")
|
98
|
+
@parser.parse.should be_nil
|
99
|
+
end
|
90
100
|
end
|
91
101
|
|
92
102
|
describe "#supports_format?" do
|
@@ -135,6 +145,12 @@ describe HTTParty::Parser do
|
|
135
145
|
end
|
136
146
|
|
137
147
|
it "parses json with MultiJson" do
|
148
|
+
MultiJson.should_receive(:load).with('body')
|
149
|
+
subject.send(:json)
|
150
|
+
end
|
151
|
+
|
152
|
+
it "uses MultiJson.decode if MultiJson does not respond to adapter" do
|
153
|
+
MultiJson.should_receive(:respond_to?).with(:adapter).and_return(false)
|
138
154
|
MultiJson.should_receive(:decode).with('body')
|
139
155
|
subject.send(:json)
|
140
156
|
end
|
@@ -45,6 +45,17 @@ describe HTTParty::Request do
|
|
45
45
|
request = HTTParty::Request.new(Net::HTTP::Get, 'http://google.com', :parser => my_parser)
|
46
46
|
request.parser.should == my_parser
|
47
47
|
end
|
48
|
+
|
49
|
+
it "sets connection_adapter to HTTPParty::ConnectionAdapter" do
|
50
|
+
request = HTTParty::Request.new(Net::HTTP::Get, 'http://google.com')
|
51
|
+
request.connection_adapter.should == HTTParty::ConnectionAdapter
|
52
|
+
end
|
53
|
+
|
54
|
+
it "sets connection_adapter to the optional connection_adapter" do
|
55
|
+
my_adapter = lambda {}
|
56
|
+
request = HTTParty::Request.new(Net::HTTP::Get, 'http://google.com', :connection_adapter => my_adapter)
|
57
|
+
request.connection_adapter.should == my_adapter
|
58
|
+
end
|
48
59
|
end
|
49
60
|
|
50
61
|
describe "#format" do
|
@@ -86,7 +97,7 @@ describe HTTParty::Request do
|
|
86
97
|
end
|
87
98
|
|
88
99
|
it "should use digest auth when configured" do
|
89
|
-
FakeWeb.register_uri(:
|
100
|
+
FakeWeb.register_uri(:get, "http://api.foo.com/v1",
|
90
101
|
:www_authenticate => 'Digest realm="Log Viewer", qop="auth", nonce="2CA0EC6B0E126C4800E56BA0C0003D3C", opaque="5ccc069c403ebaf9f0171e9517f40e41", stale=false')
|
91
102
|
|
92
103
|
@request.options[:digest_auth] = {:username => 'foobar', :password => 'secret'}
|
@@ -95,6 +106,17 @@ describe HTTParty::Request do
|
|
95
106
|
raw_request = @request.instance_variable_get(:@raw_request)
|
96
107
|
raw_request.instance_variable_get(:@header)['Authorization'].should_not be_nil
|
97
108
|
end
|
109
|
+
|
110
|
+
it "should use the right http method for digest authentication" do
|
111
|
+
@post_request = HTTParty::Request.new(Net::HTTP::Post, 'http://api.foo.com/v1', :format => :xml)
|
112
|
+
FakeWeb.register_uri(:post, "http://api.foo.com/v1", {})
|
113
|
+
|
114
|
+
http = @post_request.send(:http)
|
115
|
+
@post_request.should_receive(:http).and_return(http)
|
116
|
+
http.should_not_receive(:head).and_return({'www-authenticate' => nil})
|
117
|
+
@post_request.options[:digest_auth] = {:username => 'foobar', :password => 'secret'}
|
118
|
+
@post_request.send(:setup_raw_request)
|
119
|
+
end
|
98
120
|
end
|
99
121
|
|
100
122
|
describe "#uri" do
|
@@ -134,106 +156,12 @@ describe HTTParty::Request do
|
|
134
156
|
end
|
135
157
|
|
136
158
|
describe 'http' do
|
137
|
-
it "should
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
request = HTTParty::Request.new(Net::HTTP::Get, 'http://foobar.com')
|
144
|
-
request.send(:http).use_ssl?.should == false
|
145
|
-
end
|
146
|
-
|
147
|
-
it "uses ssl for https scheme with default port" do
|
148
|
-
request = HTTParty::Request.new(Net::HTTP::Get, 'https://foobar.com')
|
149
|
-
request.send(:http).use_ssl?.should == true
|
150
|
-
end
|
151
|
-
|
152
|
-
it "uses ssl for https scheme regardless of port" do
|
153
|
-
request = HTTParty::Request.new(Net::HTTP::Get, 'https://foobar.com:123456')
|
154
|
-
request.send(:http).use_ssl?.should == true
|
155
|
-
end
|
156
|
-
|
157
|
-
context "PEM certificates" do
|
158
|
-
before do
|
159
|
-
OpenSSL::X509::Certificate.stub(:new)
|
160
|
-
OpenSSL::PKey::RSA.stub(:new)
|
161
|
-
end
|
162
|
-
|
163
|
-
context "when scheme is https" do
|
164
|
-
before do
|
165
|
-
@request.stub!(:uri).and_return(URI.parse("https://google.com"))
|
166
|
-
pem = :pem_contents
|
167
|
-
@cert = mock("OpenSSL::X509::Certificate")
|
168
|
-
@key = mock("OpenSSL::PKey::RSA")
|
169
|
-
OpenSSL::X509::Certificate.should_receive(:new).with(pem).and_return(@cert)
|
170
|
-
OpenSSL::PKey::RSA.should_receive(:new).with(pem, "password").and_return(@key)
|
171
|
-
|
172
|
-
@request.options[:pem] = pem
|
173
|
-
@request.options[:pem_password] = "password"
|
174
|
-
@pem_http = @request.send(:http)
|
175
|
-
end
|
176
|
-
|
177
|
-
it "should use a PEM certificate when provided" do
|
178
|
-
@pem_http.cert.should == @cert
|
179
|
-
@pem_http.key.should == @key
|
180
|
-
end
|
181
|
-
|
182
|
-
it "should verify the certificate when provided" do
|
183
|
-
@pem_http = @request.send(:http)
|
184
|
-
@pem_http.verify_mode.should == OpenSSL::SSL::VERIFY_PEER
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
|
-
context "when scheme is not https" do
|
189
|
-
it "does not assign a PEM" do
|
190
|
-
http = Net::HTTP.new('google.com')
|
191
|
-
http.should_not_receive(:cert=)
|
192
|
-
http.should_not_receive(:key=)
|
193
|
-
Net::HTTP.stub(:new => http)
|
194
|
-
|
195
|
-
request = HTTParty::Request.new(Net::HTTP::Get, 'http://google.com')
|
196
|
-
request.options[:pem] = :pem_contents
|
197
|
-
request.send(:http)
|
198
|
-
end
|
199
|
-
end
|
200
|
-
|
201
|
-
context "debugging" do
|
202
|
-
before do
|
203
|
-
@http = Net::HTTP.new('google.com')
|
204
|
-
Net::HTTP.stub(:new => @http)
|
205
|
-
@request = HTTParty::Request.new(Net::HTTP::Get, 'http://google.com')
|
206
|
-
end
|
207
|
-
|
208
|
-
it "calls #set_debug_output when the option is provided" do
|
209
|
-
@request.options[:debug_output] = $stderr
|
210
|
-
@http.should_receive(:set_debug_output).with($stderr)
|
211
|
-
@request.send(:http)
|
212
|
-
end
|
213
|
-
|
214
|
-
it "does not set_debug_output when the option is not provided" do
|
215
|
-
@http.should_not_receive(:set_debug_output)
|
216
|
-
@request.send(:http)
|
217
|
-
end
|
218
|
-
end
|
219
|
-
end
|
220
|
-
|
221
|
-
context "when setting timeout" do
|
222
|
-
it "does nothing if the timeout option is a string" do
|
223
|
-
http = mock("http", :null_object => true)
|
224
|
-
http.should_not_receive(:open_timeout=)
|
225
|
-
http.should_not_receive(:read_timeout=)
|
226
|
-
Net::HTTP.stub(:new => http)
|
227
|
-
|
228
|
-
request = HTTParty::Request.new(Net::HTTP::Get, 'https://foobar.com', {:timeout => "five seconds"})
|
229
|
-
request.send(:http)
|
230
|
-
end
|
231
|
-
|
232
|
-
it "sets the timeout to 5 seconds" do
|
233
|
-
@request.options[:timeout] = 5
|
234
|
-
@request.send(:http).open_timeout.should == 5
|
235
|
-
@request.send(:http).read_timeout.should == 5
|
236
|
-
end
|
159
|
+
it "should get a connection from the connection_adapter" do
|
160
|
+
http = Net::HTTP.new('google.com')
|
161
|
+
adapter = mock('adapter')
|
162
|
+
request = HTTParty::Request.new(Net::HTTP::Get, 'https://api.foo.com/v1:443', :connection_adapter => adapter)
|
163
|
+
adapter.should_receive(:call).with(request.uri, request.options).and_return(http)
|
164
|
+
request.send(:http).should be http
|
237
165
|
end
|
238
166
|
end
|
239
167
|
|
@@ -381,6 +309,16 @@ describe HTTParty::Request do
|
|
381
309
|
resp.body.should == "<foo><bar>error</bar></foo>"
|
382
310
|
resp['foo']['bar'].should == "error"
|
383
311
|
end
|
312
|
+
|
313
|
+
it "parses response lazily so codes can be checked prior" do
|
314
|
+
stub_response 'not xml', 500
|
315
|
+
@request.options[:format] = :xml
|
316
|
+
lambda {
|
317
|
+
response = @request.perform
|
318
|
+
response.code.should == 500
|
319
|
+
response.body.should == 'not xml'
|
320
|
+
}.should_not raise_error
|
321
|
+
end
|
384
322
|
end
|
385
323
|
end
|
386
324
|
|
@@ -426,6 +364,11 @@ describe HTTParty::Request do
|
|
426
364
|
@request.perform.should == {"hash" => {"foo" => "bar"}}
|
427
365
|
end
|
428
366
|
|
367
|
+
it "should be handled by PATCH transparently" do
|
368
|
+
@request.http_method = Net::HTTP::Patch
|
369
|
+
@request.perform.should == {"hash" => {"foo" => "bar"}}
|
370
|
+
end
|
371
|
+
|
429
372
|
it "should be handled by PUT transparently" do
|
430
373
|
@request.http_method = Net::HTTP::Put
|
431
374
|
@request.perform.should == {"hash" => {"foo" => "bar"}}
|
@@ -487,6 +430,40 @@ describe HTTParty::Request do
|
|
487
430
|
end
|
488
431
|
end
|
489
432
|
|
433
|
+
describe "#handle_deflation" do
|
434
|
+
context "context-encoding" do
|
435
|
+
before do
|
436
|
+
@request.options[:format] = :html
|
437
|
+
@last_response = mock()
|
438
|
+
@last_response.stub!(:body).and_return('')
|
439
|
+
end
|
440
|
+
|
441
|
+
it "should inflate the gzipped body with content-encoding: gzip" do
|
442
|
+
@last_response.stub!(:[]).with("content-encoding").and_return("gzip")
|
443
|
+
@request.stub!(:last_response).and_return(@last_response)
|
444
|
+
Zlib::GzipReader.should_receive(:new).and_return(StringIO.new(''))
|
445
|
+
@request.last_response.should_receive(:delete).with('content-encoding')
|
446
|
+
@request.send(:handle_deflation)
|
447
|
+
end
|
448
|
+
|
449
|
+
it "should inflate the gzipped body with content-encoding: x-gzip" do
|
450
|
+
@last_response.stub!(:[]).with("content-encoding").and_return("x-gzip")
|
451
|
+
@request.stub!(:last_response).and_return(@last_response)
|
452
|
+
Zlib::GzipReader.should_receive(:new).and_return(StringIO.new(''))
|
453
|
+
@request.last_response.should_receive(:delete).with('content-encoding')
|
454
|
+
@request.send(:handle_deflation)
|
455
|
+
end
|
456
|
+
|
457
|
+
it "should inflate the deflated body" do
|
458
|
+
@last_response.stub!(:[]).with("content-encoding").and_return("deflate")
|
459
|
+
@request.stub!(:last_response).and_return(@last_response)
|
460
|
+
Zlib::Inflate.should_receive(:inflate).and_return('')
|
461
|
+
@request.last_response.should_receive(:delete).with('content-encoding')
|
462
|
+
@request.send(:handle_deflation)
|
463
|
+
end
|
464
|
+
end
|
465
|
+
end
|
466
|
+
|
490
467
|
context "with POST http method" do
|
491
468
|
it "should raise argument error if query is not a hash" do
|
492
469
|
lambda {
|