http_wrapper 2.0.0 → 2.1.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/CHANGELOG.md +95 -0
- data/Gemfile +0 -1
- data/README.md +139 -33
- data/Rakefile +1 -0
- data/lib/http_wrapper/constants.rb +16 -12
- data/lib/http_wrapper/http_wrapper.rb +37 -157
- data/lib/http_wrapper/request.rb +121 -0
- data/lib/http_wrapper/version.rb +1 -1
- data/lib/http_wrapper.rb +4 -0
- data/spec/http_wrapper_spec.rb +135 -34
- data/spec/spec_helper.rb +5 -1
- metadata +34 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a2fa8e4065e61bf929e24793f65c42273fa98884
|
4
|
+
data.tar.gz: 4e0efea520c0a5cca574430e3d8cef060004cd60
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 380fa0e02f48cb4affca5d9c74fe54352965bbd6b4630909f509ffddced19f49af661595fce73aa6387e811989ea769d0f93a5ceb31855a60600b0f15b4b7180
|
7
|
+
data.tar.gz: 833ada0ed80bd08c7d6313f6e2c07bdc4c9cdb3ee976aac359d8f44420756cbdb45bb2216e09ce8e128351fbbf687ddd625d29315f759fb561803253b3933f27
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,100 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## v2.1.0
|
4
|
+
|
5
|
+
* added ability to perform custom `Net::HTTP` requests
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
http = HTTPWrapper.new
|
9
|
+
uri = URI 'http://example.com'
|
10
|
+
|
11
|
+
# Ruby v2.0.0
|
12
|
+
request = Net::HTTP::Head.new uri
|
13
|
+
# Ruby v1.9.3
|
14
|
+
request = Net::HTTP::Head.new uri.request_uri
|
15
|
+
|
16
|
+
http.execute request, uri
|
17
|
+
```
|
18
|
+
|
19
|
+
* added ability to upload files with `multipart/form-data` content type
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
http = HTTPWrapper.new
|
23
|
+
params = {
|
24
|
+
multipart: [
|
25
|
+
# ['file input field name', 'File instance or string', {filename: 'itsfile.jpg', content_type: '...'}]
|
26
|
+
# last element is optional
|
27
|
+
['user_pic', File.open('user_pic.jpg')],
|
28
|
+
['user_photo', File.read('user_photo.jpg'), {filename: 'photo.jpg'}],
|
29
|
+
# you can also specify other parameters
|
30
|
+
['user_name', 'john griffin']
|
31
|
+
],
|
32
|
+
# or you can specify other parameters in body section
|
33
|
+
# it will be merged with multipart data
|
34
|
+
body: {
|
35
|
+
user_age: 25
|
36
|
+
}
|
37
|
+
}
|
38
|
+
response = http.post some_url, params
|
39
|
+
```
|
40
|
+
|
41
|
+
* fixed incorrect content type for `DELETE` request
|
42
|
+
* default content type changed to `text/html`
|
43
|
+
* added `:user_agent` and `:content_type` shortcuts
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
# you can specify now user agent like so:
|
47
|
+
http = HTTWrapper.new user_agent: 'custom user agent'
|
48
|
+
# - or -
|
49
|
+
http.user_agent = 'custom user agent'
|
50
|
+
http.get sample_url
|
51
|
+
# - or -
|
52
|
+
http.get sample_url, user_agent: 'custom user agent'
|
53
|
+
```
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
# you can specify now content type like so:
|
57
|
+
http.get sample_url, content_type: 'text/html'
|
58
|
+
```
|
59
|
+
|
60
|
+
* added ability to specify headers as symbols
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
http.get some_url, headers: {x_requested_with: 'XMLHttpRequest'}
|
64
|
+
# - the same as -
|
65
|
+
http.get some_url, headers: {'X-Requested-With' => 'XMLHttpRequest'}
|
66
|
+
```
|
67
|
+
|
68
|
+
* added ability to fix urls without scheme with default http scheme
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
http.get 'example.com'
|
72
|
+
# will correctly request http://example.com
|
73
|
+
```
|
74
|
+
|
75
|
+
* added `:max_redirects` option to specify redirect following limits
|
76
|
+
* added `:logger` option
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
log = Logger.new
|
80
|
+
http = HTTPWrapper.new logger: log
|
81
|
+
- or -
|
82
|
+
http.logger = $stdout
|
83
|
+
```
|
84
|
+
|
85
|
+
* massive refactoring
|
86
|
+
* `:ca_file` option removed
|
87
|
+
* `:validate_ssl_cert` option renamed to `:verify_cert`
|
88
|
+
* `soap` methods removed due to rare usage
|
89
|
+
* `:method` key removed from params
|
90
|
+
* `:params` key changed to `:query`
|
91
|
+
|
92
|
+
```ruby
|
93
|
+
http.get some_url, query: { user_id: 1, text: 'abcdefg' }
|
94
|
+
```
|
95
|
+
|
96
|
+
* fixed bug with timeout - it should be set in seconds, not microseconds
|
97
|
+
|
3
98
|
## v2.0.0
|
4
99
|
|
5
100
|
* Gem rewritten completely and renamed to 'http_wrapper'
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,12 +1,22 @@
|
|
1
1
|
# http_wrapper
|
2
2
|
|
3
|
-
Simple wrapper around standard Net::HTTP library
|
3
|
+
Simple wrapper around standard Net::HTTP library
|
4
|
+
|
5
|
+
[](http://badge.fury.io/rb/http_wrapper)
|
6
|
+
[](https://travis-ci.org/Svyatov/http_wrapper)
|
7
|
+
[](https://gemnasium.com/Svyatov/http_wrapper)
|
8
|
+
[](https://codeclimate.com/github/Svyatov/http_wrapper)
|
9
|
+
[](https://coveralls.io/r/Svyatov/http_wrapper)
|
10
|
+
|
11
|
+
---
|
4
12
|
|
5
13
|
## Installation
|
6
14
|
|
7
15
|
Add this line to your Gemfile:
|
8
16
|
|
9
|
-
|
17
|
+
```ruby
|
18
|
+
gem 'http_wrapper', '~> 2.1.0'
|
19
|
+
```
|
10
20
|
|
11
21
|
And then execute:
|
12
22
|
|
@@ -32,12 +42,26 @@ http = HTTPWrapper.new
|
|
32
42
|
|
33
43
|
### Access unprotected resource located at **some_url**:
|
34
44
|
|
35
|
-
|
45
|
+
```ruby
|
46
|
+
response = http.get some_url
|
47
|
+
|
48
|
+
# response is always an instance of Net::HTTPResponse
|
49
|
+
```
|
50
|
+
|
51
|
+
Resource is redirecting? No problem! `http_wrapper` follows up to 10 sequential redirects by default.
|
52
|
+
But you can specify your own limits.
|
36
53
|
|
37
54
|
```ruby
|
55
|
+
http.max_redirects = 5
|
38
56
|
response = http.get some_url
|
39
57
|
```
|
40
58
|
|
59
|
+
Url doesn't have scheme? `http_wrapper` prefixes url with `http://` if scheme is missing.
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
http.get 'example.com' # will correctly request 'http://example.com'
|
63
|
+
```
|
64
|
+
|
41
65
|
### Access resource protected by form-based authentication:
|
42
66
|
|
43
67
|
1. Post your credentials and get authentication cookie
|
@@ -48,7 +72,7 @@ response = http.get some_url
|
|
48
72
|
# credentials as body params
|
49
73
|
cookie = http.post_and_get_cookie some_url, body: { username: 'iamjohn', password: '$uperS1kret' }
|
50
74
|
# - or - credentials as GET query params
|
51
|
-
cookie = http.post_and_get_cookie some_url,
|
75
|
+
cookie = http.post_and_get_cookie some_url, query: { username: 'iamjohn', password: '$uperS1kret' }
|
52
76
|
```
|
53
77
|
|
54
78
|
2. Get protected resource with provided cookie
|
@@ -69,19 +93,11 @@ response = http.get 'http://example.com', auth: { login: 'iamjohn', password: 'i
|
|
69
93
|
Add special header or use special method:
|
70
94
|
|
71
95
|
```ruby
|
72
|
-
response = http.get some_url, headers: {'X-Requested-With' => 'XMLHttpRequest'}
|
73
|
-
# - or -
|
74
96
|
response = http.get_ajax some_url
|
75
|
-
```
|
76
|
-
|
77
|
-
### Access SOAP resource
|
78
|
-
|
79
|
-
Same as before, add special header or use special method:
|
80
|
-
|
81
|
-
```ruby
|
82
|
-
response = http.get some_url, headers: {'SOAPAction' => 'someSoapOperation', 'Content-Type' => 'text/xml; charset=UTF-8'}
|
83
97
|
# - or -
|
84
|
-
response = http.
|
98
|
+
response = http.get some_url, headers: {x_requested_with: 'XMLHttpRequest'}
|
99
|
+
# - or -
|
100
|
+
response = http.get some_url, headers: {'X-Requested-With' => 'XMLHttpRequest'}
|
85
101
|
```
|
86
102
|
|
87
103
|
### Access JSON resource
|
@@ -89,9 +105,13 @@ response = http.get_soap some_url
|
|
89
105
|
Same as before :)
|
90
106
|
|
91
107
|
```ruby
|
92
|
-
response = http.get some_url, headers: {'Content-Type' => 'application/json; charset=UTF-8'}
|
93
|
-
# - or -
|
94
108
|
response = http.get_json some_url
|
109
|
+
# - or -
|
110
|
+
response = http.get some_url, content_type: 'application/json; charset=UTF-8'
|
111
|
+
# - or -
|
112
|
+
response = http.get some_url, headers: {content_type: 'application/json; charset=UTF-8'}
|
113
|
+
# - or -
|
114
|
+
response = http.get some_url, headers: {'Content-Type' => 'application/json; charset=UTF-8'}
|
95
115
|
```
|
96
116
|
|
97
117
|
### Access JSON resource mimicing AJAX
|
@@ -115,34 +135,73 @@ response = http.get_json_ajax some_url, some_params
|
|
115
135
|
Don't worry about escaping, `http_wrapper` got you covered here either.
|
116
136
|
|
117
137
|
```ruby
|
118
|
-
response = http.get 'http://www.google.com',
|
138
|
+
response = http.get 'http://www.google.com', query: {message: 'Hi! M&Ms!', user: 'iamjohn'}
|
119
139
|
# => http://www.google.com/?message=Hi!%20M%26Ms!&user=iamjohn
|
120
140
|
```
|
121
141
|
|
122
142
|
Don't worry about parameters that already in URL, they'll be merged.
|
123
143
|
|
124
144
|
```ruby
|
125
|
-
response = http.get 'http://www.google.com/?q=test',
|
145
|
+
response = http.get 'http://www.google.com/?q=test', query: {user: 'iamjohn'}
|
126
146
|
# => http://www.google.com/?q=test&user=iamjohn
|
127
147
|
```
|
128
148
|
|
129
|
-
###
|
149
|
+
### Files upload
|
150
|
+
|
151
|
+
You can easily upload any number of files with `multipart/form-data` content type.
|
152
|
+
|
153
|
+
```ruby
|
154
|
+
http = HTTPWrapper.new
|
155
|
+
params = {
|
156
|
+
multipart: [
|
157
|
+
# ['file input field name', 'File instance or string', {filename: 'itsfile.jpg', content_type: '...'}]
|
158
|
+
['user_photo', File.read('user_photo.jpg'), {filename: 'photo.jpg'}],
|
159
|
+
# last element is optional
|
160
|
+
['user_pic', File.open('user_pic.jpg')],
|
161
|
+
# you can also specify other parameters
|
162
|
+
['user_name', 'john griffin']
|
163
|
+
],
|
164
|
+
# or you can specify other parameters in body section
|
165
|
+
# it will be merged with multipart data
|
166
|
+
body: {
|
167
|
+
user_age: 25
|
168
|
+
}
|
169
|
+
}
|
170
|
+
response = http.post some_url, params
|
171
|
+
```
|
172
|
+
|
173
|
+
### Set timeout
|
174
|
+
|
175
|
+
By default timeout is set to 10 seconds.
|
130
176
|
|
131
177
|
```ruby
|
132
|
-
http.timeout =
|
178
|
+
http.timeout = 5 # in seconds
|
133
179
|
# - or - on instantiation
|
134
|
-
http = HTTPWrapper.new timeout:
|
180
|
+
http = HTTPWrapper.new timeout: 5
|
181
|
+
```
|
182
|
+
|
183
|
+
### Set logger
|
184
|
+
|
185
|
+
If you need to debug your requests, it's as simple as to say to `http_wrapper` where to output debug information.
|
186
|
+
|
187
|
+
```ruby
|
188
|
+
logger = Logger.new '/path/to/log_file'
|
189
|
+
http.logger = logger
|
190
|
+
# - or -
|
191
|
+
http = HTTPWrapper.new logger: $stdout
|
192
|
+
# - to switch logger off -
|
193
|
+
http.logger = nil
|
135
194
|
```
|
136
195
|
|
137
196
|
### Work over SSL
|
138
197
|
|
139
|
-
|
198
|
+
`http_wrapper` works with SSL out of the box and by default verifying domain SSL certificate.
|
199
|
+
But you can easily turn verification off if needed.
|
140
200
|
|
141
201
|
```ruby
|
142
|
-
http.
|
143
|
-
http.ca_file = '/path/to/your/ca_file'
|
202
|
+
http.verify_cert = false
|
144
203
|
# - or - on instantiation
|
145
|
-
http = HTTPWrapper.new
|
204
|
+
http = HTTPWrapper.new verify_cert: false
|
146
205
|
```
|
147
206
|
|
148
207
|
### POST, PUT and DELETE requests
|
@@ -154,7 +213,7 @@ http.post some_url, body: {user: 'iamjohn', password: 'secret'}
|
|
154
213
|
# - or -
|
155
214
|
http.put some_url, body: {user: 'iamjohn', password: 'secret'}
|
156
215
|
# - or -
|
157
|
-
http.delete some_url,
|
216
|
+
http.delete some_url, query: {user: 'iamjohn'}
|
158
217
|
```
|
159
218
|
|
160
219
|
Default content type header for these requests is `application/x-www-form-urlencoded; charset=UTF-8`.
|
@@ -167,6 +226,33 @@ For `get_json` there are `post_json`, `put_json` and `delete_json`.
|
|
167
226
|
|
168
227
|
And for `get_ajax_json`, there are `post_ajax_json`, `put_ajax_json` and `delete_ajax_json`.
|
169
228
|
|
229
|
+
### Change User Agent
|
230
|
+
|
231
|
+
```ruby
|
232
|
+
http = HTTWrapper.new user_agent: 'custom user agent'
|
233
|
+
# - or -
|
234
|
+
http.user_agent = 'custom user agent'
|
235
|
+
http.get sample_url
|
236
|
+
# - or -
|
237
|
+
http.get sample_url, user_agent: 'custom user agent'
|
238
|
+
# - or -
|
239
|
+
http.get sample_url, headers: { user_agent: 'custom user agent' }
|
240
|
+
# the last one always replaces other definitions
|
241
|
+
```
|
242
|
+
|
243
|
+
### Perform own custom Net::HTTP requests
|
244
|
+
|
245
|
+
```ruby
|
246
|
+
uri = URI 'http://example.com'
|
247
|
+
|
248
|
+
# Ruby 2.0.0
|
249
|
+
request = Net::HTTP::Head.new uri
|
250
|
+
# Ruby 1.9.3
|
251
|
+
request = Net::HTTP::Head.new uri.request_uri
|
252
|
+
|
253
|
+
http.execute request, uri
|
254
|
+
```
|
255
|
+
|
170
256
|
### Full params hash example
|
171
257
|
|
172
258
|
```ruby
|
@@ -175,11 +261,15 @@ And for `get_ajax_json`, there are `post_ajax_json`, `put_ajax_json` and `delete
|
|
175
261
|
headers: {
|
176
262
|
'Content-Type' => 'text/html',
|
177
263
|
'X-Requested-With' => 'XMLHttpRequest',
|
178
|
-
'User-Agent' => 'Chrome v123'
|
264
|
+
'User-Agent' => 'Chrome v123',
|
265
|
+
# - or - use symbols
|
266
|
+
content_type: 'text/xml',
|
267
|
+
x_requested_with: 'XMLHttpRequest',
|
268
|
+
user_agent: 'Chrome v123'
|
179
269
|
},
|
180
270
|
|
181
271
|
# Query Parameters
|
182
|
-
|
272
|
+
query: {
|
183
273
|
user: 'iamjohn',
|
184
274
|
'user-stuff' => '123abc'
|
185
275
|
},
|
@@ -200,13 +290,29 @@ And for `get_ajax_json`, there are `post_ajax_json`, `put_ajax_json` and `delete
|
|
200
290
|
as: 'a hash'
|
201
291
|
},
|
202
292
|
|
203
|
-
#
|
204
|
-
:
|
293
|
+
# Shortcut for User-Agent header (headers hash takes precedence)
|
294
|
+
user_agent: 'UserAgent v1.2.3',
|
295
|
+
|
296
|
+
# Shortcut for Content-Type header (headers hash takes precedence)
|
297
|
+
content_type: 'text/xml',
|
298
|
+
|
299
|
+
# multipart/form-data for file uploads
|
300
|
+
# the format of array of arrays is important here!
|
301
|
+
multipart: [
|
302
|
+
# you can use File object
|
303
|
+
['file_input_name', File.open('somefile.ext')],
|
304
|
+
# - or - string and specify filename
|
305
|
+
['file_input_name', File.read('somefile.ext'), {filename: 'readme.txt'}],
|
306
|
+
# - or - full format
|
307
|
+
['file_input_name', 'some file content', {filename: 'readme.txt', content_type: 'text/text'}],
|
308
|
+
# - or - add other simple parameters
|
309
|
+
['user_name', 'john smith']
|
310
|
+
]
|
205
311
|
}
|
206
312
|
```
|
207
313
|
|
208
|
-
Don't worry if you mistype root parameters key. `http_wrapper` checks root
|
209
|
-
If any unknown options or parameters found,
|
314
|
+
Don't worry if you mistype root parameters key. `http_wrapper` checks root parameters keys and instantiation options keys.
|
315
|
+
If any unknown options or parameters found, it raises the `UnknownParameterError` exception.
|
210
316
|
|
211
317
|
## Contributing
|
212
318
|
|
data/Rakefile
CHANGED
@@ -1,16 +1,20 @@
|
|
1
1
|
class HTTPWrapper
|
2
|
-
|
3
|
-
|
2
|
+
module HEADER
|
3
|
+
CONTENT_TYPE = 'Content-Type'.freeze
|
4
|
+
USER_AGENT = 'User-Agent'.freeze
|
5
|
+
COOKIE = 'Cookie'.freeze
|
6
|
+
AJAX = 'X-Requested-With'.freeze
|
7
|
+
end
|
4
8
|
|
5
|
-
|
9
|
+
module CONTENT_TYPE
|
10
|
+
DEFAULT = 'text/html; charset=UTF-8'.freeze
|
11
|
+
JSON = 'application/json; charset=UTF-8'.freeze
|
12
|
+
POST = 'application/x-www-form-urlencoded'.freeze
|
13
|
+
MULTIPART = 'multipart/form-data'.freeze
|
14
|
+
end
|
6
15
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
HEADER_USER_AGENT = 'User-Agent'.freeze
|
12
|
-
HEADER_COOKIE = 'Cookie'.freeze
|
13
|
-
|
14
|
-
HEADER_AJAX = 'X-Requested-With'.freeze
|
15
|
-
HEADER_AJAX_VALUE = 'XMLHttpRequest'.freeze
|
16
|
+
USER_AGENT = "HTTPWrapper/#{HTTPWrapper::VERSION}; Ruby/#{RUBY_VERSION}".freeze
|
17
|
+
AJAX_HEADER = { HEADER::AJAX => 'XMLHttpRequest'.freeze }.freeze
|
18
|
+
JSON_HEADER = { HEADER::CONTENT_TYPE => CONTENT_TYPE::JSON }.freeze
|
19
|
+
AJAX_JSON_HEADER = AJAX_HEADER.dup.merge!(JSON_HEADER).freeze
|
16
20
|
end
|
@@ -1,97 +1,35 @@
|
|
1
|
-
require 'uri/common'
|
2
1
|
require 'net/https'
|
3
|
-
require_relative 'constants'
|
4
|
-
require_relative 'errors'
|
5
|
-
require_relative 'version'
|
6
2
|
|
7
3
|
class HTTPWrapper
|
8
|
-
|
4
|
+
KNOWN_OPTIONS_KEYS = [:timeout, :verify_cert, :logger, :max_redirects, :user_agent].freeze
|
9
5
|
|
10
|
-
|
11
|
-
unknown_options = options.keys - KNOWN_OPTIONS_KEYS
|
12
|
-
|
13
|
-
if unknown_options.length > 0
|
14
|
-
raise UnknownParameterError.new "Unknown options: #{unknown_options.join(', ')}"
|
15
|
-
end
|
16
|
-
|
17
|
-
@timeout = options.fetch(:timeout) { 10000 }
|
18
|
-
@ca_file = options.fetch(:ca_file) { nil }
|
19
|
-
@validate_ssl_cert = options.fetch(:validate_ssl_cert) { false }
|
20
|
-
end
|
6
|
+
attr_accessor :timeout, :verify_cert, :logger, :max_redirects, :user_agent
|
21
7
|
|
22
|
-
def
|
23
|
-
|
24
|
-
end
|
8
|
+
def initialize(options = {})
|
9
|
+
validate_options options
|
25
10
|
|
26
|
-
|
27
|
-
|
28
|
-
|
11
|
+
@timeout = options.fetch(:timeout) { 10 }
|
12
|
+
@verify_cert = options.fetch(:verify_cert) { true }
|
13
|
+
@logger = options.fetch(:logger) { nil }
|
14
|
+
@max_redirects = options.fetch(:max_redirects) { 10 }
|
15
|
+
@user_agent = options.fetch(:user_agent) { USER_AGENT }
|
29
16
|
end
|
30
17
|
|
31
|
-
[:post, :put, :delete].each do |method|
|
18
|
+
[:get, :post, :put, :delete].each do |method|
|
32
19
|
define_method method do |url, params = {}|
|
33
|
-
params
|
34
|
-
|
35
|
-
params[:method] = method
|
36
|
-
locate_response url, params
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def get_soap(url, params = {})
|
41
|
-
params = validate_parameters_and_init_headers params
|
42
|
-
params[:headers]['SOAPAction'] ||= ''
|
43
|
-
params[:headers][HEADER_CONTENT_TYPE] ||= DEFAULT_CONTENT_TYPE
|
44
|
-
locate_response url, params
|
45
|
-
end
|
46
|
-
|
47
|
-
[:post, :put, :delete].each do |method|
|
48
|
-
define_method "#{method.to_s}_soap" do |url, params = {}|
|
49
|
-
params[:method] = method
|
50
|
-
get_soap url, params
|
20
|
+
params[:user_agent] ||= @user_agent
|
21
|
+
get_response Request.new(url, method, params)
|
51
22
|
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def get_ajax(url, params = {})
|
55
|
-
params = validate_parameters_and_init_headers params
|
56
|
-
params[:headers][HEADER_AJAX] = HEADER_AJAX_VALUE
|
57
|
-
locate_response url, params
|
58
|
-
end
|
59
|
-
|
60
|
-
[:post, :put, :delete].each do |method|
|
61
|
-
define_method "#{method.to_s}_ajax" do |url, params = {}|
|
62
|
-
params[:method] = method
|
63
|
-
get_ajax url, params
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def get_json(url, params = {})
|
68
|
-
params = validate_parameters_and_init_headers params
|
69
|
-
params[:headers][HEADER_CONTENT_TYPE] = JSON_CONTENT_TYPE
|
70
|
-
locate_response url, params
|
71
|
-
end
|
72
23
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
def get_ajax_json(url, params = {})
|
81
|
-
params = validate_parameters_and_init_headers params
|
82
|
-
params[:headers][HEADER_CONTENT_TYPE] = JSON_CONTENT_TYPE
|
83
|
-
get_ajax url, params
|
84
|
-
end
|
85
|
-
|
86
|
-
[:post, :put, :delete].each do |method|
|
87
|
-
define_method "#{method.to_s}_ajax_json" do |url, params = {}|
|
88
|
-
params[:method] = method
|
89
|
-
get_ajax_json url, params
|
24
|
+
%w(ajax json ajax_json).each do |header|
|
25
|
+
define_method "#{method.to_s}_#{header}" do |url, params = {}|
|
26
|
+
params[:headers] ||= {}
|
27
|
+
params[:headers].merge! HTTPWrapper.const_get("#{header}_HEADER".upcase)
|
28
|
+
__send__ method, url, params
|
29
|
+
end
|
90
30
|
end
|
91
|
-
end
|
92
31
|
|
93
|
-
|
94
|
-
alias_method "#{method}_json_ajax", "#{method}_ajax_json"
|
32
|
+
alias_method "#{method.to_s}_json_ajax", "#{method.to_s}_ajax_json"
|
95
33
|
end
|
96
34
|
|
97
35
|
def post_and_get_cookie(url, params = {})
|
@@ -99,103 +37,45 @@ class HTTPWrapper
|
|
99
37
|
response.response['set-cookie']
|
100
38
|
end
|
101
39
|
|
40
|
+
def execute(request, uri)
|
41
|
+
connection = create_connection uri
|
42
|
+
connection.request request
|
43
|
+
end
|
44
|
+
|
102
45
|
private
|
103
46
|
|
104
|
-
def
|
105
|
-
|
106
|
-
unknown_params = params.keys - KNOWN_PARAMS_KEYS
|
47
|
+
def validate_options(options)
|
48
|
+
unknown_options = options.keys - KNOWN_OPTIONS_KEYS
|
107
49
|
|
108
|
-
if
|
109
|
-
raise UnknownParameterError.new "Unknown
|
50
|
+
if unknown_options.length > 0
|
51
|
+
raise UnknownParameterError.new "Unknown options: #{unknown_options.join(', ')}"
|
110
52
|
end
|
111
|
-
|
112
|
-
params
|
113
53
|
end
|
114
54
|
|
115
|
-
def
|
55
|
+
def get_response(request, redirects_limit = @max_redirects)
|
116
56
|
raise TooManyRedirectsError.new 'Too many redirects!' if redirects_limit == 0
|
117
57
|
|
118
|
-
response =
|
58
|
+
response = execute request.create, request.uri
|
119
59
|
|
120
60
|
if response.kind_of? Net::HTTPRedirection
|
121
|
-
|
61
|
+
request.uri = response['location']
|
62
|
+
response = get_response request, redirects_limit - 1
|
122
63
|
end
|
123
64
|
|
124
65
|
response
|
125
66
|
end
|
126
67
|
|
127
|
-
def execute_request(url, params)
|
128
|
-
params[:headers] ||= {}
|
129
|
-
params[:headers][HEADER_USER_AGENT] ||= self.class.default_user_agent
|
130
|
-
params[:headers][HEADER_CONTENT_TYPE] ||= DEFAULT_CONTENT_TYPE
|
131
|
-
params[:headers][HEADER_COOKIE] = params[:cookie] if params[:cookie]
|
132
|
-
|
133
|
-
uri = build_uri url, params[:params]
|
134
|
-
connection = create_connection uri
|
135
|
-
request = create_request uri, params
|
136
|
-
|
137
|
-
Timeout.timeout(timeout) do
|
138
|
-
connection.request(request)
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
def build_uri(url, query_params)
|
143
|
-
uri = URI url
|
144
|
-
|
145
|
-
if query_params
|
146
|
-
if uri.query && !uri.query.empty?
|
147
|
-
new_query = Hash[URI.decode_www_form(uri.query)].merge(query_params)
|
148
|
-
else
|
149
|
-
new_query = query_params
|
150
|
-
end
|
151
|
-
uri.query = URI.encode_www_form new_query
|
152
|
-
end
|
153
|
-
|
154
|
-
uri
|
155
|
-
end
|
156
|
-
|
157
68
|
def create_connection(uri)
|
158
69
|
connection = Net::HTTP.new uri.host, uri.port
|
159
|
-
connection.read_timeout = timeout
|
160
|
-
connection.open_timeout = timeout
|
70
|
+
connection.read_timeout = @timeout
|
71
|
+
connection.open_timeout = @timeout
|
161
72
|
|
162
|
-
if uri.
|
73
|
+
if uri.kind_of? URI::HTTPS
|
163
74
|
connection.use_ssl = true
|
164
|
-
|
165
|
-
if validate_ssl_cert
|
166
|
-
connection.ca_file = ca_file
|
167
|
-
connection.verify_mode = OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
|
168
|
-
else
|
169
|
-
connection.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
170
|
-
end
|
75
|
+
connection.verify_mode = OpenSSL::SSL::VERIFY_NONE unless @verify_cert
|
171
76
|
end
|
172
77
|
|
78
|
+
connection.set_debug_output(@logger)
|
173
79
|
connection
|
174
80
|
end
|
175
|
-
|
176
|
-
def create_request(uri, params)
|
177
|
-
case params[:method]
|
178
|
-
when :get
|
179
|
-
request = Net::HTTP::Get.new uri.request_uri, params[:headers]
|
180
|
-
when :post
|
181
|
-
request = Net::HTTP::Post.new uri.request_uri, params[:headers]
|
182
|
-
when :put
|
183
|
-
request = Net::HTTP::Put.new uri.request_uri, params[:headers]
|
184
|
-
when :delete
|
185
|
-
request = Net::HTTP::Delete.new uri.request_uri, params[:headers]
|
186
|
-
else
|
187
|
-
request = Net::HTTP::Get.new uri.request_uri, params[:headers]
|
188
|
-
end
|
189
|
-
|
190
|
-
if [:post, :put, :delete].include? params[:method]
|
191
|
-
request.body = params[:body] if params[:body].kind_of? String
|
192
|
-
request.set_form_data(params[:body]) if params[:body].kind_of? Hash
|
193
|
-
end
|
194
|
-
|
195
|
-
if params[:auth]
|
196
|
-
request.basic_auth params[:auth].fetch(:login), params[:auth].fetch(:password)
|
197
|
-
end
|
198
|
-
|
199
|
-
request
|
200
|
-
end
|
201
81
|
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'uri/common'
|
2
|
+
|
3
|
+
class HTTPWrapper
|
4
|
+
class Request
|
5
|
+
KNOWN_PARAMS_KEYS = [:headers, :query, :cookie, :auth, :body, :user_agent, :content_type, :multipart].freeze
|
6
|
+
|
7
|
+
def initialize(url, method, params = {})
|
8
|
+
validate_parameters params
|
9
|
+
|
10
|
+
self.uri = url
|
11
|
+
|
12
|
+
@headers = params[:headers] || {}
|
13
|
+
@query = params[:query] || {}
|
14
|
+
@cookie = params[:cookie] || @headers[HEADER::COOKIE]
|
15
|
+
@login = params[:auth] && params[:auth].fetch(:login)
|
16
|
+
@password = params[:auth] && params[:auth].fetch(:password)
|
17
|
+
|
18
|
+
@method = method
|
19
|
+
@method_class = Net::HTTP.const_get(method.to_s.capitalize)
|
20
|
+
|
21
|
+
@body = params[:body]
|
22
|
+
@user_agent = params[:user_agent]
|
23
|
+
@content_type = params[:content_type]
|
24
|
+
|
25
|
+
@multipart_data = params[:multipart] || []
|
26
|
+
|
27
|
+
initialize_headers
|
28
|
+
end
|
29
|
+
|
30
|
+
attr_reader :uri
|
31
|
+
|
32
|
+
def uri=(url)
|
33
|
+
if url.is_a? URI
|
34
|
+
@uri = url
|
35
|
+
else
|
36
|
+
url = "http://#{url}" unless url =~ /\Ahttps?:\/\//
|
37
|
+
@uri = URI.parse url
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def create
|
42
|
+
rebuild_uri_query_params
|
43
|
+
convert_symbol_headers_to_string
|
44
|
+
create_http_request
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def validate_parameters(params)
|
50
|
+
unknown_params = params.keys - KNOWN_PARAMS_KEYS
|
51
|
+
|
52
|
+
if unknown_params.length > 0
|
53
|
+
raise UnknownParameterError.new "Unknown parameters: #{unknown_params.join(', ')}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def initialize_headers
|
58
|
+
@headers[HEADER::USER_AGENT] ||= @user_agent
|
59
|
+
case @method
|
60
|
+
when :post, :put then @headers[HEADER::CONTENT_TYPE] ||= (@content_type || CONTENT_TYPE::POST)
|
61
|
+
else @headers[HEADER::CONTENT_TYPE] ||= (@content_type || CONTENT_TYPE::DEFAULT)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def rebuild_uri_query_params
|
66
|
+
return unless @query.size > 0
|
67
|
+
query = @uri.query ? query_to_hash(@uri.query).merge(@query) : @query
|
68
|
+
@uri.query = URI.encode_www_form query
|
69
|
+
end
|
70
|
+
|
71
|
+
def convert_symbol_headers_to_string
|
72
|
+
@headers.keys.select{|key| key.is_a? Symbol}.each do |key|
|
73
|
+
str_key = key.to_s.gsub(/_/, '-').capitalize
|
74
|
+
@headers[str_key] = @headers.delete key
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def create_http_request
|
79
|
+
# Ruby v1.9.3 doesn't understand full URI object, it needs just path :(
|
80
|
+
uri = RUBY_VERSION =~ /\A2/ ? @uri : @uri.request_uri
|
81
|
+
@request = @method_class.new uri, @headers
|
82
|
+
set_cookies
|
83
|
+
set_body
|
84
|
+
set_basic_auth
|
85
|
+
@request
|
86
|
+
end
|
87
|
+
|
88
|
+
def set_body
|
89
|
+
return unless @request.request_body_permitted?
|
90
|
+
if @multipart_data.length > 0
|
91
|
+
convert_body_to_multipart_data if @body
|
92
|
+
@request.set_form @multipart_data, CONTENT_TYPE::MULTIPART
|
93
|
+
elsif @body
|
94
|
+
@request.body = @body.is_a?(Hash) ? hash_to_query(@body) : @body
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def set_basic_auth
|
99
|
+
return unless @login
|
100
|
+
@request.basic_auth @login, @password
|
101
|
+
end
|
102
|
+
|
103
|
+
def set_cookies
|
104
|
+
return unless @cookie
|
105
|
+
@request['Cookie'] = @cookie
|
106
|
+
end
|
107
|
+
|
108
|
+
def convert_body_to_multipart_data
|
109
|
+
@body = query_to_hash(@body) unless @body.kind_of? Hash
|
110
|
+
@body.each{|key, value| @multipart_data << [key.to_s, value.to_s]}
|
111
|
+
end
|
112
|
+
|
113
|
+
def query_to_hash(query)
|
114
|
+
Hash[URI.decode_www_form query]
|
115
|
+
end
|
116
|
+
|
117
|
+
def hash_to_query(hash)
|
118
|
+
URI.encode_www_form hash
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
data/lib/http_wrapper/version.rb
CHANGED
data/lib/http_wrapper.rb
CHANGED
data/spec/http_wrapper_spec.rb
CHANGED
@@ -8,7 +8,6 @@ describe HTTPWrapper do
|
|
8
8
|
|
9
9
|
it 'should define all dynamic methods' do
|
10
10
|
[:get, :post, :put, :delete,
|
11
|
-
:get_soap, :post_soap, :put_soap, :delete_soap,
|
12
11
|
:get_json, :post_json, :put_json, :delete_json,
|
13
12
|
:get_ajax, :post_ajax, :put_ajax, :delete_ajax,
|
14
13
|
:get_ajax_json, :post_ajax_json, :put_ajax_json, :delete_ajax_json,
|
@@ -21,66 +20,134 @@ describe HTTPWrapper do
|
|
21
20
|
let(:sample_url) { 'http://example.com' }
|
22
21
|
let(:sample_url_with_basic_auth) { "http://#{basic_auth_login}:#{basic_auth_password}@example.com" }
|
23
22
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
23
|
+
context 'Options' do
|
24
|
+
it 'should raise UnknownParameterError if initial options key is unknown' do
|
25
|
+
expect do
|
26
|
+
HTTPWrapper.new unknown_option: 'test', maybe_this_known: '?'
|
27
|
+
end.to raise_error HTTPWrapper::UnknownParameterError, 'Unknown options: unknown_option, maybe_this_known'
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should raise UnknownParameterError if params key is unknown' do
|
31
|
+
expect do
|
32
|
+
subject.get sample_url, unknown_param_key: 'test', another_param_key: 'wow'
|
33
|
+
end.to raise_error HTTPWrapper::UnknownParameterError, 'Unknown parameters: unknown_param_key, another_param_key'
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should follow redirects no more then 10 times by default' do
|
37
|
+
stub_redirects sample_url, 9
|
38
|
+
response = subject.get sample_url
|
39
|
+
response.code.should eql '200'
|
40
|
+
|
41
|
+
stub_redirects sample_url, 10
|
42
|
+
expect { subject.get sample_url }.to raise_error HTTPWrapper::TooManyRedirectsError, 'Too many redirects!'
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should follow redirects no more times then specified' do
|
46
|
+
subject.max_redirects = 5
|
29
47
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
48
|
+
stub_redirects sample_url, 4
|
49
|
+
response = subject.get sample_url
|
50
|
+
response.code.should eql '200'
|
51
|
+
|
52
|
+
stub_redirects sample_url, 5
|
53
|
+
expect { subject.get sample_url }.to raise_error HTTPWrapper::TooManyRedirectsError, 'Too many redirects!'
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should use logger' do
|
57
|
+
require 'logger'
|
58
|
+
logger = Logger.new StringIO.new
|
59
|
+
logger.should_receive(:<<).at_least(:once)
|
60
|
+
subject.logger = logger
|
61
|
+
|
62
|
+
WebMock.allow_net_connect!
|
63
|
+
begin
|
64
|
+
subject.get 'localhost'
|
65
|
+
rescue
|
66
|
+
# NOOP, rescue from "connection refused" and such
|
67
|
+
end
|
68
|
+
WebMock.disable_net_connect!
|
69
|
+
end
|
34
70
|
end
|
35
71
|
|
36
72
|
context 'GET' do
|
73
|
+
it 'should add http uri scheme if missing' do
|
74
|
+
stub_get sample_url
|
75
|
+
subject.get sample_url.gsub(/\Ahttp:\/\//, '')
|
76
|
+
end
|
77
|
+
|
37
78
|
it 'should hit provided url with default content type' do
|
38
|
-
params = { headers: {HTTPWrapper::
|
79
|
+
params = { headers: {HTTPWrapper::HEADER::CONTENT_TYPE => HTTPWrapper::CONTENT_TYPE::DEFAULT} }
|
39
80
|
stub_get sample_url, params
|
40
81
|
subject.get sample_url
|
41
82
|
end
|
42
83
|
|
43
84
|
it 'should set content type if provided' do
|
44
|
-
params = { headers: {HTTPWrapper::
|
85
|
+
params = { headers: {HTTPWrapper::HEADER::CONTENT_TYPE => 'Custom Content Type'} }
|
45
86
|
stub_get sample_url, params
|
46
87
|
subject.get sample_url, params
|
88
|
+
subject.get sample_url, content_type: 'Custom Content Type'
|
89
|
+
subject.get sample_url, params.merge({content_type: 'Should Be Overwritten'})
|
47
90
|
end
|
48
91
|
|
49
92
|
it 'should set proper header for JSON requests' do
|
50
|
-
params = { headers:
|
93
|
+
params = { headers: HTTPWrapper::JSON_HEADER }
|
51
94
|
stub_get sample_url, params
|
52
95
|
subject.get_json sample_url
|
53
96
|
end
|
54
97
|
|
55
98
|
it 'should set proper header for AJAX requests' do
|
56
|
-
params = {
|
57
|
-
|
99
|
+
params = {
|
100
|
+
headers: {
|
101
|
+
HTTPWrapper::HEADER::CONTENT_TYPE => HTTPWrapper::CONTENT_TYPE::DEFAULT
|
102
|
+
}.merge(HTTPWrapper::AJAX_HEADER)
|
103
|
+
}
|
58
104
|
stub_get sample_url, params
|
59
105
|
subject.get_ajax sample_url
|
60
106
|
end
|
61
107
|
|
62
108
|
it 'should set proper headers for AJAX-JSON requests' do
|
63
|
-
params = { headers:
|
64
|
-
HTTPWrapper::HEADER_CONTENT_TYPE => HTTPWrapper::JSON_CONTENT_TYPE } }
|
109
|
+
params = { headers: HTTPWrapper::AJAX_JSON_HEADER }
|
65
110
|
stub_get sample_url, params
|
66
111
|
subject.get_ajax_json sample_url
|
67
112
|
end
|
68
113
|
|
69
114
|
it 'should correctly escape query parameters' do
|
70
115
|
stub_get sample_url + '/?param1=¶m2=A%26B¶m3=C%20%26%20D'
|
71
|
-
subject.get sample_url,
|
116
|
+
subject.get sample_url, query: {param1: '', param2: 'A&B', param3: 'C & D'}
|
72
117
|
end
|
73
118
|
|
74
119
|
it 'should set default user agent' do
|
75
|
-
params = { headers: {HTTPWrapper::
|
120
|
+
params = { headers: {HTTPWrapper::HEADER::USER_AGENT => HTTPWrapper::USER_AGENT} }
|
76
121
|
stub_get sample_url, params
|
77
122
|
subject.get sample_url
|
78
123
|
end
|
79
124
|
|
80
125
|
it 'should change user agent if provided' do
|
81
126
|
custom_user_agent = 'Mozilla v1.2.3'
|
82
|
-
params = { headers: {HTTPWrapper::
|
127
|
+
params = { headers: {HTTPWrapper::HEADER::USER_AGENT => custom_user_agent} }
|
128
|
+
stub_get sample_url, params
|
129
|
+
subject.get sample_url, params
|
130
|
+
|
131
|
+
subject.get sample_url, user_agent: custom_user_agent
|
132
|
+
|
133
|
+
subject.user_agent = custom_user_agent
|
134
|
+
subject.get sample_url
|
135
|
+
|
136
|
+
expect do
|
137
|
+
subject.get sample_url, user_agent: 'abracadabra'
|
138
|
+
end.to raise_error WebMock::NetConnectNotAllowedError
|
139
|
+
|
140
|
+
expect do
|
141
|
+
subject.user_agent = 'another test'
|
142
|
+
subject.get sample_url
|
143
|
+
end.to raise_error WebMock::NetConnectNotAllowedError
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'should precedence header user agent before params' do
|
147
|
+
params = { headers: {HTTPWrapper::HEADER::USER_AGENT => 'TestUserAgent'} }
|
83
148
|
stub_get sample_url, params
|
149
|
+
|
150
|
+
subject.user_agent = 'Should Be Overwritten'
|
84
151
|
subject.get sample_url, params
|
85
152
|
end
|
86
153
|
|
@@ -97,24 +164,20 @@ describe HTTPWrapper do
|
|
97
164
|
subject.get sample_url, auth: {login: basic_auth_login, password: basic_auth_password}
|
98
165
|
end
|
99
166
|
|
100
|
-
it 'should follow redirects no more then 10 times' do
|
101
|
-
stub_redirects sample_url, 9
|
102
|
-
response = subject.get sample_url
|
103
|
-
response.code.should eql '200'
|
104
|
-
|
105
|
-
stub_redirects sample_url, 10
|
106
|
-
expect { subject.get sample_url }.to raise_error HTTPWrapper::TooManyRedirectsError, 'Too many redirects!'
|
107
|
-
end
|
108
|
-
|
109
167
|
it 'should merge query parameters and params should take precedence' do
|
110
168
|
stub_get sample_url + '/?text=edf&time=16:44&user=test'
|
111
|
-
subject.get(sample_url + '/?user=test&text=abc',
|
169
|
+
subject.get(sample_url + '/?user=test&text=abc', query: {time: '16:44', text: 'edf'})
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'should equally treat header as string and header as symbol' do
|
173
|
+
stub_get sample_url, { headers: {'Content-Type' => 'Some Content Type'} }
|
174
|
+
subject.get sample_url, { headers: {content_type: 'Some Content Type'} }
|
112
175
|
end
|
113
176
|
end
|
114
177
|
|
115
178
|
context 'POST' do
|
116
179
|
it 'should set content type if provided' do
|
117
|
-
params = { headers: {HTTPWrapper::
|
180
|
+
params = { headers: {HTTPWrapper::HEADER::CONTENT_TYPE => 'Custom Content Type'} }
|
118
181
|
stub_post sample_url, params
|
119
182
|
subject.post sample_url, params
|
120
183
|
end
|
@@ -128,15 +191,37 @@ describe HTTPWrapper do
|
|
128
191
|
end
|
129
192
|
|
130
193
|
it 'should hit provided url with default content type' do
|
131
|
-
params = { headers: {HTTPWrapper::
|
194
|
+
params = { headers: {HTTPWrapper::HEADER::CONTENT_TYPE => HTTPWrapper::CONTENT_TYPE::POST } }
|
132
195
|
stub_post sample_url, params
|
133
196
|
subject.post sample_url
|
134
197
|
end
|
198
|
+
|
199
|
+
it 'should set all possible parameters correctly' do
|
200
|
+
stub_request(:post, 'http://user:passw@example.com/?a=b&c=d').
|
201
|
+
with(body: {
|
202
|
+
e: 'f',
|
203
|
+
g: 'k'
|
204
|
+
},
|
205
|
+
headers: {
|
206
|
+
'Content-Type' => 'Custom content type',
|
207
|
+
'User-Agent' => 'Custom user agent',
|
208
|
+
'Cookie' => 'cookie',
|
209
|
+
'X-Requested-With' => 'XMLHttpRequest'
|
210
|
+
})
|
211
|
+
|
212
|
+
subject.post sample_url, content_type: 'Custom content type',
|
213
|
+
user_agent: 'Custom user agent',
|
214
|
+
headers: {x_requested_with: 'XMLHttpRequest'},
|
215
|
+
query: {a: 'b', c: 'd'},
|
216
|
+
body: {e: 'f', g: 'k'},
|
217
|
+
auth: {login: 'user', password: 'passw'},
|
218
|
+
cookie: 'cookie'
|
219
|
+
end
|
135
220
|
end
|
136
221
|
|
137
222
|
context 'PUT' do
|
138
223
|
it 'should hit provided url with default content type' do
|
139
|
-
params = { headers: {HTTPWrapper::
|
224
|
+
params = { headers: {HTTPWrapper::HEADER::CONTENT_TYPE => HTTPWrapper::CONTENT_TYPE::POST } }
|
140
225
|
stub_put sample_url, params
|
141
226
|
subject.put sample_url
|
142
227
|
end
|
@@ -144,11 +229,27 @@ describe HTTPWrapper do
|
|
144
229
|
|
145
230
|
context 'DELETE' do
|
146
231
|
it 'should hit provided url with default content type' do
|
147
|
-
params = { headers: {HTTPWrapper::
|
232
|
+
params = { headers: {HTTPWrapper::HEADER::CONTENT_TYPE => HTTPWrapper::CONTENT_TYPE::DEFAULT } }
|
148
233
|
stub_delete sample_url, params
|
149
234
|
subject.delete sample_url
|
150
235
|
end
|
151
236
|
end
|
237
|
+
|
238
|
+
context 'Custom request instance' do
|
239
|
+
it 'should perform request for custom Net::HTTP request instance' do
|
240
|
+
stub_request :head, sample_url
|
241
|
+
uri = URI sample_url
|
242
|
+
|
243
|
+
if RUBY_VERSION =~ /\A2/
|
244
|
+
request = Net::HTTP::Head.new uri
|
245
|
+
subject.execute request, request.uri
|
246
|
+
else
|
247
|
+
# Ruby v1.9.3 doesn't understand full URI object, it needs just path :(
|
248
|
+
request = Net::HTTP::Head.new uri.request_uri
|
249
|
+
subject.execute request, uri
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
152
253
|
end
|
153
254
|
|
154
255
|
context 'HTTPS' do
|
data/spec/spec_helper.rb
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
require 'rspec'
|
2
2
|
require 'webmock/rspec'
|
3
3
|
|
4
|
+
if ENV['TRAVIS'] == 'true'
|
5
|
+
require 'coveralls'
|
6
|
+
Coveralls.wear!
|
7
|
+
end
|
8
|
+
|
4
9
|
$LOAD_PATH.unshift File.expand_path('../lib', File.dirname(__FILE__))
|
5
10
|
|
6
11
|
module HTTPWrapperSpecHelpers
|
@@ -23,6 +28,5 @@ module HTTPWrapperSpecHelpers
|
|
23
28
|
end
|
24
29
|
|
25
30
|
RSpec.configure do |config|
|
26
|
-
config.mock_with :mocha
|
27
31
|
config.include HTTPWrapperSpecHelpers
|
28
32
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: http_wrapper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Leonid Svyatov
|
@@ -9,8 +9,36 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-09-
|
12
|
+
date: 2013-09-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ~>
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '1.3'
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ~>
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '1.3'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rake
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ~>
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '10.1'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ~>
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '10.1'
|
14
42
|
- !ruby/object:Gem::Dependency
|
15
43
|
name: rspec
|
16
44
|
requirement: !ruby/object:Gem::Requirement
|
@@ -39,8 +67,8 @@ dependencies:
|
|
39
67
|
- - ~>
|
40
68
|
- !ruby/object:Gem::Version
|
41
69
|
version: 1.13.0
|
42
|
-
description: Simple wrapper around standard Net::HTTP library
|
43
|
-
|
70
|
+
description: Simple wrapper around standard Net::HTTP library with multipart/form-data
|
71
|
+
file upload ability
|
44
72
|
email: leonid@svyatov.ru
|
45
73
|
executables: []
|
46
74
|
extensions: []
|
@@ -54,6 +82,7 @@ files:
|
|
54
82
|
- lib/http_wrapper/constants.rb
|
55
83
|
- lib/http_wrapper/errors.rb
|
56
84
|
- lib/http_wrapper/http_wrapper.rb
|
85
|
+
- lib/http_wrapper/request.rb
|
57
86
|
- lib/http_wrapper/version.rb
|
58
87
|
- lib/http_wrapper.rb
|
59
88
|
- spec/http_wrapper_spec.rb
|
@@ -78,7 +107,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
78
107
|
version: '0'
|
79
108
|
requirements: []
|
80
109
|
rubyforge_project:
|
81
|
-
rubygems_version: 2.
|
110
|
+
rubygems_version: 2.1.4
|
82
111
|
signing_key:
|
83
112
|
specification_version: 4
|
84
113
|
summary: Simple wrapper around standard Net::HTTP library
|