httpx 0.6.7 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +7 -5
  3. data/doc/release_notes/0_0_1.md +7 -0
  4. data/doc/release_notes/0_0_2.md +9 -0
  5. data/doc/release_notes/0_0_3.md +9 -0
  6. data/doc/release_notes/0_0_4.md +7 -0
  7. data/doc/release_notes/0_0_5.md +5 -0
  8. data/doc/release_notes/0_1_0.md +9 -0
  9. data/doc/release_notes/0_2_0.md +5 -0
  10. data/doc/release_notes/0_2_1.md +16 -0
  11. data/doc/release_notes/0_3_0.md +12 -0
  12. data/doc/release_notes/0_3_1.md +6 -0
  13. data/doc/release_notes/0_4_0.md +51 -0
  14. data/doc/release_notes/0_4_1.md +3 -0
  15. data/doc/release_notes/0_5_0.md +15 -0
  16. data/doc/release_notes/0_5_1.md +14 -0
  17. data/doc/release_notes/0_6_0.md +5 -0
  18. data/doc/release_notes/0_6_1.md +6 -0
  19. data/doc/release_notes/0_6_2.md +6 -0
  20. data/doc/release_notes/0_6_3.md +13 -0
  21. data/doc/release_notes/0_6_4.md +21 -0
  22. data/doc/release_notes/0_6_5.md +22 -0
  23. data/doc/release_notes/0_6_6.md +19 -0
  24. data/doc/release_notes/0_6_7.md +5 -0
  25. data/doc/release_notes/0_7_0.md +46 -0
  26. data/doc/release_notes/0_8_0.md +27 -0
  27. data/doc/release_notes/0_8_1.md +8 -0
  28. data/doc/release_notes/0_8_2.md +7 -0
  29. data/doc/release_notes/0_9_0.md +38 -0
  30. data/lib/httpx/adapters/faraday.rb +2 -2
  31. data/lib/httpx/altsvc.rb +18 -2
  32. data/lib/httpx/chainable.rb +27 -9
  33. data/lib/httpx/connection.rb +215 -65
  34. data/lib/httpx/connection/http1.rb +54 -18
  35. data/lib/httpx/connection/http2.rb +100 -37
  36. data/lib/httpx/extensions.rb +2 -2
  37. data/lib/httpx/headers.rb +2 -2
  38. data/lib/httpx/io/ssl.rb +11 -3
  39. data/lib/httpx/io/tcp.rb +12 -2
  40. data/lib/httpx/loggable.rb +6 -6
  41. data/lib/httpx/options.rb +43 -28
  42. data/lib/httpx/plugins/authentication.rb +1 -1
  43. data/lib/httpx/plugins/compression.rb +28 -8
  44. data/lib/httpx/plugins/compression/gzip.rb +22 -12
  45. data/lib/httpx/plugins/cookies.rb +12 -8
  46. data/lib/httpx/plugins/digest_authentication.rb +2 -0
  47. data/lib/httpx/plugins/expect.rb +79 -0
  48. data/lib/httpx/plugins/follow_redirects.rb +1 -2
  49. data/lib/httpx/plugins/h2c.rb +0 -1
  50. data/lib/httpx/plugins/proxy.rb +23 -20
  51. data/lib/httpx/plugins/proxy/http.rb +9 -6
  52. data/lib/httpx/plugins/proxy/socks4.rb +1 -1
  53. data/lib/httpx/plugins/proxy/socks5.rb +5 -1
  54. data/lib/httpx/plugins/proxy/ssh.rb +0 -4
  55. data/lib/httpx/plugins/push_promise.rb +2 -2
  56. data/lib/httpx/plugins/retries.rb +32 -29
  57. data/lib/httpx/pool.rb +15 -10
  58. data/lib/httpx/registry.rb +2 -1
  59. data/lib/httpx/request.rb +8 -6
  60. data/lib/httpx/resolver.rb +7 -8
  61. data/lib/httpx/resolver/https.rb +15 -3
  62. data/lib/httpx/resolver/native.rb +22 -32
  63. data/lib/httpx/resolver/options.rb +2 -2
  64. data/lib/httpx/resolver/resolver_mixin.rb +1 -1
  65. data/lib/httpx/response.rb +17 -3
  66. data/lib/httpx/selector.rb +96 -95
  67. data/lib/httpx/session.rb +33 -34
  68. data/lib/httpx/timeout.rb +7 -1
  69. data/lib/httpx/version.rb +1 -1
  70. metadata +77 -20
@@ -5,7 +5,9 @@ module HTTPX
5
5
  include Loggable
6
6
  include Chainable
7
7
 
