lhc 11.0.2 → 12.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '08a828482abe7ecd92b963be2f85a921d5d33c21386048c0de1dd5eddd7a0c5d'
4
- data.tar.gz: afbe59a64dbf4e6a772aa045c6717694fc45c99f08818eb3892cfc3df3d24607
3
+ metadata.gz: 640050193c04d507d98ed7538bc526c3693dcef5cb1ee2c07ff99c908c171f96
4
+ data.tar.gz: e8c0772f3d7258f16a8c2b069b2f00040f6592d55d7daecbccc6ec58cb15b736
5
5
  SHA512:
6
- metadata.gz: ca154508dfeab839682d6cc9babd7d9ac3fd194ff318f0132fd05399aea04dcd155c9cf77b679ae91be6fef0971b2c13de0c14673b7f90beff77ca13d8bc2a42
7
- data.tar.gz: e24477b6e9cc94aa1faa1c3b4e366d59b466df46c9abb4a914255316cd4a9b5eef192f70157df5c50c38422b738b6b384f692180cd415b7bfd19398d87b91fa3
6
+ metadata.gz: f184fa4ea6eb799b474a747c1dbd519c4ddbf5d47867cca507525892c204d71bb7cc537411dbbf6afe4385d9f827413c8e918d19440fdcc47bc0b3c9b911050f
7
+ data.tar.gz: a7770bacfad84efe0a1c821bc2d8c02c1f3903ed2c3754f23ca5a4b290c66f975bd2af2773456b334fe35c4a0166b5ee55daff030965a62e670d472946dc1351
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,70 @@ use it like:
30
27
  ```
31
28
 
32
29
  ## Table of contents
33
- * [LHC](#lhc)
34
- * [Quick start guide](#quick-start-guide)
35
- * [Table of contents](#table-of-contents)
36
- * [Basic methods](#basic-methods)
37
- * [Request](#request)
38
- * [Formats](#formats)
39
- * [Default format](#default-format)
40
- * [Unformatted requests](#unformatted-requests)
41
- * [Upload with LHC](#upload-with-lhc)
42
- * [Parallel requests](#parallel-requests)
43
- * [Follow redirects](#follow-redirects)
44
- * [Transfer data through the request body](#transfer-data-through-the-request-body)
45
- * [Request parameters](#request-parameters)
46
- * [Array Parameter Encoding](#array-parameter-encoding)
47
- * [Request URL encoding](#request-url-encoding)
48
- * [Request URL-Templates](#request-url-templates)
49
- * [Request timeout](#request-timeout)
50
- * [Request Agent](#request-agent)
51
- * [Response](#response)
52
- * [Accessing response data](#accessing-response-data)
53
- * [Exceptions](#exceptions)
54
- * [Custom error handling](#custom-error-handling)
55
- * [Ignore certain errors](#ignore-certain-errors)
56
- * [Configuration](#configuration)
57
- * [Configuring endpoints](#configuring-endpoints)
58
- * [Configuring placeholders](#configuring-placeholders)
59
- * [Interceptors](#interceptors)
60
- * [Quick start: Configure/Enable Interceptors](#quick-start-configureenable-interceptors)
61
- * [Interceptors on local request level](#interceptors-on-local-request-level)
62
- * [Core Interceptors](#core-interceptors)
63
- * [Authentication Interceptor](#authentication-interceptor)
64
- * [Bearer Authentication](#bearer-authentication)
65
- * [Basic Authentication](#basic-authentication)
66
- * [Reauthenticate](#reauthenticate)
67
- * [Bearer Authentication with client access token](#bearer-authentication-with-client-access-token)
68
- * [Caching Interceptor](#caching-interceptor)
69
- * [Options](#options)
70
- * [Default Timeout Interceptor](#default-timeout-interceptor)
71
- * [Overwrite defaults](#overwrite-defaults)
72
- * [Logging Interceptor](#logging-interceptor)
73
- * [Installation](#installation)
74
- * [What and how it logs](#what-and-how-it-logs)
75
- * [Configure](#configure)
76
- * [Monitoring Interceptor](#monitoring-interceptor)
77
- * [Installation](#installation-1)
78
- * [Environment](#environment)
79
- * [What it tracks](#what-it-tracks)
80
- * [Configure](#configure-1)
81
- * [Prometheus Interceptor](#prometheus-interceptor)
82
- * [Retry Interceptor](#retry-interceptor)
83
- * [Limit the amount of retries while making the request](#limit-the-amount-of-retries-while-making-the-request)
84
- * [Change the default maximum of retries of the retry interceptor](#change-the-default-maximum-of-retries-of-the-retry-interceptor)
85
- * [Retry all requests](#retry-all-requests)
86
- * [Rollbar Interceptor](#rollbar-interceptor)
87
- * [Forward additional parameters](#forward-additional-parameters)
88
- * [Throttle](#throttle)
89
- * [Zipkin](#zipkin)
90
- * [Create an interceptor from scratch](#create-an-interceptor-from-scratch)
91
- * [Interceptor callbacks](#interceptor-callbacks)
92
- * [Interceptor request/response](#interceptor-requestresponse)
93
- * [Provide a response replacement through an interceptor](#provide-a-response-replacement-through-an-interceptor)
94
- * [Testing](#testing)
95
- * [License](#license)
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
+ * [Reauthenticate](#reauthenticate)
62
+ * [Bearer Authentication with client access token](#bearer-authentication-with-client-access-token)
63
+ * [Caching Interceptor](#caching-interceptor)
64
+ * [Options](#options)
65
+ * [Default Timeout Interceptor](#default-timeout-interceptor)
66
+ * [Overwrite defaults](#overwrite-defaults)
67
+ * [Logging Interceptor](#logging-interceptor)
68
+ * [Installation](#installation)
69
+ * [What and how it logs](#what-and-how-it-logs)
70
+ * [Configure](#configure)
71
+ * [Monitoring Interceptor](#monitoring-interceptor)
72
+ * [Installation](#installation-1)
73
+ * [Environment](#environment)
74
+ * [What it tracks](#what-it-tracks)
75
+ * [Configure](#configure-1)
76
+ * [Prometheus Interceptor](#prometheus-interceptor)
77
+ * [Retry Interceptor](#retry-interceptor)
78
+ * [Limit the amount of retries while making the request](#limit-the-amount-of-retries-while-making-the-request)
79
+ * [Change the default maximum of retries of the retry interceptor](#change-the-default-maximum-of-retries-of-the-retry-interceptor)
80
+ * [Retry all requests](#retry-all-requests)
81
+ * [Do not retry certain response codes](#do-not-retry-certain-response-codes)
82
+ * [Rollbar Interceptor](#rollbar-interceptor)
83
+ * [Forward additional parameters](#forward-additional-parameters)
84
+ * [Throttle](#throttle)
85
+ * [Zipkin](#zipkin)
86
+ * [Create an interceptor from scratch](#create-an-interceptor-from-scratch)
87
+ * [Interceptor callbacks](#interceptor-callbacks)
88
+ * [Interceptor request/response](#interceptor-requestresponse)
89
+ * [Provide a response replacement through an interceptor](#provide-a-response-replacement-through-an-interceptor)
90
+ * [Testing](#testing)
91
+ * [License](#license)
92
+
93
+
96
94
 
97
95
  ## Basic methods
98
96
 
@@ -403,7 +401,7 @@ timeout? => LHC::Timeout
403
401
  anything_else => LHC::UnknownError
404
402
  ```
