nxt_http_client 1.1.0 → 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 +4 -4
- data/.circleci/config.yml +11 -48
- data/.ruby-version +1 -1
- data/.travis.yml +1 -1
- data/CHANGELOG.md +5 -0
- data/Gemfile.lock +29 -25
- data/README.md +105 -61
- data/lib/nxt_http_client/client.rb +69 -3
- data/lib/nxt_http_client/client_dsl.rb +0 -2
- data/lib/nxt_http_client/config.rb +32 -7
- data/lib/nxt_http_client/version.rb +1 -1
- data/nxt_http_client.gemspec +3 -15
- metadata +7 -10
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1a6f3d4b612e96bdbb4ca6eb96ad25572bfcccee632e140945770e643cc875a7
|
|
4
|
+
data.tar.gz: 983ce0f4bc00f4b3d6dec1956736714cf3bf2f367eedd3c6cbab4c1505c56ba5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a8b12f8c808a3b71f9d23a734ecc16022adb975a0530cad5e5251745aaf4cf818f781645eb2069f60aa900dbf72996dae4a744c7bd83e89b48d0b80f02c252a2
|
|
7
|
+
data.tar.gz: 1abe1f25bbceaa78ef1198c4e5b26a2b6c3091f53b06b6aa4a85a2182f19bd26895620ecb8584c8afd13a8aa919f94b83f1efcdc2b8db1d03a37df98e9105ee4
|
data/.circleci/config.yml
CHANGED
|
@@ -1,57 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
version: 2.1
|
|
2
|
+
|
|
3
|
+
orbs:
|
|
4
|
+
ruby: circleci/ruby@2.0.1
|
|
5
|
+
|
|
6
6
|
jobs:
|
|
7
7
|
build:
|
|
8
8
|
docker:
|
|
9
|
-
- image:
|
|
10
|
-
- image:
|
|
11
|
-
environment:
|
|
12
|
-
BUNDLER_VERSION: 2.3.6
|
|
9
|
+
- image: cimg/ruby:3.2.2-node
|
|
10
|
+
- image: cimg/redis:6.0.16
|
|
13
11
|
|
|
14
12
|
working_directory: ~/repo
|
|
15
13
|
|
|
16
14
|
steps:
|
|
17
15
|
- checkout
|
|
18
16
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
- run: gem install bundler --version $BUNDLER_VERSION
|
|
25
|
-
|
|
26
|
-
- run:
|
|
27
|
-
name: install dependencies
|
|
28
|
-
command: |
|
|
29
|
-
bundle install --jobs=4 --retry=3 --path vendor/bundle
|
|
30
|
-
|
|
31
|
-
- save_cache:
|
|
32
|
-
paths:
|
|
33
|
-
- ./vendor/bundle
|
|
34
|
-
key: v1-dependencies-{{ checksum "Gemfile.lock" }}
|
|
35
|
-
|
|
36
|
-
# run tests!
|
|
37
|
-
- run:
|
|
38
|
-
name: run tests
|
|
39
|
-
command: |
|
|
40
|
-
mkdir /tmp/test-results
|
|
41
|
-
TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | \
|
|
42
|
-
circleci tests split --split-by=timings)"
|
|
43
|
-
|
|
44
|
-
bundle exec rspec \
|
|
45
|
-
--format progress \
|
|
46
|
-
--format RspecJunitFormatter \
|
|
47
|
-
--out /tmp/test-results/rspec.xml \
|
|
48
|
-
--format progress \
|
|
49
|
-
$TEST_FILES
|
|
50
|
-
|
|
51
|
-
# collect reports
|
|
52
|
-
- store_artifacts:
|
|
53
|
-
path: /tmp/rspec/
|
|
54
|
-
destination: rspec
|
|
55
|
-
|
|
56
|
-
- store_test_results:
|
|
57
|
-
path: /tmp/rspec/
|
|
17
|
+
- ruby/install-deps:
|
|
18
|
+
key: gems-v2
|
|
19
|
+
include-branch-in-cache-key: false
|
|
20
|
+
- ruby/rspec-test
|
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.
|
|
1
|
+
3.2.2
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
nxt_http_client (
|
|
4
|
+
nxt_http_client (2.0.0)
|
|
5
5
|
activesupport (< 8.0)
|
|
6
6
|
nxt_registry
|
|
7
7
|
typhoeus
|
|
@@ -9,15 +9,16 @@ PATH
|
|
|
9
9
|
GEM
|
|
10
10
|
remote: https://rubygems.org/
|
|
11
11
|
specs:
|
|
12
|
-
activesupport (7.0.
|
|
12
|
+
activesupport (7.0.7.2)
|
|
13
13
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
14
14
|
i18n (>= 1.6, < 2)
|
|
15
15
|
minitest (>= 5.1)
|
|
16
16
|
tzinfo (~> 2.0)
|
|
17
|
-
addressable (2.8.
|
|
18
|
-
public_suffix (>= 2.0.2, <
|
|
17
|
+
addressable (2.8.4)
|
|
18
|
+
public_suffix (>= 2.0.2, < 6.0)
|
|
19
19
|
coderay (1.1.3)
|
|
20
20
|
concurrent-ruby (1.2.2)
|
|
21
|
+
connection_pool (2.4.1)
|
|
21
22
|
crack (0.4.5)
|
|
22
23
|
rexml
|
|
23
24
|
diff-lcs (1.5.0)
|
|
@@ -25,44 +26,47 @@ GEM
|
|
|
25
26
|
ffi (>= 1.15.0)
|
|
26
27
|
ffi (1.15.5)
|
|
27
28
|
hashdiff (1.0.1)
|
|
28
|
-
i18n (1.
|
|
29
|
+
i18n (1.14.1)
|
|
29
30
|
concurrent-ruby (~> 1.0)
|
|
30
31
|
method_source (1.0.0)
|
|
31
|
-
minitest (5.
|
|
32
|
+
minitest (5.19.0)
|
|
32
33
|
nxt_registry (0.3.10)
|
|
33
34
|
activesupport
|
|
34
35
|
nxt_vcr_harness (0.1.4)
|
|
35
36
|
rspec (~> 3.0)
|
|
36
37
|
vcr (~> 6.0)
|
|
37
|
-
pry (0.14.
|
|
38
|
+
pry (0.14.2)
|
|
38
39
|
coderay (~> 1.1)
|
|
39
40
|
method_source (~> 1.0)
|
|
40
|
-
public_suffix (
|
|
41
|
+
public_suffix (5.0.3)
|
|
41
42
|
rake (13.0.6)
|
|
42
|
-
redis (
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
rspec-
|
|
50
|
-
|
|
43
|
+
redis (5.0.6)
|
|
44
|
+
redis-client (>= 0.9.0)
|
|
45
|
+
redis-client (0.14.1)
|
|
46
|
+
connection_pool
|
|
47
|
+
rexml (3.2.6)
|
|
48
|
+
rspec (3.12.0)
|
|
49
|
+
rspec-core (~> 3.12.0)
|
|
50
|
+
rspec-expectations (~> 3.12.0)
|
|
51
|
+
rspec-mocks (~> 3.12.0)
|
|
52
|
+
rspec-core (3.12.2)
|
|
53
|
+
rspec-support (~> 3.12.0)
|
|
54
|
+
rspec-expectations (3.12.3)
|
|
51
55
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
52
|
-
rspec-support (~> 3.
|
|
53
|
-
rspec-mocks (3.
|
|
56
|
+
rspec-support (~> 3.12.0)
|
|
57
|
+
rspec-mocks (3.12.6)
|
|
54
58
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
55
|
-
rspec-support (~> 3.
|
|
56
|
-
rspec-support (3.
|
|
57
|
-
rspec_junit_formatter (0.
|
|
59
|
+
rspec-support (~> 3.12.0)
|
|
60
|
+
rspec-support (3.12.1)
|
|
61
|
+
rspec_junit_formatter (0.6.0)
|
|
58
62
|
rspec-core (>= 2, < 4, != 2.12.0)
|
|
59
|
-
timecop (0.9.
|
|
63
|
+
timecop (0.9.6)
|
|
60
64
|
typhoeus (1.4.0)
|
|
61
65
|
ethon (>= 0.9.0)
|
|
62
66
|
tzinfo (2.0.6)
|
|
63
67
|
concurrent-ruby (~> 1.0)
|
|
64
|
-
vcr (6.
|
|
65
|
-
webmock (3.
|
|
68
|
+
vcr (6.2.0)
|
|
69
|
+
webmock (3.18.1)
|
|
66
70
|
addressable (>= 2.8.0)
|
|
67
71
|
crack (>= 0.3.2)
|
|
68
72
|
hashdiff (>= 0.4.0, < 2.0.0)
|
data/README.md
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
# NxtHttpClient
|
|
2
2
|
|
|
3
|
-
Build http clients with ease. NxtHttpClient is a
|
|
4
|
-
gem. NxtHttpClient
|
|
5
|
-
|
|
6
|
-
layer on top of [typhoeus](https://github.com/typhoeus/typhoeus) it also allows to access and configure the original
|
|
3
|
+
Build http clients with ease. NxtHttpClient is a DSL on top of the [typhoeus](https://github.com/typhoeus/typhoeus)
|
|
4
|
+
gem. NxtHttpClient provides configuration functionality to set up HTTP connections on the class level, and attach
|
|
5
|
+
callbacks that allow you to seamlessly handle responses, as well as configure the original
|
|
7
6
|
`Typhoeus::Request` before making a request.
|
|
8
7
|
|
|
9
8
|
|
|
@@ -17,102 +16,114 @@ gem 'nxt_http_client'
|
|
|
17
16
|
|
|
18
17
|
And then execute:
|
|
19
18
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
$ gem install nxt_http_client
|
|
19
|
+
```sh
|
|
20
|
+
bundle
|
|
21
|
+
````
|
|
25
22
|
|
|
26
23
|
## Usage
|
|
27
24
|
|
|
28
|
-
|
|
25
|
+
With NxtHttpClient, you can create client classes for interacting with external services:
|
|
29
26
|
|
|
30
27
|
```ruby
|
|
31
|
-
class
|
|
32
|
-
|
|
33
|
-
@url = ".../users/#{id}"
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def call
|
|
37
|
-
get(url) do |response_handler|
|
|
38
|
-
response_handler.on(:success) do |response|
|
|
39
|
-
JSON(response.body)
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
private
|
|
45
|
-
|
|
46
|
-
attr_reader :url
|
|
47
|
-
end
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
In order to setup a shared configuration you would therefore setup a client base class. The configuration and any
|
|
51
|
-
response handler or callbacks you setup in your base class are then inherited to your concrete client implementations.
|
|
52
|
-
|
|
53
|
-
```ruby
|
|
54
|
-
class Client < NxtHttpClient
|
|
28
|
+
class UserServiceClient < NxtHttpClient::Client
|
|
29
|
+
# Set a base URL, and any other request options you need
|
|
55
30
|
configure do |config|
|
|
56
31
|
config.base_url = 'www.example.com'
|
|
57
32
|
config.request_options.deep_merge!(
|
|
58
33
|
headers: { API_KEY: '1993' },
|
|
59
|
-
method: :get,
|
|
60
34
|
followlocation: true
|
|
61
35
|
)
|
|
36
|
+
config.json_request = true
|
|
37
|
+
config.raise_response_errors = true
|
|
62
38
|
config.x_request_id_proc = -> { ('a'..'z').to_a.shuffle.take(10).join }
|
|
63
39
|
end
|
|
64
40
|
|
|
41
|
+
# You may add a log handler if you wish...
|
|
65
42
|
log do |info|
|
|
66
43
|
Rails.logger.info(info)
|
|
67
44
|
end
|
|
68
45
|
|
|
46
|
+
# ...as well as a response handler
|
|
69
47
|
response_handler do |handler|
|
|
48
|
+
# Note: This error handler is set by default when you use
|
|
49
|
+
# config.raise_response_errors = true
|
|
70
50
|
handler.on(:error) do |response|
|
|
71
|
-
|
|
51
|
+
Sentry.set_extras(http_error_details: error.to_h)
|
|
72
52
|
raise StandardError, "I can't handle this: #{response.code}"
|
|
73
53
|
end
|
|
74
54
|
end
|
|
75
55
|
end
|
|
76
56
|
```
|
|
77
57
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
In order to build a request and execute it NxtHttpClient implements all http standard methods.
|
|
58
|
+
and then child classes for accessing specific endpoints and adding custom behaviours.
|
|
81
59
|
|
|
82
60
|
```ruby
|
|
83
|
-
class
|
|
84
|
-
def initialize(
|
|
85
|
-
@url =
|
|
61
|
+
class UserFetcher < UserServiceClient
|
|
62
|
+
def initialize(id)
|
|
63
|
+
@url = ".../users/#{id}"
|
|
86
64
|
end
|
|
87
65
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
66
|
+
def fetch_email
|
|
67
|
+
get(url, { fields: :email }) do |response_handler|
|
|
68
|
+
response_handler.on(:success) do |response|
|
|
69
|
+
JSON(response.body)['email']
|
|
70
|
+
end
|
|
93
71
|
end
|
|
94
72
|
end
|
|
95
73
|
|
|
96
|
-
def
|
|
97
|
-
|
|
98
|
-
|
|
74
|
+
def fetch_user_details
|
|
75
|
+
get(url) do |response_handler|
|
|
76
|
+
response_handler.on(:success) do |response|
|
|
77
|
+
body = JSON(response.body)
|
|
78
|
+
User.new(body)
|
|
79
|
+
end
|
|
99
80
|
end
|
|
100
81
|
end
|
|
101
82
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
83
|
+
private attr_reader :url
|
|
84
|
+
end
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Usage:
|
|
88
|
+
|
|
89
|
+
```ruby
|
|
90
|
+
client = UserFetcher.new('1234')
|
|
91
|
+
client.fetch_email
|
|
92
|
+
client.fetch_user_details
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
However, if you need a simple ad hoc client for a one-off task, you can use `.make` to instantiate one.
|
|
107
96
|
|
|
108
|
-
|
|
97
|
+
```ruby
|
|
98
|
+
client = NxtHttpClient::Client.make do
|
|
99
|
+
configure do |config|
|
|
100
|
+
config.base_url = 'www.httpstat.us'
|
|
101
|
+
config.request_options.deep_merge!(
|
|
102
|
+
headers: { API_KEY: '1993' },
|
|
103
|
+
followlocation: true
|
|
104
|
+
)
|
|
105
|
+
config.json_request = true
|
|
106
|
+
config.json_response = true
|
|
107
|
+
end
|
|
109
108
|
end
|
|
109
|
+
|
|
110
|
+
client.get('/data')
|
|
111
|
+
client.post('/data', body: { some: 'content'})
|
|
110
112
|
```
|
|
111
113
|
|
|
112
114
|
### configure
|
|
113
115
|
|
|
114
|
-
Register your default request options on the class level. Available options are
|
|
115
|
-
directly to the underlying Typhoeus Request
|
|
116
|
+
Register your default request options on the class level. Available options are:
|
|
117
|
+
- `request_options`, passed directly to the underlying Typhoeus Request
|
|
118
|
+
- `base_url=`
|
|
119
|
+
- `x_request_id_proc=`
|
|
120
|
+
- `json_request=`: Shorthand to set the Content-Type request header to JSON and automatically convert request bodies to JSON
|
|
121
|
+
- `json_response=`: Shorthand to set the Accept request header and automatically convert success response bodies to JSON
|
|
122
|
+
- `raise_response_errors=`: Makes the client raise a `NxtHttpClient::Error` for a non-success response.
|
|
123
|
+
You can also do this manually by setting a response_handler.
|
|
124
|
+
- `bearer_auth=`: Set a bearer token to be sent in the Authorization header
|
|
125
|
+
- `basic_auth=`: Pass a Hash containing `:username` and `:password`, to be sent as Basic credentials in the Authorization header
|
|
126
|
+
- `timeouts(total:, connect: nil)`: Configure timeouts
|
|
116
127
|
|
|
117
128
|
### response_handler
|
|
118
129
|
|
|
@@ -121,7 +132,7 @@ on the instance level.
|
|
|
121
132
|
|
|
122
133
|
### fire
|
|
123
134
|
|
|
124
|
-
All http methods internally are delegate to `fire(
|
|
135
|
+
All http methods internally are delegate to `fire(uri, **request_options)`. Since `fire` is a public method you can
|
|
125
136
|
also use it to fire your requests and use the response handler to register callbacks for specific responses.
|
|
126
137
|
|
|
127
138
|
Registered callbacks have a hierarchy by which they are executed. Specific callbacks will come first
|
|
@@ -194,7 +205,22 @@ requires the response for initialization. Furthermore it has a handy `to_h` meth
|
|
|
194
205
|
the request and response.
|
|
195
206
|
|
|
196
207
|
#### Timeouts
|
|
197
|
-
|
|
208
|
+
**You must set a timeout on every request (or when configuring the client class).**
|
|
209
|
+
Otherwise, this gem will raise an error. The idea is to enforce the best practice
|
|
210
|
+
of [always setting a timeout](https://dev.to/bearer/the-importance-of-request-timeouts-l3n).
|
|
211
|
+
|
|
212
|
+
To set a timeout, use the `timeout_seconds` config method:
|
|
213
|
+
|
|
214
|
+
```rb
|
|
215
|
+
configure do |config|
|
|
216
|
+
config.timeout_seconds(total: 10)
|
|
217
|
+
# You can also set a connect timeout
|
|
218
|
+
config.timeout_seconds(total: 10, connecttimeout: 2)
|
|
219
|
+
end
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
NxtHttpClient::Error exposes the `timed_out?` method from `Typhoeus::Response`, so you can check if an error is raised due to a timeout.
|
|
223
|
+
This is useful when setting a custom timeout value in your configuration.
|
|
198
224
|
|
|
199
225
|
### Logging
|
|
200
226
|
|
|
@@ -248,7 +274,25 @@ end
|
|
|
248
274
|
|
|
249
275
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
250
276
|
|
|
251
|
-
To install this gem onto your local machine, run `bundle exec rake install`.
|
|
277
|
+
To install this gem onto your local machine, run `bundle exec rake install`.
|
|
278
|
+
|
|
279
|
+
## Releasing
|
|
280
|
+
|
|
281
|
+
First, if you don't want to always log in with your RubyGems password,
|
|
282
|
+
you can create an API key on Rubygems.org, and then run:
|
|
283
|
+
|
|
284
|
+
```shell
|
|
285
|
+
bundle config set --local gem.push_key rubygems
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
Add to `~/.gem/credentials` (create if it doesn't exist):
|
|
289
|
+
|
|
290
|
+
```shell
|
|
291
|
+
:rubygems: <your Rubygems API key>
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`,
|
|
295
|
+
which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
252
296
|
|
|
253
297
|
## Contributing
|
|
254
298
|
|
|
@@ -1,13 +1,34 @@
|
|
|
1
1
|
module NxtHttpClient
|
|
2
|
+
# The entry point to this gem. The Client class is designed to be extended into custom base classes,
|
|
3
|
+
# but you can also create a one-off instance with the `.make` method.`
|
|
2
4
|
class Client
|
|
3
5
|
extend ClientDsl
|
|
6
|
+
|
|
4
7
|
CACHE_STRATEGIES = %w[global thread].freeze
|
|
5
8
|
HTTP_METHODS = %w[get post patch put delete head].freeze
|
|
6
9
|
|
|
10
|
+
# Get an anonymous client for one-off use. Example:
|
|
11
|
+
#
|
|
12
|
+
# client = NxtHttpClient::Client.make do
|
|
13
|
+
# configure do |config|
|
|
14
|
+
# config.base_url = 'www.httpstat.us'
|
|
15
|
+
# end
|
|
16
|
+
# end
|
|
17
|
+
# client.get('200')
|
|
18
|
+
def self.make(&block)
|
|
19
|
+
Class.new(self, &block).new
|
|
20
|
+
end
|
|
21
|
+
|
|
7
22
|
def build_request(url, **opts)
|
|
8
23
|
url = build_url(opts, url)
|
|
9
24
|
opts = build_headers(opts)
|
|
10
25
|
|
|
26
|
+
set_timeouts(opts)
|
|
27
|
+
|
|
28
|
+
if config.json_request
|
|
29
|
+
opts[:body] = opts[:body].to_json # Typhoeus requires userland JSON encoding
|
|
30
|
+
end
|
|
31
|
+
|
|
11
32
|
Typhoeus::Request.new(url, **opts.symbolize_keys)
|
|
12
33
|
end
|
|
13
34
|
|
|
@@ -41,7 +62,7 @@ module NxtHttpClient
|
|
|
41
62
|
|
|
42
63
|
HTTP_METHODS.each do |method|
|
|
43
64
|
define_method method do |url = '', **opts, &block|
|
|
44
|
-
fire(url, **opts.reverse_merge(method:
|
|
65
|
+
fire(url, **opts.reverse_merge(method:), &block)
|
|
45
66
|
end
|
|
46
67
|
end
|
|
47
68
|
|
|
@@ -59,10 +80,22 @@ module NxtHttpClient
|
|
|
59
80
|
opts = config.request_options.with_indifferent_access.deep_merge(opts.with_indifferent_access)
|
|
60
81
|
opts[:headers] ||= {}
|
|
61
82
|
|
|
62
|
-
if config.
|
|
63
|
-
|
|
83
|
+
opts[:headers]['Content-Type'] ||= ApplicationJson if config.json_request
|
|
84
|
+
opts[:headers]['Accept'] ||= ApplicationJson if config.json_response
|
|
85
|
+
|
|
86
|
+
if config.basic_auth
|
|
87
|
+
begin
|
|
88
|
+
config.basic_auth => { username:, password: }
|
|
89
|
+
rescue NoMatchingPatternKeyError
|
|
90
|
+
raise ArgumentError, 'basic_auth must be a Hash with :username and :password'
|
|
91
|
+
end
|
|
92
|
+
opts[:userpwd] ||= "#{username}:#{password}"
|
|
93
|
+
elsif (bearer_token = config.bearer_auth)
|
|
94
|
+
opts[:headers]['Authorization'] ||= "Bearer #{bearer_token}"
|
|
64
95
|
end
|
|
65
96
|
|
|
97
|
+
opts[:headers][XRequestId] ||= config.x_request_id_proc.call if config.x_request_id_proc
|
|
98
|
+
|
|
66
99
|
build_cache_header(opts)
|
|
67
100
|
opts
|
|
68
101
|
end
|
|
@@ -91,6 +124,15 @@ module NxtHttpClient
|
|
|
91
124
|
end
|
|
92
125
|
end
|
|
93
126
|
|
|
127
|
+
def set_timeouts(opts)
|
|
128
|
+
if (timeouts = config.timeouts).is_a?(Hash)
|
|
129
|
+
opts[:timeout] ||= timeouts[:total]
|
|
130
|
+
opts[:connecttimeout] ||= timeouts[:connect]
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
raise ArgumentError, 'You must configure a total timeout for this client or request' unless timeout_configured?(opts)
|
|
134
|
+
end
|
|
135
|
+
|
|
94
136
|
def url_without_duplicated_hashes(url)
|
|
95
137
|
duplicated_slashes = url.match(/([^:]\/{2,})/)
|
|
96
138
|
duplicated_slashes && duplicated_slashes.captures.each do |capture|
|
|
@@ -107,6 +149,26 @@ module NxtHttpClient
|
|
|
107
149
|
|
|
108
150
|
def build_response_handler(handler, &block)
|
|
109
151
|
response_handler = handler || dup_handler_from_class || NxtHttpClient::ResponseHandler.new
|
|
152
|
+
|
|
153
|
+
if config.json_response
|
|
154
|
+
response_handler.configure do |handler|
|
|
155
|
+
handler.on(:success) do |response|
|
|
156
|
+
response.define_singleton_method(:body) { JSON(response.response_body) }
|
|
157
|
+
response
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
if config.raise_response_errors
|
|
163
|
+
response_handler.configure do |handler|
|
|
164
|
+
handler.on(:error) do |response|
|
|
165
|
+
error = NxtHttpClient::Error.new(response)
|
|
166
|
+
::Sentry.set_extras(http_error_details: error.to_h) if defined?(::Sentry)
|
|
167
|
+
raise error
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
110
172
|
response_handler.configure(&block) if block_given?
|
|
111
173
|
response_handler
|
|
112
174
|
end
|
|
@@ -155,5 +217,9 @@ module NxtHttpClient
|
|
|
155
217
|
def callbacks
|
|
156
218
|
@callbacks ||= self.class.callbacks
|
|
157
219
|
end
|
|
220
|
+
|
|
221
|
+
def timeout_configured?(opts)
|
|
222
|
+
[:timeout, :timeout_ms].any? { opts[_1].present? }
|
|
223
|
+
end
|
|
158
224
|
end
|
|
159
225
|
end
|
|
@@ -1,15 +1,40 @@
|
|
|
1
1
|
module NxtHttpClient
|
|
2
|
-
CONFIGURABLE_OPTIONS =
|
|
2
|
+
CONFIGURABLE_OPTIONS = {
|
|
3
|
+
request_options: ActiveSupport::HashWithIndifferentAccess.new,
|
|
4
|
+
base_url: '',
|
|
5
|
+
x_request_id_proc: nil,
|
|
3
6
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
# Helper to set the Content-Type request header and automatically convert request bodies to JSON
|
|
8
|
+
json_request: false,
|
|
9
|
+
# Helper to set the Accept request header and automatically convert success response bodies to JSON
|
|
10
|
+
json_response: false,
|
|
11
|
+
raise_response_errors: false,
|
|
12
|
+
|
|
13
|
+
bearer_auth: nil,
|
|
14
|
+
basic_auth: nil,
|
|
15
|
+
timeouts: nil,
|
|
16
|
+
}.freeze
|
|
17
|
+
|
|
18
|
+
Config = Struct.new('Config', *CONFIGURABLE_OPTIONS.keys) do
|
|
19
|
+
def initialize
|
|
20
|
+
CONFIGURABLE_OPTIONS.each do |key, default_value|
|
|
21
|
+
self.send(:"#{key}=", default_value.dup)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def timeout_seconds(total:, connect: nil)
|
|
26
|
+
timeouts = { total:, connect:, }.compact
|
|
27
|
+
|
|
28
|
+
self.timeouts = timeouts
|
|
9
29
|
end
|
|
10
30
|
|
|
11
31
|
def dup
|
|
12
|
-
|
|
32
|
+
options = to_h
|
|
33
|
+
self.class.new.tap do |instance|
|
|
34
|
+
options.each do |key, value|
|
|
35
|
+
instance.send(:"#{key}=", value.dup)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
13
38
|
end
|
|
14
39
|
end
|
|
15
40
|
end
|
data/nxt_http_client.gemspec
CHANGED
|
@@ -8,23 +8,11 @@ Gem::Specification.new do |spec|
|
|
|
8
8
|
spec.authors = ["Andreas Robecke", "Nils Sommer", "Raphael Kallensee", "Luetfi Demirci"]
|
|
9
9
|
spec.email = ["a.robecke@getsafe.de"]
|
|
10
10
|
|
|
11
|
-
spec.summary = %q{
|
|
12
|
-
spec.description = %q{
|
|
13
|
-
spec.homepage = "https://github.com/nxt-insurance"
|
|
11
|
+
spec.summary = %q{NxtHttpClient is a simple DSL on top the typhoeus http gem}
|
|
12
|
+
spec.description = %q{NxtHttpClient allows you to easily create and configure http clients.}
|
|
13
|
+
spec.homepage = "https://github.com/nxt-insurance/nxt_http_client"
|
|
14
14
|
spec.license = "MIT"
|
|
15
15
|
|
|
16
|
-
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
|
17
|
-
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
|
18
|
-
if spec.respond_to?(:metadata)
|
|
19
|
-
spec.metadata["allowed_push_host"] = 'https://rubygems.org'
|
|
20
|
-
|
|
21
|
-
spec.metadata["homepage_uri"] = spec.homepage
|
|
22
|
-
spec.metadata["source_code_uri"] = "https://github.com/nxt-insurance/nxt_http_client"
|
|
23
|
-
else
|
|
24
|
-
raise "RubyGems 2.0 or newer is required to protect against " \
|
|
25
|
-
"public gem pushes."
|
|
26
|
-
end
|
|
27
|
-
|
|
28
16
|
# Specify which files should be added to the gem when it is released.
|
|
29
17
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
30
18
|
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: nxt_http_client
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andreas Robecke
|
|
@@ -11,7 +11,7 @@ authors:
|
|
|
11
11
|
autorequire:
|
|
12
12
|
bindir: exe
|
|
13
13
|
cert_chain: []
|
|
14
|
-
date: 2023-
|
|
14
|
+
date: 2023-08-31 00:00:00.000000000 Z
|
|
15
15
|
dependencies:
|
|
16
16
|
- !ruby/object:Gem::Dependency
|
|
17
17
|
name: typhoeus
|
|
@@ -195,7 +195,7 @@ dependencies:
|
|
|
195
195
|
- - ">="
|
|
196
196
|
- !ruby/object:Gem::Version
|
|
197
197
|
version: '0'
|
|
198
|
-
description:
|
|
198
|
+
description: NxtHttpClient allows you to easily create and configure http clients.
|
|
199
199
|
email:
|
|
200
200
|
- a.robecke@getsafe.de
|
|
201
201
|
executables: []
|
|
@@ -229,13 +229,10 @@ files:
|
|
|
229
229
|
- lib/nxt_http_client/undefined.rb
|
|
230
230
|
- lib/nxt_http_client/version.rb
|
|
231
231
|
- nxt_http_client.gemspec
|
|
232
|
-
homepage: https://github.com/nxt-insurance
|
|
232
|
+
homepage: https://github.com/nxt-insurance/nxt_http_client
|
|
233
233
|
licenses:
|
|
234
234
|
- MIT
|
|
235
|
-
metadata:
|
|
236
|
-
allowed_push_host: https://rubygems.org
|
|
237
|
-
homepage_uri: https://github.com/nxt-insurance
|
|
238
|
-
source_code_uri: https://github.com/nxt-insurance/nxt_http_client
|
|
235
|
+
metadata: {}
|
|
239
236
|
post_install_message:
|
|
240
237
|
rdoc_options: []
|
|
241
238
|
require_paths:
|
|
@@ -251,8 +248,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
251
248
|
- !ruby/object:Gem::Version
|
|
252
249
|
version: '0'
|
|
253
250
|
requirements: []
|
|
254
|
-
rubygems_version: 3.
|
|
251
|
+
rubygems_version: 3.4.10
|
|
255
252
|
signing_key:
|
|
256
253
|
specification_version: 4
|
|
257
|
-
summary:
|
|
254
|
+
summary: NxtHttpClient is a simple DSL on top the typhoeus http gem
|
|
258
255
|
test_files: []
|