twingly-http 0.1.0 → 0.3.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c96f42ded2e94d947bd2a15cc7de75669e3f2dc06a17ff7d648eb3c0cf862c5e
4
- data.tar.gz: 5203e3833efe611708b1b185708735b2c6a027d20d8edd0e79c80dcca696d73a
3
+ metadata.gz: cc5e134cf7d77a56bda5f8d4c40ef90f6c80c0230aea262cada8c943b4defa77
4
+ data.tar.gz: ad54778da0dddff2b0bb14e4205333758a43272cfd9d6458566fbb4fc48c9816
5
5
  SHA512:
6
- metadata.gz: 6869f39208327e4b834f999e96a1a0d7253768022aca54f259c1f0cf57bf60331e4aabc966919ad0a7bef08e3091ff7090c9e576986f7d4f5336894ac47b250b
7
- data.tar.gz: 4cf992e7c60229b8fcbfd3ab62b0584e8531b229fd8a863d8ab1a47b248c5c2697eb225beecb6ec26377bce50009bf6ba295e1fee45622951be2809ffb5b4640
6
+ metadata.gz: 83b57d12d30e4a3f38c5e4b71d06d1ed894ab7ecca32495d9607bb2cf434e0f5bc1b1ffea0d4855b06e3e7791987c60ffe2d0e0c69be739bf0f5eabcb0ff4ed1
7
+ data.tar.gz: 138b97d64ed9b979c942eecd48728fd1427b26054b6c614ee19799e3046695dc7f1523c113f4f9efdb289fdfac092315f15e084e6ab3b2ad8fa723d091100ff1
data/README.md CHANGED
@@ -1,7 +1,44 @@
1
1
  # Twingly::HTTP
2
2
 
