httpx 0.12.0 → 0.13.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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/doc/release_notes/0_13_0.md +58 -0
  3. data/lib/httpx/chainable.rb +2 -2
  4. data/lib/httpx/connection.rb +17 -13
  5. data/lib/httpx/connection/http1.rb +4 -2
  6. data/lib/httpx/connection/http2.rb +1 -1
  7. data/lib/httpx/io/ssl.rb +30 -17
  8. data/lib/httpx/io/tcp.rb +45 -26
  9. data/lib/httpx/io/unix.rb +27 -12
  10. data/lib/httpx/options.rb +11 -23
  11. data/lib/httpx/plugins/compression.rb +20 -8
  12. data/lib/httpx/plugins/compression/brotli.rb +8 -6
  13. data/lib/httpx/plugins/compression/deflate.rb +2 -2
  14. data/lib/httpx/plugins/compression/gzip.rb +2 -2
  15. data/lib/httpx/plugins/digest_authentication.rb +1 -1
  16. data/lib/httpx/plugins/follow_redirects.rb +1 -1
  17. data/lib/httpx/plugins/h2c.rb +43 -58
  18. data/lib/httpx/plugins/internal_telemetry.rb +1 -1
  19. data/lib/httpx/plugins/retries.rb +1 -1
  20. data/lib/httpx/plugins/stream.rb +3 -1
  21. data/lib/httpx/plugins/upgrade.rb +83 -0
  22. data/lib/httpx/plugins/upgrade/h2.rb +54 -0
  23. data/lib/httpx/pool.rb +14 -5
  24. data/lib/httpx/response.rb +5 -5
  25. data/lib/httpx/version.rb +1 -1
  26. data/sig/chainable.rbs +2 -1
  27. data/sig/connection/http1.rbs +1 -0
  28. data/sig/options.rbs +7 -20
  29. data/sig/plugins/aws_sigv4.rbs +0 -1
  30. data/sig/plugins/compression.rbs +5 -3
  31. data/sig/plugins/compression/brotli.rbs +1 -1
  32. data/sig/plugins/compression/deflate.rbs +1 -1
  33. data/sig/plugins/compression/gzip.rbs +1 -1
  34. data/sig/plugins/cookies.rbs +0 -1
  35. data/sig/plugins/digest_authentication.rbs +0 -1
  36. data/sig/plugins/expect.rbs +0 -2
  37. data/sig/plugins/follow_redirects.rbs +0 -2
  38. data/sig/plugins/h2c.rbs +5 -10
  39. data/sig/plugins/persistent.rbs +0 -1
  40. data/sig/plugins/proxy.rbs +0 -1
  41. data/sig/plugins/retries.rbs +0 -4
  42. data/sig/plugins/upgrade.rbs +23 -0
  43. data/sig/response.rbs +3 -1
  44. metadata +7 -2
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HTTPX
4
+ module Plugins
5
+ #
6
+ # This plugin adds support for upgrading an HTTP/1.1 connection to HTTP/2
7
+ # via an Upgrade: h2 response declaration
8
+ #
9
+ # https://gitlab.com/honeyryderchuck/httpx/wikis/Upgrade#h2
10
+ #
11
+ module H2
12
+ class << self
13
+ def configure(klass)
14
+ klass.default_options.upgrade_handlers.register "h2", self
15
+ end
16
+
17
+ def call(connection, _request, _response)
18
+ connection.upgrade_to_h2
19
+ end
20
+ end
21
+
22
+ module ConnectionMethods
23
+ using URIExtensions
24
+
25
+ def upgrade_to_h2
26
+ prev_parser = @parser
27
+
28
+ if prev_parser
29
+ prev_parser.reset
30
+ @inflight -= prev_parser.requests.size
31
+ end
32
+
33
+ @parser = Connection::HTTP2.new(@write_buffer, @options)
34
+ set_parser_callbacks(@parser)
35
+ @upgrade_protocol = :h2
36
+
37
+ # what's happening here:
38
+ # a deviation from the state machine is done to perform the actions when a
39
+ # connection is closed, without transitioning, so the connection is kept in the pool.
40
+ # the state is reset to initial, so that the socket reconnect works out of the box,
41
+ # while the parser is already here.
42
+ purge_after_closed
43
+ transition(:idle)
44
+
45
+ prev_parser.requests.each do |req|
46
+ req.transition(:idle)
47
+ send(req)
48
+ end
49
+ end
50
+ end
51
+ end
52
+ register_plugin(:"upgrade/h2", H2)
53
+ end
54
+ end
data/lib/httpx/pool.rb CHANGED
@@ -64,11 +64,6 @@ module HTTPX
64
64
  connection.on(:open) do