405
403
 
406
- ### Custom error handling
404
+ ### Custom error handling (rescue)
407
405
 
408
406
  You can provide custom error handlers to handle errors happening during the request.
409
407
 
@@ -413,19 +411,21 @@ If your error handler returns anything else but `nil` it replaces the response b
413
411
 
414
412
  ```ruby
415
413
  handler = ->(response){ do_something_with_response; return {name: 'unknown'} }
416
- response = LHC.get('http://something', error_handler: handler)
414
+ response = LHC.get('http://something', rescue: handler)
417
415
  response.data.name # 'unknown'
418
416
  ```
419
417
 
420
418
  ### Ignore certain errors
421
419
 
422
420
  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 `ignored_errors` option.
421
+ but you often want to continue working with `nil`, LHC provides the `ignore` option.
424
422
 
425
423
  Errors listed in this option will not be raised and will leave the `response.body` and `response.data` to stay `nil`.
426
424
 
425
+ You can either pass the LHC error class you want to be ignored or an array of LHC error classes.
426
+
427
427
  ```ruby
428
- response = LHC.get('http://something', ignored_errors: [LHC::NotFound])
428
+ response = LHC.get('http://something', ignore: LHC::NotFound)
429
429
 
430
430
  response.body # nil
431
431
  response.data # nil
@@ -817,16 +817,16 @@ If you want to retry all requests made from your application, you just need to c
817
817
 
818
818
  ##### Do not retry certain response codes
819
819
 
820
- If you do not want to retry based on certain response codes, use retry in combination with explicit `ignore_errors`:
820
+ If you do not want to retry based on certain response codes, use retry in combination with explicit `ignore`:
821
821
 
822
822
  ```ruby
