braintreehttp 0.3.0 → 0.4.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.
- checksums.yaml +4 -4
- data/lib/braintreehttp/encoder.rb +26 -100
- data/lib/braintreehttp/http_client.rb +10 -1
- data/lib/braintreehttp/serializers/form_encoded.rb +22 -0
- data/lib/braintreehttp/serializers/json.rb +17 -0
- data/lib/braintreehttp/serializers/multipart.rb +50 -0
- data/lib/braintreehttp/serializers/text.rb +15 -0
- data/lib/braintreehttp/version.rb +1 -1
- data/spec/braintreehttp/encoder_spec.rb +77 -13
- data/spec/braintreehttp/http_client_spec.rb +30 -15
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5713242e8cfed8abeb24124ba10ca92c3e95ec2b
|
4
|
+
data.tar.gz: 93e09fa466ce4c6ecf25a506da8fd8305d7da6b5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2ddacb0b0df421383f074526d9cff0fbdce994f6b0c5f853498e16c9cb4d292b57638e26ee5b60576b05f73854abbb8690927792430ef3a14187fa9bc0ac4f8c
|
7
|
+
data.tar.gz: 1cbe84a0729e3077412e21b881c461aa07e6b73ba66ea0ebb1156bf808c7b0c5089a8b39e1c4420fdab5d2a190c9c79b19453c2d41d174764edad8313be9dab7
|
@@ -1,5 +1,9 @@
|
|
1
|
-
require '
|
2
|
-
|
1
|
+
require 'zlib'
|
2
|
+
|
3
|
+
require_relative './serializers/json'
|
4
|
+
require_relative './serializers/form_encoded'
|
5
|
+
require_relative './serializers/text'
|
6
|
+
require_relative './serializers/multipart'
|
3
7
|
|
4
8
|
module BraintreeHttp
|
5
9
|
class Encoder
|
@@ -10,24 +14,35 @@ module BraintreeHttp
|
|
10
14
|
def serialize_request(req)
|
11
15
|
raise UnsupportedEncodingError.new('HttpRequest did not have Content-Type header set') unless req.headers && (req.headers['content-type'] || req.headers['Content-Type'])
|
12
16
|
|
13
|
-
content_type = req.headers
|
14
|
-
content_type = content_type.first if content_type.kind_of?(Array)
|
17
|
+
content_type = _extract_header(req.headers, 'Content-Type')
|
15
18
|
|
16
19
|
enc = _encoder(content_type)
|
17
20
|
raise UnsupportedEncodingError.new("Unable to serialize request with Content-Type #{content_type}. Supported encodings are #{supported_encodings}") unless enc
|
18
21
|
|
19
|
-
enc.encode(req)
|
22
|
+
encoded = enc.encode(req)
|
23
|
+
content_encoding = _extract_header(req.headers, 'Content-Encoding')
|
24
|
+
|
25
|
+
if content_encoding == 'gzip'
|
26
|
+
encoded = Zlib::Deflate.deflate(encoded)
|
27
|
+
end
|
28
|
+
|
29
|
+
encoded
|
20
30
|
end
|
21
31
|
|
22
32
|
def deserialize_response(resp, headers)
|
23
33
|
raise UnsupportedEncodingError.new('HttpResponse did not have Content-Type header set') unless headers && (headers['content-type'] || headers['Content-Type'])
|
24
34
|
|
25
|
-
content_type = headers
|
26
|
-
content_type = content_type.first if content_type.kind_of?(Array)
|
35
|
+
content_type = _extract_header(headers, 'Content-Type')
|
27
36
|
|
28
37
|
enc = _encoder(content_type)
|
29
38
|
raise UnsupportedEncodingError.new("Unable to deserialize response with Content-Type #{content_type}. Supported decodings are #{supported_encodings}") unless enc
|
30
39
|
|
40
|
+
content_encoding = _extract_header(headers, 'Content-Encoding')
|
41
|
+
|
42
|
+
if content_encoding == 'gzip'
|
43
|
+
resp = Zlib::Inflate.inflate(resp)
|
44
|
+
end
|
45
|
+
|
31
46
|
enc.decode(resp)
|
32
47
|
end
|
33
48
|
|
@@ -40,101 +55,12 @@ module BraintreeHttp
|
|
40
55
|
|
41
56
|
@encoders[idx] if idx
|
42
57
|
end
|
43
|
-
end
|
44
|
-
|
45
|
-
class Json
|
46
|
-
def encode(request)
|
47
|
-
JSON.generate(request.body)
|
48
|
-
end
|
49
|
-
|
50
|
-
def decode(body)
|
51
|
-
JSON.parse(body)
|
52
|
-
end
|
53
|
-
|
54
|
-
def content_type
|
55
|
-
/^application\/json$/
|
56
|
-
end
|
57
|
-
end
|
58
58
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
end
|
59
|
+
def _extract_header(headers, key)
|
60
|
+
value = headers[key] || headers[key.downcase]
|
61
|
+
value = value.first if value.kind_of?(Array)
|
63
62
|
|
64
|
-
|
65
|
-
body.to_s
|
66
|
-
end
|
67
|
-
|
68
|
-
def content_type
|
69
|
-
/^text\/.*/
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
class FormEncoded
|
74
|
-
def encode(request)
|
75
|
-
encoded_params = []
|
76
|
-
request.body.each do |k, v|
|
77
|
-
encoded_params.push("#{URI.escape(k.to_s)}=#{URI.escape(v.to_s)}")
|
78
|
-
end
|
79
|
-
|
80
|
-
encoded_params.join("&")
|
81
|
-
end
|
82
|
-
|
83
|
-
def decode(body)
|
84
|
-
raise UnsupportedEncodingError.new("FormEncoded does not support deserialization")
|
85
|
-
end
|
86
|
-
|
87
|
-
def content_type
|
88
|
-
/^application\/x-www-form-urlencoded/
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
class Multipart
|
93
|
-
def encode(request)
|
94
|
-
boundary = DateTime.now.strftime("%Q")
|
95
|
-
request.headers["Content-Type"] = "multipart/form-data; boundary=#{boundary}"
|
96
|
-
|
97
|
-
form_params = []
|
98
|
-
request.body.each do |k, v|
|
99
|
-
if v.is_a? File
|
100
|
-
form_params.push(_add_file_part(k, v))
|
101
|
-
else
|
102
|
-
form_params.push(_add_form_field(k, v))
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
form_params.collect {|p| "--" + boundary + "#{LINE_FEED}" + p}.join("") + "--" + boundary + "--"
|
107
|
-
end
|
108
|
-
|
109
|
-
def decode(body)
|
110
|
-
raise UnsupportedEncodingError.new("Multipart does not support deserialization")
|
111
|
-
end
|
112
|
-
|
113
|
-
def content_type
|
114
|
-
/^multipart\/.*/
|
115
|
-
end
|
116
|
-
|
117
|
-
def _add_form_field(key, value)
|
118
|
-
return "Content-Disposition: form-data; name=\"#{key}\"#{LINE_FEED}#{LINE_FEED}#{value}#{LINE_FEED}"
|
119
|
-
end
|
120
|
-
|
121
|
-
def _add_file_part(key, file)
|
122
|
-
mime_type = _mime_type_for_file_name(file.path)
|
123
|
-
return "Content-Disposition: form-data; name=\"#{key}\"; filename=\"#{File.basename(file.path)}\"#{LINE_FEED}" +
|
124
|
-
"Content-Type: #{mime_type}#{LINE_FEED}#{LINE_FEED}#{file.read}#{LINE_FEED}"
|
125
|
-
end
|
126
|
-
|
127
|
-
def _mime_type_for_file_name(filename)
|
128
|
-
file_extension = File.extname(filename).strip.downcase[1..-1]
|
129
|
-
if file_extension == "jpeg" || file_extension == "jpg"
|
130
|
-
return "image/jpeg"
|
131
|
-
elsif file_extension == "png"
|
132
|
-
return "image/png"
|
133
|
-
elsif file_extension == "pdf"
|
134
|
-
return "application/pdf"
|
135
|
-
else
|
136
|
-
return "application/octet-stream"
|
137
|
-
end
|
63
|
+
value
|
138
64
|
end
|
139
65
|
end
|
140
66
|
end
|
@@ -27,7 +27,16 @@ module BraintreeHttp
|
|
27
27
|
request.respond_to?(:body) and request.body
|
28
28
|
end
|
29
29
|
|
30
|
-
def execute(
|
30
|
+
def execute(req)
|
31
|
+
headers = req.headers || {}
|
32
|
+
|
33
|
+
request = OpenStruct.new({
|
34
|
+
:verb => req.verb,
|
35
|
+
:path => req.path,
|
36
|
+
:headers => headers.clone,
|
37
|
+
:body => req.body,
|
38
|
+
})
|
39
|
+
|
31
40
|
if !request.headers
|
32
41
|
request.headers = {}
|
33
42
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
module BraintreeHttp
|
4
|
+
class FormEncoded
|
5
|
+
def encode(request)
|
6
|
+
encoded_params = []
|
7
|
+
request.body.each do |k, v|
|
8
|
+
encoded_params.push("#{URI.escape(k.to_s)}=#{URI.escape(v.to_s)}")
|
9
|
+
end
|
10
|
+
|
11
|
+
encoded_params.join("&")
|
12
|
+
end
|
13
|
+
|
14
|
+
def decode(body)
|
15
|
+
raise UnsupportedEncodingError.new("FormEncoded does not support deserialization")
|
16
|
+
end
|
17
|
+
|
18
|
+
def content_type
|
19
|
+
/^application\/x-www-form-urlencoded/
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module BraintreeHttp
|
2
|
+
class Multipart
|
3
|
+
def encode(request)
|
4
|
+
boundary = DateTime.now.strftime("%Q")
|
5
|
+
request.headers["Content-Type"] = "multipart/form-data; boundary=#{boundary}"
|
6
|
+
|
7
|
+
form_params = []
|
8
|
+
request.body.each do |k, v|
|
9
|
+
if v.is_a? File
|
10
|
+
form_params.push(_add_file_part(k, v))
|
11
|
+
else
|
12
|
+
form_params.push(_add_form_field(k, v))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
form_params.collect {|p| "--" + boundary + "#{LINE_FEED}" + p}.join("") + "--" + boundary + "--"
|
17
|
+
end
|
18
|
+
|
19
|
+
def decode(body)
|
20
|
+
raise UnsupportedEncodingError.new("Multipart does not support deserialization")
|
21
|
+
end
|
22
|
+
|
23
|
+
def content_type
|
24
|
+
/multipart\/.*/
|
25
|
+
end
|
26
|
+
|
27
|
+
def _add_form_field(key, value)
|
28
|
+
return "Content-Disposition: form-data; name=\"#{key}\"#{LINE_FEED}#{LINE_FEED}#{value}#{LINE_FEED}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def _add_file_part(key, file)
|
32
|
+
mime_type = _mime_type_for_file_name(file.path)
|
33
|
+
return "Content-Disposition: form-data; name=\"#{key}\"; filename=\"#{File.basename(file.path)}\"#{LINE_FEED}" +
|
34
|
+
"Content-Type: #{mime_type}#{LINE_FEED}#{LINE_FEED}#{file.read}#{LINE_FEED}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def _mime_type_for_file_name(filename)
|
38
|
+
file_extension = File.extname(filename).strip.downcase[1..-1]
|
39
|
+
if file_extension == "jpeg" || file_extension == "jpg"
|
40
|
+
return "image/jpeg"
|
41
|
+
elsif file_extension == "png"
|
42
|
+
return "image/png"
|
43
|
+
elsif file_extension == "pdf"
|
44
|
+
return "application/pdf"
|
45
|
+
else
|
46
|
+
return "application/octet-stream"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -1 +1 @@
|
|
1
|
-
VERSION = "0.
|
1
|
+
VERSION = "0.4.0"
|
@@ -1,4 +1,6 @@
|
|
1
1
|
require 'ostruct'
|
2
|
+
require 'json'
|
3
|
+
require 'zlib'
|
2
4
|
|
3
5
|
describe Encoder do
|
4
6
|
|
@@ -6,7 +8,7 @@ describe Encoder do
|
|
6
8
|
it 'serializes the request when content-type == application/json' do
|
7
9
|
req = OpenStruct.new({
|
8
10
|
:headers => {
|
9
|
-
"content-type" => "application/json"
|
11
|
+
"content-type" => "application/json; charset=utf8"
|
10
12
|
},
|
11
13
|
:body => {
|
12
14
|
"string" => "value",
|
@@ -28,7 +30,7 @@ describe Encoder do
|
|
28
30
|
it 'serializes the request when content-type == text/*' do
|
29
31
|
req = OpenStruct.new({
|
30
32
|
:headers => {
|
31
|
-
"content-type" => "text/plain"
|
33
|
+
"content-type" => "text/plain; charset=utf8"
|
32
34
|
},
|
33
35
|
:body => "some text"
|
34
36
|
})
|
@@ -39,10 +41,10 @@ describe Encoder do
|
|
39
41
|
it 'serializes the request when content-type == multipart/form-data' do
|
40
42
|
file = File.new("README.md", "r")
|
41
43
|
req = OpenStruct.new({
|
42
|
-
:verb => "POST",
|
43
|
-
:path => "/v1/api",
|
44
|
+
:verb => "POST",
|
45
|
+
:path => "/v1/api",
|
44
46
|
:headers => {
|
45
|
-
"Content-Type" => "multipart/form-data"
|
47
|
+
"Content-Type" => "multipart/form-data; charset=utf8"
|
46
48
|
},
|
47
49
|
:body => {
|
48
50
|
:key => "value",
|
@@ -63,10 +65,10 @@ describe Encoder do
|
|
63
65
|
|
64
66
|
it 'serializes the request when content-type == application/x-www-form-urlencoded' do
|
65
67
|
req = OpenStruct.new({
|
66
|
-
:verb => "POST",
|
67
|
-
:path => "/v1/api",
|
68
|
+
:verb => "POST",
|
69
|
+
:path => "/v1/api",
|
68
70
|
:headers => {
|
69
|
-
"Content-Type" => "application/x-www-form-urlencoded"
|
71
|
+
"Content-Type" => "application/x-www-form-urlencoded; charset=utf8"
|
70
72
|
},
|
71
73
|
:body => {
|
72
74
|
:key => "value with a space",
|
@@ -78,10 +80,10 @@ describe Encoder do
|
|
78
80
|
expect(serialized).to eq("key=value%20with%20a%20space&another_key=1013")
|
79
81
|
end
|
80
82
|
|
81
|
-
it 'throws when content-type is
|
83
|
+
it 'throws when content-type is unsupported' do
|
82
84
|
req = OpenStruct.new({
|
83
85
|
:headers => {
|
84
|
-
"content-type" => "
|
86
|
+
"content-type" => "fake/content-type"
|
85
87
|
},
|
86
88
|
:body => { :string => "value" }
|
87
89
|
})
|
@@ -96,10 +98,38 @@ describe Encoder do
|
|
96
98
|
|
97
99
|
expect{Encoder.new.serialize_request(req)}.to raise_error(UnsupportedEncodingError, 'HttpRequest did not have Content-Type header set')
|
98
100
|
end
|
101
|
+
|
102
|
+
it 'throws when conent-type undefined' do
|
103
|
+
req = OpenStruct.new({
|
104
|
+
:headers => {},
|
105
|
+
:body => { :key => "value" }
|
106
|
+
})
|
107
|
+
|
108
|
+
|
109
|
+
expect{Encoder.new.serialize_request(req)}.to raise_error(UnsupportedEncodingError, 'HttpRequest did not have Content-Type header set')
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'encodes data as gzip when content-encoding == gzip' do
|
113
|
+
req = OpenStruct.new({
|
114
|
+
:path => '/143j2bz1',
|
115
|
+
:verb => "POST",
|
116
|
+
:headers => {
|
117
|
+
'Content-Type' => 'application/json',
|
118
|
+
'Content-Encoding' => 'gzip'
|
119
|
+
},
|
120
|
+
:body => {
|
121
|
+
:one => "two"
|
122
|
+
}
|
123
|
+
})
|
124
|
+
|
125
|
+
encoder = Encoder.new
|
126
|
+
|
127
|
+
expect(encoder.serialize_request(req)).to eq(Zlib::Deflate.deflate(JSON.generate(req.body)))
|
128
|
+
end
|
99
129
|
end
|
100
130
|
|
101
131
|
describe 'deserialize_response' do
|
102
|
-
it 'throws when content-type
|
132
|
+
it 'throws when content-type unsupported' do
|
103
133
|
body = '{"string":"value","number":1.23,"bool":true,"array":["one","two","three"],"nested":{"nested_string":"nested_value","nested_array":[1,2,3]}}'
|
104
134
|
headers = {
|
105
135
|
"content-type" => ["application/xml"]
|
@@ -114,6 +144,12 @@ describe Encoder do
|
|
114
144
|
expect{Encoder.new.deserialize_response(body, nil)}.to raise_error(UnsupportedEncodingError, 'HttpResponse did not have Content-Type header set')
|
115
145
|
end
|
116
146
|
|
147
|
+
it 'throws when content-type undefined' do
|
148
|
+
body = '{"string":"value","number":1.23,"bool":true,"array":["one","two","three"],"nested":{"nested_string":"nested_value","nested_array":[1,2,3]}}'
|
149
|
+
|
150
|
+
expect{Encoder.new.deserialize_response(body, {})}.to raise_error(UnsupportedEncodingError, 'HttpResponse did not have Content-Type header set')
|
151
|
+
end
|
152
|
+
|
117
153
|
it 'deserializes the response when content-type == application/json' do
|
118
154
|
expected = {
|
119
155
|
"string" => "value",
|
@@ -126,17 +162,45 @@ describe Encoder do
|
|
126
162
|
}
|
127
163
|
}
|
128
164
|
|
129
|
-
headers = {"content-type" => ["application/json"]}
|
165
|
+
headers = {"content-type" => ["application/json; charset=utf8"]}
|
130
166
|
body = '{"string":"value","number":1.23,"bool":true,"array":["one","two","three"],"nested":{"nested_string":"nested_value","nested_array":[1,2,3]}}'
|
131
167
|
|
132
168
|
expect(Encoder.new.deserialize_response(body, headers)).to eq(expected)
|
133
169
|
end
|
134
170
|
|
135
171
|
it 'deserializes the response when content-type == text/*' do
|
136
|
-
headers = {"content-type" => ["text/plain"]}
|
172
|
+
headers = {"content-type" => ["text/plain; charset=utf8"]}
|
137
173
|
body = 'some text'
|
138
174
|
|
139
175
|
expect(Encoder.new.deserialize_response(body, headers)).to eq('some text')
|
140
176
|
end
|
177
|
+
|
178
|
+
it 'throws when attempting to deserialize multipart/*' do
|
179
|
+
headers = {"content-type" => ["multipart/form-data"]}
|
180
|
+
body = 'some multipart encoded data here'
|
181
|
+
|
182
|
+
expect{Encoder.new.deserialize_response(body, headers)}.to raise_error(UnsupportedEncodingError, 'Multipart does not support deserialization')
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'throws when attempting to deserialize application/x-www-form-urlencoded' do
|
186
|
+
headers = {"content-type" => ["application/x-www-form-urlencoded"]}
|
187
|
+
body = 'some multipart encoded data here'
|
188
|
+
|
189
|
+
expect{Encoder.new.deserialize_response(body, headers)}.to raise_error(UnsupportedEncodingError, 'FormEncoded does not support deserialization')
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'decodes data from gzip when content-encoding == gzip' do
|
193
|
+
headers = {
|
194
|
+
'content-type' => 'application/json',
|
195
|
+
'content-encoding' => 'gzip'
|
196
|
+
}
|
197
|
+
body = JSON.generate({
|
198
|
+
:one => 'two'
|
199
|
+
})
|
200
|
+
|
201
|
+
encoded_body = Zlib::Deflate.deflate(body)
|
202
|
+
|
203
|
+
expect(Encoder.new.deserialize_response(encoded_body, headers)).to eq({'one' => 'two'})
|
204
|
+
end
|
141
205
|
end
|
142
206
|
end
|
@@ -23,7 +23,10 @@ describe HttpClient do
|
|
23
23
|
|
24
24
|
http_client.execute(req)
|
25
25
|
|
26
|
-
|
26
|
+
assert_requested :get, "#{@environment.base_url}/", {
|
27
|
+
:headers => {'Some-Key' => 'Some Value'},
|
28
|
+
:times => 1
|
29
|
+
}
|
27
30
|
end
|
28
31
|
|
29
32
|
it "uses method injector to modify request" do
|
@@ -43,7 +46,10 @@ describe HttpClient do
|
|
43
46
|
|
44
47
|
http_client.execute(req)
|
45
48
|
|
46
|
-
|
49
|
+
assert_requested :get, "#{@environment.base_url}/", {
|
50
|
+
:headers => {'Some-Key' => 'Some Value'},
|
51
|
+
:times => 1
|
52
|
+
}
|
47
53
|
end
|
48
54
|
|
49
55
|
it "sets User-Agent header in request if not set" do
|
@@ -56,7 +62,10 @@ describe HttpClient do
|
|
56
62
|
|
57
63
|
http_client.execute(req)
|
58
64
|
|
59
|
-
|
65
|
+
assert_requested :get, "#{@environment.base_url}/", {
|
66
|
+
:headers => {"User-Agent" => "BraintreeHttp-Ruby HTTP/1.1"},
|
67
|
+
:times => 1
|
68
|
+
}
|
60
69
|
end
|
61
70
|
|
62
71
|
it "does not overwrite User-Agent header if set" do
|
@@ -70,7 +79,24 @@ describe HttpClient do
|
|
70
79
|
|
71
80
|
http_client.execute(req)
|
72
81
|
|
73
|
-
|
82
|
+
assert_requested :get, "#{@environment.base_url}/", {
|
83
|
+
:headers => {"User-Agent" => "Not Ruby Http/1.1"},
|
84
|
+
:times => 1
|
85
|
+
}
|
86
|
+
end
|
87
|
+
|
88
|
+
it "does not modify the original request" do
|
89
|
+
WebMock.enable!
|
90
|
+
|
91
|
+
http_client = HttpClient.new(@environment)
|
92
|
+
|
93
|
+
req = OpenStruct.new({:verb => "GET", :path => "/"})
|
94
|
+
|
95
|
+
stub_request(:any, @environment.base_url)
|
96
|
+
|
97
|
+
http_client.execute(req)
|
98
|
+
|
99
|
+
expect(req.headers).to be_nil
|
74
100
|
end
|
75
101
|
|
76
102
|
it "uses body in request" do
|
@@ -210,15 +236,6 @@ describe HttpClient do
|
|
210
236
|
@verb = "POST"
|
211
237
|
@path = "/v1/api"
|
212
238
|
end
|
213
|
-
|
214
|
-
def requestBody(body)
|
215
|
-
@body = body
|
216
|
-
end
|
217
|
-
|
218
|
-
def setFile(file)
|
219
|
-
@file = file
|
220
|
-
end
|
221
|
-
|
222
239
|
end
|
223
240
|
|
224
241
|
WebMock.enable!
|
@@ -231,8 +248,6 @@ describe HttpClient do
|
|
231
248
|
rescue Exception => e
|
232
249
|
fail e.message
|
233
250
|
end
|
234
|
-
|
235
251
|
end
|
236
|
-
|
237
252
|
end
|
238
253
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: braintreehttp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Braintree
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-11-18 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Used for generated API clients
|
14
14
|
email: code@getbraintree.com
|
@@ -22,6 +22,10 @@ files:
|
|
22
22
|
- lib/braintreehttp/environment.rb
|
23
23
|
- lib/braintreehttp/errors.rb
|
24
24
|
- lib/braintreehttp/http_client.rb
|
25
|
+
- lib/braintreehttp/serializers/form_encoded.rb
|
26
|
+
- lib/braintreehttp/serializers/json.rb
|
27
|
+
- lib/braintreehttp/serializers/multipart.rb
|
28
|
+
- lib/braintreehttp/serializers/text.rb
|
25
29
|
- lib/braintreehttp/version.rb
|
26
30
|
- spec/braintreehttp/encoder_spec.rb
|
27
31
|
- spec/braintreehttp/http_client_spec.rb
|
@@ -46,7 +50,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
46
50
|
version: '0'
|
47
51
|
requirements: []
|
48
52
|
rubyforge_project: braintreehttp
|
49
|
-
rubygems_version: 2.
|
53
|
+
rubygems_version: 2.5.2
|
50
54
|
signing_key:
|
51
55
|
specification_version: 4
|
52
56
|
summary: BraintreeHttp Client Library
|