65
65
  @connected_connections += 1
66
66
  end
67
- connection.on(:unreachable) do
68
- resolver = find_resolver_for(connection)
69
- resolver.uncache(connection) if resolver
70
- resolve_connection(connection)
71
- end
72
67
  end
73
68
 
74
69
  # opens a connection to the IP reachable through +uri+.
@@ -85,6 +80,20 @@ module HTTPX
85
80
 
86
81
  def resolve_connection(connection)
87
82
  @connections << connection unless @connections.include?(connection)
83
+
84
+ if connection.addresses || connection.state == :open
85
+ #
86
+ # there are two cases in which we want to activate initialization of
87
+ # connection immediately:
88
+ #
89
+ # 1. when the connection already has addresses, i.e. it doesn't need to
90
+ # resolve a name (not the same as name being an IP, yet)
91
+ # 2. when the connection is initialized with an external already open IO.
92
+ #
93
+ on_resolver_connection(connection)
94
+ return
95
+ end
96
+
88
97
  resolver = find_resolver_for(connection)
89
98
  resolver << connection
90
99
  return if resolver.empty?
@@ -27,8 +27,7 @@ module HTTPX
27
27
  @version = version
28
28
  @status = Integer(status)
29
29
  @headers = @options.headers_class.new(headers)
30
- @body = @options.response_body_class.new(self, threshold_size: @options.body_threshold_size,
31
- window_size: @options.window_size)
30
+ @body = @options.response_body_class.new(self, @options)
32
31
  end
33
32
 
34
33
  def merge_headers(h)
@@ -83,11 +82,12 @@ module HTTPX
83
82
  end
84
83
 
85
84
  class Body
86
- def initialize(response, threshold_size:, window_size: 1 << 14)
85
+ def initialize(response, options)
87
86
  @response = response
88
87
  @headers = response.headers
89
- @threshold_size = threshold_size
90
- @window_size = window_size
88
+ @options = options
89
+ @threshold_size = options.body_threshold_size
90
+ @window_size = options.window_size
91
91
  @encoding = response.content_type.charset || Encoding::BINARY
92
92
  @length = 0
93
93
  @buffer = nil
data/lib/httpx/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module HTTPX
4
- VERSION = "0.12.0"
4
+ VERSION = "0.13.0"
5
5
  end
data/sig/chainable.rbs CHANGED
@@ -18,7 +18,8 @@ module HTTPX
18
18
  | (:cookies) -> Plugins::sessionCookies
19
19
  | (:expect) -> Session
20
20
  | (:follow_redirects) -> Plugins::sessionFollowRedirects
21
- | (:h2c) -> Plugins::sessionH2C
21
+ | (:upgrade) -> Session
22
+ | (:h2c) -> Session
22
23
  | (:multipart) -> Session
23
24
  | (:persistent) -> Plugins::sessionPersistent
24
25
  | (:proxy) -> Plugins::sessionProxy
@@ -4,6 +4,7 @@ module HTTPX
4
4
  include Loggable
5
5
 
6
6
  attr_reader pending: Array[Request]
7
+ attr_reader requests: Array[Request]
7
8
 
8
9
  @options: Options
9
10
  @max_concurrent_requests: Integer
data/sig/options.rbs CHANGED
@@ -11,62 +11,54 @@ module HTTPX
11
11
  # headers
12
12
  attr_reader headers: Headers?
13
13
  def headers=: (headers) -> void
14
- def with_headers: (headers) -> instance
15
14
 
16
15
  # timeout
17
16
  attr_reader timeout: Timeout?
