httparty 0.15.7 → 0.16.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/Changelog.md +4 -0
- data/examples/custom_parsers.rb +4 -0
- data/examples/headers_and_user_agents.rb +7 -3
- data/examples/logging.rb +3 -3
- data/lib/httparty/hash_conversions.rb +23 -12
- data/lib/httparty/request.rb +12 -5
- data/lib/httparty/request/body.rb +77 -0
- data/lib/httparty/request/multipart_boundary.rb +11 -0
- data/lib/httparty/version.rb +1 -1
- data/spec/fixtures/tiny.gif +0 -0
- data/spec/httparty/request/body_spec.rb +55 -0
- data/spec/httparty_spec.rb +17 -0
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3b3d9cd5bf2c8c65e7c422ee6424b08fabde5bee
|
4
|
+
data.tar.gz: c5e5164791c0c4ab0c1dca1ad1b87385b382d36a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 27268caca0723458d76464e7e510eb737feb425a9a9f2007337d9f1e12976b0bfb5c39850a5654f990fe66d1f7a4a53d2de4de80b57bfd670e470c9269c25b1f
|
7
|
+
data.tar.gz: 3c7360f0232df51be5491f3c98bba7998b9321c42a5a845680be055b7929edc024a4a9fdad7aad14501ea3dba8875a5d9debfd24ba31e6a9779accf2e1935a9f
|
data/Changelog.md
CHANGED
data/examples/custom_parsers.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
# To send custom user agents to identify your application to a web service (or mask as a specific browser for testing), send "User-Agent" as a hash to headers as shown below.
|
2
2
|
|
3
|
-
|
3
|
+
dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
4
|
+
require File.join(dir, 'httparty')
|
5
|
+
require 'pp'
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
+
response = HTTParty.get('http://example.com', {
|
8
|
+
headers: {"User-Agent" => "Httparty"},
|
9
|
+
debug_output: STDOUT, # To show that User-Agent is Httparty
|
10
|
+
})
|
data/examples/logging.rb
CHANGED
@@ -3,7 +3,7 @@ require File.join(dir, 'httparty')
|
|
3
3
|
require 'logger'
|
4
4
|
require 'pp'
|
5
5
|
|
6
|
-
my_logger = Logger.new
|
6
|
+
my_logger = Logger.new STDOUT
|
7
7
|
|
8
8
|
my_logger.info "Logging can be used on the main HTTParty class. It logs redirects too."
|
9
9
|
HTTParty.get "http://google.com", logger: my_logger
|
@@ -14,7 +14,7 @@ my_logger.info "It can be used also on a custom class."
|
|
14
14
|
|
15
15
|
class Google
|
16
16
|
include HTTParty
|
17
|
-
logger ::Logger.new
|
17
|
+
logger ::Logger.new STDOUT
|
18
18
|
end
|
19
19
|
|
20
20
|
Google.get "http://google.com"
|
@@ -30,7 +30,7 @@ my_logger.info '*' * 70
|
|
30
30
|
my_logger.info "These configs are also available on custom classes."
|
31
31
|
class Google
|
32
32
|
include HTTParty
|
33
|
-
logger ::Logger.new(
|
33
|
+
logger ::Logger.new(STDOUT), :debug, :curl
|
34
34
|
end
|
35
35
|
|
36
36
|
Google.get "http://google.com"
|
@@ -24,32 +24,43 @@ module HTTParty
|
|
24
24
|
#
|
25
25
|
# @example normalize_param(:name, "Bob Jones") #=> "name=Bob%20Jones&"
|
26
26
|
def self.normalize_param(key, value)
|
27
|
-
|
27
|
+
normalized_keys = normalize_keys(key, value)
|
28
|
+
|
29
|
+
normalized_keys.inject('') do |string, (k, v)|
|
30
|
+
string + "#{k}=#{ERB::Util.url_encode(v.to_s)}&"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.normalize_keys(key, value)
|
28
35
|
stack = []
|
36
|
+
normalized_keys = []
|
29
37
|
|
30
38
|
if value.respond_to?(:to_ary)
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
39
|
+
if value.empty?
|
40
|
+
normalized_keys << ["#{key}[]", '']
|
41
|
+
else
|
42
|
+
normalized_keys = value.to_ary.flat_map { |element| normalize_keys("#{key}[]", element) }
|
43
|
+
end
|
36
44
|
elsif value.respond_to?(:to_hash)
|
37
45
|
stack << [key, value.to_hash]
|
38
46
|
else
|
39
|
-
|
47
|
+
normalized_keys << [key.to_s, value]
|
40
48
|
end
|
41
49
|
|
50
|
+
|
42
51
|
stack.each do |parent, hash|
|
43
|
-
hash.each do |
|
44
|
-
if
|
45
|
-
stack << ["#{parent}[#{
|
52
|
+
hash.each do |key, value|
|
53
|
+
if value.respond_to?(:to_hash)
|
54
|
+
stack << ["#{parent}[#{key}]", value.to_hash]
|
55
|
+
elsif value.respond_to?(:to_ary)
|
56
|
+
value.to_ary.each { |v| normalized_keys << normalize_keys("#{parent}[#{key}][]", v).flatten }
|
46
57
|
else
|
47
|
-
|
58
|
+
normalized_keys << normalize_keys("#{parent}[#{key}]", value).flatten
|
48
59
|
end
|
49
60
|
end
|
50
61
|
end
|
51
62
|
|
52
|
-
|
63
|
+
normalized_keys
|
53
64
|
end
|
54
65
|
end
|
55
66
|
end
|
data/lib/httparty/request.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'erb'
|
2
|
+
require 'httparty/request/body'
|
2
3
|
|
3
4
|
module HTTParty
|
4
5
|
class Request #:nodoc:
|
@@ -176,10 +177,6 @@ module HTTParty
|
|
176
177
|
connection_adapter.call(uri, options)
|
177
178
|
end
|
178
179
|
|
179
|
-
def body
|
180
|
-
options[:body].respond_to?(:to_hash) ? normalize_query(options[:body]) : options[:body]
|
181
|
-
end
|
182
|
-
|
183
180
|
def credentials
|
184
181
|
(options[:basic_auth] || options[:digest_auth]).to_hash
|
185
182
|
end
|
@@ -206,8 +203,17 @@ module HTTParty
|
|
206
203
|
|
207
204
|
def setup_raw_request
|
208
205
|
@raw_request = http_method.new(request_uri(uri))
|
209
|
-
@raw_request.body = body if body
|
210
206
|
@raw_request.body_stream = options[:body_stream] if options[:body_stream]
|
207
|
+
|
208
|
+
if options[:body]
|
209
|
+
body = Body.new(options[:body], query_string_normalizer: query_string_normalizer)
|
210
|
+
if body.multipart?
|
211
|
+
content_type = "multipart/form-data; boundary=#{body.boundary}"
|
212
|
+
@raw_request.initialize_http_header('Content-Type' => content_type)
|
213
|
+
end
|
214
|
+
@raw_request.body = body.call
|
215
|
+
end
|
216
|
+
|
211
217
|
if options[:headers].respond_to?(:to_hash)
|
212
218
|
headers_hash = options[:headers].to_hash
|
213
219
|
|
@@ -220,6 +226,7 @@ module HTTParty
|
|
220
226
|
@raw_request['accept-encoding'] = @raw_request['accept-encoding']
|
221
227
|
end
|
222
228
|
end
|
229
|
+
|
223
230
|
if options[:basic_auth] && send_authorization_header?
|
224
231
|
@raw_request.basic_auth(username, password)
|
225
232
|
@credentials_sent = true
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require_relative 'multipart_boundary'
|
2
|
+
|
3
|
+
module HTTParty
|
4
|
+
class Request
|
5
|
+
class Body
|
6
|
+
def initialize(params, query_string_normalizer: nil)
|
7
|
+
@params = params
|
8
|
+
@query_string_normalizer = query_string_normalizer
|
9
|
+
end
|
10
|
+
|
11
|
+
def call
|
12
|
+
if params.respond_to?(:to_hash)
|
13
|
+
multipart? ? generate_multipart : normalize_query(params)
|
14
|
+
else
|
15
|
+
params
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def boundary
|
20
|
+
@boundary ||= MultipartBoundary.generate
|
21
|
+
end
|
22
|
+
|
23
|
+
def multipart?
|
24
|
+
params.respond_to?(:to_hash) && has_file?(params.to_hash)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def generate_multipart
|
30
|
+
normalized_params = params.flat_map { |key, value| HashConversions.normalize_keys(key, value) }
|
31
|
+
|
32
|
+
multipart = normalized_params.inject('') do |memo, (key, value)|
|
33
|
+
memo += "--#{boundary}\r\n"
|
34
|
+
memo += %(Content-Disposition: form-data; name="#{key}")
|
35
|
+
memo += %(; filename="#{File.basename(value)}") if file?(value)
|
36
|
+
memo += "\r\n"
|
37
|
+
memo += "Content-Type: application/octet-stream\r\n" if file?(value)
|
38
|
+
memo += "\r\n"
|
39
|
+
memo += file?(value) ? value.read : value
|
40
|
+
memo += "\r\n"
|
41
|
+
end
|
42
|
+
|
43
|
+
multipart += "--#{boundary}--\r\n"
|
44
|
+
end
|
45
|
+
|
46
|
+
def has_file?(hash)
|
47
|
+
hash.detect do |key, value|
|
48
|
+
if value.respond_to?(:to_hash) || includes_hash?(value)
|
49
|
+
has_file?(value)
|
50
|
+
elsif value.respond_to?(:to_ary)
|
51
|
+
value.any? { |e| file?(e) }
|
52
|
+
else
|
53
|
+
file?(value)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def file?(object)
|
59
|
+
object.respond_to?(:path) && object.respond_to?(:read) # add memoization
|
60
|
+
end
|
61
|
+
|
62
|
+
def includes_hash?(object)
|
63
|
+
object.respond_to?(:to_ary) && object.any? { |e| e.respond_to?(:hash) }
|
64
|
+
end
|
65
|
+
|
66
|
+
def normalize_query(query)
|
67
|
+
if query_string_normalizer
|
68
|
+
query_string_normalizer.call(query)
|
69
|
+
else
|
70
|
+
HashConversions.to_params(query)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
attr_reader :params, :query_string_normalizer
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
data/lib/httparty/version.rb
CHANGED
Binary file
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require_relative '../../spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe HTTParty::Request::Body do
|
4
|
+
describe '#call' do
|
5
|
+
subject { described_class.new(params).call }
|
6
|
+
|
7
|
+
context 'when params is string' do
|
8
|
+
let(:params) { 'name=Bob%20Jones' }
|
9
|
+
|
10
|
+
it { is_expected.to eq params }
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'when params is hash' do
|
14
|
+
let(:params) { { people: ["Bob Jones", "Mike Smith"] } }
|
15
|
+
let(:converted_params) { "people[]=Bob%20Jones&people[]=Mike%20Smith"}
|
16
|
+
|
17
|
+
it { is_expected.to eq converted_params }
|
18
|
+
|
19
|
+
context 'when params has file' do
|
20
|
+
before do
|
21
|
+
allow(HTTParty::Request::MultipartBoundary).
|
22
|
+
to receive(:generate).and_return("------------------------c772861a5109d5ef")
|
23
|
+
end
|
24
|
+
|
25
|
+
let(:params) do
|
26
|
+
{
|
27
|
+
user: {
|
28
|
+
avatar: File.open('spec/fixtures/tiny.gif'),
|
29
|
+
first_name: 'John',
|
30
|
+
last_name: 'Doe'
|
31
|
+
}
|
32
|
+
}
|
33
|
+
end
|
34
|
+
let(:multipart_params) do
|
35
|
+
"--------------------------c772861a5109d5ef\r\n" \
|
36
|
+
"Content-Disposition: form-data; name=\"user[avatar]\"; filename=\"tiny.gif\"\r\n" \
|
37
|
+
"Content-Type: application/octet-stream\r\n" \
|
38
|
+
"\r\n" \
|
39
|
+
"GIF89a\u0001\u0000\u0001\u0000\u0000\xFF\u0000,\u0000\u0000\u0000\u0000\u0001\u0000\u0001\u0000\u0000\u0002\u0000;\r\n" \
|
40
|
+
"--------------------------c772861a5109d5ef\r\n" \
|
41
|
+
"Content-Disposition: form-data; name=\"user[first_name]\"\r\n" \
|
42
|
+
"\r\n" \
|
43
|
+
"John\r\n" \
|
44
|
+
"--------------------------c772861a5109d5ef\r\n" \
|
45
|
+
"Content-Disposition: form-data; name=\"user[last_name]\"\r\n" \
|
46
|
+
"\r\n" \
|
47
|
+
"Doe\r\n" \
|
48
|
+
"--------------------------c772861a5109d5ef--\r\n"
|
49
|
+
end
|
50
|
+
|
51
|
+
it { is_expected.to eq multipart_params }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/spec/httparty_spec.rb
CHANGED
@@ -188,6 +188,23 @@ RSpec.describe HTTParty do
|
|
188
188
|
@klass.get('', cookies: {type: 'snickerdoodle'}, headers: {baz: 'spax'})
|
189
189
|
end
|
190
190
|
end
|
191
|
+
|
192
|
+
context 'when posting file' do
|
193
|
+
let(:boundary) { '------------------------c772861a5109d5ef' }
|
194
|
+
let(:headers) do
|
195
|
+
{ 'Content-Type'=>"multipart/form-data; boundary=#{boundary}" }
|
196
|
+
end
|
197
|
+
|
198
|
+
before do
|
199
|
+
expect(HTTParty::Request::MultipartBoundary).to receive(:generate).and_return(boundary)
|
200
|
+
end
|
201
|
+
|
202
|
+
it 'changes content-type headers to multipart/form-data' do
|
203
|
+
stub_request(:post, "http://example.com/").with(headers: headers)
|
204
|
+
|
205
|
+
@klass.post('http://example.com', body: { file: File.open('spec/fixtures/tiny.gif')})
|
206
|
+
end
|
207
|
+
end
|
191
208
|
end
|
192
209
|
|
193
210
|
describe "cookies" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: httparty
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.16.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Nunemaker
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2018-02-
|
12
|
+
date: 2018-02-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: multi_xml
|
@@ -92,6 +92,8 @@ files:
|
|
92
92
|
- lib/httparty/net_digest_auth.rb
|
93
93
|
- lib/httparty/parser.rb
|
94
94
|
- lib/httparty/request.rb
|
95
|
+
- lib/httparty/request/body.rb
|
96
|
+
- lib/httparty/request/multipart_boundary.rb
|
95
97
|
- lib/httparty/response.rb
|
96
98
|
- lib/httparty/response/headers.rb
|
97
99
|
- lib/httparty/version.rb
|
@@ -107,6 +109,7 @@ files:
|
|
107
109
|
- spec/fixtures/ssl/generated/server.crt
|
108
110
|
- spec/fixtures/ssl/generated/server.key
|
109
111
|
- spec/fixtures/ssl/openssl-exts.cnf
|
112
|
+
- spec/fixtures/tiny.gif
|
110
113
|
- spec/fixtures/twitter.csv
|
111
114
|
- spec/fixtures/twitter.json
|
112
115
|
- spec/fixtures/twitter.xml
|
@@ -120,6 +123,7 @@ files:
|
|
120
123
|
- spec/httparty/logger/logger_spec.rb
|
121
124
|
- spec/httparty/net_digest_auth_spec.rb
|
122
125
|
- spec/httparty/parser_spec.rb
|
126
|
+
- spec/httparty/request/body_spec.rb
|
123
127
|
- spec/httparty/request_spec.rb
|
124
128
|
- spec/httparty/response_spec.rb
|
125
129
|
- spec/httparty/ssl_spec.rb
|
@@ -180,6 +184,7 @@ test_files:
|
|
180
184
|
- spec/fixtures/ssl/generated/server.crt
|
181
185
|
- spec/fixtures/ssl/generated/server.key
|
182
186
|
- spec/fixtures/ssl/openssl-exts.cnf
|
187
|
+
- spec/fixtures/tiny.gif
|
183
188
|
- spec/fixtures/twitter.csv
|
184
189
|
- spec/fixtures/twitter.json
|
185
190
|
- spec/fixtures/twitter.xml
|
@@ -193,6 +198,7 @@ test_files:
|
|
193
198
|
- spec/httparty/logger/logger_spec.rb
|
194
199
|
- spec/httparty/net_digest_auth_spec.rb
|
195
200
|
- spec/httparty/parser_spec.rb
|
201
|
+
- spec/httparty/request/body_spec.rb
|
196
202
|
- spec/httparty/request_spec.rb
|
197
203
|
- spec/httparty/response_spec.rb
|
198
204
|
- spec/httparty/ssl_spec.rb
|