3
- Robust HTTP client
3
+ [![GitHub Build Status](https://github.com/twingly/twingly-http/workflows/CI/badge.svg?branch=master)](https://github.com/twingly/twingly-http/actions)
4
4
 
5
+ Robust HTTP client, tailored by Twingly.
6
+
7
+ ## Getting Started
8
+
9
+ Install the gem:
10
+
11
+ gem install twingly-http
12
+
13
+ Example "one-liner" usage:
14
+
15
+ ```
16
+ ruby -rlogger -rtwingly/http -e '\
17
+ logger = Logger.new(STDOUT); logger.level = :INFO; \
18
+ puts Twingly::HTTP::Client.new(logger: logger, \
19
+ base_user_agent: "").get("http://example.org").status'
20
+ ```
21
+
22
+ Example `irb` usage:
23
+
24
+ ```
25
+ irb -rlogger -rtwingly/http
26
+ ```
27
+ ```ruby
28
+ logger = Logger.new(STDOUT); logger.level = :INFO
29
+ client = Twingly::HTTP::Client.new(logger: logger, base_user_agent: "")
30
+ client.get("http://example.org").status
31
+ ```
32
+
33
+ ## Tests
34
+
35
+ The tests require [Toxiproxy](https://github.com/Shopify/toxiproxy)
36
+
37
+ docker-compose up
38
+
39
+ Run tests with
40
+
41
+ bundle exec rake
5
42
 
6
43
  ## Release workflow
7
44
 
@@ -18,6 +55,3 @@ Robust HTTP client
18
55
  github_changelog_generator
19
56
 
20
57
  [twingly-rubygems]: https://rubygems.org/profiles/twingly
21
- [ruby-prof]: http://ruby-prof.rubyforge.org/
22
- [memory_profiler]: https://github.com/SamSaffron/memory_profiler
23
- [examples]: examples/url.rb
data/lib/twingly/http.rb CHANGED
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "logger"
3
4
  require "net/http"
4
5
  require "faraday"
6
+ require "faraday_middleware"
5
7
 
6
8
  require_relative "../faraday/logfmt_logger"
7
9
  require_relative "../faraday/url_size_limit"
@@ -12,6 +14,7 @@ module Twingly
12
14
  module HTTP
13
15
  class ConnectionError < StandardError; end
14
16
  class UrlSizeLimitExceededError < StandardError; end
17
+ class RedirectLimitReachedError < StandardError; end
15
18
  class Client # rubocop:disable Metrics/ClassLength
16
19
  DEFAULT_RETRYABLE_EXCEPTIONS = [
17
20
  Faraday::ConnectionFailed,
@@ -28,6 +31,7 @@ module Twingly
28
31
  DEFAULT_NUMBER_OF_RETRIES = 0
29
32
  DEFAULT_RETRY_INTERVAL = 1
30
33
  DEFAULT_MAX_URL_SIZE_BYTES = Float::INFINITY
34
+ DEFAULT_FOLLOW_REDIRECTS_LIMIT = 3
31
35
 
32
36
  attr_writer :http_timeout
33
37
  attr_writer :http_open_timeout
@@ -36,27 +40,21 @@ module Twingly
36
40
  attr_writer :on_retry_callback
37
41
  attr_writer :max_url_size_bytes
38
42
  attr_writer :request_id
43
+ attr_writer :follow_redirects
39
44
 
45
+ attr_accessor :follow_redirects_limit
46
+ attr_accessor :logger
40
47
  attr_accessor :retryable_exceptions
41
48
 
42
- def initialize(logger:, base_user_agent:)
43
- @logger = logger
49
+ def initialize(base_user_agent:, logger: default_logger)
44
50
  @base_user_agent = base_user_agent
45
- @request_id = nil
46
-
47
- @http_timeout = DEFAULT_HTTP_TIMEOUT
48
- @http_open_timeout = DEFAULT_HTTP_OPEN_TIMEOUT
49
-
50
- @retryable_exceptions = DEFAULT_RETRYABLE_EXCEPTIONS
51
- @number_of_retries = DEFAULT_NUMBER_OF_RETRIES
52
- @retry_interval = DEFAULT_RETRY_INTERVAL
53
- @on_retry_callback = nil
51
+ @logger = logger
54
52
 
55
- @max_url_size_bytes = DEFAULT_MAX_URL_SIZE_BYTES
53
+ initialize_defaults
56
54
  end
57
55
 
58
- def get(url, params: {})
59
- http_response_for(:get, url: url, params: params)
56
+ def get(url, params: {}, headers: {})
57
+ http_response_for(:get, url: url, params: params, headers: headers)
60
58
  end
61
59
 
62
60
  def post(url, body:, headers: {})
@@ -65,13 +63,30 @@ module Twingly
65
63
 
66
64
  private
67
65
 
66
+ def default_logger
67
+ Logger.new(File::NULL)
68
+ end
69
+
70
+ def initialize_defaults
71
+ @request_id = nil
72
+ @http_timeout = DEFAULT_HTTP_TIMEOUT
73
+ @http_open_timeout = DEFAULT_HTTP_OPEN_TIMEOUT
74
+ @retryable_exceptions = DEFAULT_RETRYABLE_EXCEPTIONS
75
+ @number_of_retries = DEFAULT_NUMBER_OF_RETRIES
76
+ @retry_interval = DEFAULT_RETRY_INTERVAL
77
+ @on_retry_callback = nil
78
+ @follow_redirects = false
79
+ @follow_redirects_limit = DEFAULT_FOLLOW_REDIRECTS_LIMIT
80
+ @max_url_size_bytes = DEFAULT_MAX_URL_SIZE_BYTES
81
+ end
82
+
68
83
  # rubocop:disable Metrics/MethodLength
69
- def http_response_for(method, *args)
84
+ def http_response_for(method, **args)
70
85
  response = case method
71
86
  when :get
72
- http_get_response(*args)
87
+ http_get_response(**args)
73
88
  when :post
74
- http_post_response(*args)
89
+ http_post_response(**args)
75
90
  end
76
91
 
77
92
  Response.new(headers: response.headers.to_h,
@@ -81,14 +96,16 @@ module Twingly
81
96
  raise ConnectionError
82
97
  rescue Faraday::UrlSizeLimit::LimitExceededError => error
83
98
  raise UrlSizeLimitExceededError, error.message
99
+ rescue FaradayMiddleware::RedirectLimitReached => error
100
+ raise RedirectLimitReachedError, error.message
84
101
  end
85
102
  # rubocop:enable all
86
103
 
87
- def http_get_response(url:, params: {})
104
+ def http_get_response(url:, params:, headers:)
88
105
  binary_url = url.dup.force_encoding(Encoding::BINARY)
89
106
  http_client = create_http_client
90
107
 
91
- headers = default_headers
108
+ headers = default_headers.merge(headers)
92
109
 
93
110
  http_client.get do |request|
94
111
  request.url(binary_url)
@@ -128,6 +145,10 @@ module Twingly
128
145
  headers: true,
129
146
  bodies: true,
130
147
  request_id: @request_id
148
+ if @follow_redirects
149
+ faraday.use FaradayMiddleware::FollowRedirects,
150
+ limit: @follow_redirects_limit
151
+ end
131
152
  faraday.adapter Faraday.default_adapter
132
153
  faraday.headers[:user_agent] = user_agent
133
154
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Twingly
4
4
  module HTTP
5
- VERSION = "0.1.0"
5
+ VERSION = "0.3.2"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twingly-http
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Twingly AB
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-11-07 00:00:00.000000000 Z
11
+ date: 2021-06-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -16,14 +16,34 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.15'
19
+ version: '1'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.0.1
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '1'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.0.1
33
+ - !ruby/object:Gem::Dependency
34
+ name: faraday_middleware
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: 1.0.0
20
40
  type: :runtime
21
41
  prerelease: false
22
42
  version_requirements: !ruby/object:Gem::Requirement
23
43
  requirements:
24
44
  - - "~>"
25
45
  - !ruby/object:Gem::Version
26
- version: '0.15'
46
+ version: 1.0.0
27
47
  - !ruby/object:Gem::Dependency
28
48
  name: climate_control
29
49
  requirement: !ruby/object:Gem::Requirement
@@ -72,14 +92,14 @@ dependencies:
72
92
  requirements:
73
93
  - - "~>"
74
94
  - !ruby/object:Gem::Version
75
- version: '0.76'
95
+ version: 0.77.0
76
96
  type: :development
77
97
  prerelease: false
78
98
  version_requirements: !ruby/object:Gem::Requirement
79
99
  requirements:
80
100
  - - "~>"
81
101
  - !ruby/object:Gem::Version
82
- version: '0.76'
102
+ version: 0.77.0
83
103
  - !ruby/object:Gem::Dependency
84
104
  name: rubocop-rspec
85
105
  requirement: !ruby/object:Gem::Requirement
@@ -158,13 +178,13 @@ homepage: http://github.com/twingly/twingly-http
158
178
  licenses:
159
179
  - MIT
160
180
  metadata: {}
161
- post_install_message:
181
+ post_install_message:
162
182
  rdoc_options: []
163
183
  require_paths:
164
184
  - lib
165
185
  required_ruby_version: !ruby/object:Gem::Requirement
166
186
  requirements:
167
- - - "~>"
187
+ - - ">="
168
188
  - !ruby/object:Gem::Version
169
189
  version: '2.5'
170
190
  required_rubygems_version: !ruby/object:Gem::Requirement
@@ -173,8 +193,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
173
193
  - !ruby/object:Gem::Version
174
194
  version: '0'
175
195
  requirements: []
176
- rubygems_version: 3.0.6
177
- signing_key:
196
+ rubygems_version: 3.1.6
197
+ signing_key:
178
198
  specification_version: 4
179
199
  summary: Robust HTTP client
180
200
  test_files: []