18
17
  def timeout=: (Hash[Symbol, untyped] | Timeout) -> void
19
- def with_timeout: (Hash[Symbol, untyped] | Timeout) -> instance
20
18
 
21
19
  # max_concurrent_requests
22
20
  attr_reader max_concurrent_requests: Integer?
23
21
  def max_concurrent_requests=: (Integer) -> void
24
- def with_max_concurrent_requests: (Integer) -> instance
25
22
 
26
23
  # max_requests
27
24
  attr_reader max_requests: Integer?
28
25
  def max_requests=: (Integer) -> void
29
- def with_max_requests: (Integer) -> instance
30
26
 
31
27
  # window_size
32
28
  attr_reader window_size: int?
33
29
  def window_size=: (int) -> void
34
- def with_window_size: (int) -> instance
35
30
 
36
31
  # body_threshold_size
37
32
  attr_reader body_threshold_size: int?
38
33
  def body_threshold_size=: (int) -> void
39
- def with_body_threshold_size: (int) -> instance
40
34
 
41
35
  # transport
42
36
  attr_reader transport: _ToS?
43
37
  def transport=: (_ToS) -> void
44
- def with_transport: (_ToS) -> instance
45
38
 
46
39
  # transport_options
47
40
  attr_reader transport_options: Hash[untyped, untyped]?
48
41
  def transport_options=: (Hash[untyped, untyped]) -> void
49
- def with_transport_options: (Hash[untyped, untyped]) -> instance
42
+
43
+ # addresses
44
+ attr_reader addresses: _ToAry[untyped]?
45
+ def addresses=: (_ToAry[untyped]) -> void
50
46
 
51
47
  # params
52
48
  attr_reader params: Transcoder::urlencoded_input?
53
49
  def params=: (Transcoder::urlencoded_input) -> void
54
- def with_params: (Transcoder::urlencoded_input) -> instance
55
50
 
56
51
  # form
57
52
  attr_reader form: Transcoder::urlencoded_input?
58
53
  def form=: (Transcoder::urlencoded_input) -> void
59
- def with_form: (Transcoder::urlencoded_input) -> instance
60
54
 
61
55
  # json
62
56
  attr_reader json: _ToJson?
63
57
  def json=: (_ToJson) -> void
64
- def with_json: (_ToJson) -> instance
65
58
 
66
59
  # body
67
60
  attr_reader body: bodyIO?
68
61
  def body=: (bodyIO) -> void
69
- def with_body: (bodyIO) -> instance
70
62
 
71
63
  # ssl
72
64
 
@@ -79,32 +71,27 @@ module HTTPX
79
71
  # request_class
80
72
  attr_reader request_class: singleton(Request)
81
73
  def request_class=: (singleton(Request)) -> void
82
- def with_request_class: (singleton(Request)) -> instance
83
74
 
84
75
  # io
85
- attr_reader io: _ToIO?
86
- def io=: (_ToIO) -> void
87
- def with_io: (_ToIO) -> instance
76
+ type io_option = _ToIO | Hash[String, _ToIO]
77
+ attr_reader io: io_option?
78
+ def io=: (io_option) -> void
88
79
 
89
80
  # fallback_protocol
90
81
  attr_reader fallback_protocol: String?
91
82
  def fallback_protocol=: (String) -> void
92
- def with_fallback_protocol: (String) -> instance
93
83
 
94
84
  # debug
95
85
  attr_reader debug: _IOLogger?
96
86
  def debug=: (_IOLogger) -> void
97
- def with_debug: (_IOLogger) -> instance
98
87
 
99
88
  # debug_level
100
89
  attr_reader debug_level: Integer?
101
90
  def debug_level=: (Integer) -> void
102
- def with_debug_level: (Integer) -> instance
103
91
 
104
92
  # persistent
105
93
  attr_reader persistent: bool?
106
94
  def persistent=: (bool) -> void
107
- def with_persistent: (bool) -> instance
108
95
 
109
96
  def ==: (untyped other) -> bool
110
97
  def merge: (_ToHash other) -> instance
@@ -43,7 +43,6 @@ module HTTPX
43
43
  interface _SigV4Options
