httparty 0.16.4 → 0.20.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 httparty might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/.github/workflows/ci.yml +23 -0
- data/.rubocop_todo.yml +1 -1
- data/Changelog.md +55 -0
- data/Gemfile +5 -0
- data/README.md +4 -4
- data/docs/README.md +70 -5
- data/examples/README.md +6 -0
- data/examples/aaws.rb +6 -2
- data/examples/idn.rb +10 -0
- data/examples/peer_cert.rb +9 -0
- data/httparty.gemspec +1 -2
- data/lib/httparty/connection_adapter.rb +41 -10
- data/lib/httparty/cookie_hash.rb +10 -8
- data/lib/httparty/decompressor.rb +92 -0
- data/lib/httparty/exceptions.rb +3 -1
- data/lib/httparty/hash_conversions.rb +4 -2
- data/lib/httparty/headers_processor.rb +32 -0
- data/lib/httparty/logger/apache_formatter.rb +4 -2
- data/lib/httparty/logger/curl_formatter.rb +6 -4
- data/lib/httparty/logger/logger.rb +2 -0
- data/lib/httparty/logger/logstash_formatter.rb +4 -2
- data/lib/httparty/module_inheritable_attributes.rb +3 -1
- data/lib/httparty/net_digest_auth.rb +9 -10
- data/lib/httparty/parser.rb +9 -5
- data/lib/httparty/request/body.rb +24 -10
- data/lib/httparty/request/multipart_boundary.rb +2 -0
- data/lib/httparty/request.rb +67 -96
- data/lib/httparty/response/headers.rb +2 -0
- data/lib/httparty/response.rb +24 -4
- data/lib/httparty/{fragment_with_response.rb → response_fragment.rb} +6 -5
- data/lib/httparty/text_encoder.rb +72 -0
- data/lib/httparty/utils.rb +2 -0
- data/lib/httparty/version.rb +3 -1
- data/lib/httparty.rb +58 -35
- metadata +12 -108
- data/.travis.yml +0 -11
- data/features/basic_authentication.feature +0 -20
- data/features/command_line.feature +0 -95
- data/features/deals_with_http_error_codes.feature +0 -26
- data/features/digest_authentication.feature +0 -30
- data/features/handles_compressed_responses.feature +0 -27
- data/features/handles_multiple_formats.feature +0 -57
- data/features/steps/env.rb +0 -27
- data/features/steps/httparty_response_steps.rb +0 -56
- data/features/steps/httparty_steps.rb +0 -43
- data/features/steps/mongrel_helper.rb +0 -127
- data/features/steps/remote_service_steps.rb +0 -92
- data/features/supports_read_timeout_option.feature +0 -13
- data/features/supports_redirection.feature +0 -22
- data/features/supports_timeout_option.feature +0 -13
- data/spec/fixtures/delicious.xml +0 -23
- data/spec/fixtures/empty.xml +0 -0
- data/spec/fixtures/example.html +0 -10
- data/spec/fixtures/ssl/generate.sh +0 -29
- data/spec/fixtures/ssl/generated/bogushost.crt +0 -13
- data/spec/fixtures/ssl/generated/ca.crt +0 -16
- data/spec/fixtures/ssl/generated/ca.key +0 -15
- data/spec/fixtures/ssl/generated/selfsigned.crt +0 -14
- data/spec/fixtures/ssl/generated/server.crt +0 -13
- data/spec/fixtures/ssl/generated/server.key +0 -15
- data/spec/fixtures/ssl/openssl-exts.cnf +0 -9
- data/spec/fixtures/tiny.gif +0 -0
- data/spec/fixtures/twitter.csv +0 -2
- data/spec/fixtures/twitter.json +0 -1
- data/spec/fixtures/twitter.xml +0 -403
- data/spec/fixtures/undefined_method_add_node_for_nil.xml +0 -2
- data/spec/httparty/connection_adapter_spec.rb +0 -502
- data/spec/httparty/cookie_hash_spec.rb +0 -100
- data/spec/httparty/exception_spec.rb +0 -45
- data/spec/httparty/fragment_with_response_spec.rb +0 -14
- data/spec/httparty/hash_conversions_spec.rb +0 -58
- data/spec/httparty/logger/apache_formatter_spec.rb +0 -40
- data/spec/httparty/logger/curl_formatter_spec.rb +0 -119
- data/spec/httparty/logger/logger_spec.rb +0 -43
- data/spec/httparty/logger/logstash_formatter_spec.rb +0 -44
- data/spec/httparty/net_digest_auth_spec.rb +0 -270
- data/spec/httparty/parser_spec.rb +0 -190
- data/spec/httparty/request/body_spec.rb +0 -165
- data/spec/httparty/request_spec.rb +0 -1367
- data/spec/httparty/response_spec.rb +0 -368
- data/spec/httparty/ssl_spec.rb +0 -74
- data/spec/httparty_spec.rb +0 -923
- data/spec/spec_helper.rb +0 -56
- data/spec/support/ssl_test_helper.rb +0 -47
- data/spec/support/ssl_test_server.rb +0 -80
- data/spec/support/stub_response.rb +0 -49
@@ -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
|
@@ -1,165 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'tempfile'
|
3
|
-
|
4
|
-
RSpec.describe HTTParty::Request::Body do
|
5
|
-
describe '#call' do
|
6
|
-
let(:options) { {} }
|
7
|
-
|
8
|
-
subject { described_class.new(params, options).call }
|
9
|
-
|
10
|
-
context 'when params is string' do
|
11
|
-
let(:params) { 'name=Bob%20Jones' }
|
12
|
-
|
13
|
-
it { is_expected.to eq params }
|
14
|
-
end
|
15
|
-
|
16
|
-
context 'when params is hash' do
|
17
|
-
let(:params) { { people: ["Bob Jones", "Mike Smith"] } }
|
18
|
-
let(:converted_params) { "people[]=Bob%20Jones&people[]=Mike%20Smith"}
|
19
|
-
|
20
|
-
it { is_expected.to eq converted_params }
|
21
|
-
|
22
|
-
context 'when params has file' do
|
23
|
-
before do
|
24
|
-
allow(HTTParty::Request::MultipartBoundary)
|
25
|
-
.to receive(:generate).and_return("------------------------c772861a5109d5ef")
|
26
|
-
end
|
27
|
-
|
28
|
-
let(:file) { File.open('spec/fixtures/tiny.gif') }
|
29
|
-
let(:params) do
|
30
|
-
{
|
31
|
-
user: {
|
32
|
-
avatar: file,
|
33
|
-
first_name: 'John',
|
34
|
-
last_name: 'Doe',
|
35
|
-
enabled: true
|
36
|
-
}
|
37
|
-
}
|
38
|
-
end
|
39
|
-
let(:expected_file_name) { 'tiny.gif' }
|
40
|
-
let(:expected_file_contents) { "GIF89a\u0001\u0000\u0001\u0000\u0000\xFF\u0000,\u0000\u0000\u0000\u0000\u0001\u0000\u0001\u0000\u0000\u0002\u0000;" }
|
41
|
-
let(:expected_content_type) { 'image/gif' }
|
42
|
-
let(:multipart_params) do
|
43
|
-
"--------------------------c772861a5109d5ef\r\n" \
|
44
|
-
"Content-Disposition: form-data; name=\"user[avatar]\"; filename=\"#{expected_file_name}\"\r\n" \
|
45
|
-
"Content-Type: #{expected_content_type}\r\n" \
|
46
|
-
"\r\n" \
|
47
|
-
"#{expected_file_contents}\r\n" \
|
48
|
-
"--------------------------c772861a5109d5ef\r\n" \
|
49
|
-
"Content-Disposition: form-data; name=\"user[first_name]\"\r\n" \
|
50
|
-
"\r\n" \
|
51
|
-
"John\r\n" \
|
52
|
-
"--------------------------c772861a5109d5ef\r\n" \
|
53
|
-
"Content-Disposition: form-data; name=\"user[last_name]\"\r\n" \
|
54
|
-
"\r\n" \
|
55
|
-
"Doe\r\n" \
|
56
|
-
"--------------------------c772861a5109d5ef\r\n" \
|
57
|
-
"Content-Disposition: form-data; name=\"user[enabled]\"\r\n" \
|
58
|
-
"\r\n" \
|
59
|
-
"true\r\n" \
|
60
|
-
"--------------------------c772861a5109d5ef--\r\n"
|
61
|
-
end
|
62
|
-
|
63
|
-
it { is_expected.to eq multipart_params }
|
64
|
-
|
65
|
-
context 'when passing multipart as an option' do
|
66
|
-
let(:options) { { force_multipart: true } }
|
67
|
-
let(:params) do
|
68
|
-
{
|
69
|
-
user: {
|
70
|
-
first_name: 'John',
|
71
|
-
last_name: 'Doe',
|
72
|
-
enabled: true
|
73
|
-
}
|
74
|
-
}
|
75
|
-
end
|
76
|
-
let(:multipart_params) do
|
77
|
-
"--------------------------c772861a5109d5ef\r\n" \
|
78
|
-
"Content-Disposition: form-data; name=\"user[first_name]\"\r\n" \
|
79
|
-
"\r\n" \
|
80
|
-
"John\r\n" \
|
81
|
-
"--------------------------c772861a5109d5ef\r\n" \
|
82
|
-
"Content-Disposition: form-data; name=\"user[last_name]\"\r\n" \
|
83
|
-
"\r\n" \
|
84
|
-
"Doe\r\n" \
|
85
|
-
"--------------------------c772861a5109d5ef\r\n" \
|
86
|
-
"Content-Disposition: form-data; name=\"user[enabled]\"\r\n" \
|
87
|
-
"\r\n" \
|
88
|
-
"true\r\n" \
|
89
|
-
"--------------------------c772861a5109d5ef--\r\n"
|
90
|
-
end
|
91
|
-
|
92
|
-
it { is_expected.to eq multipart_params }
|
93
|
-
|
94
|
-
end
|
95
|
-
|
96
|
-
context 'file object responds to original_filename' do
|
97
|
-
let(:some_temp_file) { Tempfile.new(['some_temp_file','.gif']) }
|
98
|
-
let(:expected_file_name) { "some_temp_file.gif" }
|
99
|
-
let(:expected_file_contents) { "Hello" }
|
100
|
-
let(:file) { double(:mocked_action_dispatch, path: some_temp_file.path, original_filename: 'some_temp_file.gif', read: expected_file_contents) }
|
101
|
-
|
102
|
-
before { some_temp_file.write('Hello') }
|
103
|
-
|
104
|
-
it { is_expected.to eq multipart_params }
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
describe '#multipart?' do
|
111
|
-
let(:force_multipart) { false }
|
112
|
-
let(:file) { File.open('spec/fixtures/tiny.gif') }
|
113
|
-
|
114
|
-
subject { described_class.new(params, force_multipart: force_multipart).multipart? }
|
115
|
-
|
116
|
-
context 'when params does not respond to to_hash' do
|
117
|
-
let(:params) { 'name=Bob%20Jones' }
|
118
|
-
|
119
|
-
it { is_expected.to be false }
|
120
|
-
end
|
121
|
-
|
122
|
-
context 'when params responds to to_hash' do
|
123
|
-
class HashLike
|
124
|
-
def initialize(hash)
|
125
|
-
@hash = hash
|
126
|
-
end
|
127
|
-
|
128
|
-
def to_hash
|
129
|
-
@hash
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
class ArrayLike
|
134
|
-
def initialize(ary)
|
135
|
-
@ary = ary
|
136
|
-
end
|
137
|
-
|
138
|
-
def to_ary
|
139
|
-
@ary
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
context 'when force_multipart is true' do
|
144
|
-
let(:params) { { name: 'Bob Jones' } }
|
145
|
-
let(:force_multipart) { true }
|
146
|
-
|
147
|
-
it { is_expected.to be true }
|
148
|
-
end
|
149
|
-
|
150
|
-
context 'when it does not contain a file' do
|
151
|
-
let(:hash_like_param) { HashLike.new(first: 'Bob', last: ArrayLike.new(['Jones'])) }
|
152
|
-
let(:params) { { name: ArrayLike.new([hash_like_param]) } }
|
153
|
-
|
154
|
-
it { is_expected.to eq false }
|
155
|
-
end
|
156
|
-
|
157
|
-
context 'when it contains file' do
|
158
|
-
let(:hash_like_param) { HashLike.new(first: 'Bob', last: 'Jones', file: ArrayLike.new([file])) }
|
159
|
-
let(:params) { { name: ArrayLike.new([hash_like_param]) } }
|
160
|
-
|
161
|
-
it { is_expected.to be true }
|
162
|
-
end
|
163
|
-
end
|
164
|
-
end
|
165
|
-
end
|