http_wrapper 3.0.0 → 5.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 +4 -4
- data/CHANGELOG.md +163 -152
- data/README.md +35 -28
- data/http_wrapper.gemspec +26 -0
- data/lib/http_wrapper/constants.rb +8 -2
- data/lib/http_wrapper/errors.rb +5 -3
- data/lib/http_wrapper/http_wrapper.rb +34 -26
- data/lib/http_wrapper/request.rb +29 -36
- data/lib/http_wrapper/version.rb +1 -1
- data/lib/http_wrapper.rb +0 -1
- metadata +13 -116
- data/Gemfile +0 -4
- data/Rakefile +0 -8
- data/lib/http_wrapper/util.rb +0 -20
- data/spec/http_wrapper_spec.rb +0 -269
- data/spec/spec_helper.rb +0 -39
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8fd156005004d496b92087a6129e9f79e71c0bd49e587e3ac8d1f85d863732d4
|
|
4
|
+
data.tar.gz: 9e2d595b7780f8679943e994ea988b32794d59d2d30ce1e32c76ca89fdba3d16
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7f9e62d75265d2c1fe9c3b4e7eb92ba4113c43d9789762edcc5200d31b5cda68d0172940c90a1ad4cd92332d79191e2308229be187bdb51c2e3c8f241f3c657a
|
|
7
|
+
data.tar.gz: 793f83e054901155d5515473b2f08c853c728c3ad5a3d8a53ace4bea889b4b76e74efb605cbc6d39daeaf93c382545f11cd237c2c925dc471cfd7d9da165b995
|
data/CHANGELOG.md
CHANGED
|
@@ -1,154 +1,165 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
##
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
##
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [5.0.0] - 2026-03-02
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- **BREAKING:** Hash options replaced with keyword arguments across the entire public API
|
|
15
|
+
- `HTTPWrapper.new(options = {})` → `HTTPWrapper.new(timeout:, verify_cert:, logger:, max_redirects:, user_agent:)`
|
|
16
|
+
- All HTTP methods (`get`, `post`, `put`, `delete`) now accept keyword arguments instead of an options hash
|
|
17
|
+
- Type-specific methods (`get_ajax`, `post_json`, etc.) forward `**kwargs` to the base methods
|
|
18
|
+
- `post_and_get_cookie` accepts `**kwargs` forwarded to `post`
|
|
19
|
+
- **BREAKING:** Minimum Ruby version raised from 2.5 to 3.2
|
|
20
|
+
- `write_timeout` now set on HTTP connections (in addition to `read_timeout` and `open_timeout`)
|
|
21
|
+
|
|
22
|
+
### Removed
|
|
23
|
+
|
|
24
|
+
- **BREAKING:** `UnknownKeyError` class (keyword arguments handle unknown key validation natively)
|
|
25
|
+
- **BREAKING:** `Util` module (`validate_hash_keys`, `query_to_hash`, `hash_to_query`)
|
|
26
|
+
- Support for Ruby < 3.2
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- CI testing against Ruby head, 4.0, 3.4, 3.3, and 3.2
|
|
31
|
+
- Integration test suite with live HTTP server for end-to-end coverage
|
|
32
|
+
|
|
33
|
+
## [4.0.0]
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
|
|
37
|
+
- All development dependencies updated
|
|
38
|
+
|
|
39
|
+
### Removed
|
|
40
|
+
|
|
41
|
+
- Support for Ruby 2.3 and 2.4
|
|
42
|
+
|
|
43
|
+
### Added
|
|
44
|
+
|
|
45
|
+
- Ruby 2.7 to the Travis CI config
|
|
46
|
+
- `rubocop-performance` gem
|
|
47
|
+
- RuboCop rake task added to the default rake task
|
|
48
|
+
|
|
49
|
+
## [3.0.0]
|
|
50
|
+
|
|
51
|
+
### Changed
|
|
52
|
+
|
|
53
|
+
- Code refactored for RuboCop compliance
|
|
54
|
+
|
|
55
|
+
### Removed
|
|
56
|
+
|
|
57
|
+
- Support for Ruby 1.9–2.2 and Rubinius
|
|
58
|
+
|
|
59
|
+
### Added
|
|
60
|
+
|
|
61
|
+
- `rubocop` and `rubocop-rspec` gems for code quality
|
|
62
|
+
- `simplecov` gem for test coverage tracking
|
|
63
|
+
|
|
64
|
+
## [2.1.1]
|
|
65
|
+
|
|
66
|
+
### Changed
|
|
67
|
+
|
|
68
|
+
- `UnknownParameterError` renamed to `UnknownKeyError`
|
|
69
|
+
- Removed options and parameters validation code duplication
|
|
70
|
+
|
|
71
|
+
### Fixed
|
|
72
|
+
|
|
73
|
+
- `post_and_get_cookie` method (warning: HTTPResponse#response is obsolete)
|
|
74
|
+
|
|
75
|
+
## [2.1.0]
|
|
76
|
+
|
|
77
|
+
### Added
|
|
78
|
+
|
|
79
|
+
- Ability to perform custom `Net::HTTP` requests via `#execute`
|
|
80
|
+
- File uploads with `multipart/form-data` content type
|
|
81
|
+
- `:user_agent` and `:content_type` parameter shortcuts
|
|
82
|
+
- Ability to specify headers as symbols
|
|
83
|
+
- URL scheme auto-prefixing (`http://`) when missing
|
|
84
|
+
- `:max_redirects` option for redirect limits
|
|
85
|
+
- `:logger` option for request debugging
|
|
86
|
+
|
|
87
|
+
### Changed
|
|
88
|
+
|
|
89
|
+
- Default content type changed to `text/html`
|
|
90
|
+
- `:params` key changed to `:query`
|
|
91
|
+
- `:validate_ssl_cert` option renamed to `:verify_cert`
|
|
92
|
+
- Massive refactoring
|
|
93
|
+
|
|
94
|
+
### Removed
|
|
95
|
+
|
|
96
|
+
- `:ca_file` option
|
|
97
|
+
- `soap` methods (rare usage)
|
|
98
|
+
- `:method` key from params
|
|
99
|
+
|
|
100
|
+
### Fixed
|
|
101
|
+
|
|
102
|
+
- Incorrect content type for `DELETE` request
|
|
103
|
+
- Timeout should be set in seconds, not microseconds
|
|
104
|
+
|
|
105
|
+
## [2.0.0]
|
|
106
|
+
|
|
107
|
+
### Changed
|
|
108
|
+
|
|
109
|
+
- Gem rewritten completely and renamed to `http_wrapper`
|
|
110
|
+
- `#get_response` renamed to `#get`
|
|
111
|
+
- `#get_ajax_response` renamed to `#get_ajax`
|
|
112
|
+
- `#get_soap_response` renamed to `#get_soap`
|
|
113
|
+
- `#get_json_response` renamed to `#get_json`
|
|
114
|
+
- `#get_cookie` renamed to `#post_and_get_cookie`
|
|
115
|
+
- Constructor uses options hash instead of separate parameters
|
|
116
|
+
- Methods signature changed to `method(url, params)`
|
|
117
|
+
- Tests rewritten completely using `webmock` gem
|
|
118
|
+
- Development gem dependencies reduced
|
|
119
|
+
|
|
120
|
+
### Added
|
|
121
|
+
|
|
122
|
+
- `#post`, `#put`, `#delete` methods
|
|
123
|
+
- `#get_ajax_json`, `#post_ajax_json`, `#put_ajax_json`, `#delete_ajax_json` methods
|
|
124
|
+
- `#post_[ajax|soap|json]`, `#put_[ajax|soap|json]`, `#delete_[ajax|soap|json]` methods
|
|
125
|
+
|
|
126
|
+
## [1.1.1]
|
|
127
|
+
|
|
128
|
+
### Added
|
|
129
|
+
|
|
130
|
+
- Query parameter support
|
|
131
|
+
- Specs
|
|
132
|
+
|
|
133
|
+
## [1.1.0]
|
|
134
|
+
|
|
135
|
+
### Changed
|
|
136
|
+
|
|
137
|
+
- API change
|
|
138
|
+
|
|
139
|
+
### Added
|
|
140
|
+
|
|
141
|
+
- Documentation
|
|
142
|
+
|
|
143
|
+
## [1.0.1]
|
|
144
|
+
|
|
145
|
+
### Fixed
|
|
146
|
+
|
|
147
|
+
- Bug fix
|
|
148
|
+
|
|
149
|
+
## [1.0.0]
|
|
150
|
+
|
|
151
|
+
### Added
|
|
152
|
+
|
|
153
|
+
- Initial release
|
|
154
|
+
|
|
155
|
+
[Unreleased]: https://github.com/svyatov/http_wrapper/compare/v5.0.0...HEAD
|
|
156
|
+
[5.0.0]: https://github.com/svyatov/http_wrapper/compare/v4.0.0...v5.0.0
|
|
157
|
+
[4.0.0]: https://github.com/svyatov/http_wrapper/compare/v3.0.0...v4.0.0
|
|
158
|
+
[3.0.0]: https://github.com/svyatov/http_wrapper/compare/v2.1.1...v3.0.0
|
|
159
|
+
[2.1.1]: https://github.com/svyatov/http_wrapper/compare/v2.1.0...v2.1.1
|
|
160
|
+
[2.1.0]: https://github.com/svyatov/http_wrapper/compare/v2.0.0...v2.1.0
|
|
161
|
+
[2.0.0]: https://github.com/svyatov/http_wrapper/compare/v1.1.1...v2.0.0
|
|
162
|
+
[1.1.1]: https://github.com/svyatov/http_wrapper/compare/v1.1.0...v1.1.1
|
|
163
|
+
[1.1.0]: https://github.com/svyatov/http_wrapper/compare/v1.0.1...v1.1.0
|
|
164
|
+
[1.0.1]: https://github.com/svyatov/http_wrapper/compare/v1.0.0...v1.0.1
|
|
165
|
+
[1.0.0]: https://github.com/svyatov/http_wrapper/releases/tag/v1.0.0
|
data/README.md
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
# http_wrapper
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://rubygems.org/gems/http_wrapper)
|
|
4
|
+
[](https://github.com/svyatov/http_wrapper/actions/workflows/main.yml)
|
|
5
|
+
[](https://codecov.io/gh/svyatov/http_wrapper)
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
[
|
|
8
|
-
|
|
7
|
+
A simple wrapper around standard Ruby Net::HTTP library.
|
|
8
|
+
|
|
9
|
+
If you need something more fully-featured you should use absolutely awesome [HTTP](https://github.com/httprb/http) gem. ([Why?](https://twin.github.io/httprb-is-great/))
|
|
10
|
+
|
|
11
|
+
## Supported Ruby Versions
|
|
12
|
+
|
|
13
|
+
- Ruby 3.2+
|
|
9
14
|
|
|
10
15
|
---
|
|
11
16
|
|
|
@@ -14,7 +19,7 @@ Simple wrapper around standard Net::HTTP library
|
|
|
14
19
|
Add this line to your Gemfile:
|
|
15
20
|
|
|
16
21
|
```ruby
|
|
17
|
-
gem 'http_wrapper', '~>
|
|
22
|
+
gem 'http_wrapper', '~> 5.0'
|
|
18
23
|
```
|
|
19
24
|
|
|
20
25
|
And then execute:
|
|
@@ -94,9 +99,9 @@ Add special header or use special method:
|
|
|
94
99
|
```ruby
|
|
95
100
|
response = http.get_ajax some_url
|
|
96
101
|
# - or -
|
|
97
|
-
response = http.get some_url, headers: {x_requested_with: 'XMLHttpRequest'}
|
|
102
|
+
response = http.get some_url, headers: { x_requested_with: 'XMLHttpRequest' }
|
|
98
103
|
# - or -
|
|
99
|
-
response = http.get some_url, headers: {'X-Requested-With' => 'XMLHttpRequest'}
|
|
104
|
+
response = http.get some_url, headers: { 'X-Requested-With' => 'XMLHttpRequest' }
|
|
100
105
|
```
|
|
101
106
|
|
|
102
107
|
### Access JSON resource
|
|
@@ -108,9 +113,9 @@ response = http.get_json some_url
|
|
|
108
113
|
# - or -
|
|
109
114
|
response = http.get some_url, content_type: 'application/json; charset=UTF-8'
|
|
110
115
|
# - or -
|
|
111
|
-
response = http.get some_url, headers: {content_type: 'application/json; charset=UTF-8'}
|
|
116
|
+
response = http.get some_url, headers: { content_type: 'application/json; charset=UTF-8' }
|
|
112
117
|
# - or -
|
|
113
|
-
response = http.get some_url, headers: {'Content-Type' => 'application/json; charset=UTF-8'}
|
|
118
|
+
response = http.get some_url, headers: { 'Content-Type' => 'application/json; charset=UTF-8' }
|
|
114
119
|
```
|
|
115
120
|
|
|
116
121
|
### Access JSON resource mimicing AJAX
|
|
@@ -134,14 +139,14 @@ response = http.get_json_ajax some_url, some_params
|
|
|
134
139
|
Don't worry about escaping, `http_wrapper` got you covered here either.
|
|
135
140
|
|
|
136
141
|
```ruby
|
|
137
|
-
response = http.get 'http://www.google.com', query: {message: 'Hi! M&Ms!', user: 'iamjohn'}
|
|
142
|
+
response = http.get 'http://www.google.com', query: { message: 'Hi! M&Ms!', user: 'iamjohn' }
|
|
138
143
|
# => http://www.google.com/?message=Hi!%20M%26Ms!&user=iamjohn
|
|
139
144
|
```
|
|
140
145
|
|
|
141
146
|
Don't worry about parameters that already in URL, they'll be merged.
|
|
142
147
|
|
|
143
148
|
```ruby
|
|
144
|
-
response = http.get 'http://www.google.com/?q=test', query: {user: 'iamjohn'}
|
|
149
|
+
response = http.get 'http://www.google.com/?q=test', query: { user: 'iamjohn' }
|
|
145
150
|
# => http://www.google.com/?q=test&user=iamjohn
|
|
146
151
|
```
|
|
147
152
|
|
|
@@ -153,8 +158,8 @@ You can easily upload any number of files with `multipart/form-data` content typ
|
|
|
153
158
|
http = HTTPWrapper.new
|
|
154
159
|
params = {
|
|
155
160
|
multipart: [
|
|
156
|
-
# ['file input field name', 'File instance or string', {filename: 'itsfile.jpg', content_type: '...'}]
|
|
157
|
-
['user_photo', File.read('user_photo.jpg'), {filename: 'photo.jpg'}],
|
|
161
|
+
# ['file input field name', 'File instance or string', { filename: 'itsfile.jpg', content_type: '...' }]
|
|
162
|
+
['user_photo', File.read('user_photo.jpg'), { filename: 'photo.jpg' }],
|
|
158
163
|
# last element is optional
|
|
159
164
|
['user_pic', File.open('user_pic.jpg')],
|
|
160
165
|
# you can also specify other parameters
|
|
@@ -208,19 +213,17 @@ http = HTTPWrapper.new verify_cert: false
|
|
|
208
213
|
On each `get` method there are `post`, `put` and `delete` methods. Examples:
|
|
209
214
|
|
|
210
215
|
```ruby
|
|
211
|
-
http.post some_url, body: {user: 'iamjohn', password: 'secret'}
|
|
216
|
+
http.post some_url, body: { user: 'iamjohn', password: 'secret' }
|
|
212
217
|
# - or -
|
|
213
|
-
http.put some_url, body: {user: 'iamjohn', password: 'secret'}
|
|
218
|
+
http.put some_url, body: { user: 'iamjohn', password: 'secret' }
|
|
214
219
|
# - or -
|
|
215
|
-
http.delete some_url, query: {user: 'iamjohn'}
|
|
220
|
+
http.delete some_url, query: { user: 'iamjohn' }
|
|
216
221
|
```
|
|
217
222
|
|
|
218
223
|
Default content type header for these requests is `application/x-www-form-urlencoded; charset=UTF-8`.
|
|
219
224
|
|
|
220
225
|
So for `get_ajax` there are `post_ajax`, `put_ajax` and `delete_ajax`.
|
|
221
226
|
|
|
222
|
-
For `get_soap` there are `post_soap`, `put_soap` and `delete_soap`.
|
|
223
|
-
|
|
224
227
|
For `get_json` there are `post_json`, `put_json` and `delete_json`.
|
|
225
228
|
|
|
226
229
|
And for `get_ajax_json`, there are `post_ajax_json`, `put_ajax_json` and `delete_ajax_json`.
|
|
@@ -228,7 +231,7 @@ And for `get_ajax_json`, there are `post_ajax_json`, `put_ajax_json` and `delete
|
|
|
228
231
|
### Change User Agent
|
|
229
232
|
|
|
230
233
|
```ruby
|
|
231
|
-
http =
|
|
234
|
+
http = HTTPWrapper.new user_agent: 'custom user agent'
|
|
232
235
|
# - or -
|
|
233
236
|
http.user_agent = 'custom user agent'
|
|
234
237
|
http.get sample_url
|
|
@@ -298,9 +301,9 @@ http.execute request, uri
|
|
|
298
301
|
# you can use File object
|
|
299
302
|
['file_input_name', File.open('somefile.ext')],
|
|
300
303
|
# - or - string and specify filename
|
|
301
|
-
['file_input_name', File.read('somefile.ext'), {filename: 'readme.txt'}],
|
|
304
|
+
['file_input_name', File.read('somefile.ext'), { filename: 'readme.txt' }],
|
|
302
305
|
# - or - full format
|
|
303
|
-
['file_input_name', 'some file content', {filename: 'readme.txt', content_type: 'text/text'}],
|
|
306
|
+
['file_input_name', 'some file content', { filename: 'readme.txt', content_type: 'text/text' }],
|
|
304
307
|
# - or - add other simple parameters
|
|
305
308
|
['user_name', 'john smith']
|
|
306
309
|
]
|
|
@@ -308,12 +311,16 @@ http.execute request, uri
|
|
|
308
311
|
```
|
|
309
312
|
|
|
310
313
|
Don't worry if you mistype root parameters key. `http_wrapper` checks root parameters keys and instantiation options keys.
|
|
311
|
-
If any unknown options or parameters found, it raises
|
|
314
|
+
If any unknown options or parameters found, it raises an `ArgumentError` exception.
|
|
312
315
|
|
|
313
316
|
## Contributing
|
|
314
317
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
318
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
319
|
+
|
|
320
|
+
## Code of Conduct
|
|
321
|
+
|
|
322
|
+
This project follows the [Contributor Covenant Code of Conduct](CODE_OF_CONDUCT.md).
|
|
323
|
+
|
|
324
|
+
## Security
|
|
325
|
+
|
|
326
|
+
See [SECURITY.md](SECURITY.md) for reporting vulnerabilities.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'lib/http_wrapper/version'
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = 'http_wrapper'
|
|
7
|
+
spec.version = HTTPWrapper::VERSION
|
|
8
|
+
spec.authors = ['Leonid Svyatov', 'Alexander Shvets']
|
|
9
|
+
spec.email = 'leonid@svyatov.ru'
|
|
10
|
+
spec.description = 'Simple wrapper around standard Net::HTTP library with multipart/form-data file upload ability'
|
|
11
|
+
spec.summary = 'Simple wrapper around standard Net::HTTP library'
|
|
12
|
+
spec.homepage = 'https://github.com/svyatov/http_wrapper'
|
|
13
|
+
spec.license = 'MIT'
|
|
14
|
+
|
|
15
|
+
spec.files = Dir['lib/**/*.rb'] + %w[CHANGELOG.md LICENSE README.md http_wrapper.gemspec]
|
|
16
|
+
spec.require_paths = %w[lib]
|
|
17
|
+
|
|
18
|
+
spec.required_ruby_version = '>= 3.2.0'
|
|
19
|
+
|
|
20
|
+
spec.metadata = {
|
|
21
|
+
'rubygems_mfa_required' => 'true',
|
|
22
|
+
'source_code_uri' => 'https://github.com/svyatov/http_wrapper',
|
|
23
|
+
'changelog_uri' => 'https://github.com/svyatov/http_wrapper/blob/master/CHANGELOG.md',
|
|
24
|
+
'bug_tracker_uri' => 'https://github.com/svyatov/http_wrapper/issues'
|
|
25
|
+
}
|
|
26
|
+
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class HTTPWrapper
|
|
4
|
-
USER_AGENT = "HTTPWrapper/#{HTTPWrapper::VERSION}; Ruby/#{RUBY_VERSION}"
|
|
4
|
+
USER_AGENT = "HTTPWrapper/#{HTTPWrapper::VERSION}; Ruby/#{RUBY_VERSION}".freeze
|
|
5
5
|
|
|
6
6
|
CONTENT_TYPE_HEADER_NAME = 'content-type'
|
|
7
7
|
USER_AGENT_HEADER_NAME = 'user-agent'
|
|
@@ -15,5 +15,11 @@ class HTTPWrapper
|
|
|
15
15
|
|
|
16
16
|
AJAX_HEADER = { AJAX_HEADER_NAME => 'XMLHttpRequest' }.freeze
|
|
17
17
|
JSON_HEADER = { CONTENT_TYPE_HEADER_NAME => JSON_CONTENT_TYPE }.freeze
|
|
18
|
-
AJAX_JSON_HEADER = AJAX_HEADER.
|
|
18
|
+
AJAX_JSON_HEADER = AJAX_HEADER.merge(JSON_HEADER).freeze
|
|
19
|
+
|
|
20
|
+
HEADERS_FOR_REQUEST_TYPE = {
|
|
21
|
+
'ajax' => AJAX_HEADER,
|
|
22
|
+
'json' => JSON_HEADER,
|
|
23
|
+
'ajax_json' => AJAX_JSON_HEADER
|
|
24
|
+
}.freeze
|
|
19
25
|
end
|
data/lib/http_wrapper/errors.rb
CHANGED
|
@@ -3,40 +3,51 @@
|
|
|
3
3
|
require 'net/https'
|
|
4
4
|
|
|
5
5
|
class HTTPWrapper
|
|
6
|
-
|
|
6
|
+
HTTP_METHODS = {
|
|
7
|
+
get: Net::HTTP::Get,
|
|
8
|
+
post: Net::HTTP::Post,
|
|
9
|
+
put: Net::HTTP::Put,
|
|
10
|
+
delete: Net::HTTP::Delete
|
|
11
|
+
}.freeze
|
|
7
12
|
|
|
8
|
-
|
|
13
|
+
REQUEST_TYPES = %w[ajax json ajax_json].freeze
|
|
9
14
|
|
|
10
|
-
|
|
11
|
-
Util.validate_hash_keys options, KNOWN_OPTIONS_KEYS
|
|
15
|
+
attr_accessor :timeout, :verify_cert, :logger, :max_redirects, :user_agent
|
|
12
16
|
|
|
13
|
-
|
|
14
|
-
@
|
|
15
|
-
@
|
|
16
|
-
@
|
|
17
|
-
@
|
|
17
|
+
def initialize(timeout: 10, verify_cert: true, logger: nil, max_redirects: 10, user_agent: USER_AGENT)
|
|
18
|
+
@timeout = timeout
|
|
19
|
+
@verify_cert = verify_cert
|
|
20
|
+
@logger = logger
|
|
21
|
+
@max_redirects = max_redirects
|
|
22
|
+
@user_agent = user_agent
|
|
18
23
|
end
|
|
19
24
|
|
|
20
25
|
%i[get post put delete].each do |method_as_symbol|
|
|
21
|
-
define_method method_as_symbol do |url,
|
|
22
|
-
|
|
23
|
-
|
|
26
|
+
define_method method_as_symbol do |url, headers: nil, query: nil, cookie: nil,
|
|
27
|
+
auth: nil, body: nil, user_agent: nil,
|
|
28
|
+
content_type: nil, multipart: nil|
|
|
29
|
+
user_agent ||= @user_agent
|
|
30
|
+
request = Request.new(url, method_as_symbol,
|
|
31
|
+
headers:, query:, cookie:, auth:, body:,
|
|
32
|
+
user_agent:, content_type:, multipart:)
|
|
33
|
+
perform_request(request)
|
|
24
34
|
end
|
|
25
35
|
|
|
26
36
|
method_as_string = method_as_symbol.to_s
|
|
27
37
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
38
|
+
REQUEST_TYPES.each do |request_type|
|
|
39
|
+
type_headers = HEADERS_FOR_REQUEST_TYPE.fetch(request_type)
|
|
40
|
+
define_method "#{method_as_string}_#{request_type}" do |url, **params|
|
|
41
|
+
params[:headers] = (params[:headers] || {}).merge(type_headers)
|
|
42
|
+
public_send(method_as_symbol, url, **params)
|
|
32
43
|
end
|
|
33
44
|
end
|
|
34
45
|
|
|
35
46
|
alias_method "#{method_as_string}_json_ajax", "#{method_as_string}_ajax_json"
|
|
36
47
|
end
|
|
37
48
|
|
|
38
|
-
def post_and_get_cookie(url, params
|
|
39
|
-
response = post
|
|
49
|
+
def post_and_get_cookie(url, **params)
|
|
50
|
+
response = post(url, **params)
|
|
40
51
|
response['set-cookie']
|
|
41
52
|
end
|
|
42
53
|
|
|
@@ -47,27 +58,24 @@ class HTTPWrapper
|
|
|
47
58
|
|
|
48
59
|
private
|
|
49
60
|
|
|
50
|
-
def
|
|
61
|
+
def perform_request(request, redirects_limit = @max_redirects)
|
|
51
62
|
raise TooManyRedirectsError, 'Too many redirects!' if redirects_limit == 0
|
|
52
63
|
|
|
53
64
|
response = execute request.create, request.uri
|
|
54
65
|
|
|
55
66
|
if response.is_a? Net::HTTPRedirection
|
|
56
67
|
request.uri = response['location']
|
|
57
|
-
response =
|
|
68
|
+
response = perform_request request, redirects_limit - 1
|
|
58
69
|
end
|
|
59
70
|
|
|
60
71
|
response
|
|
61
72
|
end
|
|
62
73
|
|
|
63
|
-
def headers_specific_for(request_type)
|
|
64
|
-
self.class.const_get "#{request_type.upcase}_HEADER"
|
|
65
|
-
end
|
|
66
|
-
|
|
67
74
|
def create_connection(uri)
|
|
68
75
|
connection = Net::HTTP.new uri.host, uri.port
|
|
69
|
-
connection.read_timeout
|
|
70
|
-
connection.open_timeout
|
|
76
|
+
connection.read_timeout = @timeout
|
|
77
|
+
connection.open_timeout = @timeout
|
|
78
|
+
connection.write_timeout = @timeout
|
|
71
79
|
|
|
72
80
|
if uri.is_a? URI::HTTPS
|
|
73
81
|
connection.use_ssl = true
|
data/lib/http_wrapper/request.rb
CHANGED
|
@@ -4,26 +4,23 @@ require 'uri/common'
|
|
|
4
4
|
|
|
5
5
|
class HTTPWrapper
|
|
6
6
|
class Request
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def initialize(url, method, params = {}) # rubocop:disable Metrics/AbcSize
|
|
10
|
-
Util.validate_hash_keys params, KNOWN_PARAMS_KEYS
|
|
11
|
-
|
|
7
|
+
def initialize(url, method, headers: nil, query: nil, cookie: nil, auth: nil,
|
|
8
|
+
body: nil, user_agent: nil, content_type: nil, multipart: nil)
|
|
12
9
|
self.uri = url
|
|
13
10
|
|
|
14
|
-
@query =
|
|
15
|
-
@headers = normalize_headers
|
|
16
|
-
@method =
|
|
17
|
-
@cookie =
|
|
11
|
+
@query = query || {}
|
|
12
|
+
@headers = normalize_headers(headers)
|
|
13
|
+
@method = HTTP_METHODS.fetch(method)
|
|
14
|
+
@cookie = cookie
|
|
18
15
|
|
|
19
|
-
@body_data =
|
|
20
|
-
@multipart_data =
|
|
21
|
-
@user_agent =
|
|
22
|
-
@content_type =
|
|
16
|
+
@body_data = body
|
|
17
|
+
@multipart_data = multipart
|
|
18
|
+
@user_agent = user_agent
|
|
19
|
+
@content_type = content_type || default_content_type_for(method)
|
|
23
20
|
|
|
24
|
-
if
|
|
25
|
-
@login =
|
|
26
|
-
@password =
|
|
21
|
+
if auth
|
|
22
|
+
@login = auth.fetch(:login)
|
|
23
|
+
@password = auth.fetch(:password)
|
|
27
24
|
end
|
|
28
25
|
|
|
29
26
|
initialize_headers
|
|
@@ -32,7 +29,7 @@ class HTTPWrapper
|
|
|
32
29
|
attr_reader :uri
|
|
33
30
|
|
|
34
31
|
def uri=(url)
|
|
35
|
-
url = "http://#{url}" unless
|
|
32
|
+
url = "http://#{url}" unless %r{\Ahttps?://}.match?(url)
|
|
36
33
|
@uri = URI.parse url
|
|
37
34
|
end
|
|
38
35
|
|
|
@@ -46,7 +43,7 @@ class HTTPWrapper
|
|
|
46
43
|
def normalize_headers(headers)
|
|
47
44
|
normal_headers = {}
|
|
48
45
|
headers&.each do |header, value|
|
|
49
|
-
normal_headers[normalize_header
|
|
46
|
+
normal_headers[normalize_header(header)] = value
|
|
50
47
|
end
|
|
51
48
|
normal_headers
|
|
52
49
|
end
|
|
@@ -56,10 +53,6 @@ class HTTPWrapper
|
|
|
56
53
|
header.downcase
|
|
57
54
|
end
|
|
58
55
|
|
|
59
|
-
def http_method_class_for(method)
|
|
60
|
-
Net::HTTP.const_get method.to_s.capitalize
|
|
61
|
-
end
|
|
62
|
-
|
|
63
56
|
def default_content_type_for(method)
|
|
64
57
|
case method
|
|
65
58
|
when :post, :put then POST_CONTENT_TYPE
|
|
@@ -76,45 +69,45 @@ class HTTPWrapper
|
|
|
76
69
|
def merge_uri_query
|
|
77
70
|
return if @query.empty?
|
|
78
71
|
|
|
79
|
-
original_query = @uri.query ?
|
|
72
|
+
original_query = @uri.query ? URI.decode_www_form(@uri.query).to_h : {}
|
|
80
73
|
merged_query = original_query.merge @query
|
|
81
|
-
@uri.query =
|
|
74
|
+
@uri.query = URI.encode_www_form(merged_query)
|
|
82
75
|
end
|
|
83
76
|
|
|
84
77
|
def create_method_specific_request
|
|
85
78
|
@request = @method.new @uri, @headers
|
|
86
|
-
|
|
87
|
-
|
|
79
|
+
apply_body
|
|
80
|
+
apply_basic_auth
|
|
88
81
|
@request
|
|
89
82
|
end
|
|
90
83
|
|
|
91
|
-
def
|
|
84
|
+
def apply_body
|
|
92
85
|
return unless @request.request_body_permitted?
|
|
93
86
|
|
|
94
87
|
if @multipart_data
|
|
95
|
-
|
|
88
|
+
apply_multipart_body
|
|
96
89
|
else
|
|
97
|
-
|
|
90
|
+
apply_regular_body
|
|
98
91
|
end
|
|
99
92
|
end
|
|
100
93
|
|
|
101
|
-
def
|
|
102
|
-
|
|
94
|
+
def apply_multipart_body
|
|
95
|
+
merge_body_into_multipart if @body_data
|
|
103
96
|
@request.set_form @multipart_data, MULTIPART_CONTENT_TYPE
|
|
104
97
|
end
|
|
105
98
|
|
|
106
|
-
def
|
|
107
|
-
@body_data =
|
|
99
|
+
def merge_body_into_multipart
|
|
100
|
+
@body_data = URI.decode_www_form(@body_data).to_h unless @body_data.is_a? Hash
|
|
108
101
|
@body_data.each { |key, value| @multipart_data << [key.to_s, value.to_s] }
|
|
109
102
|
end
|
|
110
103
|
|
|
111
|
-
def
|
|
104
|
+
def apply_regular_body
|
|
112
105
|
return unless @body_data
|
|
113
106
|
|
|
114
|
-
@request.body = @body_data.is_a?(Hash) ?
|
|
107
|
+
@request.body = @body_data.is_a?(Hash) ? URI.encode_www_form(@body_data) : @body_data
|
|
115
108
|
end
|
|
116
109
|
|
|
117
|
-
def
|
|
110
|
+
def apply_basic_auth
|
|
118
111
|
return unless @login && @password
|
|
119
112
|
|
|
120
113
|
@request.basic_auth @login, @password
|
data/lib/http_wrapper/version.rb
CHANGED
data/lib/http_wrapper.rb
CHANGED
metadata
CHANGED
|
@@ -1,114 +1,15 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: http_wrapper
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 5.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Leonid Svyatov
|
|
8
8
|
- Alexander Shvets
|
|
9
|
-
autorequire:
|
|
10
9
|
bindir: bin
|
|
11
10
|
cert_chain: []
|
|
12
|
-
date:
|
|
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: '0'
|
|
21
|
-
type: :development
|
|
22
|
-
prerelease: false
|
|
23
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
24
|
-
requirements:
|
|
25
|
-
- - ">="
|
|
26
|
-
- !ruby/object:Gem::Version
|
|
27
|
-
version: '0'
|
|
28
|
-
- !ruby/object:Gem::Dependency
|
|
29
|
-
name: rake
|
|
30
|
-
requirement: !ruby/object:Gem::Requirement
|
|
31
|
-
requirements:
|
|
32
|
-
- - ">="
|
|
33
|
-
- !ruby/object:Gem::Version
|
|
34
|
-
version: '0'
|
|
35
|
-
type: :development
|
|
36
|
-
prerelease: false
|
|
37
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
38
|
-
requirements:
|
|
39
|
-
- - ">="
|
|
40
|
-
- !ruby/object:Gem::Version
|
|
41
|
-
version: '0'
|
|
42
|
-
- !ruby/object:Gem::Dependency
|
|
43
|
-
name: rspec
|
|
44
|
-
requirement: !ruby/object:Gem::Requirement
|
|
45
|
-
requirements:
|
|
46
|
-
- - "~>"
|
|
47
|
-
- !ruby/object:Gem::Version
|
|
48
|
-
version: '3.7'
|
|
49
|
-
type: :development
|
|
50
|
-
prerelease: false
|
|
51
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
52
|
-
requirements:
|
|
53
|
-
- - "~>"
|
|
54
|
-
- !ruby/object:Gem::Version
|
|
55
|
-
version: '3.7'
|
|
56
|
-
- !ruby/object:Gem::Dependency
|
|
57
|
-
name: rubocop
|
|
58
|
-
requirement: !ruby/object:Gem::Requirement
|
|
59
|
-
requirements:
|
|
60
|
-
- - "~>"
|
|
61
|
-
- !ruby/object:Gem::Version
|
|
62
|
-
version: 0.63.1
|
|
63
|
-
type: :development
|
|
64
|
-
prerelease: false
|
|
65
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
66
|
-
requirements:
|
|
67
|
-
- - "~>"
|
|
68
|
-
- !ruby/object:Gem::Version
|
|
69
|
-
version: 0.63.1
|
|
70
|
-
- !ruby/object:Gem::Dependency
|
|
71
|
-
name: rubocop-rspec
|
|
72
|
-
requirement: !ruby/object:Gem::Requirement
|
|
73
|
-
requirements:
|
|
74
|
-
- - "~>"
|
|
75
|
-
- !ruby/object:Gem::Version
|
|
76
|
-
version: '1.32'
|
|
77
|
-
type: :development
|
|
78
|
-
prerelease: false
|
|
79
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
80
|
-
requirements:
|
|
81
|
-
- - "~>"
|
|
82
|
-
- !ruby/object:Gem::Version
|
|
83
|
-
version: '1.32'
|
|
84
|
-
- !ruby/object:Gem::Dependency
|
|
85
|
-
name: simplecov
|
|
86
|
-
requirement: !ruby/object:Gem::Requirement
|
|
87
|
-
requirements:
|
|
88
|
-
- - "~>"
|
|
89
|
-
- !ruby/object:Gem::Version
|
|
90
|
-
version: 0.16.1
|
|
91
|
-
type: :development
|
|
92
|
-
prerelease: false
|
|
93
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
94
|
-
requirements:
|
|
95
|
-
- - "~>"
|
|
96
|
-
- !ruby/object:Gem::Version
|
|
97
|
-
version: 0.16.1
|
|
98
|
-
- !ruby/object:Gem::Dependency
|
|
99
|
-
name: webmock
|
|
100
|
-
requirement: !ruby/object:Gem::Requirement
|
|
101
|
-
requirements:
|
|
102
|
-
- - "~>"
|
|
103
|
-
- !ruby/object:Gem::Version
|
|
104
|
-
version: '3.5'
|
|
105
|
-
type: :development
|
|
106
|
-
prerelease: false
|
|
107
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
108
|
-
requirements:
|
|
109
|
-
- - "~>"
|
|
110
|
-
- !ruby/object:Gem::Version
|
|
111
|
-
version: '3.5'
|
|
11
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
112
13
|
description: Simple wrapper around standard Net::HTTP library with multipart/form-data
|
|
113
14
|
file upload ability
|
|
114
15
|
email: leonid@svyatov.ru
|
|
@@ -117,24 +18,23 @@ extensions: []
|
|
|
117
18
|
extra_rdoc_files: []
|
|
118
19
|
files:
|
|
119
20
|
- CHANGELOG.md
|
|
120
|
-
- Gemfile
|
|
121
21
|
- LICENSE
|
|
122
22
|
- README.md
|
|
123
|
-
-
|
|
23
|
+
- http_wrapper.gemspec
|
|
124
24
|
- lib/http_wrapper.rb
|
|
125
25
|
- lib/http_wrapper/constants.rb
|
|
126
26
|
- lib/http_wrapper/errors.rb
|
|
127
27
|
- lib/http_wrapper/http_wrapper.rb
|
|
128
28
|
- lib/http_wrapper/request.rb
|
|
129
|
-
- lib/http_wrapper/util.rb
|
|
130
29
|
- lib/http_wrapper/version.rb
|
|
131
|
-
|
|
132
|
-
- spec/spec_helper.rb
|
|
133
|
-
homepage: http://github.com/svyatov/http_wrapper
|
|
30
|
+
homepage: https://github.com/svyatov/http_wrapper
|
|
134
31
|
licenses:
|
|
135
32
|
- MIT
|
|
136
|
-
metadata:
|
|
137
|
-
|
|
33
|
+
metadata:
|
|
34
|
+
rubygems_mfa_required: 'true'
|
|
35
|
+
source_code_uri: https://github.com/svyatov/http_wrapper
|
|
36
|
+
changelog_uri: https://github.com/svyatov/http_wrapper/blob/master/CHANGELOG.md
|
|
37
|
+
bug_tracker_uri: https://github.com/svyatov/http_wrapper/issues
|
|
138
38
|
rdoc_options: []
|
|
139
39
|
require_paths:
|
|
140
40
|
- lib
|
|
@@ -142,17 +42,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
142
42
|
requirements:
|
|
143
43
|
- - ">="
|
|
144
44
|
- !ruby/object:Gem::Version
|
|
145
|
-
version: 2.
|
|
45
|
+
version: 3.2.0
|
|
146
46
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
147
47
|
requirements:
|
|
148
48
|
- - ">="
|
|
149
49
|
- !ruby/object:Gem::Version
|
|
150
50
|
version: '0'
|
|
151
51
|
requirements: []
|
|
152
|
-
rubygems_version:
|
|
153
|
-
signing_key:
|
|
52
|
+
rubygems_version: 4.0.6
|
|
154
53
|
specification_version: 4
|
|
155
54
|
summary: Simple wrapper around standard Net::HTTP library
|
|
156
|
-
test_files:
|
|
157
|
-
- spec/spec_helper.rb
|
|
158
|
-
- spec/http_wrapper_spec.rb
|
|
55
|
+
test_files: []
|
data/Gemfile
DELETED
data/Rakefile
DELETED
data/lib/http_wrapper/util.rb
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class HTTPWrapper
|
|
4
|
-
module Util
|
|
5
|
-
def self.validate_hash_keys(hash_to_check, known_keys_array)
|
|
6
|
-
unknown_keys = hash_to_check.keys - known_keys_array
|
|
7
|
-
return if unknown_keys.empty?
|
|
8
|
-
|
|
9
|
-
raise UnknownKeyError, "Unknown keys: #{unknown_keys.join(', ')}"
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def self.query_to_hash(query)
|
|
13
|
-
Hash[URI.decode_www_form query]
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def self.hash_to_query(hash)
|
|
17
|
-
URI.encode_www_form hash
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
data/spec/http_wrapper_spec.rb
DELETED
|
@@ -1,269 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative 'spec_helper'
|
|
4
|
-
|
|
5
|
-
require 'http_wrapper'
|
|
6
|
-
|
|
7
|
-
RSpec.describe HTTPWrapper do
|
|
8
|
-
subject(:http) { described_class.new }
|
|
9
|
-
|
|
10
|
-
let(:basic_auth_login) { 'balogin' }
|
|
11
|
-
let(:basic_auth_password) { 'bapassword' }
|
|
12
|
-
|
|
13
|
-
it 'defines all dynamic methods' do
|
|
14
|
-
%i[get post put delete
|
|
15
|
-
get_json post_json put_json delete_json
|
|
16
|
-
get_ajax post_ajax put_ajax delete_ajax
|
|
17
|
-
get_ajax_json post_ajax_json put_ajax_json delete_ajax_json
|
|
18
|
-
get_json_ajax post_json_ajax put_json_ajax delete_json_ajax].each do |method|
|
|
19
|
-
expect(http).to respond_to method
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
describe 'HTTP' do
|
|
24
|
-
let(:sample_url) { 'http://example.com' }
|
|
25
|
-
|
|
26
|
-
describe 'Options' do
|
|
27
|
-
it 'raises UnknownParameterError if initial options key is unknown' do
|
|
28
|
-
expect do
|
|
29
|
-
described_class.new unknown_option: 'test', maybe_this_known: '?'
|
|
30
|
-
end.to raise_error HTTPWrapper::UnknownKeyError, 'Unknown keys: unknown_option, maybe_this_known'
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
it 'raises UnknownParameterError if params key is unknown' do
|
|
34
|
-
expect do
|
|
35
|
-
http.get sample_url, unknown_param_key: 'test', another_param_key: 'wow'
|
|
36
|
-
end.to raise_error HTTPWrapper::UnknownKeyError, 'Unknown keys: unknown_param_key, another_param_key'
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
it 'follows redirects no more then 10 times by default' do
|
|
40
|
-
stub_redirects sample_url, 9
|
|
41
|
-
response = http.get sample_url
|
|
42
|
-
expect(response.code).to eq '200'
|
|
43
|
-
|
|
44
|
-
stub_redirects sample_url, 10
|
|
45
|
-
expect { http.get sample_url }.to raise_error HTTPWrapper::TooManyRedirectsError, 'Too many redirects!'
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
it 'follows redirects no more times then specified' do
|
|
49
|
-
http.max_redirects = 5
|
|
50
|
-
|
|
51
|
-
stub_redirects sample_url, 4
|
|
52
|
-
response = http.get sample_url
|
|
53
|
-
expect(response.code).to eq '200'
|
|
54
|
-
|
|
55
|
-
stub_redirects sample_url, 5
|
|
56
|
-
expect { http.get sample_url }.to raise_error HTTPWrapper::TooManyRedirectsError, 'Too many redirects!'
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
it 'uses logger' do
|
|
60
|
-
require 'logger'
|
|
61
|
-
logger = Logger.new StringIO.new
|
|
62
|
-
allow(logger).to receive(:<<)
|
|
63
|
-
http.logger = logger
|
|
64
|
-
|
|
65
|
-
WebMock.allow_net_connect!
|
|
66
|
-
begin
|
|
67
|
-
http.get 'localhost'
|
|
68
|
-
rescue StandardError # rubocop:disable Lint/HandleExceptions
|
|
69
|
-
# NOOP, rescue from "connection refused" and such
|
|
70
|
-
end
|
|
71
|
-
WebMock.disable_net_connect!
|
|
72
|
-
|
|
73
|
-
expect(logger).to have_received(:<<).at_least(:once)
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
describe 'GET' do
|
|
78
|
-
it 'adds http uri scheme if missing' do
|
|
79
|
-
stub_get sample_url
|
|
80
|
-
http.get sample_url.gsub(%r{\Ahttp://}, '')
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
it 'hits provided url with default content type' do
|
|
84
|
-
params = { headers: { HTTPWrapper::CONTENT_TYPE_HEADER_NAME => HTTPWrapper::DEFAULT_CONTENT_TYPE } }
|
|
85
|
-
stub_get sample_url, params
|
|
86
|
-
http.get sample_url
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
it 'sets content type if provided' do
|
|
90
|
-
params = { headers: { HTTPWrapper::CONTENT_TYPE_HEADER_NAME => 'Custom Content Type' } }
|
|
91
|
-
stub_get sample_url, params
|
|
92
|
-
http.get sample_url, params
|
|
93
|
-
http.get sample_url, content_type: 'Custom Content Type'
|
|
94
|
-
http.get sample_url, params.merge(content_type: 'Should Be Overwritten')
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
it 'sets proper header for JSON requests' do
|
|
98
|
-
params = { headers: HTTPWrapper::JSON_HEADER }
|
|
99
|
-
stub_get sample_url, params
|
|
100
|
-
http.get_json sample_url
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
it 'sets proper header for AJAX requests' do
|
|
104
|
-
params = {
|
|
105
|
-
headers: {
|
|
106
|
-
HTTPWrapper::CONTENT_TYPE_HEADER_NAME => HTTPWrapper::DEFAULT_CONTENT_TYPE
|
|
107
|
-
}.merge(HTTPWrapper::AJAX_HEADER)
|
|
108
|
-
}
|
|
109
|
-
stub_get sample_url, params
|
|
110
|
-
http.get_ajax sample_url
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
it 'sets proper headers for AJAX-JSON requests' do
|
|
114
|
-
params = { headers: HTTPWrapper::AJAX_JSON_HEADER }
|
|
115
|
-
stub_get sample_url, params
|
|
116
|
-
http.get_ajax_json sample_url
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
it 'correctlies escape query parameters' do
|
|
120
|
-
stub_get "#{sample_url}/?param1=¶m2=A%26B¶m3=C%20%26%20D"
|
|
121
|
-
http.get sample_url, query: { param1: '', param2: 'A&B', param3: 'C & D' }
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
it 'sets default user agent' do
|
|
125
|
-
params = { headers: { HTTPWrapper::USER_AGENT_HEADER_NAME => HTTPWrapper::USER_AGENT } }
|
|
126
|
-
stub_get sample_url, params
|
|
127
|
-
http.get sample_url
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
it 'changes user agent if provided' do
|
|
131
|
-
custom_user_agent = 'Mozilla v1.2.3'
|
|
132
|
-
params = { headers: { HTTPWrapper::USER_AGENT_HEADER_NAME => custom_user_agent } }
|
|
133
|
-
stub_get sample_url, params
|
|
134
|
-
http.get sample_url, params
|
|
135
|
-
|
|
136
|
-
http.get sample_url, user_agent: custom_user_agent
|
|
137
|
-
|
|
138
|
-
http.user_agent = custom_user_agent
|
|
139
|
-
http.get sample_url
|
|
140
|
-
|
|
141
|
-
expect do
|
|
142
|
-
http.get sample_url, user_agent: 'abracadabra'
|
|
143
|
-
end.to raise_error WebMock::NetConnectNotAllowedError
|
|
144
|
-
|
|
145
|
-
expect do
|
|
146
|
-
http.user_agent = 'another test'
|
|
147
|
-
http.get sample_url
|
|
148
|
-
end.to raise_error WebMock::NetConnectNotAllowedError
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
it 'precedences header user agent before params' do
|
|
152
|
-
params = { headers: { HTTPWrapper::USER_AGENT_HEADER_NAME => 'TestUserAgent' } }
|
|
153
|
-
stub_get sample_url, params
|
|
154
|
-
|
|
155
|
-
http.user_agent = 'Should Be Overwritten'
|
|
156
|
-
http.get sample_url, params
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
it 'sends cookie if provided' do
|
|
160
|
-
cookie_value = 'some cookie'
|
|
161
|
-
params = { headers: { 'Cookie' => cookie_value } }
|
|
162
|
-
stub_get sample_url, params
|
|
163
|
-
http.get sample_url, cookie: cookie_value
|
|
164
|
-
http.get sample_url, params
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
it 'uses headers cookie if both (headers and parameters) cookies provided' do
|
|
168
|
-
params = { headers: { 'Cookie' => 'Custom cookie' } }
|
|
169
|
-
stub_get sample_url, params
|
|
170
|
-
http.get sample_url, params.merge(cookie: 'should not use this one')
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
it 'hits provided url with basic auth' do
|
|
174
|
-
stub_request(:get, sample_url).with(basic_auth: [basic_auth_login, basic_auth_password])
|
|
175
|
-
http.get sample_url, auth: { login: basic_auth_login, password: basic_auth_password }
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
it 'merges query parameters and params should take precedence' do
|
|
179
|
-
stub_get "#{sample_url}/?text=edf&time=16:44&user=test"
|
|
180
|
-
http.get "#{sample_url}/?user=test&text=abc", query: { time: '16:44', text: 'edf' }
|
|
181
|
-
end
|
|
182
|
-
|
|
183
|
-
it 'equallies treat header as string and header as symbol' do
|
|
184
|
-
custom_content_type = 'Some Content Type'
|
|
185
|
-
stub_get sample_url, headers: { 'Content-Type' => custom_content_type }
|
|
186
|
-
http.get sample_url, headers: { content_type: custom_content_type }
|
|
187
|
-
end
|
|
188
|
-
end
|
|
189
|
-
|
|
190
|
-
describe 'POST' do
|
|
191
|
-
it 'sets content type if provided' do
|
|
192
|
-
params = { headers: { HTTPWrapper::CONTENT_TYPE_HEADER_NAME => 'Custom Content Type' } }
|
|
193
|
-
stub_post sample_url, params
|
|
194
|
-
http.post sample_url, params
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
it 'returns cookies after post' do
|
|
198
|
-
cookie_value = 'some cookie'
|
|
199
|
-
params = { body: { username: 'test', password: 'test' } }
|
|
200
|
-
stub_post(sample_url, params).to_return(headers: { 'Set-Cookie' => cookie_value })
|
|
201
|
-
cookie = http.post_and_get_cookie sample_url, params
|
|
202
|
-
expect(cookie).to eq cookie_value
|
|
203
|
-
end
|
|
204
|
-
|
|
205
|
-
it 'hits provided url with default content type' do
|
|
206
|
-
params = { headers: { HTTPWrapper::CONTENT_TYPE_HEADER_NAME => HTTPWrapper::POST_CONTENT_TYPE } }
|
|
207
|
-
stub_post sample_url, params
|
|
208
|
-
http.post sample_url
|
|
209
|
-
end
|
|
210
|
-
|
|
211
|
-
it 'sets all possible parameters correctly' do
|
|
212
|
-
stub_request(:post, "#{sample_url}/?a=b&c=d")
|
|
213
|
-
.with(
|
|
214
|
-
body: 'e=f&g=k',
|
|
215
|
-
headers: {
|
|
216
|
-
'Content-Type' => 'Custom content type',
|
|
217
|
-
'User-Agent' => 'Custom user agent',
|
|
218
|
-
'Cookie' => 'cookie',
|
|
219
|
-
'X-Requested-With' => 'XMLHttpRequest'
|
|
220
|
-
},
|
|
221
|
-
basic_auth: %w[user passw]
|
|
222
|
-
)
|
|
223
|
-
|
|
224
|
-
http.post sample_url,
|
|
225
|
-
content_type: 'Custom content type',
|
|
226
|
-
user_agent: 'Custom user agent',
|
|
227
|
-
headers: { x_requested_with: 'XMLHttpRequest' },
|
|
228
|
-
query: { a: 'b', c: 'd' },
|
|
229
|
-
body: { e: 'f', g: 'k' },
|
|
230
|
-
auth: { login: 'user', password: 'passw' },
|
|
231
|
-
cookie: 'cookie'
|
|
232
|
-
end
|
|
233
|
-
end
|
|
234
|
-
|
|
235
|
-
describe 'PUT' do
|
|
236
|
-
it 'hits provided url with default content type' do
|
|
237
|
-
params = { headers: { HTTPWrapper::CONTENT_TYPE_HEADER_NAME => HTTPWrapper::POST_CONTENT_TYPE } }
|
|
238
|
-
stub_put sample_url, params
|
|
239
|
-
http.put sample_url
|
|
240
|
-
end
|
|
241
|
-
end
|
|
242
|
-
|
|
243
|
-
describe 'DELETE' do
|
|
244
|
-
it 'hits provided url with default content type' do
|
|
245
|
-
params = { headers: { HTTPWrapper::CONTENT_TYPE_HEADER_NAME => HTTPWrapper::DEFAULT_CONTENT_TYPE } }
|
|
246
|
-
stub_delete sample_url, params
|
|
247
|
-
http.delete sample_url
|
|
248
|
-
end
|
|
249
|
-
end
|
|
250
|
-
|
|
251
|
-
describe 'Custom request instance' do
|
|
252
|
-
it 'performs request for custom Net::HTTP request instance' do
|
|
253
|
-
stub_request :head, sample_url
|
|
254
|
-
uri = URI sample_url
|
|
255
|
-
request = Net::HTTP::Head.new uri
|
|
256
|
-
http.execute request, request.uri
|
|
257
|
-
end
|
|
258
|
-
end
|
|
259
|
-
end
|
|
260
|
-
|
|
261
|
-
describe 'HTTPS' do
|
|
262
|
-
let(:sample_url) { 'https://example.com' }
|
|
263
|
-
|
|
264
|
-
it 'hits provided url with HTTPS protocol' do
|
|
265
|
-
stub_get sample_url
|
|
266
|
-
http.get sample_url
|
|
267
|
-
end
|
|
268
|
-
end
|
|
269
|
-
end
|
data/spec/spec_helper.rb
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'bundler/setup'
|
|
4
|
-
require 'webmock/rspec'
|
|
5
|
-
|
|
6
|
-
if ENV['TRAVIS'] == 'true'
|
|
7
|
-
require 'simplecov'
|
|
8
|
-
SimpleCov.start
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
module HTTPWrapperSpecHelpers
|
|
12
|
-
%i[get post put delete].each do |type|
|
|
13
|
-
define_method("stub_#{type}") do |url, params = nil|
|
|
14
|
-
if params
|
|
15
|
-
stub_request(type, url).with(params)
|
|
16
|
-
else
|
|
17
|
-
stub_request(type, url)
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def stub_redirects(url, amount_of_redirects)
|
|
23
|
-
stub_get(url).to_return(status: 301, headers: { 'Location' => url })
|
|
24
|
-
.times(amount_of_redirects)
|
|
25
|
-
.then
|
|
26
|
-
.to_return(status: 200)
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
RSpec.configure do |config|
|
|
31
|
-
config.include HTTPWrapperSpecHelpers
|
|
32
|
-
|
|
33
|
-
# Disable RSpec exposing methods globally on `Module` and `main`
|
|
34
|
-
config.disable_monkey_patching!
|
|
35
|
-
|
|
36
|
-
config.expect_with :rspec do |c|
|
|
37
|
-
c.syntax = :expect
|
|
38
|
-
end
|
|
39
|
-
end
|