44
44
  def sigv4_signer: () -> Signer?
45
45
  def sigv4_signer=: (Signer) -> Signer
46
- def with_sigv4_signer: (Signer) -> instance
47
46
  end
48
47
 
49
48
  def self.extra_options: (Options) -> (Options & _SigV4Options)
@@ -1,7 +1,7 @@
1
1
  module HTTPX
2
2
  module Plugins
3
3
  module Compression
4
- extend Registry[Symbol, Class]
4
+ type encodings_registry = Registry[Symbol, Class]
5
5
 
6
6
  type deflatable = _Reader | _ToS
7
7
 
@@ -16,12 +16,14 @@ module HTTPX
16
16
  def initialize: (Numeric bytesize) -> untyped
17
17
  end
18
18
 
19
- def self.load_dependencies: (singleton(Session)) -> void
19
+ def self.configure: (singleton(Session)) -> void
20
20
 
21
21
  interface _CompressionOptions
22
22
  def compression_threshold_size: () -> _Integer?
23
23
  def compression_threshold_size=: (int) -> int
24
- def with_compression_threshold_size: (int) -> instance
24
+
25
+ def encodings: () -> encodings_registry?
26
+ def encodings=: (encodings_registry) -> encodings_registry
25
27
  end
26
28
 
27
29
  def self.extra_options: (Options) -> (Options & _CompressionOptions)
@@ -3,7 +3,7 @@ module HTTPX
3
3
  module Compression
4
4
  module Brotli
5
5
  def self.load_dependencies: (singleton(Session)) -> void
6
- def self.configure: (*untyped) -> void
6
+ def self.configure: (singleton(Session)) -> void
7
7
 
8
8
  def self?.deflater: () -> _Deflater
9
9
  def self?.decoder: (Numeric bytesize) -> Inflater
@@ -3,7 +3,7 @@ module HTTPX
3
3
  module Compression
4
4
  module Deflate
5
5
  def self.load_dependencies: (singleton(Session)) -> void
6
- def self.configure: (*untyped) -> void
6
+ def self.configure: (singleton(Session)) -> void
7
7
 
8
8
  def self?.deflater: () -> _Deflater
9
9
  def self?.inflater: (Numeric bytesize) -> GZIP::Inflater
@@ -3,7 +3,7 @@ module HTTPX
3
3
  module Compression
4
4
  module GZIP
5
5
  def self.load_dependencies: (singleton(Session)) -> void
6
- def self.configure: (*untyped) -> void
6
+ def self.configure: (singleton(Session)) -> void
7
7
 
8
8
  def self?.deflater: () -> _Deflater
9
9
  def self?.inflater: (Numeric bytesize) -> Inflater
@@ -6,7 +6,6 @@ module HTTPX
6
6
  interface _CookieOptions
7
7
  def cookies: () -> Jar?
8
8
  def cookies=: (jar) -> Jar
9
- def with_cookies: (jar) -> instance
10
9
  end
11
10
 
12
11
  def self.extra_options: (Options) -> (Options & _CookieOptions)
@@ -6,7 +6,6 @@ module HTTPX
6
6
  interface _DigestOptions
7
7
  def digest: () -> Digest?
8
8
  def digest=: (Digest) -> Digest
9
- def with_digest: (Digest) -> instance
10
9
  end
11
10
 
12
11
  def self.extra_options: (Options) -> (Options & _DigestOptions)
@@ -6,11 +6,9 @@ module HTTPX
6
6
  interface _ExpectOptions
7
7
  def expect_timeout: () -> Integer?
8
8
  def expect_timeout=: (int) -> Integer
9
- def with_expect_timeout: (int) -> instance
10
9
 
11
10
  def expect_threshold_size: () -> Integer?
12
11
  def expect_threshold_size=: (int) -> Integer
13
- def with_expect_threshold_size: (int) -> instance
14
12
  end
15
13
 
16
14
  def self.extra_options: (Options) -> (Options & _ExpectOptions)
@@ -9,11 +9,9 @@ module HTTPX
9
9
  interface _FollowRedirectsOptions
10
10
  def max_redirects: () -> Integer?