8
- def initialize(options = {}, &blk)
8
+ EMPTY_HASH = {}.freeze
9
+
10
+ def initialize(options = EMPTY_HASH, &blk)
9
11
  @options = self.class.default_options.merge(options)
10
12
  @responses = {}
11
13
  @persistent = @options.persistent
@@ -29,13 +31,21 @@ module HTTPX
29
31
  end
30
32
 
31
33
  def request(*args, **options)
32
- requests = build_requests(*args, options)
34
+ requests = args.first.is_a?(Request) ? args : build_requests(*args, options)
33
35
  responses = send_requests(*requests, options)
34
36
  return responses.first if responses.size == 1
35
37
 
36
38
  responses
37
39
  end
38
40
 
41
+ def build_request(verb, uri, options = EMPTY_HASH)
42
+ rklass = @options.request_class
43
+ request = rklass.new(verb, uri, @options.merge(options).merge(persistent: @persistent))
44
+ request.on(:response, &method(:on_response).curry[request])
45
+ request.on(:promise, &method(:on_promise))
46
+ request
47
+ end
48
+
39
49
  private
40
50
 
41
51
  def pool
@@ -47,7 +57,7 @@ module HTTPX
47
57
  end
48
58
 
49
59
  def on_promise(_, stream)
50
- log(level: 2, label: "#{stream.id}: ") { "refusing stream!" }
60
+ log(level: 2) { "#{stream.id}: refusing stream!" }
51
61
  stream.refuse
52
62
  end
53
63
 
@@ -60,22 +70,33 @@ module HTTPX
60
70
  connection = pool.find_connection(uri, options) || build_connection(uri, options)
61
71
  unless connections.nil? || connections.include?(connection)
62
72
  connections << connection
63
- set_connection_callbacks(connection, options)
73
+ set_connection_callbacks(connection, connections, options)
64
74
  end
65
75
  connection
66
76
  end
67
77
 
68
- def set_connection_callbacks(connection, options)
78
+ def set_connection_callbacks(connection, connections, options)
69
79
  connection.on(:uncoalesce) do |uncoalesced_uri|
70
80
  other_connection = build_connection(uncoalesced_uri, options)
81
+ connections << other_connection
71
82
  connection.unmerge(other_connection)
72
83
  end
73
84
  connection.on(:altsvc) do |alt_origin, origin, alt_params|
74
- build_altsvc_connection(connection, alt_origin, origin, alt_params, options)
85
+ other_connection = build_altsvc_connection(connection, connections, alt_origin, origin, alt_params, options)
86
+ connections << other_connection if other_connection
87
+ end
88
+ connection.on(:exhausted) do
89
+ other_connection = connection.create_idle
90
+ other_connection.merge(connection)
91
+ catch(:coalesced) do
92
+ pool.init_connection(other_connection, options)
93
+ end
94
+ set_connection_callbacks(other_connection, connections, options)
95
+ connections << other_connection
75
96
  end
76
97
  end
77
98
 
78
- def build_altsvc_connection(existing_connection, alt_origin, origin, alt_params, options)
99
+ def build_altsvc_connection(existing_connection, connections, alt_origin, origin, alt_params, options)
79
100
  altsvc = AltSvc.cached_altsvc_set(origin, alt_params.merge("origin" => alt_origin))
80
101
 
81
102
  # altsvc already exists, somehow it wasn't advertised, probably noop
@@ -85,7 +106,7 @@ module HTTPX
85
106
  # advertised altsvc is the same origin being used, ignore
86
107
  return if connection == existing_connection
87
108
 
88
- set_connection_callbacks(connection, options)
109
+ set_connection_callbacks(connection, connections, options)
89
110
 
90
111
  log(level: 1) { "#{origin} alt-svc: #{alt_origin}" }
91
112
 
@@ -99,8 +120,10 @@ module HTTPX
99
120
  end
100
121
 
101
122
  connection.merge(existing_connection)
123
+ connection
102
124
  rescue UnsupportedSchemeError
103
125
  altsvc["noop"] = true
126
+ nil
104
127
  end
105
128
 
106
129
  def build_requests(*args, options)
@@ -109,8 +132,8 @@ module HTTPX
109
132
  requests = case args.size
110
133
  when 1
111
134
  reqs = args.first
112
- reqs.map do |verb, uri|
113
- build_request(verb, uri, request_options)
135
+ reqs.map do |verb, uri, opts = EMPTY_HASH|
136
+ build_request(verb, uri, request_options.merge(opts))
114
137
  end
115
138
  when 2, 3
116
139
  verb, uris = args
@@ -155,7 +178,6 @@ module HTTPX
155
178
  error = catch(:resolve_error) do
156
179
  connection = find_connection(request, connections, request_options)
