lhc 11.2.0 → 12.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +89 -73
- data/lhc.gemspec +1 -1
- data/lib/lhc/interceptors/auth.rb +10 -8
- data/lib/lhc/request.rb +2 -2
- data/lib/lhc/version.rb +1 -1
- data/spec/interceptors/auth/body_spec.rb +36 -0
- data/spec/interceptors/auth/long_basic_auth_credentials_spec.rb +17 -0
- data/spec/interceptors/retry/main_spec.rb +1 -1
- data/spec/request/error_handling_spec.rb +3 -3
- data/spec/request/ignore_errors_spec.rb +6 -6
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 20beb1550ea6286010ac46dd969bcdd8cdcc4dbb968d5ebbfdf3b591eb118fb1
|
4
|
+
data.tar.gz: c219d6d5bfb4b7a00e7c2d2273162d2cf3b1d106742dc803e9abfaa0987c0fae
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 609167a963677ba5191a5579a43b9740c08b16be259041da52cb5459e5e5c0eb481361a4115323b6bfa1c444b068669760dc530a5cbaea35af747f63650cea62
|
7
|
+
data.tar.gz: 47e4cbc20c4ab60befb908c719b0c7625a982325b7b756c48ceedec11f649c082c0715a26b0e8f76ce6124b1ef5dd2b0df475e1c13cfef568147b989a317dbe7
|
data/README.md
CHANGED
@@ -1,6 +1,3 @@
|
|
1
|
-
LHC
|
2
|
-
===
|
3
|
-
|
4
1
|
LHC is an extended/advanced HTTP client. Implementing basic http-communication enhancements like interceptors, exception handling, format handling, accessing response data, configuring endpoints and placeholders and fully compatible, RFC-compliant URL-template support.
|
5
2
|
|
6
3
|
LHC uses [typhoeus](https://github.com/typhoeus/typhoeus) for low level http communication.
|
@@ -30,69 +27,72 @@ use it like:
|
|
30
27
|
```
|
31
28
|
|
32
29
|
## Table of contents
|
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
|
-
|
30
|
+
* [Quick start guide](#quick-start-guide)
|
31
|
+
* [Basic methods](#basic-methods)
|
32
|
+
* [Request](#request)
|
33
|
+
* [Formats](#formats)
|
34
|
+
* [Default format](#default-format)
|
35
|
+
* [Unformatted requests](#unformatted-requests)
|
36
|
+
* [Upload with LHC](#upload-with-lhc)
|
37
|
+
* [Parallel requests](#parallel-requests)
|
38
|
+
* [Follow redirects](#follow-redirects)
|
39
|
+
* [Transfer data through the request body](#transfer-data-through-the-request-body)
|
40
|
+
* [Request parameters](#request-parameters)
|
41
|
+
* [Array Parameter Encoding](#array-parameter-encoding)
|
42
|
+
* [Request URL encoding](#request-url-encoding)
|
43
|
+
* [Request URL-Templates](#request-url-templates)
|
44
|
+
* [Request timeout](#request-timeout)
|
45
|
+
* [Request Agent](#request-agent)
|
46
|
+
* [Response](#response)
|
47
|
+
* [Accessing response data](#accessing-response-data)
|
48
|
+
* [Exceptions](#exceptions)
|
49
|
+
* [Custom error handling (rescue)](#custom-error-handling-rescue)
|
50
|
+
* [Ignore certain errors](#ignore-certain-errors)
|
51
|
+
* [Configuration](#configuration)
|
52
|
+
* [Configuring endpoints](#configuring-endpoints)
|
53
|
+
* [Configuring placeholders](#configuring-placeholders)
|
54
|
+
* [Interceptors](#interceptors)
|
55
|
+
* [Quick start: Configure/Enable Interceptors](#quick-start-configureenable-interceptors)
|
56
|
+
* [Interceptors on local request level](#interceptors-on-local-request-level)
|
57
|
+
* [Core Interceptors](#core-interceptors)
|
58
|
+
* [Authentication Interceptor](#authentication-interceptor)
|
59
|
+
* [Bearer Authentication](#bearer-authentication)
|
60
|
+
* [Basic Authentication](#basic-authentication)
|
61
|
+
* [Body Authentication](#body-authentication)
|
62
|
+
* [Reauthenticate](#reauthenticate)
|
63
|
+
* [Bearer Authentication with client access token](#bearer-authentication-with-client-access-token)
|
64
|
+
* [Caching Interceptor](#caching-interceptor)
|
65
|
+
* [Options](#options)
|
66
|
+
* [Default Timeout Interceptor](#default-timeout-interceptor)
|
67
|
+
* [Overwrite defaults](#overwrite-defaults)
|
68
|
+
* [Logging Interceptor](#logging-interceptor)
|
69
|
+
* [Installation](#installation)
|
70
|
+
* [What and how it logs](#what-and-how-it-logs)
|
71
|
+
* [Configure](#configure)
|
72
|
+
* [Monitoring Interceptor](#monitoring-interceptor)
|
73
|
+
* [Installation](#installation-1)
|
74
|
+
* [Environment](#environment)
|
75
|
+
* [What it tracks](#what-it-tracks)
|
76
|
+
* [Configure](#configure-1)
|
77
|
+
* [Prometheus Interceptor](#prometheus-interceptor)
|
78
|
+
* [Retry Interceptor](#retry-interceptor)
|
79
|
+
* [Limit the amount of retries while making the request](#limit-the-amount-of-retries-while-making-the-request)
|
80
|
+
* [Change the default maximum of retries of the retry interceptor](#change-the-default-maximum-of-retries-of-the-retry-interceptor)
|
81
|
+
* [Retry all requests](#retry-all-requests)
|
82
|
+
* [Do not retry certain response codes](#do-not-retry-certain-response-codes)
|
83
|
+
* [Rollbar Interceptor](#rollbar-interceptor)
|
84
|
+
* [Forward additional parameters](#forward-additional-parameters)
|
85
|
+
* [Throttle](#throttle)
|
86
|
+
* [Zipkin](#zipkin)
|
87
|
+
* [Create an interceptor from scratch](#create-an-interceptor-from-scratch)
|
88
|
+
* [Interceptor callbacks](#interceptor-callbacks)
|
89
|
+
* [Interceptor request/response](#interceptor-requestresponse)
|
90
|
+
* [Provide a response replacement through an interceptor](#provide-a-response-replacement-through-an-interceptor)
|
91
|
+
* [Testing](#testing)
|
92
|
+
* [License](#license)
|
93
|
+
|
94
|
+
|
95
|
+
|
96
96
|
|
97
97
|
## Basic methods
|
98
98
|
|
@@ -403,7 +403,7 @@ timeout? => LHC::Timeout
|
|
403
403
|
anything_else => LHC::UnknownError
|
404
404
|
```
|
405
405
|
|
406
|
-
### Custom error handling
|
406
|
+
### Custom error handling (rescue)
|
407
407
|
|
408
408
|
You can provide custom error handlers to handle errors happening during the request.
|
409
409
|
|
@@ -413,19 +413,21 @@ If your error handler returns anything else but `nil` it replaces the response b
|
|
413
413
|
|
414
414
|
```ruby
|
415
415
|
handler = ->(response){ do_something_with_response; return {name: 'unknown'} }
|
416
|
-
response = LHC.get('http://something',
|
416
|
+
response = LHC.get('http://something', rescue: handler)
|
417
417
|
response.data.name # 'unknown'
|
418
418
|
```
|
419
419
|
|
420
420
|
### Ignore certain errors
|
421
421
|
|
422
422
|
As it's discouraged to rescue errors and then don't handle them (ruby styleguide)[https://github.com/bbatsov/ruby-style-guide#dont-hide-exceptions],
|
423
|
-
but you often want to continue working with `nil`, LHC provides the `
|
423
|
+
but you often want to continue working with `nil`, LHC provides the `ignore` option.
|
424
424
|
|
425
425
|
Errors listed in this option will not be raised and will leave the `response.body` and `response.data` to stay `nil`.
|
426
426
|
|
427
|
+
You can either pass the LHC error class you want to be ignored or an array of LHC error classes.
|
428
|
+
|
427
429
|
```ruby
|
428
|
-
response = LHC.get('http://something',
|
430
|
+
response = LHC.get('http://something', ignore: LHC::NotFound)
|
429
431
|
|
430
432
|
response.body # nil
|
431
433
|
response.data # nil
|
@@ -549,6 +551,20 @@ Adds the following header to the request:
|
|
549
551
|
|
550
552
|
Which is the base64 encoded credentials "username:password".
|
551
553
|
|
554
|
+
##### Body Authentication
|
555
|
+
|
556
|
+
```ruby
|
557
|
+
LHC.post('http://local.ch', auth: { body: { userToken: 'dheur5hrk3' } })
|
558
|
+
```
|
559
|
+
|
560
|
+
Adds the following to body of all requests:
|
561
|
+
|
562
|
+
```
|
563
|
+
{
|
564
|
+
"userToken": "dheur5hrk3"
|
565
|
+
}
|
566
|
+
```
|
567
|
+
|
552
568
|
##### Reauthenticate
|
553
569
|
|
554
570
|
The current implementation can only offer reauthenticate for _client access tokens_. For this to work the following has to be given:
|
@@ -817,16 +833,16 @@ If you want to retry all requests made from your application, you just need to c
|
|
817
833
|
|
818
834
|
##### Do not retry certain response codes
|
819
835
|
|
820
|
-
If you do not want to retry based on certain response codes, use retry in combination with explicit `
|
836
|
+
If you do not want to retry based on certain response codes, use retry in combination with explicit `ignore`:
|
821
837
|
|
822
838
|
```ruby
|
823
|
-
LHC.get('http://local.ch',
|
839
|
+
LHC.get('http://local.ch', ignore: LHC::NotFound, retry: { max: 1 })
|
824
840
|
```
|
825
841
|
|
826
842
|
Or if you use `LHC::Retry.all`:
|
827
843
|
|
828
844
|
```ruby
|
829
|
-
LHC.get('http://local.ch',
|
845
|
+
LHC.get('http://local.ch', ignore: LHC::NotFound)
|
830
846
|
```
|
831
847
|
|
832
848
|
#### Rollbar Interceptor
|
data/lhc.gemspec
CHANGED
@@ -4,8 +4,13 @@ class LHC::Auth < LHC::Interceptor
|
|
4
4
|
include ActiveSupport::Configurable
|
5
5
|
config_accessor :refresh_client_token
|
6
6
|
|
7
|
+
def before_raw_request
|
8
|
+
body_authentication! if auth_options[:body]
|
9
|
+
end
|
10
|
+
|
7
11
|
def before_request
|
8
|
-
|
12
|
+
bearer_authentication! if auth_options[:bearer]
|
13
|
+
basic_authentication! if auth_options[:basic]
|
9
14
|
end
|
10
15
|
|
11
16
|
def after_response
|
@@ -16,18 +21,15 @@ class LHC::Auth < LHC::Interceptor
|
|
16
21
|
|
17
22
|
private
|
18
23
|
|
19
|
-
def
|
20
|
-
|
21
|
-
|
22
|
-
elsif auth_options[:basic]
|
23
|
-
basic_authentication!
|
24
|
-
end
|
24
|
+
def body_authentication!
|
25
|
+
auth = auth_options[:body]
|
26
|
+
request.options[:body] = (request.options[:body] || {}).merge(auth)
|
25
27
|
end
|
26
28
|
|
27
29
|
def basic_authentication!
|
28
30
|
auth = auth_options[:basic]
|
29
31
|
credentials = "#{auth[:username]}:#{auth[:password]}"
|
30
|
-
set_authorization_header("Basic #{Base64.
|
32
|
+
set_authorization_header("Basic #{Base64.strict_encode64(credentials).chomp}")
|
31
33
|
end
|
32
34
|
|
33
35
|
def bearer_authentication!
|
data/lib/lhc/request.rb
CHANGED
@@ -15,10 +15,10 @@ class LHC::Request
|
|
15
15
|
attr_accessor :response, :options, :raw, :format, :error_handler, :errors_ignored, :source
|
16
16
|
|
17
17
|
def initialize(options, self_executing = true)
|
18
|
-
self.errors_ignored = (options.fetch(:
|
18
|
+
self.errors_ignored = (options.fetch(:ignore, []) || []).to_a.compact
|
19
19
|
self.source = options&.dig(:source)
|
20
20
|
self.options = format!(options.deep_dup || {})
|
21
|
-
self.error_handler = options.delete :
|
21
|
+
self.error_handler = options.delete :rescue
|
22
22
|
use_configured_endpoint!
|
23
23
|
generate_url_from_template!
|
24
24
|
self.interceptors = LHC::Interceptors.new(self)
|
data/lib/lhc/version.rb
CHANGED
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
describe LHC::Auth do
|
6
|
+
before(:each) do
|
7
|
+
LHC.config.interceptors = [LHC::Auth]
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'adds body authentication to the existing request body' do
|
11
|
+
stub_request(:post, "http://local.ch/")
|
12
|
+
.with(body: {
|
13
|
+
message: 'body',
|
14
|
+
userToken: 'dheur5hrk3'
|
15
|
+
}.to_json)
|
16
|
+
|
17
|
+
LHC.post('http://local.ch', auth: { body: { userToken: 'dheur5hrk3' } }, body: {
|
18
|
+
message: 'body'
|
19
|
+
})
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'adds body authentication to an empty request body' do
|
23
|
+
stub_request(:post, "http://local.ch/")
|
24
|
+
.with(body: {
|
25
|
+
userToken: 'dheur5hrk3'
|
26
|
+
}.to_json)
|
27
|
+
|
28
|
+
LHC.post('http://local.ch', auth: { body: { userToken: 'dheur5hrk3' } })
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'adds nothing if request method is GET' do
|
32
|
+
stub_request(:get, "http://local.ch/")
|
33
|
+
|
34
|
+
LHC.get('http://local.ch', auth: { body: { userToken: 'dheur5hrk3' } })
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
describe LHC::Auth do
|
6
|
+
before(:each) do
|
7
|
+
LHC.config.interceptors = [LHC::Auth]
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'adds basic auth in a correct way even if username and password are especially long' do
|
11
|
+
options = { basic: { username: '123456789101234', password: '12345678901234567890123456789012' } }
|
12
|
+
LHC.config.endpoint(:local, 'http://local.ch', auth: options)
|
13
|
+
stub_request(:get, 'http://local.ch')
|
14
|
+
.with(headers: { 'Authorization' => 'Basic MTIzNDU2Nzg5MTAxMjM0OjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEy' })
|
15
|
+
LHC.get(:local)
|
16
|
+
end
|
17
|
+
end
|
@@ -66,7 +66,7 @@ describe LHC::Rollbar do
|
|
66
66
|
|
67
67
|
it 'does not retry if the error is explicitly ignored' do
|
68
68
|
request_stub
|
69
|
-
LHC.get('http://local.ch', retry: { max: 1 },
|
69
|
+
LHC.get('http://local.ch', retry: { max: 1 }, ignore: [LHC::NotFound])
|
70
70
|
expect(request_stub).to have_been_requested.times(1)
|
71
71
|
end
|
72
72
|
end
|
@@ -67,21 +67,21 @@ describe LHC::Request do
|
|
67
67
|
it 'handles errors with the provided handler and does not raise them' do
|
68
68
|
stub_request(:get, "http://something").to_return(status: 400)
|
69
69
|
handler = double('handler', call: -> {})
|
70
|
-
LHC::Request.new(url: "http://something",
|
70
|
+
LHC::Request.new(url: "http://something", rescue: handler)
|
71
71
|
expect(handler).to have_received(:call)
|
72
72
|
end
|
73
73
|
|
74
74
|
it 'exchanges body with handlers return if the handler returns something' do
|
75
75
|
stub_request(:get, "http://something").to_return(status: 400)
|
76
76
|
handler = ->(_response) { { name: 'unknown' }.to_json }
|
77
|
-
request = LHC::Request.new(url: "http://something",
|
77
|
+
request = LHC::Request.new(url: "http://something", rescue: handler)
|
78
78
|
expect(request.response.data.name).to eq 'unknown'
|
79
79
|
end
|
80
80
|
|
81
81
|
it 'does not exchange body with handlers return if the handler returns nil' do
|
82
82
|
stub_request(:get, "http://something").to_return(status: 400, body: { message: 'an error occurred' }.to_json)
|
83
83
|
handler = ->(_response) { nil }
|
84
|
-
request = LHC::Request.new(url: "http://something",
|
84
|
+
request = LHC::Request.new(url: "http://something", rescue: handler)
|
85
85
|
expect(request.response.data.message).to eq 'an error occurred'
|
86
86
|
end
|
87
87
|
end
|
@@ -4,7 +4,7 @@ require 'rails_helper'
|
|
4
4
|
|
5
5
|
describe LHC::Request do
|
6
6
|
context 'ignoring LHC::NotFound' do
|
7
|
-
let(:response) { LHC.get('http://local.ch',
|
7
|
+
let(:response) { LHC.get('http://local.ch', ignore: [LHC::NotFound]) }
|
8
8
|
|
9
9
|
before { stub_request(:get, 'http://local.ch').to_return(status: 404) }
|
10
10
|
|
@@ -36,13 +36,13 @@ describe LHC::Request do
|
|
36
36
|
|
37
37
|
it "does not raise an error when it's a subclass of the ignored error" do
|
38
38
|
expect {
|
39
|
-
LHC.get('http://local.ch',
|
39
|
+
LHC.get('http://local.ch', ignore: [LHC::Error])
|
40
40
|
}.not_to raise_error
|
41
41
|
end
|
42
42
|
|
43
43
|
it "does raise an error if it's not a subclass of the ignored error" do
|
44
44
|
expect {
|
45
|
-
LHC.get('http://local.ch',
|
45
|
+
LHC.get('http://local.ch', ignore: [ArgumentError])
|
46
46
|
}.to raise_error(LHC::NotFound)
|
47
47
|
end
|
48
48
|
end
|
@@ -52,13 +52,13 @@ describe LHC::Request do
|
|
52
52
|
|
53
53
|
it "does not raise an error when ignored errors is set to array with nil" do
|
54
54
|
expect {
|
55
|
-
LHC.get('http://local.ch',
|
55
|
+
LHC.get('http://local.ch', ignore: [nil])
|
56
56
|
}.to raise_error(LHC::NotFound)
|
57
57
|
end
|
58
58
|
|
59
59
|
it "does not raise an error when ignored errors is set to nil" do
|
60
60
|
expect {
|
61
|
-
LHC.get('http://local.ch',
|
61
|
+
LHC.get('http://local.ch', ignore: nil)
|
62
62
|
}.to raise_error(LHC::NotFound)
|
63
63
|
end
|
64
64
|
end
|
@@ -67,7 +67,7 @@ describe LHC::Request do
|
|
67
67
|
before { stub_request(:get, 'http://local.ch').to_return(status: 404) }
|
68
68
|
|
69
69
|
it "does not raise an error when ignored errors is a key instead of an array" do
|
70
|
-
LHC.get('http://local.ch',
|
70
|
+
LHC.get('http://local.ch', ignore: LHC::NotFound)
|
71
71
|
end
|
72
72
|
end
|
73
73
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lhc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 12.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- https://github.com/local-ch/lhc/contributors
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-07-
|
11
|
+
date: 2020-07-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -325,6 +325,8 @@ files:
|
|
325
325
|
- spec/interceptors/after_response_spec.rb
|
326
326
|
- spec/interceptors/auth/basic_auth_spec.rb
|
327
327
|
- spec/interceptors/auth/bearer_spec.rb
|
328
|
+
- spec/interceptors/auth/body_spec.rb
|
329
|
+
- spec/interceptors/auth/long_basic_auth_credentials_spec.rb
|
328
330
|
- spec/interceptors/auth/reauthentication_configuration_spec.rb
|
329
331
|
- spec/interceptors/auth/reauthentication_spec.rb
|
330
332
|
- spec/interceptors/before_request_spec.rb
|
@@ -384,7 +386,7 @@ files:
|
|
384
386
|
- spec/timeouts/timings_spec.rb
|
385
387
|
homepage: https://github.com/local-ch/lhc
|
386
388
|
licenses:
|
387
|
-
- GPL-3
|
389
|
+
- GPL-3.0
|
388
390
|
metadata: {}
|
389
391
|
post_install_message:
|
390
392
|
rdoc_options: []
|
@@ -475,6 +477,8 @@ test_files:
|
|
475
477
|
- spec/interceptors/after_response_spec.rb
|
476
478
|
- spec/interceptors/auth/basic_auth_spec.rb
|
477
479
|
- spec/interceptors/auth/bearer_spec.rb
|
480
|
+
- spec/interceptors/auth/body_spec.rb
|
481
|
+
- spec/interceptors/auth/long_basic_auth_credentials_spec.rb
|
478
482
|
- spec/interceptors/auth/reauthentication_configuration_spec.rb
|
479
483
|
- spec/interceptors/auth/reauthentication_spec.rb
|
480
484
|
- spec/interceptors/before_request_spec.rb
|