httparty 0.13.0 → 0.14.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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +92 -0
- data/.rubocop_todo.yml +124 -0
- data/.simplecov +1 -0
- data/.travis.yml +4 -2
- data/CONTRIBUTING.md +23 -0
- data/Gemfile +8 -3
- data/Guardfile +3 -3
- data/History +106 -11
- data/README.md +19 -20
- data/Rakefile +5 -7
- data/bin/httparty +18 -14
- data/docs/README.md +100 -0
- data/examples/README.md +67 -0
- data/examples/aaws.rb +5 -5
- data/examples/basic.rb +6 -10
- data/examples/crack.rb +2 -2
- data/examples/custom_parsers.rb +1 -4
- data/examples/delicious.rb +8 -8
- data/examples/google.rb +2 -2
- data/examples/headers_and_user_agents.rb +1 -1
- data/examples/logging.rb +36 -0
- data/examples/nokogiri_html_parser.rb +0 -3
- data/examples/rescue_json.rb +17 -0
- data/examples/rubyurl.rb +3 -3
- data/examples/stackexchange.rb +24 -0
- data/examples/tripit_sign_in.rb +20 -9
- data/examples/twitter.rb +7 -7
- data/examples/whoismyrep.rb +1 -1
- data/features/command_line.feature +90 -2
- data/features/digest_authentication.feature +10 -0
- data/features/steps/env.rb +16 -11
- data/features/steps/httparty_response_steps.rb +18 -14
- data/features/steps/httparty_steps.rb +10 -2
- data/features/steps/mongrel_helper.rb +35 -2
- data/features/steps/remote_service_steps.rb +26 -8
- data/features/supports_read_timeout_option.feature +13 -0
- data/httparty.gemspec +6 -5
- data/lib/httparty/connection_adapter.rb +36 -13
- data/lib/httparty/cookie_hash.rb +3 -4
- data/lib/httparty/exceptions.rb +4 -1
- data/lib/httparty/hash_conversions.rb +17 -15
- data/lib/httparty/logger/{apache_logger.rb → apache_formatter.rb} +3 -3
- data/lib/httparty/logger/curl_formatter.rb +91 -0
- data/lib/httparty/logger/logger.rb +18 -10
- data/lib/httparty/module_inheritable_attributes.rb +1 -1
- data/lib/httparty/net_digest_auth.rb +69 -18
- data/lib/httparty/parser.rb +4 -2
- data/lib/httparty/request.rb +105 -48
- data/lib/httparty/response.rb +31 -6
- data/lib/httparty/version.rb +1 -1
- data/lib/httparty.rb +132 -72
- data/spec/httparty/connection_adapter_spec.rb +285 -88
- data/spec/httparty/cookie_hash_spec.rb +46 -29
- data/spec/httparty/exception_spec.rb +29 -7
- data/spec/httparty/hash_conversions_spec.rb +49 -0
- data/spec/httparty/logger/apache_formatter_spec.rb +41 -0
- data/spec/httparty/logger/curl_formatter_spec.rb +119 -0
- data/spec/httparty/logger/logger_spec.rb +23 -7
- data/spec/httparty/net_digest_auth_spec.rb +118 -30
- data/spec/httparty/parser_spec.rb +43 -35
- data/spec/httparty/request_spec.rb +734 -182
- data/spec/httparty/response_spec.rb +139 -69
- data/spec/httparty/ssl_spec.rb +22 -22
- data/spec/httparty_spec.rb +307 -199
- data/spec/spec_helper.rb +34 -12
- data/spec/support/ssl_test_helper.rb +6 -6
- data/spec/support/ssl_test_server.rb +21 -21
- data/spec/support/stub_response.rb +20 -14
- data/website/index.html +3 -3
- metadata +30 -33
- data/lib/httparty/core_extensions.rb +0 -32
- data/lib/httparty/logger/curl_logger.rb +0 -48
- data/spec/httparty/logger/apache_logger_spec.rb +0 -26
- data/spec/httparty/logger/curl_logger_spec.rb +0 -18
- data/spec/spec.opts +0 -2
@@ -4,10 +4,22 @@ require 'net/http'
|
|
4
4
|
module Net
|
5
5
|
module HTTPHeader
|
6
6
|
def digest_auth(username, password, response)
|
7
|
-
|
8
|
-
|
7
|
+
authenticator = DigestAuthenticator.new(
|
8
|
+
username,
|
9
|
+
password,
|
10
|
+
@method,
|
11
|
+
@path,
|
12
|
+
response
|
13
|
+
)
|
14
|
+
|
15
|
+
@header['Authorization'] = authenticator.authorization_header
|
16
|
+
@header['cookie'] = append_cookies(authenticator) if response['Set-Cookie']
|
9
17
|
end
|
10
18
|
|
19
|
+
def append_cookies(authenticator)
|
20
|
+
cookies = @header['cookie'] ? @header['cookie'] : []
|
21
|
+
cookies.concat(authenticator.cookie_header)
|
22
|
+
end
|
11
23
|
|
12
24
|
class DigestAuthenticator
|
13
25
|
def initialize(username, password, method, path, response_header)
|
@@ -16,50 +28,76 @@ module Net
|
|
16
28
|
@method = method
|
17
29
|
@path = path
|
18
30
|
@response = parse(response_header)
|
31
|
+
@cookies = parse_cookies(response_header)
|
19
32
|
end
|
20
33
|
|
21
34
|
def authorization_header
|
22
35
|
@cnonce = md5(random)
|
23
36
|
header = [
|
24
|
-
%
|
25
|
-
%
|
26
|
-
%
|
27
|
-
%
|
28
|
-
%
|
37
|
+
%(Digest username="#{@username}"),
|
38
|
+
%(realm="#{@response['realm']}"),
|
39
|
+
%(nonce="#{@response['nonce']}"),
|
40
|
+
%(uri="#{@path}"),
|
41
|
+
%(response="#{request_digest}")
|
29
42
|
]
|
30
43
|
|
44
|
+
header << %(algorithm="#{@response['algorithm']}") if algorithm_present?
|
45
|
+
|
31
46
|
if qop_present?
|
32
47
|
fields = [
|
33
|
-
%
|
34
|
-
%
|
35
|
-
|
48
|
+
%(cnonce="#{@cnonce}"),
|
49
|
+
%(qop="#{@response['qop']}"),
|
50
|
+
"nc=00000001"
|
36
51
|
]
|
37
52
|
fields.each { |field| header << field }
|
38
53
|
end
|
39
54
|
|
40
|
-
header << %
|
55
|
+
header << %(opaque="#{@response['opaque']}") if opaque_present?
|
41
56
|
header
|
42
57
|
end
|
43
58
|
|
44
|
-
|
59
|
+
def cookie_header
|
60
|
+
@cookies
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
45
64
|
|
46
65
|
def parse(response_header)
|
47
|
-
response_header['www-authenticate']
|
66
|
+
header = response_header['www-authenticate']
|
67
|
+
.gsub(/qop=(auth(?:-int)?)/, 'qop="\\1"')
|
68
|
+
|
69
|
+
header =~ /Digest (.*)/
|
48
70
|
params = {}
|
49
|
-
|
71
|
+
if $1
|
72
|
+
non_quoted = $1.gsub(/(\w+)="(.*?)"/) { params[$1] = $2 }
|
73
|
+
non_quoted.gsub(/(\w+)=([^,]*)/) { params[$1] = $2 }
|
74
|
+
end
|
50
75
|
params
|
51
76
|
end
|
52
77
|
|
78
|
+
def parse_cookies(response_header)
|
79
|
+
return [] unless response_header['Set-Cookie']
|
80
|
+
|
81
|
+
cookies = response_header['Set-Cookie'].split('; ')
|
82
|
+
|
83
|
+
cookies.reduce([]) do |ret, cookie|
|
84
|
+
ret << cookie
|
85
|
+
ret
|
86
|
+
end
|
87
|
+
|
88
|
+
cookies
|
89
|
+
end
|
90
|
+
|
53
91
|
def opaque_present?
|
54
|
-
@response.
|
92
|
+
@response.key?('opaque') && !@response['opaque'].empty?
|
55
93
|
end
|
56
94
|
|
57
95
|
def qop_present?
|
58
|
-
@response.
|
96
|
+
@response.key?('qop') && !@response['qop'].empty?
|
59
97
|
end
|
60
98
|
|
61
99
|
def random
|
62
|
-
"%x"
|
100
|
+
format "%x", (Time.now.to_i + rand(65535))
|
63
101
|
end
|
64
102
|
|
65
103
|
def request_digest
|
@@ -72,8 +110,21 @@ module Net
|
|
72
110
|
Digest::MD5.hexdigest(str)
|
73
111
|
end
|
74
112
|
|
113
|
+
def algorithm_present?
|
114
|
+
@response.key?('algorithm') && !@response['algorithm'].empty?
|
115
|
+
end
|
116
|
+
|
117
|
+
def use_md5_sess?
|
118
|
+
algorithm_present? && @response['algorithm'] == 'MD5-sess'
|
119
|
+
end
|
120
|
+
|
75
121
|
def a1
|
76
|
-
[@username, @response['realm'], @password].join(
|
122
|
+
a1_user_realm_pwd = [@username, @response['realm'], @password].join(':')
|
123
|
+
if use_md5_sess?
|
124
|
+
[ md5(a1_user_realm_pwd), @response['nonce'], @cnonce ].join(':')
|
125
|
+
else
|
126
|
+
a1_user_realm_pwd
|
127
|
+
end
|
77
128
|
end
|
78
129
|
|
79
130
|
def a2
|
data/lib/httparty/parser.rb
CHANGED
@@ -98,7 +98,9 @@ module HTTParty
|
|
98
98
|
# @return [Object] the parsed body
|
99
99
|
# @return [nil] when the response body is nil, an empty string, spaces only or "null"
|
100
100
|
def parse
|
101
|
-
return nil if body.nil?
|
101
|
+
return nil if body.nil?
|
102
|
+
return nil if body == "null"
|
103
|
+
return nil if body.valid_encoding? && body.strip.empty?
|
102
104
|
if supports_format?
|
103
105
|
parse_supported_format
|
104
106
|
else
|
@@ -113,7 +115,7 @@ module HTTParty
|
|
113
115
|
end
|
114
116
|
|
115
117
|
def json
|
116
|
-
JSON.
|
118
|
+
JSON.parse(body, :quirks_mode => true, :allow_nan => true)
|
117
119
|
end
|
118
120
|
|
119
121
|
def csv
|
data/lib/httparty/request.rb
CHANGED
@@ -9,17 +9,18 @@ module HTTParty
|
|
9
9
|
Net::HTTP::Head,
|
10
10
|
Net::HTTP::Options,
|
11
11
|
Net::HTTP::Move,
|
12
|
-
Net::HTTP::Copy
|
12
|
+
Net::HTTP::Copy,
|
13
|
+
Net::HTTP::Mkcol,
|
13
14
|
]
|
14
15
|
|
15
|
-
SupportedURISchemes = [
|
16
|
+
SupportedURISchemes = ['http', 'https', 'webcal', nil]
|
16
17
|
|
17
|
-
NON_RAILS_QUERY_STRING_NORMALIZER =
|
18
|
+
NON_RAILS_QUERY_STRING_NORMALIZER = proc do |query|
|
18
19
|
Array(query).sort_by { |a| a[0].to_s }.map do |key, value|
|
19
20
|
if value.nil?
|
20
21
|
key.to_s
|
21
|
-
elsif value.
|
22
|
-
value.map {|v| "#{key}=#{
|
22
|
+
elsif value.respond_to?(:to_ary)
|
23
|
+
value.to_ary.map {|v| "#{key}=#{ERB::Util.url_encode(v.to_s)}"}
|
23
24
|
else
|
24
25
|
HashConversions.to_params(key => value)
|
25
26
|
end
|
@@ -29,21 +30,32 @@ module HTTParty
|
|
29
30
|
attr_accessor :http_method, :options, :last_response, :redirect, :last_uri
|
30
31
|
attr_reader :path
|
31
32
|
|
32
|
-
def initialize(http_method, path, o={})
|
33
|
+
def initialize(http_method, path, o = {})
|
33
34
|
self.http_method = http_method
|
34
|
-
self.path = path
|
35
35
|
self.options = {
|
36
|
-
:
|
37
|
-
:
|
38
|
-
:
|
39
|
-
:
|
40
|
-
:
|
41
|
-
:
|
36
|
+
limit: o.delete(:no_follow) ? 1 : 5,
|
37
|
+
assume_utf16_is_big_endian: true,
|
38
|
+
default_params: {},
|
39
|
+
follow_redirects: true,
|
40
|
+
parser: Parser,
|
41
|
+
uri_adapter: URI,
|
42
|
+
connection_adapter: ConnectionAdapter
|
42
43
|
}.merge(o)
|
44
|
+
self.path = path
|
45
|
+
set_basic_auth_from_uri
|
43
46
|
end
|
44
47
|
|
45
48
|
def path=(uri)
|
46
|
-
|
49
|
+
uri_adapter = options[:uri_adapter]
|
50
|
+
|
51
|
+
@path = if uri.is_a?(uri_adapter)
|
52
|
+
uri
|
53
|
+
elsif String.try_convert(uri)
|
54
|
+
uri_adapter.parse uri
|
55
|
+
else
|
56
|
+
raise ArgumentError,
|
57
|
+
"bad argument (expected #{uri_adapter} object or URI string)"
|
58
|
+
end
|
47
59
|
end
|
48
60
|
|
49
61
|
def request_uri(uri)
|
@@ -55,14 +67,21 @@ module HTTParty
|
|
55
67
|
end
|
56
68
|
|
57
69
|
def uri
|
58
|
-
|
70
|
+
if redirect && path.relative? && path.path[0] != "/"
|
71
|
+
last_uri_host = @last_uri.path.gsub(/[^\/]+$/, "")
|
72
|
+
|
73
|
+
path.path = "/#{path.path}" if last_uri_host[-1] != "/"
|
74
|
+
path.path = last_uri_host + path.path
|
75
|
+
end
|
76
|
+
|
77
|
+
new_uri = path.relative? ? options[:uri_adapter].parse("#{base_uri}#{path}") : path.clone
|
59
78
|
|
60
79
|
# avoid double query string on redirects [#12]
|
61
80
|
unless redirect
|
62
81
|
new_uri.query = query_string(new_uri)
|
63
82
|
end
|
64
83
|
|
65
|
-
unless SupportedURISchemes.include? new_uri.
|
84
|
+
unless SupportedURISchemes.include? new_uri.scheme
|
66
85
|
raise UnsupportedURIScheme, "'#{new_uri}' Must be HTTP, HTTPS or Generic"
|
67
86
|
end
|
68
87
|
|
@@ -70,7 +89,13 @@ module HTTParty
|
|
70
89
|
end
|
71
90
|
|
72
91
|
def base_uri
|
73
|
-
redirect
|
92
|
+
if redirect
|
93
|
+
base_uri = "#{@last_uri.scheme}://#{@last_uri.host}"
|
94
|
+
base_uri += ":#{@last_uri.port}" if @last_uri.port != 80
|
95
|
+
base_uri
|
96
|
+
else
|
97
|
+
options[:base_uri] && HTTParty.normalize_base_uri(options[:base_uri])
|
98
|
+
end
|
74
99
|
end
|
75
100
|
|
76
101
|
def format
|
@@ -95,7 +120,7 @@ module HTTParty
|
|
95
120
|
chunks = []
|
96
121
|
|
97
122
|
http_response.read_body do |fragment|
|
98
|
-
chunks << fragment
|
123
|
+
chunks << fragment unless options[:stream_body]
|
99
124
|
block.call(fragment)
|
100
125
|
end
|
101
126
|
|
@@ -104,6 +129,7 @@ module HTTParty
|
|
104
129
|
end
|
105
130
|
|
106
131
|
handle_deflation unless http_method == Net::HTTP::Head
|
132
|
+
handle_host_redirection if response_redirects?
|
107
133
|
handle_response(chunked_body, &block)
|
108
134
|
end
|
109
135
|
|
@@ -118,11 +144,11 @@ module HTTParty
|
|
118
144
|
end
|
119
145
|
|
120
146
|
def body
|
121
|
-
options[:body].
|
147
|
+
options[:body].respond_to?(:to_hash) ? normalize_query(options[:body]) : options[:body]
|
122
148
|
end
|
123
149
|
|
124
150
|
def credentials
|
125
|
-
options[:basic_auth] || options[:digest_auth]
|
151
|
+
(options[:basic_auth] || options[:digest_auth]).to_hash
|
126
152
|
end
|
127
153
|
|
128
154
|
def username
|
@@ -148,17 +174,18 @@ module HTTParty
|
|
148
174
|
def setup_raw_request
|
149
175
|
@raw_request = http_method.new(request_uri(uri))
|
150
176
|
@raw_request.body = body if body
|
151
|
-
@raw_request.
|
152
|
-
@raw_request.
|
177
|
+
@raw_request.body_stream = options[:body_stream] if options[:body_stream]
|
178
|
+
@raw_request.initialize_http_header(options[:headers].to_hash) if options[:headers].respond_to?(:to_hash)
|
179
|
+
@raw_request.basic_auth(username, password) if options[:basic_auth] && send_authorization_header?
|
153
180
|
setup_digest_auth if options[:digest_auth]
|
154
181
|
end
|
155
182
|
|
156
183
|
def setup_digest_auth
|
157
184
|
auth_request = http_method.new(uri.request_uri)
|
158
|
-
auth_request.initialize_http_header(options[:headers])
|
185
|
+
auth_request.initialize_http_header(options[:headers].to_hash) if options[:headers].respond_to?(:to_hash)
|
159
186
|
res = http.request(auth_request)
|
160
187
|
|
161
|
-
if res['www-authenticate']
|
188
|
+
if !res['www-authenticate'].nil? && res['www-authenticate'].length > 0
|
162
189
|
@raw_request.digest_auth(username, password, res)
|
163
190
|
end
|
164
191
|
end
|
@@ -167,8 +194,8 @@ module HTTParty
|
|
167
194
|
query_string_parts = []
|
168
195
|
query_string_parts << uri.query unless uri.query.nil?
|
169
196
|
|
170
|
-
if options[:query].
|
171
|
-
query_string_parts << normalize_query(options[:default_params].merge(options[:query]))
|
197
|
+
if options[:query].respond_to?(:to_hash)
|
198
|
+
query_string_parts << normalize_query(options[:default_params].merge(options[:query].to_hash))
|
172
199
|
else
|
173
200
|
query_string_parts << normalize_query(options[:default_params]) unless options[:default_params].empty?
|
174
201
|
query_string_parts << options[:query] unless options[:query].nil?
|
@@ -196,12 +223,10 @@ module HTTParty
|
|
196
223
|
end
|
197
224
|
|
198
225
|
def encode_with_ruby_encoding(body, charset)
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
body
|
204
|
-
end
|
226
|
+
encoding = Encoding.find(charset)
|
227
|
+
body.force_encoding(encoding)
|
228
|
+
rescue
|
229
|
+
body
|
205
230
|
end
|
206
231
|
|
207
232
|
def assume_utf16_is_big_endian
|
@@ -222,7 +247,6 @@ module HTTParty
|
|
222
247
|
else
|
223
248
|
body.force_encoding("UTF-16LE")
|
224
249
|
end
|
225
|
-
|
226
250
|
end
|
227
251
|
|
228
252
|
def _encode_body(body)
|
@@ -256,18 +280,29 @@ module HTTParty
|
|
256
280
|
end
|
257
281
|
self.path = last_response['location']
|
258
282
|
self.redirect = true
|
259
|
-
|
283
|
+
if last_response.class == Net::HTTPSeeOther
|
284
|
+
unless options[:maintain_method_across_redirects] && options[:resend_on_redirect]
|
285
|
+
self.http_method = Net::HTTP::Get
|
286
|
+
end
|
287
|
+
elsif last_response.code != '307' && last_response.code != '308'
|
288
|
+
unless options[:maintain_method_across_redirects]
|
289
|
+
self.http_method = Net::HTTP::Get
|
290
|
+
end
|
291
|
+
end
|
260
292
|
capture_cookies(last_response)
|
261
293
|
perform(&block)
|
262
294
|
else
|
263
|
-
body
|
295
|
+
body ||= last_response.body
|
264
296
|
body = encode_body(body)
|
265
|
-
Response.new(self, last_response, lambda { parse_response(body) }, :
|
297
|
+
Response.new(self, last_response, lambda { parse_response(body) }, body: body)
|
266
298
|
end
|
267
299
|
end
|
268
300
|
|
269
301
|
# Inspired by Ruby 1.9
|
270
302
|
def handle_deflation
|
303
|
+
return if response_redirects?
|
304
|
+
return if last_response.body.nil?
|
305
|
+
|
271
306
|
case last_response["content-encoding"]
|
272
307
|
when "gzip", "x-gzip"
|
273
308
|
body_io = StringIO.new(last_response.body)
|
@@ -279,14 +314,29 @@ module HTTParty
|
|
279
314
|
end
|
280
315
|
end
|
281
316
|
|
317
|
+
def handle_host_redirection
|
318
|
+
check_duplicate_location_header
|
319
|
+
redirect_path = options[:uri_adapter].parse last_response['location']
|
320
|
+
return if redirect_path.relative? || path.host == redirect_path.host
|
321
|
+
@changed_hosts = true
|
322
|
+
end
|
323
|
+
|
324
|
+
def check_duplicate_location_header
|
325
|
+
location = last_response.get_fields('location')
|
326
|
+
if location.is_a?(Array) && location.count > 1
|
327
|
+
raise DuplicateLocationHeader.new(last_response)
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
def send_authorization_header?
|
332
|
+
!defined?(@changed_hosts)
|
333
|
+
end
|
334
|
+
|
282
335
|
def response_redirects?
|
283
336
|
case last_response
|
284
|
-
when Net::
|
285
|
-
|
286
|
-
|
287
|
-
Net::HTTPSeeOther, # 303
|
288
|
-
Net::HTTPUseProxy, # 305
|
289
|
-
Net::HTTPTemporaryRedirect
|
337
|
+
when Net::HTTPNotModified # 304
|
338
|
+
false
|
339
|
+
when Net::HTTPRedirection
|
290
340
|
options[:follow_redirects] && last_response.key?('location')
|
291
341
|
end
|
292
342
|
end
|
@@ -297,8 +347,8 @@ module HTTParty
|
|
297
347
|
|
298
348
|
def capture_cookies(response)
|
299
349
|
return unless response['Set-Cookie']
|
300
|
-
cookies_hash = HTTParty::CookieHash.new
|
301
|
-
cookies_hash.add_cookies(options[:headers]['Cookie']) if options[:headers] && options[:headers]['Cookie']
|
350
|
+
cookies_hash = HTTParty::CookieHash.new
|
351
|
+
cookies_hash.add_cookies(options[:headers].to_hash['Cookie']) if options[:headers] && options[:headers].to_hash['Cookie']
|
302
352
|
response.get_fields('Set-Cookie').each { |cookie| cookies_hash.add_cookies(cookie) }
|
303
353
|
options[:headers] ||= {}
|
304
354
|
options[:headers]['Cookie'] = cookies_hash.to_cookie_string
|
@@ -316,15 +366,22 @@ module HTTParty
|
|
316
366
|
def validate
|
317
367
|
raise HTTParty::RedirectionTooDeep.new(last_response), 'HTTP redirects too deep' if options[:limit].to_i <= 0
|
318
368
|
raise ArgumentError, 'only get, post, patch, put, delete, head, and options methods are supported' unless SupportedHTTPMethods.include?(http_method)
|
319
|
-
raise ArgumentError, ':headers must be a hash' if options[:headers] && !options[:headers].
|
369
|
+
raise ArgumentError, ':headers must be a hash' if options[:headers] && !options[:headers].respond_to?(:to_hash)
|
320
370
|
raise ArgumentError, 'only one authentication method, :basic_auth or :digest_auth may be used at a time' if options[:basic_auth] && options[:digest_auth]
|
321
|
-
raise ArgumentError, ':basic_auth must be a hash' if options[:basic_auth] && !options[:basic_auth].
|
322
|
-
raise ArgumentError, ':digest_auth must be a hash' if options[:digest_auth] && !options[:digest_auth].
|
323
|
-
raise ArgumentError, ':query must be hash if using HTTP Post' if post? && !options[:query].nil? && !options[:query].
|
371
|
+
raise ArgumentError, ':basic_auth must be a hash' if options[:basic_auth] && !options[:basic_auth].respond_to?(:to_hash)
|
372
|
+
raise ArgumentError, ':digest_auth must be a hash' if options[:digest_auth] && !options[:digest_auth].respond_to?(:to_hash)
|
373
|
+
raise ArgumentError, ':query must be hash if using HTTP Post' if post? && !options[:query].nil? && !options[:query].respond_to?(:to_hash)
|
324
374
|
end
|
325
375
|
|
326
376
|
def post?
|
327
377
|
Net::HTTP::Post == http_method
|
328
378
|
end
|
379
|
+
|
380
|
+
def set_basic_auth_from_uri
|
381
|
+
if path.userinfo
|
382
|
+
username, password = path.userinfo.split(':')
|
383
|
+
options[:basic_auth] = {username: username, password: password}
|
384
|
+
end
|
385
|
+
end
|
329
386
|
end
|
330
387
|
end
|
data/lib/httparty/response.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
module HTTParty
|
2
|
-
class Response <
|
2
|
+
class Response < BasicObject
|
3
3
|
def self.underscore(string)
|
4
|
-
string.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').gsub(/([a-z])([A-Z])/,'\1_\2').downcase
|
4
|
+
string.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').gsub(/([a-z])([A-Z])/, '\1_\2').downcase
|
5
5
|
end
|
6
6
|
|
7
7
|
attr_reader :request, :response, :body, :headers
|
8
8
|
|
9
|
-
def initialize(request, response, parsed_block, options={})
|
9
|
+
def initialize(request, response, parsed_block, options = {})
|
10
10
|
@request = request
|
11
11
|
@response = response
|
12
12
|
@body = options[:body] || response.body
|
@@ -17,6 +17,8 @@ module HTTParty
|
|
17
17
|
logger = ::HTTParty::Logger.build(request.options[:logger], request.options[:log_level], request.options[:log_format])
|
18
18
|
logger.format(request, self)
|
19
19
|
end
|
20
|
+
|
21
|
+
throw_exception
|
20
22
|
end
|
21
23
|
|
22
24
|
def parsed_response
|
@@ -27,20 +29,37 @@ module HTTParty
|
|
27
29
|
Response
|
28
30
|
end
|
29
31
|
|
32
|
+
def is_a?(klass)
|
33
|
+
self.class == klass || self.class < klass
|
34
|
+
end
|
35
|
+
|
36
|
+
alias_method :kind_of?, :is_a?
|
37
|
+
|
30
38
|
def code
|
31
39
|
response.code.to_i
|
32
40
|
end
|
33
41
|
|
42
|
+
def tap
|
43
|
+
yield self
|
44
|
+
self
|
45
|
+
end
|
46
|
+
|
34
47
|
def inspect
|
35
|
-
inspect_id = "%x"
|
48
|
+
inspect_id = ::Kernel::format "%x", (object_id * 2)
|
36
49
|
%(#<#{self.class}:0x#{inspect_id} parsed_response=#{parsed_response.inspect}, @response=#{response.inspect}, @headers=#{headers.inspect}>)
|
37
50
|
end
|
38
51
|
|
52
|
+
RESPOND_TO_METHODS = [:request, :response, :parsed_response, :body, :headers]
|
53
|
+
|
39
54
|
CODES_TO_OBJ = ::Net::HTTPResponse::CODE_CLASS_TO_OBJ.merge ::Net::HTTPResponse::CODE_TO_OBJ
|
40
55
|
|
41
56
|
CODES_TO_OBJ.each do |response_code, klass|
|
42
57
|
name = klass.name.sub("Net::HTTP", '')
|
43
|
-
|
58
|
+
name = "#{underscore(name)}?".to_sym
|
59
|
+
|
60
|
+
RESPOND_TO_METHODS << name
|
61
|
+
|
62
|
+
define_method(name) do
|
44
63
|
klass === response
|
45
64
|
end
|
46
65
|
end
|
@@ -51,7 +70,7 @@ module HTTParty
|
|
51
70
|
end
|
52
71
|
|
53
72
|
def respond_to?(name, include_all = false)
|
54
|
-
return true if
|
73
|
+
return true if RESPOND_TO_METHODS.include?(name)
|
55
74
|
parsed_response.respond_to?(name, include_all) || response.respond_to?(name, include_all)
|
56
75
|
end
|
57
76
|
|
@@ -66,6 +85,12 @@ module HTTParty
|
|
66
85
|
super
|
67
86
|
end
|
68
87
|
end
|
88
|
+
|
89
|
+
def throw_exception
|
90
|
+
if @request.options[:raise_on] && @request.options[:raise_on].include?(code)
|
91
|
+
::Kernel.raise ::HTTParty::ResponseError.new(@response), "Code #{code} - #{body}"
|
92
|
+
end
|
93
|
+
end
|
69
94
|
end
|
70
95
|
end
|
71
96
|
|
data/lib/httparty/version.rb
CHANGED