11
11
  def max_redirects=: (int) -> Integer
12
- def with_max_redirects: (int) -> instance
13
12
 
14
13
  def follow_insecure_redirects: () -> bool?
15
14
  def follow_insecure_redirects=: (bool) -> bool
16
- def with_follow_insecure_redirects: (bool) -> instance
17
15
  end
18
16
 
19
17
  def self.extra_options: (Options) -> (Options & _FollowRedirectsOptions)
data/sig/plugins/h2c.rbs CHANGED
@@ -1,23 +1,18 @@
1
1
  module HTTPX
2
2
  module Plugins
3
3
  module H2C
4
- def self.load_dependencies: (singleton(Session)) -> void
5
-
6
- module InstanceMethods
7
- VALID_H2C_METHODS: Array[Symbol]
8
-
9
- private
4
+ VALID_H2C_VERBS: Array[Symbol]
10
5
 
11
- def valid_h2c_upgrade_request: (Request) -> bool
12
- def valid_h2c_upgrade?: (Request, Response, Options) -> bool
13
- end
6
+ def self.load_dependencies: (*untyped) -> void
7
+ def self.configure: (singleton(Session)) -> void
8
+ def self.call: (Connection, Request, response) -> void
14
9
 
15
10
  class H2CParser < Connection::HTTP2
16
11
  def upgrade: (Request, Response) -> void
17
12
  end
18
13
 
19
14
  module ConnectionMethods
20
- def upgrade: (Request, Response) -> void
15
+ def upgrade_to_h2c: (Request, Response) -> void
21
16
  end
22
17
  end
23
18
 
@@ -6,7 +6,6 @@ module HTTPX
6
6
  interface _PersistentOptions
7
7
  def persistent: () -> bool?
8
8
  def persistent=: (bool) -> bool
9
- def with_persistent: (bool) -> instance
10
9
  end
11
10
 
12
11
  def self.extra_options: (Options) -> (Options & _PersistentOptions)
@@ -28,7 +28,6 @@ module HTTPX
28
28
  interface _ProxyOptions
29
29
  def proxy: () -> proxyParam?
30
30
  def proxy=: (Parameters | _ToHash) -> proxyParam
31
- def with_proxy: (Parameters | _ToHash) -> instance
32
31
  end
33
32
 
34
33
  def self.extra_options: (Options) -> (Options & _ProxyOptions)
@@ -12,19 +12,15 @@ module HTTPX
12
12
  interface _RetriesOptions
13
13
  def retry_after: () -> Numeric?
14
14
  def retry_after=: (Numeric) -> Numeric
15
- def with_retry_after: (Numeric) -> instance
16
15
 
17
16
  def max_retries: () -> Integer?
18
17
  def max_retries=: (int) -> Integer
19
- def with_max_retries: (int) -> instance
20
18
 
21
19
  def retry_change_requests: () -> bool?
22
20
  def retry_change_requests=: (bool) -> bool
23
- def with_retry_change_requests: (bool) -> instance
24
21
 
25
22
  def retry_on: () -> _RetryCallback?
26
23
  def retry_on=: (_RetryCallback) -> _RetryCallback
27
- def with_retry_on: (_RetryCallback) -> instance
28
24
  end
29
25
 
30
26
  def self.extra_options: (Options) -> (Options & _RetriesOptions)
@@ -0,0 +1,23 @@
1
+ module HTTPX
2
+ module Plugins
3
+ module Upgrade
4
+ type handlers_registry = Registry[Symbol, Class]
5
+
6
+ def self.configure: (singleton(Session)) -> void
7
+
8
+ interface _UpgradeOptions
9
+ def upgrade_handlers: () -> handlers_registry?
10
+ def upgrade_handlers=: (handlers_registry) -> handlers_registry
11
+ end
12
+
13
+ def self.extra_options: (Options) -> (Options & _UpgradeOptions)
14
+
15
+ module ConnectionMethods
16
+ attr_reader upgrade_protocol: Symbol?
17
+ attr_reader hijacked: boolish
18
+
19
+ def hijack_io: () -> void
20
+ end
21
+ end
22
+ end
23
+ end