157
180
  connection.send(request)
158
- set_request_timeout(connection, request, request_options)
159
181
  end
160
182
  next unless error.is_a?(ResolveError)
161
183
 
@@ -183,29 +205,6 @@ module HTTPX
183
205
  end
184
206
  end
185
207
 
186
- def build_request(verb, uri, options)
187
- rklass = @options.request_class
188
- request = rklass.new(verb, uri, @options.merge(options))
189
- request.on(:response, &method(:on_response).curry[request])
190
- request.on(:promise, &method(:on_promise))
191
- request
192
- end
193
-
194
- def set_request_timeout(connection, request, options)
195
- total = options.timeout.total_timeout
196
- return unless total
197
-
198
- timer = pool.after(total) do
199
- unless @responses[request]
200
- error = TotalTimeoutError.new(total, "Timed out after #{total} seconds")
201
- response = ErrorResponse.new(request, error, options)
202
- request.emit(:response, response)
203
- connection.reset
204
- end
205
- end
206
- request.timer = timer
207
- end
208
-
209
208
  @default_options = Options.new
210
209
  @default_options.freeze
211
210
  @plugins = []
@@ -6,6 +6,7 @@ module HTTPX
6
6
  class Timeout
7
7
  CONNECT_TIMEOUT = 60
8
8
  OPERATION_TIMEOUT = 60
9
+ KEEP_ALIVE_TIMEOUT = 20
9
10
 
10
11
  def self.new(opts = {})
11
12
  return opts if opts.is_a?(Timeout)
@@ -13,14 +14,16 @@ module HTTPX
13
14
  super(**opts)
14
15
  end
15
16
 
16
- attr_reader :connect_timeout, :operation_timeout, :total_timeout
17
+ attr_reader :connect_timeout, :operation_timeout, :keep_alive_timeout, :total_timeout
17
18
 
18
19
  def initialize(connect_timeout: CONNECT_TIMEOUT,
19
20
  operation_timeout: OPERATION_TIMEOUT,
21
+ keep_alive_timeout: KEEP_ALIVE_TIMEOUT,
20
22
  total_timeout: nil,
21
23
  loop_timeout: nil)
22
24
  @connect_timeout = connect_timeout
23
25
  @operation_timeout = operation_timeout
26
+ @keep_alive_timeout = keep_alive_timeout
24
27
  @total_timeout = total_timeout
25
28
 
26
29
  return unless loop_timeout
@@ -35,6 +38,7 @@ module HTTPX
35
38
  if other.is_a?(Timeout)
36
39
  @connect_timeout == other.instance_variable_get(:@connect_timeout) &&
37
40
  @operation_timeout == other.instance_variable_get(:@operation_timeout) &&
41
+ @keep_alive_timeout == other.instance_variable_get(:@keep_alive_timeout) &&
38
42
  @total_timeout == other.instance_variable_get(:@total_timeout)
39
43
  else
40
44
  super
@@ -49,9 +53,11 @@ module HTTPX
49
53
  when Timeout
50
54
  connect_timeout = other.instance_variable_get(:@connect_timeout) || @connect_timeout
51
55
  operation_timeout = other.instance_variable_get(:@operation_timeout) || @operation_timeout
56
+ keep_alive_timeout = other.instance_variable_get(:@keep_alive_timeout) || @keep_alive_timeout
52
57
  total_timeout = other.instance_variable_get(:@total_timeout) || @total_timeout
53
58
  Timeout.new(connect_timeout: connect_timeout,
54
59
  operation_timeout: operation_timeout,
60
+ keep_alive_timeout: keep_alive_timeout,
55
61
  total_timeout: total_timeout)
56
62
  else
57
63
  raise ArgumentError, "can't merge with #{other.class}"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module HTTPX
4
- VERSION = "0.6.7"
4
+ VERSION = "0.9.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: httpx
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.7
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tiago Cardoso
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-29 00:00:00.000000000 Z
11
+ date: 2020-10-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: http-2-next
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: http-cookie
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: http-form_data
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -58,29 +72,71 @@ dependencies:
58
72
  - - "<"
59
73
  - !ruby/object:Gem::Version
60
74
  version: '3'
61
- - !ruby/object:Gem::Dependency
62
- name: http-cookie
63
- requirement: !ruby/object:Gem::Requirement
64
- requirements:
65
- - - "~>"
66
- - !ruby/object:Gem::Version
67
- version: '1.0'
68
- type: :development
69
- prerelease: false
70
- version_requirements: !ruby/object:Gem::Requirement
71
- requirements:
72
- - - "~>"
73
- - !ruby/object:Gem::Version
74
- version: '1.0'
75
75
  description: A client library for making HTTP requests from Ruby.
