http_wrapper 2.0.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 +7 -0
- data/CHANGELOG.md +45 -0
- data/Gemfile +3 -0
- data/LICENSE +23 -0
- data/README.md +217 -0
- data/Rakefile +11 -0
- data/lib/http_wrapper/constants.rb +16 -0
- data/lib/http_wrapper/errors.rb +5 -0
- data/lib/http_wrapper/http_wrapper.rb +201 -0
- data/lib/http_wrapper/version.rb +3 -0
- data/lib/http_wrapper.rb +1 -0
- data/spec/http_wrapper_spec.rb +163 -0
- data/spec/spec_helper.rb +28 -0
- metadata +87 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 425cf2e9d257f1b5fa7740175a8f73cb016c3a30
|
4
|
+
data.tar.gz: ac5befa4cc51dd8ea3370a6ab86bbcb145c37a54
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5d7ea56a231b668b36017f6f0b12aeab2c76ad83fad1618e6e25736f394445c6537cef1f19d96611408bec41acff5883189308dd93477cd5322e40e9bf6519b2
|
7
|
+
data.tar.gz: 9b5d9c375e60c37f658a33b54eb4ef4cec6892ce50e36e5399c93bcf7d397f2f3f536e192c2e9189ce35be7ecc0984c6b866c21b65e2815426756c9abbfacbd3
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
## v2.0.0
|
4
|
+
|
5
|
+
* Gem rewritten completely and renamed to 'http_wrapper'
|
6
|
+
* `#get_response` now simply `#get`
|
7
|
+
* `#get_ajax_response` now `#get_ajax`
|
8
|
+
* `#get_soap_response` now `#get_soap`
|
9
|
+
* `#get_json_response` now `#get_json`
|
10
|
+
* `#get_cookie` now `#post_and_get_cookie`
|
11
|
+
* new methods `#post`, `#put`, `#delete`,
|
12
|
+
* new methods `#get_ajax_json`, `#post_ajax_json`, `#put_ajax_json`, `#delete_ajax_json`
|
13
|
+
* new methods `#post_[ajax|soap|json]`, `#put_[ajax|soap|json]`, `#delete_[ajax|soap|json]`
|
14
|
+
* class constructor now use options hash as a parameter instead of separate parameters
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
# was
|
18
|
+
accessor = ResourceAccessor.new(5000, '/path/to/ca_file', true)
|
19
|
+
# now
|
20
|
+
http = HTTWrapper.new(timeout: 5000, ca_file: '/path/to/ca_file', validate_ssl_cert: true)
|
21
|
+
```
|
22
|
+
|
23
|
+
* methods signature changed to `method(url, params)`
|
24
|
+
* development gem dependencies reduced
|
25
|
+
* tests rewritten completely using `webmock` gem
|
26
|
+
* changelog order reversed
|
27
|
+
* changelog file renamed to `CHANGELOG.md`
|
28
|
+
|
29
|
+
## v1.1.1
|
30
|
+
|
31
|
+
* Adding query parameter
|
32
|
+
* Adding specs
|
33
|
+
|
34
|
+
## v1.1.0
|
35
|
+
|
36
|
+
* Write documentation
|
37
|
+
* API change
|
38
|
+
|
39
|
+
## v1.0.1
|
40
|
+
|
41
|
+
* Bug fix
|
42
|
+
|
43
|
+
## v1.0.0
|
44
|
+
|
45
|
+
* Initial release
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
Copyright (c) 2013 Leonid Svyatov
|
2
|
+
Copyright (c) 2012 Alexander Shvets
|
3
|
+
|
4
|
+
MIT License
|
5
|
+
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
7
|
+
a copy of this software and associated documentation files (the
|
8
|
+
"Software"), to deal in the Software without restriction, including
|
9
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
10
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
11
|
+
permit persons to whom the Software is furnished to do so, subject to
|
12
|
+
the following conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be
|
15
|
+
included in all copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
18
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
19
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
20
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
21
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
22
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
23
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,217 @@
|
|
1
|
+
# http_wrapper
|
2
|
+
|
3
|
+
Simple wrapper around standard Net::HTTP library to simplify common http[s] tasks usage
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your Gemfile:
|
8
|
+
|
9
|
+
gem 'http_wrapper', '~> 2.0.0'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it manually:
|
16
|
+
|
17
|
+
$ gem install http_wrapper
|
18
|
+
|
19
|
+
And require it in you code:
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
require 'http_wrapper'
|
23
|
+
```
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
Create wrapper object:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
http = HTTPWrapper.new
|
31
|
+
```
|
32
|
+
|
33
|
+
### Access unprotected resource located at **some_url**:
|
34
|
+
|
35
|
+
Resource is redirecting? No problem! `http_wrapper` follows up to 10 sequential redirects (you cannot change that limit yet).
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
response = http.get some_url
|
39
|
+
```
|
40
|
+
|
41
|
+
### Access resource protected by form-based authentication:
|
42
|
+
|
43
|
+
1. Post your credentials and get authentication cookie
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
# 'username' and 'password' fields are examples, it's just query parameters
|
47
|
+
|
48
|
+
# credentials as body params
|
49
|
+
cookie = http.post_and_get_cookie some_url, body: { username: 'iamjohn', password: '$uperS1kret' }
|
50
|
+
# - or - credentials as GET query params
|
51
|
+
cookie = http.post_and_get_cookie some_url, params: { username: 'iamjohn', password: '$uperS1kret' }
|
52
|
+
```
|
53
|
+
|
54
|
+
2. Get protected resource with provided cookie
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
response = http.get some_url, cookie: cookie
|
58
|
+
```
|
59
|
+
|
60
|
+
### Access resource protected by basic access authentication:
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
response = http.get 'http://example.com', auth: { login: 'iamjohn', password: 'iamnotjohn' }
|
64
|
+
# => http://iamjohn:iamnotjohn@example.com
|
65
|
+
```
|
66
|
+
|
67
|
+
### Access resource mimicing AJAX
|
68
|
+
|
69
|
+
Add special header or use special method:
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
response = http.get some_url, headers: {'X-Requested-With' => 'XMLHttpRequest'}
|
73
|
+
# - or -
|
74
|
+
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
|
+
# - or -
|
84
|
+
response = http.get_soap some_url
|
85
|
+
```
|
86
|
+
|
87
|
+
### Access JSON resource
|
88
|
+
|
89
|
+
Same as before :)
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
response = http.get some_url, headers: {'Content-Type' => 'application/json; charset=UTF-8'}
|
93
|
+
# - or -
|
94
|
+
response = http.get_json some_url
|
95
|
+
```
|
96
|
+
|
97
|
+
### Access JSON resource mimicing AJAX
|
98
|
+
|
99
|
+
Just use special method :) (which sets `X-Requested-With` and `Content-Type` headers for you)
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
response = http.get_ajax_json some_url, some_params
|
103
|
+
```
|
104
|
+
|
105
|
+
Difficult to remember what goes after what: `get_ajax_json` or `get_json_ajax`?
|
106
|
+
`http_wrapper` got you covered. They both work, use whatever variant you like better.
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
# the same as above
|
110
|
+
response = http.get_json_ajax some_url, some_params
|
111
|
+
```
|
112
|
+
|
113
|
+
### Provide additional query parameters
|
114
|
+
|
115
|
+
Don't worry about escaping, `http_wrapper` got you covered here either.
|
116
|
+
|
117
|
+
```ruby
|
118
|
+
response = http.get 'http://www.google.com', params: {message: 'Hi! M&Ms!', user: 'iamjohn'}
|
119
|
+
# => http://www.google.com/?message=Hi!%20M%26Ms!&user=iamjohn
|
120
|
+
```
|
121
|
+
|
122
|
+
Don't worry about parameters that already in URL, they'll be merged.
|
123
|
+
|
124
|
+
```ruby
|
125
|
+
response = http.get 'http://www.google.com/?q=test', params: {user: 'iamjohn'}
|
126
|
+
# => http://www.google.com/?q=test&user=iamjohn
|
127
|
+
```
|
128
|
+
|
129
|
+
### Set timeout for wrapper:
|
130
|
+
|
131
|
+
```ruby
|
132
|
+
http.timeout = 10000 # in milliseconds
|
133
|
+
# - or - on instantiation
|
134
|
+
http = HTTPWrapper.new timeout: 10000
|
135
|
+
```
|
136
|
+
|
137
|
+
### Work over SSL
|
138
|
+
|
139
|
+
To work over SSL enable certificate validation before any calls:
|
140
|
+
|
141
|
+
```ruby
|
142
|
+
http.validate_ssl_cert = true
|
143
|
+
http.ca_file = '/path/to/your/ca_file'
|
144
|
+
# - or - on instantiation
|
145
|
+
http = HTTPWrapper.new ca_file: '/path/to/your/ca_file', validate_ssl_cert: true
|
146
|
+
```
|
147
|
+
|
148
|
+
### POST, PUT and DELETE requests
|
149
|
+
|
150
|
+
On each `get` method there are `post`, `put` and `delete` methods. Examples:
|
151
|
+
|
152
|
+
```ruby
|
153
|
+
http.post some_url, body: {user: 'iamjohn', password: 'secret'}
|
154
|
+
# - or -
|
155
|
+
http.put some_url, body: {user: 'iamjohn', password: 'secret'}
|
156
|
+
# - or -
|
157
|
+
http.delete some_url, params: {user: 'iamjohn'}
|
158
|
+
```
|
159
|
+
|
160
|
+
Default content type header for these requests is `application/x-www-form-urlencoded; charset=UTF-8`.
|
161
|
+
|
162
|
+
So for `get_ajax` there are `post_ajax`, `put_ajax` and `delete_ajax`.
|
163
|
+
|
164
|
+
For `get_soap` there are `post_soap`, `put_soap` and `delete_soap`.
|
165
|
+
|
166
|
+
For `get_json` there are `post_json`, `put_json` and `delete_json`.
|
167
|
+
|
168
|
+
And for `get_ajax_json`, there are `post_ajax_json`, `put_ajax_json` and `delete_ajax_json`.
|
169
|
+
|
170
|
+
### Full params hash example
|
171
|
+
|
172
|
+
```ruby
|
173
|
+
{
|
174
|
+
# Request Headers
|
175
|
+
headers: {
|
176
|
+
'Content-Type' => 'text/html',
|
177
|
+
'X-Requested-With' => 'XMLHttpRequest',
|
178
|
+
'User-Agent' => 'Chrome v123'
|
179
|
+
},
|
180
|
+
|
181
|
+
# Query Parameters
|
182
|
+
params: {
|
183
|
+
user: 'iamjohn',
|
184
|
+
'user-stuff' => '123abc'
|
185
|
+
},
|
186
|
+
|
187
|
+
# Cookie
|
188
|
+
cookie: 'all cookies in one string',
|
189
|
+
|
190
|
+
# Basic authentication credentials
|
191
|
+
auth: {
|
192
|
+
login: 'iamjohn',
|
193
|
+
password: 'secret'
|
194
|
+
},
|
195
|
+
|
196
|
+
# Request body
|
197
|
+
body: 'as a string',
|
198
|
+
# - or -
|
199
|
+
body: {
|
200
|
+
as: 'a hash'
|
201
|
+
},
|
202
|
+
|
203
|
+
# Request method - :get, :post, :put, :delete
|
204
|
+
:method => :get
|
205
|
+
}
|
206
|
+
```
|
207
|
+
|
208
|
+
Don't worry if you mistype root parameters key. `http_wrapper` checks root params keys and instantiation options keys.
|
209
|
+
If any unknown options or parameters found, they raise the `UnknownParameterError` exception.
|
210
|
+
|
211
|
+
## Contributing
|
212
|
+
|
213
|
+
1. Fork it
|
214
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
215
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
216
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
217
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
class HTTPWrapper
|
2
|
+
KNOWN_OPTIONS_KEYS = [:timeout, :ca_file, :validate_ssl_cert].freeze
|
3
|
+
KNOWN_PARAMS_KEYS = [:headers, :params, :cookie, :auth, :body, :method].freeze
|
4
|
+
|
5
|
+
HEADER_CONTENT_TYPE = 'Content-Type'.freeze
|
6
|
+
|
7
|
+
DEFAULT_CONTENT_TYPE = 'text/xml; charset=UTF-8'.freeze
|
8
|
+
JSON_CONTENT_TYPE = 'application/json; charset=UTF-8'.freeze
|
9
|
+
POST_CONTENT_TYPE = 'application/x-www-form-urlencoded; charset=UTF-8'.freeze
|
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
|
+
end
|
@@ -0,0 +1,201 @@
|
|
1
|
+
require 'uri/common'
|
2
|
+
require 'net/https'
|
3
|
+
require_relative 'constants'
|
4
|
+
require_relative 'errors'
|
5
|
+
require_relative 'version'
|
6
|
+
|
7
|
+
class HTTPWrapper
|
8
|
+
attr_accessor :timeout, :ca_file, :validate_ssl_cert
|
9
|
+
|
10
|
+
def initialize(options = {})
|
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
|
21
|
+
|
22
|
+
def self.default_user_agent
|
23
|
+
"HTTPWrapper/#{VERSION}; Ruby/#{RUBY_VERSION}"
|
24
|
+
end
|
25
|
+
|
26
|
+
def get(url, params = {})
|
27
|
+
params = validate_parameters_and_init_headers params
|
28
|
+
locate_response url, params
|
29
|
+
end
|
30
|
+
|
31
|
+
[:post, :put, :delete].each do |method|
|
32
|
+
define_method method do |url, params = {}|
|
33
|
+
params = validate_parameters_and_init_headers params
|
34
|
+
params[:headers][HEADER_CONTENT_TYPE] ||= POST_CONTENT_TYPE
|
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
|
51
|
+
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
|
+
|
73
|
+
[:post, :put, :delete].each do |method|
|
74
|
+
define_method "#{method.to_s}_json" do |url, params = {}|
|
75
|
+
params[:method] = method
|
76
|
+
get_json url, params
|
77
|
+
end
|
78
|
+
end
|
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
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
%w(get post put delete).each do |method|
|
94
|
+
alias_method "#{method}_json_ajax", "#{method}_ajax_json"
|
95
|
+
end
|
96
|
+
|
97
|
+
def post_and_get_cookie(url, params = {})
|
98
|
+
response = post url, params
|
99
|
+
response.response['set-cookie']
|
100
|
+
end
|
101
|
+
|
102
|
+
private
|
103
|
+
|
104
|
+
def validate_parameters_and_init_headers(params)
|
105
|
+
params[:headers] ||= {}
|
106
|
+
unknown_params = params.keys - KNOWN_PARAMS_KEYS
|
107
|
+
|
108
|
+
if unknown_params.length > 0
|
109
|
+
raise UnknownParameterError.new "Unknown parameters: #{unknown_params.join(', ')}"
|
110
|
+
end
|
111
|
+
|
112
|
+
params
|
113
|
+
end
|
114
|
+
|
115
|
+
def locate_response(url, params, redirects_limit = 10)
|
116
|
+
raise TooManyRedirectsError.new 'Too many redirects!' if redirects_limit == 0
|
117
|
+
|
118
|
+
response = execute_request url, params
|
119
|
+
|
120
|
+
if response.kind_of? Net::HTTPRedirection
|
121
|
+
response = locate_response response['location'], params, redirects_limit - 1
|
122
|
+
end
|
123
|
+
|
124
|
+
response
|
125
|
+
end
|
126
|
+
|
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
|
+
def create_connection(uri)
|
158
|
+
connection = Net::HTTP.new uri.host, uri.port
|
159
|
+
connection.read_timeout = timeout
|
160
|
+
connection.open_timeout = timeout
|
161
|
+
|
162
|
+
if uri.scheme == 'https'
|
163
|
+
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
|
171
|
+
end
|
172
|
+
|
173
|
+
connection
|
174
|
+
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
|
+
end
|
data/lib/http_wrapper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'http_wrapper/http_wrapper'
|
@@ -0,0 +1,163 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
require 'http_wrapper'
|
4
|
+
|
5
|
+
describe HTTPWrapper do
|
6
|
+
let(:basic_auth_login) { 'balogin' }
|
7
|
+
let(:basic_auth_password) { 'bapassword' }
|
8
|
+
|
9
|
+
it 'should define all dynamic methods' do
|
10
|
+
[:get, :post, :put, :delete,
|
11
|
+
:get_soap, :post_soap, :put_soap, :delete_soap,
|
12
|
+
:get_json, :post_json, :put_json, :delete_json,
|
13
|
+
:get_ajax, :post_ajax, :put_ajax, :delete_ajax,
|
14
|
+
:get_ajax_json, :post_ajax_json, :put_ajax_json, :delete_ajax_json,
|
15
|
+
:get_json_ajax, :post_json_ajax, :put_json_ajax, :delete_json_ajax].each do |method|
|
16
|
+
subject.should be_respond_to method
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'HTTP' do
|
21
|
+
let(:sample_url) { 'http://example.com' }
|
22
|
+
let(:sample_url_with_basic_auth) { "http://#{basic_auth_login}:#{basic_auth_password}@example.com" }
|
23
|
+
|
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
|
+
context 'GET' do
|
37
|
+
it 'should hit provided url with default content type' do
|
38
|
+
params = { headers: {HTTPWrapper::HEADER_CONTENT_TYPE => HTTPWrapper::DEFAULT_CONTENT_TYPE} }
|
39
|
+
stub_get sample_url, params
|
40
|
+
subject.get sample_url
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should set content type if provided' do
|
44
|
+
params = { headers: {HTTPWrapper::HEADER_CONTENT_TYPE => 'Custom Content Type'} }
|
45
|
+
stub_get sample_url, params
|
46
|
+
subject.get sample_url, params
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should set proper header for JSON requests' do
|
50
|
+
params = { headers: {HTTPWrapper::HEADER_CONTENT_TYPE => HTTPWrapper::JSON_CONTENT_TYPE} }
|
51
|
+
stub_get sample_url, params
|
52
|
+
subject.get_json sample_url
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should set proper header for AJAX requests' do
|
56
|
+
params = { headers: {HTTPWrapper::HEADER_AJAX => HTTPWrapper::HEADER_AJAX_VALUE,
|
57
|
+
HTTPWrapper::HEADER_CONTENT_TYPE => HTTPWrapper::DEFAULT_CONTENT_TYPE } }
|
58
|
+
stub_get sample_url, params
|
59
|
+
subject.get_ajax sample_url
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'should set proper headers for AJAX-JSON requests' do
|
63
|
+
params = { headers: {HTTPWrapper::HEADER_AJAX => HTTPWrapper::HEADER_AJAX_VALUE,
|
64
|
+
HTTPWrapper::HEADER_CONTENT_TYPE => HTTPWrapper::JSON_CONTENT_TYPE } }
|
65
|
+
stub_get sample_url, params
|
66
|
+
subject.get_ajax_json sample_url
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should correctly escape query parameters' do
|
70
|
+
stub_get sample_url + '/?param1=¶m2=A%26B¶m3=C%20%26%20D'
|
71
|
+
subject.get sample_url, params: {param1: '', param2: 'A&B', param3: 'C & D'}
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should set default user agent' do
|
75
|
+
params = { headers: {HTTPWrapper::HEADER_USER_AGENT => HTTPWrapper.default_user_agent} }
|
76
|
+
stub_get sample_url, params
|
77
|
+
subject.get sample_url
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'should change user agent if provided' do
|
81
|
+
custom_user_agent = 'Mozilla v1.2.3'
|
82
|
+
params = { headers: {HTTPWrapper::HEADER_USER_AGENT => custom_user_agent} }
|
83
|
+
stub_get sample_url, params
|
84
|
+
subject.get sample_url, params
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'should send cookie if provided' do
|
88
|
+
cookie_value = 'some cookie'
|
89
|
+
params = { headers: {'Cookie' => cookie_value} }
|
90
|
+
stub_get sample_url, params
|
91
|
+
subject.get sample_url, cookie: cookie_value
|
92
|
+
subject.get sample_url, params
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'should hit provided url with basic auth' do
|
96
|
+
stub_get sample_url_with_basic_auth
|
97
|
+
subject.get sample_url, auth: {login: basic_auth_login, password: basic_auth_password}
|
98
|
+
end
|
99
|
+
|
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
|
+
it 'should merge query parameters and params should take precedence' do
|
110
|
+
stub_get sample_url + '/?text=edf&time=16:44&user=test'
|
111
|
+
subject.get(sample_url + '/?user=test&text=abc', params: {time: '16:44', text: 'edf'})
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context 'POST' do
|
116
|
+
it 'should set content type if provided' do
|
117
|
+
params = { headers: {HTTPWrapper::HEADER_CONTENT_TYPE => 'Custom Content Type'} }
|
118
|
+
stub_post sample_url, params
|
119
|
+
subject.post sample_url, params
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'should return cookies after post' do
|
123
|
+
cookie_value = 'some cookie'
|
124
|
+
params = { body: {username: 'test', password: 'test'} }
|
125
|
+
stub_post(sample_url, params).to_return({headers: {'Set-Cookie' => cookie_value}})
|
126
|
+
cookie = subject.post_and_get_cookie sample_url, params
|
127
|
+
cookie.should eql cookie_value
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'should hit provided url with default content type' do
|
131
|
+
params = { headers: {HTTPWrapper::HEADER_CONTENT_TYPE => HTTPWrapper::POST_CONTENT_TYPE } }
|
132
|
+
stub_post sample_url, params
|
133
|
+
subject.post sample_url
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
context 'PUT' do
|
138
|
+
it 'should hit provided url with default content type' do
|
139
|
+
params = { headers: {HTTPWrapper::HEADER_CONTENT_TYPE => HTTPWrapper::POST_CONTENT_TYPE } }
|
140
|
+
stub_put sample_url, params
|
141
|
+
subject.put sample_url
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
context 'DELETE' do
|
146
|
+
it 'should hit provided url with default content type' do
|
147
|
+
params = { headers: {HTTPWrapper::HEADER_CONTENT_TYPE => HTTPWrapper::POST_CONTENT_TYPE } }
|
148
|
+
stub_delete sample_url, params
|
149
|
+
subject.delete sample_url
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
context 'HTTPS' do
|
155
|
+
let(:sample_url) { 'https://example.com' }
|
156
|
+
|
157
|
+
it 'should hit provided url with HTTPS protocol' do
|
158
|
+
stub_get sample_url
|
159
|
+
subject.get sample_url
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'webmock/rspec'
|
3
|
+
|
4
|
+
$LOAD_PATH.unshift File.expand_path('../lib', File.dirname(__FILE__))
|
5
|
+
|
6
|
+
module HTTPWrapperSpecHelpers
|
7
|
+
[:get, :post, :put, :delete].each do |type|
|
8
|
+
define_method("stub_#{type.to_s}") do |url, params = nil|
|
9
|
+
if params
|
10
|
+
stub_request(type, url).with(params)
|
11
|
+
else
|
12
|
+
stub_request(type, url)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def stub_redirects(url, amount_of_redirects)
|
18
|
+
stub_get(url).to_return(status: 301, headers: {'Location' => url})
|
19
|
+
.times(amount_of_redirects)
|
20
|
+
.then
|
21
|
+
.to_return(status: 200)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
RSpec.configure do |config|
|
26
|
+
config.mock_with :mocha
|
27
|
+
config.include HTTPWrapperSpecHelpers
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: http_wrapper
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Leonid Svyatov
|
8
|
+
- Alexander Shvets
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-09-09 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ~>
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: 2.14.1
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ~>
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: 2.14.1
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: webmock
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ~>
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: 1.13.0
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ~>
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: 1.13.0
|
42
|
+
description: Simple wrapper around standard Net::HTTP library to simplify common http[s]
|
43
|
+
tasks usage
|
44
|
+
email: leonid@svyatov.ru
|
45
|
+
executables: []
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files: []
|
48
|
+
files:
|
49
|
+
- Gemfile
|
50
|
+
- LICENSE
|
51
|
+
- README.md
|
52
|
+
- CHANGELOG.md
|
53
|
+
- Rakefile
|
54
|
+
- lib/http_wrapper/constants.rb
|
55
|
+
- lib/http_wrapper/errors.rb
|
56
|
+
- lib/http_wrapper/http_wrapper.rb
|
57
|
+
- lib/http_wrapper/version.rb
|
58
|
+
- lib/http_wrapper.rb
|
59
|
+
- spec/http_wrapper_spec.rb
|
60
|
+
- spec/spec_helper.rb
|
61
|
+
homepage: http://github.com/Svyatov/http_wrapper
|
62
|
+
licenses:
|
63
|
+
- MIT
|
64
|
+
metadata: {}
|
65
|
+
post_install_message:
|
66
|
+
rdoc_options: []
|
67
|
+
require_paths:
|
68
|
+
- lib
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - '>='
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: 1.9.3
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - '>='
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
requirements: []
|
80
|
+
rubyforge_project:
|
81
|
+
rubygems_version: 2.0.7
|
82
|
+
signing_key:
|
83
|
+
specification_version: 4
|
84
|
+
summary: Simple wrapper around standard Net::HTTP library
|
85
|
+
test_files:
|
86
|
+
- spec/http_wrapper_spec.rb
|
87
|
+
- spec/spec_helper.rb
|