httparty 0.17.0 → 0.18.1

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.

Files changed (66) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop_todo.yml +1 -1
  3. data/Changelog.md +28 -0
  4. data/Gemfile +1 -0
  5. data/README.md +2 -0
  6. data/docs/README.md +1 -1
  7. data/httparty.gemspec +0 -1
  8. data/lib/httparty.rb +7 -23
  9. data/lib/httparty/connection_adapter.rb +10 -0
  10. data/lib/httparty/cookie_hash.rb +7 -7
  11. data/lib/httparty/hash_conversions.rb +1 -1
  12. data/lib/httparty/headers_processor.rb +30 -0
  13. data/lib/httparty/request.rb +9 -16
  14. data/lib/httparty/response.rb +14 -0
  15. data/lib/httparty/version.rb +1 -1
  16. metadata +5 -105
  17. data/features/basic_authentication.feature +0 -20
  18. data/features/command_line.feature +0 -95
  19. data/features/deals_with_http_error_codes.feature +0 -26
  20. data/features/digest_authentication.feature +0 -30
  21. data/features/handles_compressed_responses.feature +0 -27
  22. data/features/handles_multiple_formats.feature +0 -57
  23. data/features/steps/env.rb +0 -27
  24. data/features/steps/httparty_response_steps.rb +0 -56
  25. data/features/steps/httparty_steps.rb +0 -43
  26. data/features/steps/mongrel_helper.rb +0 -127
  27. data/features/steps/remote_service_steps.rb +0 -92
  28. data/features/supports_read_timeout_option.feature +0 -13
  29. data/features/supports_redirection.feature +0 -22
  30. data/features/supports_timeout_option.feature +0 -13
  31. data/spec/fixtures/delicious.xml +0 -23
  32. data/spec/fixtures/empty.xml +0 -0
  33. data/spec/fixtures/example.html +0 -10
  34. data/spec/fixtures/ssl/generate.sh +0 -29
  35. data/spec/fixtures/ssl/generated/bogushost.crt +0 -29
  36. data/spec/fixtures/ssl/generated/ca.crt +0 -31
  37. data/spec/fixtures/ssl/generated/ca.key +0 -52
  38. data/spec/fixtures/ssl/generated/selfsigned.crt +0 -29
  39. data/spec/fixtures/ssl/generated/server.crt +0 -30
  40. data/spec/fixtures/ssl/generated/server.key +0 -52
  41. data/spec/fixtures/ssl/openssl-exts.cnf +0 -9
  42. data/spec/fixtures/tiny.gif +0 -0
  43. data/spec/fixtures/twitter.csv +0 -2
  44. data/spec/fixtures/twitter.json +0 -1
  45. data/spec/fixtures/twitter.xml +0 -403
  46. data/spec/fixtures/undefined_method_add_node_for_nil.xml +0 -2
  47. data/spec/httparty/connection_adapter_spec.rb +0 -628
  48. data/spec/httparty/cookie_hash_spec.rb +0 -100
  49. data/spec/httparty/exception_spec.rb +0 -45
  50. data/spec/httparty/hash_conversions_spec.rb +0 -58
  51. data/spec/httparty/logger/apache_formatter_spec.rb +0 -40
  52. data/spec/httparty/logger/curl_formatter_spec.rb +0 -119
  53. data/spec/httparty/logger/logger_spec.rb +0 -43
  54. data/spec/httparty/logger/logstash_formatter_spec.rb +0 -44
  55. data/spec/httparty/net_digest_auth_spec.rb +0 -270
  56. data/spec/httparty/parser_spec.rb +0 -190
  57. data/spec/httparty/request/body_spec.rb +0 -165
  58. data/spec/httparty/request_spec.rb +0 -1389
  59. data/spec/httparty/response_fragment_spec.rb +0 -17
  60. data/spec/httparty/response_spec.rb +0 -374
  61. data/spec/httparty/ssl_spec.rb +0 -82
  62. data/spec/httparty_spec.rb +0 -943
  63. data/spec/spec_helper.rb +0 -57
  64. data/spec/support/ssl_test_helper.rb +0 -47
  65. data/spec/support/ssl_test_server.rb +0 -80
  66. data/spec/support/stub_response.rb +0 -50