823
- LHC.get('http://local.ch', ignore_errors: [LHC::NotFound], retry: { max: 1 })
823
+ LHC.get('http://local.ch', ignore: LHC::NotFound, retry: { max: 1 })
824
824
  ```
825
825
 
826
826
  Or if you use `LHC::Retry.all`:
827
827
 
828
828
  ```ruby
829
- LHC.get('http://local.ch', ignore_errors: [LHC::NotFound])
829
+ LHC.get('http://local.ch', ignore: LHC::NotFound)
830
830
  ```
831
831
 
832
832
  #### Rollbar Interceptor
@@ -5,6 +5,10 @@ module LHC
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  module ClassMethods
8
+ def form
9
+ LHC::Formats::Form
10
+ end
11
+
8
12
  def json
9
13
  LHC::Formats::JSON
10
14
  end
@@ -59,6 +59,10 @@ class LHC::Error < StandardError
59
59
  self.response = response
60
60
  end
61
61
 
62
+ def self.to_a
63
+ [self]
64
+ end
65
+
62
66
  def to_s
63
67
  return response if response.is_a?(String)
64
68
  request = response.request
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LHC::Formats
4
+ autoload :Form, 'lhc/formats/form'
4
5
  autoload :JSON, 'lhc/formats/json'
5
6
  autoload :Multipart, 'lhc/formats/multipart'
6
7
  autoload :Plain, 'lhc/formats/plain'
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LHC::Formats
4
+ class Form < LHC::Format
5
+ include LHC::BasicMethodsConcern
6
+
7
+ def self.request(options)
8
+ options[:format] = new
9
+ super(options)
10
+ end
11
+
12
+ def format_options(options)
13
+ options[:headers] ||= {}
14
+ no_content_type_header!(options)
15
+ options[:headers]['Content-Type'] = 'application/x-www-form-urlencoded'
16
+ options
17
+ end
18
+
19
+ def as_json(input)
20
+ parse(input)
21
+ end
22
+
23
+ def as_open_struct(input)
24
+ parse(input)
25
+ end
26
+
27
+ def to_body(input)
28
+ input
29
+ end
30
+
31
+ def to_s
32
+ 'form'
33
+ end
34
+
35
+ def to_sym
36
+ to_s.to_sym
37
+ end
38
+
39
+ private
40
+
41
+ def parse(input)
42
+ input
43
+ end
44
+ end
45
+ end
@@ -66,7 +66,7 @@ class LHC::Auth < LHC::Interceptor
66
66
  end
67
67
 
68
68
  def bearer_header_present?
69
- @has_bearer_header ||= request.headers['Authorization'] =~ /^Bearer [0-9a-f-]+$/i
69
+ @has_bearer_header ||= request.headers['Authorization'] =~ /^Bearer .+$/i
70
70
  end
71
71
 
72
72
  def refresh_client_token_option
@@ -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(:ignored_errors, []) || []).compact
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 :error_handler
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)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LHC
4
- VERSION ||= '11.0.2'
4
+ VERSION ||= '12.0.1'
5
5
  end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHC do
6
+ include ActionDispatch::TestProcess
7
+
8
+ context 'form' do
9
+ it 'formats requests to be application/x-www-form-urlencoded' do
10
+ stub = stub_request(:post, 'http://local.ch/')
11
+ .with(body: 'client_id=1234&client_secret=4567&grant_type=client_credentials')
12
+ .with(headers: { 'Content-Type': 'application/x-www-form-urlencoded' })
13
+ .to_return(status: 200)
14
+
15
+ LHC.form.post(
16
+ 'http://local.ch',
17
+ body: {
18
+ client_id: '1234',
19
+ client_secret: '4567',
20
+ grant_type: 'client_credentials'
21
+ }
22
+ )
23
+
24
+ expect(stub).to have_been_requested
25
+ end
26
+ end
27
+ end
@@ -10,7 +10,7 @@ describe LHC do
10
10
  let(:body) { { size: 2231 }.to_json }
11
11
  let(:location) { 'http://local.ch/uploads/image.jpg' }
12
12
 
13
- it 'leaves plains requests unformatted' do
13
+ it 'formats requests to be multipart/form-data' do
14
14
  stub_request(:post, 'http://local.ch/') do |request|
15
15
  raise 'Content-Type header wrong' unless request.headers['Content-Type'] == 'multipart/form-data'
16
16
  raise 'Body wrongly formatted' unless request.body.match(/file=%23%3CActionDispatch%3A%3AHttp%3A%3AUploadedFile%3A.*%3E&type=Image/)
@@ -31,4 +31,14 @@ describe LHC::Auth do
31
31
  LHC.config.endpoint(:local, 'http://local.ch', auth: options.merge(reauthenticated: true))
32
32
  expect { LHC.get(:local) }.to raise_error(LHC::Unauthorized)
33
33
  end
34
+
35
+ context 'token format' do
36
+ let(:initial_token) { 'BAsZ-98-ZZZ' }
37
+
38
+ it 'refreshes tokens with various formats' do
39
+ LHC.config.endpoint(:local, 'http://local.ch', auth: options)
40
+ LHC.get(:local)
41
+ expect(auth_suceeding_after_recovery).to have_been_made.once
42
+ end
43
+ end
34
44
  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 }, ignored_errors: [LHC::NotFound])
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", error_handler: handler)
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", error_handler: handler)
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", error_handler: handler)
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', ignored_errors: [LHC::NotFound]) }
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', ignored_errors: [LHC::Error])
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', ignored_errors: [ArgumentError])
45
+ LHC.get('http://local.ch', ignore: [ArgumentError])
46
46
  }.to raise_error(LHC::NotFound)
47
47
  end
48
48
  end
@@ -52,14 +52,22 @@ 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', ignored_errors: [nil])
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', ignored_errors: nil)
61
+ LHC.get('http://local.ch', ignore: nil)
62
62
  }.to raise_error(LHC::NotFound)
63
63
  end
64
64
  end
65
+
66
+ context 'passing keys instead of arrays' do
67
+ before { stub_request(:get, 'http://local.ch').to_return(status: 404) }
68
+
69
+ it "does not raise an error when ignored errors is a key instead of an array" do
70
+ LHC.get('http://local.ch', ignore: LHC::NotFound)
71
+ end
72
+ end
65
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: 11.0.2
4
+ version: 12.0.1
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-02-10 00:00:00.000000000 Z
11
+ date: 2020-07-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -230,6 +230,7 @@ files:
230
230
  - lib/lhc/errors/unknown_error.rb
231
231
  - lib/lhc/format.rb
232
232
  - lib/lhc/formats.rb
233
+ - lib/lhc/formats/form.rb
233
234
  - lib/lhc/formats/json.rb
234
235
  - lib/lhc/formats/multipart.rb
235
236
  - lib/lhc/formats/plain.rb
@@ -316,6 +317,7 @@ files:
316
317
  - spec/error/response_spec.rb
317
318
  - spec/error/timeout_spec.rb
318
319
  - spec/error/to_s_spec.rb
320
+ - spec/formats/form_spec.rb
319
321
  - spec/formats/json_spec.rb
320
322
  - spec/formats/multipart_spec.rb
321
323
  - spec/formats/plain_spec.rb
@@ -465,6 +467,7 @@ test_files:
465
467
  - spec/error/response_spec.rb
466
468
  - spec/error/timeout_spec.rb
467
469
  - spec/error/to_s_spec.rb
470
+ - spec/formats/form_spec.rb
468
471
  - spec/formats/json_spec.rb
469
472
  - spec/formats/multipart_spec.rb
470
473
  - spec/formats/plain_spec.rb