twingly-http 0.1.0 → 0.3.2

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: 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: []