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.
- checksums.yaml +4 -4
- data/doc/release_notes/0_13_0.md +58 -0
- data/lib/httpx/chainable.rb +2 -2
- data/lib/httpx/connection.rb +17 -13
- data/lib/httpx/connection/http1.rb +4 -2
- data/lib/httpx/connection/http2.rb +1 -1
- data/lib/httpx/io/ssl.rb +30 -17
- data/lib/httpx/io/tcp.rb +45 -26
- data/lib/httpx/io/unix.rb +27 -12
- data/lib/httpx/options.rb +11 -23
- data/lib/httpx/plugins/compression.rb +20 -8
- data/lib/httpx/plugins/compression/brotli.rb +8 -6
- data/lib/httpx/plugins/compression/deflate.rb +2 -2
- data/lib/httpx/plugins/compression/gzip.rb +2 -2
- data/lib/httpx/plugins/digest_authentication.rb +1 -1
- data/lib/httpx/plugins/follow_redirects.rb +1 -1
- data/lib/httpx/plugins/h2c.rb +43 -58
- data/lib/httpx/plugins/internal_telemetry.rb +1 -1
- data/lib/httpx/plugins/retries.rb +1 -1
- data/lib/httpx/plugins/stream.rb +3 -1
- data/lib/httpx/plugins/upgrade.rb +83 -0
- data/lib/httpx/plugins/upgrade/h2.rb +54 -0
- data/lib/httpx/pool.rb +14 -5
- data/lib/httpx/response.rb +5 -5
- data/lib/httpx/version.rb +1 -1
- data/sig/chainable.rbs +2 -1
- data/sig/connection/http1.rbs +1 -0
- data/sig/options.rbs +7 -20
- data/sig/plugins/aws_sigv4.rbs +0 -1
- data/sig/plugins/compression.rbs +5 -3
- data/sig/plugins/compression/brotli.rbs +1 -1
- data/sig/plugins/compression/deflate.rbs +1 -1
- data/sig/plugins/compression/gzip.rbs +1 -1
- data/sig/plugins/cookies.rbs +0 -1
- data/sig/plugins/digest_authentication.rbs +0 -1
- data/sig/plugins/expect.rbs +0 -2
- data/sig/plugins/follow_redirects.rbs +0 -2
- data/sig/plugins/h2c.rbs +5 -10
- data/sig/plugins/persistent.rbs +0 -1
- data/sig/plugins/proxy.rbs +0 -1
- data/sig/plugins/retries.rbs +0 -4
- data/sig/plugins/upgrade.rbs +23 -0
- data/sig/response.rbs +3 -1
- 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?
|
data/lib/httpx/response.rb
CHANGED
@@ -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,
|
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,
|
85
|
+
def initialize(response, options)
|
87
86
|
@response = response
|
88
87
|
@headers = response.headers
|
89
|
-
@
|
90
|
-
@
|
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
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
|
-
| (:
|
21
|
+
| (:upgrade) -> Session
|
22
|
+
| (:h2c) -> Session
|
22
23
|
| (:multipart) -> Session
|
23
24
|
| (:persistent) -> Plugins::sessionPersistent
|
24
25
|
| (:proxy) -> Plugins::sessionProxy
|
data/sig/connection/http1.rbs
CHANGED
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
|
-
|
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
|
-
|
86
|
-
|
87
|
-
def
|
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
|
data/sig/plugins/aws_sigv4.rbs
CHANGED
data/sig/plugins/compression.rbs
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module HTTPX
|
2
2
|
module Plugins
|
3
3
|
module Compression
|
4
|
-
|
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.
|
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
|
-
|
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: (
|
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: (
|
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: (
|
6
|
+
def self.configure: (singleton(Session)) -> void
|
7
7
|
|
8
8
|
def self?.deflater: () -> _Deflater
|
9
9
|
def self?.inflater: (Numeric bytesize) -> Inflater
|
data/sig/plugins/cookies.rbs
CHANGED
data/sig/plugins/expect.rbs
CHANGED
@@ -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
|
-
|
5
|
-
|
6
|
-
module InstanceMethods
|
7
|
-
VALID_H2C_METHODS: Array[Symbol]
|
8
|
-
|
9
|
-
private
|
4
|
+
VALID_H2C_VERBS: Array[Symbol]
|
10
5
|
|
11
|
-
|
12
|
-
|
13
|
-
|
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
|
15
|
+
def upgrade_to_h2c: (Request, Response) -> void
|
21
16
|
end
|
22
17
|
end
|
23
18
|
|
data/sig/plugins/persistent.rbs
CHANGED
data/sig/plugins/proxy.rbs
CHANGED
data/sig/plugins/retries.rbs
CHANGED
@@ -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
|