@@ -1,270 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe Net::HTTPHeader::DigestAuthenticator do
4
- def setup_digest(response)
5
- digest = Net::HTTPHeader::DigestAuthenticator.new("Mufasa",
6
- "Circle Of Life", "GET", "/dir/index.html", response)
7
- allow(digest).to receive(:random).and_return("deadbeef")
8
- allow(Digest::MD5).to receive(:hexdigest) { |str| "md5(#{str})" }
9
- digest
10
- end
11
-
12
- def authorization_header
13
- @digest.authorization_header.join(", ")
14
- end
15
-
16
- def cookie_header
17
- @digest.cookie_header
18
- end
19
-
20
- context 'Net::HTTPHeader#digest_auth' do
21
- let(:headers) {
22
- (Class.new do
23
- include Net::HTTPHeader
24
- def initialize
25
- @header = {}
26
- @path = '/'
27
- @method = 'GET'
28
- end
29
- end).new
30
- }
31
-
32
- let(:response){
33
- (Class.new do
34
- include Net::HTTPHeader
35
- def initialize
36
- @header = {}
37
- self['WWW-Authenticate'] =
38
- 'Digest realm="testrealm@host.com", qop="auth,auth-int", nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", opaque="5ccc069c403ebaf9f0171e9517f40e41"'
39
- end
40
- end).new
41
- }
42
-
43
- it 'should set the authorization header' do
44
- expect(headers['authorization']).to be_nil
45
- headers.digest_auth('user','pass', response)
46
- expect(headers['authorization']).to_not be_empty
47
- end
48
- end
49
-
50
- context "with a cookie value in the response header" do
51
- before do
52
- @digest = setup_digest({
53
- 'www-authenticate' => 'Digest realm="myhost@testrealm.com"',
54
- 'Set-Cookie' => 'custom-cookie=1234567'
55
- })
56
- end
57
-
58
- it "should set cookie header" do
59
- expect(cookie_header).to include('custom-cookie=1234567')
60
- end
61
- end
62
-
63
- context "without a cookie value in the response header" do
64
- before do
65
- @digest = setup_digest({
66
- 'www-authenticate' => 'Digest realm="myhost@testrealm.com"'
67
- })
68
- end
69
-
70
- it "should set empty cookie header array" do
71
- expect(cookie_header).to eql []
72
- end
73
- end
74
-
75
- context "with an opaque value in the response header" do
76
- before do
77
- @digest = setup_digest({
78
- 'www-authenticate' => 'Digest realm="myhost@testrealm.com", opaque="solid"'
79
- })
80
- end
81
-
82
- it "should set opaque" do
83
- expect(authorization_header).to include('opaque="solid"')
84
- end
85
- end
86
-
87
- context "without an opaque valid in the response header" do
88
- before do
89
- @digest = setup_digest({
90
- 'www-authenticate' => 'Digest realm="myhost@testrealm.com"'
91
- })
92
- end
93
-
94
- it "should not set opaque" do
95
- expect(authorization_header).not_to include("opaque=")
96
- end
97
- end
98
-
99
- context "with specified quality of protection (qop)" do
100
- before do
101
- @digest = setup_digest({
102
- 'www-authenticate' => 'Digest realm="myhost@testrealm.com", nonce="NONCE", qop="auth"'
103
- })
104
- end
105
-
106
- it "should set prefix" do
107
- expect(authorization_header).to match(/^Digest /)
108
- end
109
-
110
- it "should set username" do
111
- expect(authorization_header).to include('username="Mufasa"')
112
- end
113
-
114
- it "should set digest-uri" do
115
- expect(authorization_header).to include('uri="/dir/index.html"')
116
- end
117
-
118
- it "should set qop" do
119
- expect(authorization_header).to include('qop="auth"')
120
- end
121
-
122
- it "should set cnonce" do
123
- expect(authorization_header).to include('cnonce="md5(deadbeef)"')
124
- end
125
-
126
- it "should set nonce-count" do
127
- expect(authorization_header).to include("nc=00000001")
128
- end
129
-
130
- it "should set response" do
131
- request_digest = "md5(md5(Mufasa:myhost@testrealm.com:Circle Of Life):NONCE:00000001:md5(deadbeef):auth:md5(GET:/dir/index.html))"
132
- expect(authorization_header).to include(%(response="#{request_digest}"))
133
- end
134
- end
135
-
136
- context "when quality of protection (qop) is unquoted" do
137
- before do
138
- @digest = setup_digest({
139
- 'www-authenticate' => 'Digest realm="myhost@testrealm.com", nonce="NONCE", qop=auth'
140
- })
141
- end
142
-
143
- it "should still set qop" do
144
- expect(authorization_header).to include('qop="auth"')
145
- end
146
- end
147
-
148
- context "with unspecified quality of protection (qop)" do
149
- before do
150
- @digest = setup_digest({
151
- 'www-authenticate' => 'Digest realm="myhost@testrealm.com", nonce="NONCE"'
152
- })
153
- end
154
-
155
- it "should set prefix" do
156
- expect(authorization_header).to match(/^Digest /)
157
- end
158
-
159
- it "should set username" do
160
- expect(authorization_header).to include('username="Mufasa"')
161
- end
162
-
163
- it "should set digest-uri" do
164
- expect(authorization_header).to include('uri="/dir/index.html"')
165
- end
166
-
167
- it "should not set qop" do
168
- expect(authorization_header).not_to include("qop=")
169
- end
170
-
171
- it "should not set cnonce" do
172
- expect(authorization_header).not_to include("cnonce=")
173
- end
174
-
175
- it "should not set nonce-count" do
176
- expect(authorization_header).not_to include("nc=")
177
- end
178
-
179
- it "should set response" do
180
- request_digest = "md5(md5(Mufasa:myhost@testrealm.com:Circle Of Life):NONCE:md5(GET:/dir/index.html))"
181
- expect(authorization_header).to include(%(response="#{request_digest}"))
182
- end
183
- end
184
-
185
- context "with http basic auth response when net digest auth expected" do
186
- it "should not fail" do
187
- @digest = setup_digest({
188
- 'www-authenticate' => 'WWW-Authenticate: Basic realm="testrealm.com""'
189
- })
190
-
191
- expect(authorization_header).to include("Digest")
192
- end
193
- end
194
-
195
- context "with multiple authenticate headers" do
196
- before do
197
- @digest = setup_digest({
198
- 'www-authenticate' => 'NTLM, Digest realm="myhost@testrealm.com", nonce="NONCE", qop="auth"'
199
- })
200
- end
201
-
202
- it "should set prefix" do
203
- expect(authorization_header).to match(/^Digest /)
204
- end
205
-
206
- it "should set username" do
207
- expect(authorization_header).to include('username="Mufasa"')
208
- end
209
-
210
- it "should set digest-uri" do
211
- expect(authorization_header).to include('uri="/dir/index.html"')
212
- end
213
-
214
- it "should set qop" do
215
- expect(authorization_header).to include('qop="auth"')
216
- end
217
-
218
- it "should set cnonce" do
219
- expect(authorization_header).to include('cnonce="md5(deadbeef)"')
220
- end
221
-
222
- it "should set nonce-count" do
223
- expect(authorization_header).to include("nc=00000001")
224
- end
225
-
226
- it "should set response" do
227
- request_digest = "md5(md5(Mufasa:myhost@testrealm.com:Circle Of Life):NONCE:00000001:md5(deadbeef):auth:md5(GET:/dir/index.html))"
228
- expect(authorization_header).to include(%(response="#{request_digest}"))
229
- end
230
- end
231
-
232
- context "with algorithm specified" do
233
- before do
234
- @digest = setup_digest({
235
- 'www-authenticate' => 'Digest realm="myhost@testrealm.com", nonce="NONCE", qop="auth", algorithm=MD5'
236
- })
237
- end
238
-
239
- it "should recognise algorithm was specified" do
240
- expect( @digest.send :algorithm_present? ).to be(true)
241
- end
242
-
243
- it "should set the algorithm header" do
244
- expect(authorization_header).to include('algorithm="MD5"')
245
- end
246
- end
247
-
248
- context "with md5-sess algorithm specified" do
249
- before do
250
- @digest = setup_digest({
251
- 'www-authenticate' => 'Digest realm="myhost@testrealm.com", nonce="NONCE", qop="auth", algorithm=MD5-sess'
252
- })
253
- end
254
-
255
- it "should recognise algorithm was specified" do
256
- expect( @digest.send :algorithm_present? ).to be(true)
257
- end
258
-
259
- it "should set the algorithm header" do
260
- expect(authorization_header).to include('algorithm="MD5-sess"')
261
- end
262
-
263
- it "should set response using md5-sess algorithm" do
264
- request_digest = "md5(md5(md5(Mufasa:myhost@testrealm.com:Circle Of Life):NONCE:md5(deadbeef)):NONCE:00000001:md5(deadbeef):auth:md5(GET:/dir/index.html))"
265
- expect(authorization_header).to include(%(response="#{request_digest}"))
266
- end
267
-
268
- end
269
-
270
- end
@@ -1,190 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe HTTParty::Parser do
4
- describe ".SupportedFormats" do
5
- it "returns a hash" do
6
- expect(HTTParty::Parser::SupportedFormats).to be_instance_of(Hash)
7
- end
8
- end
9
-
10
- describe ".call" do
11
- it "generates an HTTParty::Parser instance with the given body and format" do
12
- expect(HTTParty::Parser).to receive(:new).with('body', :plain).and_return(double(parse: nil))
13
- HTTParty::Parser.call('body', :plain)
14
- end
15
-
16
- it "calls #parse on the parser" do
17
- parser = double('Parser')
18
- expect(parser).to receive(:parse)
19
- allow(HTTParty::Parser).to receive_messages(new: parser)
20
- parser = HTTParty::Parser.call('body', :plain)
21
- end
22
- end
23
-
24
- describe ".formats" do
25
- it "returns the SupportedFormats constant" do
26
- expect(HTTParty::Parser.formats).to eq(HTTParty::Parser::SupportedFormats)
27
- end
28
-
29
- it "returns the SupportedFormats constant for subclasses" do
30
- klass = Class.new(HTTParty::Parser)
31
- klass::SupportedFormats = { "application/atom+xml" => :atom }
32
-
33
- expect(klass.formats).to eq({"application/atom+xml" => :atom})
34
- end
35
- end
36
-
37
- describe ".format_from_mimetype" do
38
- it "returns a symbol representing the format mimetype" do
39
- expect(HTTParty::Parser.format_from_mimetype("text/plain")).to eq(:plain)
40
- end
41
-
42
- it "returns nil when the mimetype is not supported" do
43
- expect(HTTParty::Parser.format_from_mimetype("application/atom+xml")).to be_nil
44
- end
45
- end
46
-
47
- describe ".supported_formats" do
48
- it "returns a unique set of supported formats represented by symbols" do
49
- expect(HTTParty::Parser.supported_formats).to eq(HTTParty::Parser::SupportedFormats.values.uniq)
50
- end
51
- end
52
-
53
- describe ".supports_format?" do
54
- it "returns true for a supported format" do
55
- allow(HTTParty::Parser).to receive_messages(supported_formats: [:json])
56
- expect(HTTParty::Parser.supports_format?(:json)).to be_truthy
57
- end
58
-
59
- it "returns false for an unsupported format" do
60
- allow(HTTParty::Parser).to receive_messages(supported_formats: [])
61
- expect(HTTParty::Parser.supports_format?(:json)).to be_falsey
62
- end
63
- end
64
-
65
- describe "#parse" do
66
- it "attempts to parse supported formats" do
67
- parser = HTTParty::Parser.new('body', :json)
68
- allow(parser).to receive_messages(supports_format?: true)
69
-
70
- expect(parser).to receive(:parse_supported_format)
71
- parser.parse
72
- end
73
-
74
- it "returns the unparsed body when the format is unsupported" do
75
- parser = HTTParty::Parser.new('body', :json)
76
- allow(parser).to receive_messages(supports_format?: false)
77
-
78
- expect(parser.parse).to eq(parser.body)
79
- end
80
-
81
- it "returns nil for an empty body" do
82
- parser = HTTParty::Parser.new('', :json)
83
- expect(parser.parse).to be_nil
84
- end
85
-
86
- it "returns nil for a nil body" do
87
- parser = HTTParty::Parser.new(nil, :json)
88
- expect(parser.parse).to be_nil
89
- end
90
-
91
- it "returns nil for a 'null' body" do
92
- parser = HTTParty::Parser.new("null", :json)
93
- expect(parser.parse).to be_nil
94
- end
95
-
96
- it "returns nil for a body with spaces only" do
97
- parser = HTTParty::Parser.new(" ", :json)
98
- expect(parser.parse).to be_nil
99
- end
100
-
101
- it "does not raise exceptions for bodies with invalid encodings" do
102
- parser = HTTParty::Parser.new("\x80", :invalid_format)
103
- expect(parser.parse).to_not be_nil
104
- end
105
-
106
- it "ignores utf-8 bom" do
107
- parser = HTTParty::Parser.new("\xEF\xBB\xBF\{\"hi\":\"yo\"\}", :json)
108
- expect(parser.parse).to eq({"hi"=>"yo"})
109
- end
110
-
111
- it "parses ascii 8bit encoding" do
112
- parser = HTTParty::Parser.new(
113
- "{\"currency\":\"\xE2\x82\xAC\"}".force_encoding('ASCII-8BIT'),
114
- :json
115
- )
116
- expect(parser.parse).to eq({"currency" => "€"})
117
- end
118
-
119
- it "parses frozen strings" do
120
- parser = HTTParty::Parser.new('{"a":1}'.freeze, :json)
121
- expect(parser.parse).to eq("a" => 1)
122
- end
123
- end
124
-
125
- describe "#supports_format?" do
126
- it "utilizes the class method to determine if the format is supported" do
127
- expect(HTTParty::Parser).to receive(:supports_format?).with(:json)
128
- parser = HTTParty::Parser.new('body', :json)
129
- parser.send(:supports_format?)
130
- end
131
- end
132
-
133
- describe "#parse_supported_format" do
134
- it "calls the parser for the given format" do
135
- parser = HTTParty::Parser.new('body', :json)
136
- expect(parser).to receive(:json)
137
- parser.send(:parse_supported_format)
138
- end
139
-
140
- context "when a parsing method does not exist for the given format" do
141
- it "raises an exception" do
142
- parser = HTTParty::Parser.new('body', :atom)
143
- expect do
144
- parser.send(:parse_supported_format)
145
- end.to raise_error(NotImplementedError, "HTTParty::Parser has not implemented a parsing method for the :atom format.")
146
- end
147
-
148
- it "raises a useful exception message for subclasses" do
149
- atom_parser = Class.new(HTTParty::Parser) do
150
- def self.name
151
- 'AtomParser'
152
- end
153
- end
154
- parser = atom_parser.new 'body', :atom
155
- expect do
156
- parser.send(:parse_supported_format)
157
- end.to raise_error(NotImplementedError, "AtomParser has not implemented a parsing method for the :atom format.")
158
- end
159
- end
160
- end
161
-
162
- context "parsers" do
163
- subject do
164
- HTTParty::Parser.new('body', nil)
165
- end
166
-
167
- it "parses xml with MultiXml" do
168
- expect(MultiXml).to receive(:parse).with('body')
169
- subject.send(:xml)
170
- end
171
-
172
- it "parses json with JSON" do
173
- expect(JSON).to receive(:parse).with('body', :quirks_mode => true, :allow_nan => true)
174
- subject.send(:json)
175
- end
176
-
177
- it "parses html by simply returning the body" do
178
- expect(subject.send(:html)).to eq('body')
179
- end
180
-
181
- it "parses plain text by simply returning the body" do
182
- expect(subject.send(:plain)).to eq('body')
183
- end
184
-
185
- it "parses csv with CSV" do
186
- expect(CSV).to receive(:parse).with('body')
187
- subject.send(:csv)
188
- end
189
- end
190
- end