76
76
  email:
77
77
  - cardoso_tiago@hotmail.com
78
78
  executables: []
79
79
  extensions: []
80
- extra_rdoc_files: []
80
+ extra_rdoc_files:
81
+ - LICENSE.txt
82
+ - README.md
83
+ - doc/release_notes/0_0_1.md
84
+ - doc/release_notes/0_1_0.md
85
+ - doc/release_notes/0_0_5.md
86
+ - doc/release_notes/0_0_4.md
87
+ - doc/release_notes/0_6_5.md
88
+ - doc/release_notes/0_6_1.md
89
+ - doc/release_notes/0_7_0.md
90
+ - doc/release_notes/0_6_0.md
91
+ - doc/release_notes/0_8_2.md
92
+ - doc/release_notes/0_6_4.md
93
+ - doc/release_notes/0_9_0.md
94
+ - doc/release_notes/0_6_3.md
95
+ - doc/release_notes/0_8_1.md
96
+ - doc/release_notes/0_5_0.md
97
+ - doc/release_notes/0_6_7.md
98
+ - doc/release_notes/0_4_1.md
99
+ - doc/release_notes/0_5_1.md
100
+ - doc/release_notes/0_6_6.md
101
+ - doc/release_notes/0_4_0.md
102
+ - doc/release_notes/0_6_2.md
103
+ - doc/release_notes/0_8_0.md
104
+ - doc/release_notes/0_3_0.md
105
+ - doc/release_notes/0_2_1.md
106
+ - doc/release_notes/0_0_3.md
107
+ - doc/release_notes/0_0_2.md
108
+ - doc/release_notes/0_3_1.md
109
+ - doc/release_notes/0_2_0.md
81
110
  files:
82
111
  - LICENSE.txt
83
112
  - README.md
113
+ - doc/release_notes/0_0_1.md
114
+ - doc/release_notes/0_0_2.md
115
+ - doc/release_notes/0_0_3.md
116
+ - doc/release_notes/0_0_4.md
117
+ - doc/release_notes/0_0_5.md
118
+ - doc/release_notes/0_1_0.md
119
+ - doc/release_notes/0_2_0.md
120
+ - doc/release_notes/0_2_1.md
121
+ - doc/release_notes/0_3_0.md
122
+ - doc/release_notes/0_3_1.md
123
+ - doc/release_notes/0_4_0.md
124
+ - doc/release_notes/0_4_1.md
125
+ - doc/release_notes/0_5_0.md
126
+ - doc/release_notes/0_5_1.md
127
+ - doc/release_notes/0_6_0.md
128
+ - doc/release_notes/0_6_1.md
129
+ - doc/release_notes/0_6_2.md
130
+ - doc/release_notes/0_6_3.md
131
+ - doc/release_notes/0_6_4.md
132
+ - doc/release_notes/0_6_5.md
133
+ - doc/release_notes/0_6_6.md
134
+ - doc/release_notes/0_6_7.md
135
+ - doc/release_notes/0_7_0.md
136
+ - doc/release_notes/0_8_0.md
137
+ - doc/release_notes/0_8_1.md
138
+ - doc/release_notes/0_8_2.md
139
+ - doc/release_notes/0_9_0.md
84
140
  - lib/httpx.rb
85
141
  - lib/httpx/adapters/faraday.rb
86
142
  - lib/httpx/altsvc.rb
@@ -109,6 +165,7 @@ files:
109
165
  - lib/httpx/plugins/compression/gzip.rb
110
166
  - lib/httpx/plugins/cookies.rb
111
167
  - lib/httpx/plugins/digest_authentication.rb
168
+ - lib/httpx/plugins/expect.rb
112
169
  - lib/httpx/plugins/follow_redirects.rb
113
170
  - lib/httpx/plugins/h2c.rb
114
171
  - lib/httpx/plugins/multipart.rb
@@ -148,7 +205,7 @@ metadata:
148
205
  changelog_uri: https://honeyryderchuck.gitlab.io/httpx/#release-notes
149
206
  documentation_uri: https://honeyryderchuck.gitlab.io/httpx/rdoc/
150
207
  source_code_uri: https://gitlab.com/honeyryderchuck/httpx
151
- post_install_message:
208
+ post_install_message:
152
209
  rdoc_options: []
153
210
  require_paths:
154
211
  - lib
@@ -164,7 +221,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
164
221
  version: '0'
165
222
  requirements: []
166
223
  rubygems_version: 3.1.2
167
- signing_key:
224
+ signing_key:
168
225
  specification_version: 4
169
226
  summary: HTTPX, to the future, and beyond
170
227
  test_files: []