httpx 0.15.3 → 0.17.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_15_4.md +5 -0
- data/doc/release_notes/0_16_0.md +93 -0
- data/doc/release_notes/0_16_1.md +5 -0
- data/doc/release_notes/0_17_0.md +49 -0
- data/lib/httpx/adapters/faraday.rb +3 -11
- data/lib/httpx/adapters/webmock.rb +2 -2
- data/lib/httpx/buffer.rb +1 -1
- data/lib/httpx/callbacks.rb +1 -1
- data/lib/httpx/chainable.rb +15 -8
- data/lib/httpx/connection/http1.rb +18 -10
- data/lib/httpx/connection/http2.rb +14 -21
- data/lib/httpx/connection.rb +6 -7
- data/lib/httpx/errors.rb +11 -11
- data/lib/httpx/headers.rb +1 -1
- data/lib/httpx/io/ssl.rb +2 -2
- data/lib/httpx/io/tls.rb +1 -1
- data/lib/httpx/options.rb +108 -81
- data/lib/httpx/parser/http1.rb +11 -7
- data/lib/httpx/plugins/aws_sigv4.rb +10 -9
- data/lib/httpx/plugins/compression.rb +12 -11
- data/lib/httpx/plugins/cookies/cookie.rb +4 -2
- data/lib/httpx/plugins/cookies/jar.rb +20 -1
- data/lib/httpx/plugins/cookies.rb +20 -7
- data/lib/httpx/plugins/digest_authentication.rb +19 -15
- data/lib/httpx/plugins/expect.rb +19 -15
- data/lib/httpx/plugins/follow_redirects.rb +9 -9
- data/lib/httpx/plugins/grpc/call.rb +4 -1
- data/lib/httpx/plugins/grpc.rb +73 -47
- data/lib/httpx/plugins/h2c.rb +7 -3
- data/lib/httpx/plugins/multipart/decoder.rb +187 -0
- data/lib/httpx/plugins/multipart/mime_type_detector.rb +3 -3
- data/lib/httpx/plugins/multipart/part.rb +2 -2
- data/lib/httpx/plugins/multipart.rb +14 -0
- data/lib/httpx/plugins/ntlm_authentication.rb +12 -10
- data/lib/httpx/plugins/proxy/socks4.rb +2 -1
- data/lib/httpx/plugins/proxy/socks5.rb +2 -1
- data/lib/httpx/plugins/proxy/ssh.rb +20 -13
- data/lib/httpx/plugins/proxy.rb +10 -10
- data/lib/httpx/plugins/retries.rb +25 -21
- data/lib/httpx/plugins/stream.rb +2 -3
- data/lib/httpx/plugins/upgrade.rb +7 -6
- data/lib/httpx/registry.rb +2 -2
- data/lib/httpx/request.rb +10 -19
- data/lib/httpx/resolver/https.rb +0 -2
- data/lib/httpx/resolver/native.rb +15 -3
- data/lib/httpx/resolver/resolver_mixin.rb +2 -1
- data/lib/httpx/response.rb +72 -38
- data/lib/httpx/selector.rb +6 -7
- data/lib/httpx/session.rb +34 -21
- data/lib/httpx/session2.rb +23 -0
- data/lib/httpx/transcoder/body.rb +1 -1
- data/lib/httpx/transcoder/chunker.rb +2 -1
- data/lib/httpx/transcoder/form.rb +20 -0
- data/lib/httpx/transcoder/json.rb +12 -0
- data/lib/httpx/transcoder.rb +62 -1
- data/lib/httpx/utils.rb +2 -2
- data/lib/httpx/version.rb +1 -1
- data/lib/httpx.rb +6 -3
- data/sig/buffer.rbs +3 -1
- data/sig/chainable.rbs +30 -29
- data/sig/connection/http1.rbs +11 -5
- data/sig/connection/http2.rbs +16 -5
- data/sig/connection.rbs +23 -11
- data/sig/errors.rbs +35 -1
- data/sig/headers.rbs +20 -19
- data/sig/httpx.rbs +4 -1
- data/sig/loggable.rbs +3 -1
- data/sig/options.rbs +45 -34
- data/sig/parser/http1.rbs +3 -3
- data/sig/plugins/authentication.rbs +1 -1
- data/sig/plugins/aws_sdk_authentication.rbs +5 -1
- data/sig/plugins/aws_sigv4.rbs +13 -5
- data/sig/plugins/basic_authentication.rbs +1 -1
- data/sig/plugins/compression.rbs +4 -6
- data/sig/plugins/cookies/cookie.rbs +5 -7
- data/sig/plugins/cookies/jar.rbs +9 -10
- data/sig/plugins/cookies.rbs +4 -5
- data/sig/plugins/digest_authentication.rbs +2 -3
- data/sig/plugins/expect.rbs +2 -4
- data/sig/plugins/follow_redirects.rbs +3 -5
- data/sig/plugins/grpc.rbs +4 -7
- data/sig/plugins/h2c.rbs +0 -2
- data/sig/plugins/multipart.rbs +64 -10
- data/sig/plugins/ntlm_authentication.rbs +2 -3
- data/sig/plugins/persistent.rbs +3 -8
- data/sig/plugins/proxy/ssh.rbs +4 -4
- data/sig/plugins/proxy.rbs +13 -13
- data/sig/plugins/push_promise.rbs +0 -2
- data/sig/plugins/retries.rbs +4 -8
- data/sig/plugins/stream.rbs +1 -1
- data/sig/plugins/upgrade.rbs +2 -3
- data/sig/pool.rbs +1 -2
- data/sig/registry.rbs +1 -1
- data/sig/request.rbs +11 -8
- data/sig/resolver/native.rbs +12 -6
- data/sig/resolver/resolver_mixin.rbs +4 -5
- data/sig/resolver/system.rbs +2 -0
- data/sig/resolver.rbs +7 -0
- data/sig/response.rbs +24 -12
- data/sig/selector.rbs +11 -9
- data/sig/session.rbs +22 -23
- data/sig/transcoder/body.rbs +6 -1
- data/sig/transcoder/chunker.rbs +8 -2
- data/sig/transcoder/form.rbs +3 -1
- data/sig/transcoder/json.rbs +2 -0
- data/sig/transcoder.rbs +13 -5
- data/sig/utils.rbs +2 -0
- metadata +12 -2
|
@@ -17,39 +17,43 @@ module HTTPX
|
|
|
17
17
|
Errno::ECONNRESET,
|
|
18
18
|
Errno::ECONNABORTED,
|
|
19
19
|
Errno::EPIPE,
|
|
20
|
-
|
|
20
|
+
TLSError,
|
|
21
21
|
TimeoutError,
|
|
22
22
|
Parser::Error,
|
|
23
23
|
Errno::EINVAL,
|
|
24
24
|
Errno::ETIMEDOUT].freeze
|
|
25
25
|
|
|
26
26
|
def self.extra_options(options)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
27
|
+
options.merge(max_retries: MAX_RETRIES)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
module OptionsMethods
|
|
31
|
+
def option_retry_after(value)
|
|
32
|
+
# return early if callable
|
|
33
|
+
unless value.respond_to?(:call)
|
|
34
|
+
value = Integer(value)
|
|
35
|
+
raise TypeError, ":retry_after must be positive" unless value.positive?
|
|
36
|
+
end
|
|
34
37
|
|
|
35
|
-
|
|
36
|
-
|
|
38
|
+
value
|
|
39
|
+
end
|
|
37
40
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
+
def option_max_retries(value)
|
|
42
|
+
num = Integer(value)
|
|
43
|
+
raise TypeError, ":max_retries must be positive" unless num.positive?
|
|
41
44
|
|
|
42
|
-
|
|
43
|
-
|
|
45
|
+
num
|
|
46
|
+
end
|
|
44
47
|
|
|
45
|
-
|
|
48
|
+
def option_retry_change_requests(v)
|
|
49
|
+
v
|
|
50
|
+
end
|
|
46
51
|
|
|
47
|
-
|
|
48
|
-
|
|
52
|
+
def option_retry_on(value)
|
|
53
|
+
raise ":retry_on must be called with the response" unless value.respond_to?(:call)
|
|
49
54
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
end.new(options).merge(max_retries: MAX_RETRIES)
|
|
55
|
+
value
|
|
56
|
+
end
|
|
53
57
|
end
|
|
54
58
|
|
|
55
59
|
module InstanceMethods
|
data/lib/httpx/plugins/stream.rb
CHANGED
|
@@ -6,7 +6,6 @@ module HTTPX
|
|
|
6
6
|
@request = request
|
|
7
7
|
@session = session
|
|
8
8
|
@connections = connections
|
|
9
|
-
@options = @request.options
|
|
10
9
|
end
|
|
11
10
|
|
|
12
11
|
def each(&block)
|
|
@@ -72,7 +71,7 @@ module HTTPX
|
|
|
72
71
|
private
|
|
73
72
|
|
|
74
73
|
def response
|
|
75
|
-
@session.__send__(:receive_requests, [@request], @connections
|
|
74
|
+
@session.__send__(:receive_requests, [@request], @connections) until @request.response
|
|
76
75
|
|
|
77
76
|
@request.response
|
|
78
77
|
end
|
|
@@ -106,7 +105,7 @@ module HTTPX
|
|
|
106
105
|
|
|
107
106
|
request = requests.first
|
|
108
107
|
|
|
109
|
-
connections = _send_requests(requests
|
|
108
|
+
connections = _send_requests(requests)
|
|
110
109
|
|
|
111
110
|
StreamResponse.new(request, self, connections)
|
|
112
111
|
end
|
|
@@ -18,14 +18,15 @@ module HTTPX
|
|
|
18
18
|
upgrade_handlers = Module.new do
|
|
19
19
|
extend Registry
|
|
20
20
|
end
|
|
21
|
+
options.merge(upgrade_handlers: upgrade_handlers)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
21
24
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
+
module OptionsMethods
|
|
26
|
+
def option_upgrade_handlers(value)
|
|
27
|
+
raise TypeError, ":upgrade_handlers must be a registry" unless value.respond_to?(:registry)
|
|
25
28
|
|
|
26
|
-
|
|
27
|
-
OUT
|
|
28
|
-
end.new(options).merge(upgrade_handlers: upgrade_handlers)
|
|
29
|
+
value
|
|
29
30
|
end
|
|
30
31
|
end
|
|
31
32
|
|
data/lib/httpx/registry.rb
CHANGED
|
@@ -31,7 +31,7 @@ module HTTPX
|
|
|
31
31
|
#
|
|
32
32
|
module Registry
|
|
33
33
|
# Base Registry Error
|
|
34
|
-
Error
|
|
34
|
+
class Error < Error; end
|
|
35
35
|
|
|
36
36
|
def self.extended(klass)
|
|
37
37
|
super
|
|
@@ -59,7 +59,7 @@ module HTTPX
|
|
|
59
59
|
@registry ||= {}
|
|
60
60
|
return @registry if tag.nil?
|
|
61
61
|
|
|
62
|
-
handler = @registry
|
|
62
|
+
handler = @registry[tag]
|
|
63
63
|
raise(Error, "#{tag} is not registered in #{self}") unless handler
|
|
64
64
|
|
|
65
65
|
handler
|
data/lib/httpx/request.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "delegate"
|
|
3
4
|
require "forwardable"
|
|
4
5
|
|
|
5
6
|
module HTTPX
|
|
@@ -40,16 +41,15 @@ module HTTPX
|
|
|
40
41
|
|
|
41
42
|
def_delegator :@body, :empty?
|
|
42
43
|
|
|
43
|
-
def_delegator :@body, :chunk!
|
|
44
|
-
|
|
45
44
|
def initialize(verb, uri, options = {})
|
|
46
45
|
@verb = verb.to_s.downcase.to_sym
|
|
47
46
|
@options = Options.new(options)
|
|
48
47
|
@uri = Utils.to_uri(uri)
|
|
49
48
|
if @uri.relative?
|
|
50
|
-
|
|
49
|
+
origin = @options.origin
|
|
50
|
+
raise(Error, "invalid URI: #{@uri}") unless origin
|
|
51
51
|
|
|
52
|
-
@uri =
|
|
52
|
+
@uri = origin.merge(@uri)
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
raise(Error, "unknown method: #{verb}") unless METHODS.include?(@verb)
|
|
@@ -97,7 +97,7 @@ module HTTPX
|
|
|
97
97
|
def response=(response)
|
|
98
98
|
return unless response
|
|
99
99
|
|
|
100
|
-
if response.status == 100
|
|
100
|
+
if response.is_a?(Response) && response.status == 100
|
|
101
101
|
@informational_status = response.status
|
|
102
102
|
return
|
|
103
103
|
end
|
|
@@ -155,9 +155,9 @@ module HTTPX
|
|
|
155
155
|
end
|
|
156
156
|
# :nocov:
|
|
157
157
|
|
|
158
|
-
class Body
|
|
158
|
+
class Body < SimpleDelegator
|
|
159
159
|
class << self
|
|
160
|
-
def new(
|
|
160
|
+
def new(_, options)
|
|
161
161
|
return options.body if options.body.is_a?(self)
|
|
162
162
|
|
|
163
163
|
super
|
|
@@ -177,6 +177,7 @@ module HTTPX
|
|
|
177
177
|
|
|
178
178
|
@headers["content-type"] ||= @body.content_type
|
|
179
179
|
@headers["content-length"] = @body.bytesize unless unbounded_body?
|
|
180
|
+
super(@body)
|
|
180
181
|
end
|
|
181
182
|
|
|
182
183
|
def each(&block)
|
|
@@ -214,14 +215,14 @@ module HTTPX
|
|
|
214
215
|
|
|
215
216
|
def stream(body)
|
|
216
217
|
encoded = body
|
|
217
|
-
encoded = Transcoder.registry("chunker").encode(body) if chunked?
|
|
218
|
+
encoded = Transcoder.registry("chunker").encode(body.enum_for(:each)) if chunked?
|
|
218
219
|
encoded
|
|
219
220
|
end
|
|
220
221
|
|
|
221
222
|
def unbounded_body?
|
|
222
223
|
return @unbounded_body if defined?(@unbounded_body)
|
|
223
224
|
|
|
224
|
-
@unbounded_body = (chunked? || @body.bytesize == Float::INFINITY)
|
|
225
|
+
@unbounded_body = !@body.nil? && (chunked? || @body.bytesize == Float::INFINITY)
|
|
225
226
|
end
|
|
226
227
|
|
|
227
228
|
def chunked?
|
|
@@ -238,16 +239,6 @@ module HTTPX
|
|
|
238
239
|
"#{unbounded_body? ? "stream" : "@bytesize=#{bytesize}"}>"
|
|
239
240
|
end
|
|
240
241
|
# :nocov:
|
|
241
|
-
|
|
242
|
-
def respond_to_missing?(meth, *args)
|
|
243
|
-
@body.respond_to?(meth, *args) || super
|
|
244
|
-
end
|
|
245
|
-
|
|
246
|
-
def method_missing(meth, *args, &block)
|
|
247
|
-
return super unless @body.respond_to?(meth)
|
|
248
|
-
|
|
249
|
-
@body.__send__(meth, *args, &block)
|
|
250
|
-
end
|
|
251
242
|
end
|
|
252
243
|
|
|
253
244
|
def transition(nextstate)
|
data/lib/httpx/resolver/https.rb
CHANGED
|
@@ -217,15 +217,27 @@ module HTTPX
|
|
|
217
217
|
end
|
|
218
218
|
else
|
|
219
219
|
address = addresses.first
|
|
220
|
-
|
|
221
|
-
|
|
220
|
+
name = address["name"]
|
|
221
|
+
|
|
222
|
+
connection = @queries.delete(name)
|
|
223
|
+
|
|
224
|
+
unless connection
|
|
225
|
+
# absolute name
|
|
226
|
+
name_labels = Resolv::DNS::Name.create(name).to_a
|
|
227
|
+
name = @queries.keys.first { |hname| name_labels == Resolv::DNS::Name.create(hname).to_a }
|
|
228
|
+
|
|
229
|
+
# probably a retried query for which there's an answer
|
|
230
|
+
return unless name
|
|
231
|
+
|
|
232
|
+
address["name"] = name
|
|
233
|
+
connection = @queries.delete(name)
|
|
234
|
+
end
|
|
222
235
|
|
|
223
236
|
if address.key?("alias") # CNAME
|
|
224
237
|
if early_resolve(connection, hostname: address["alias"])
|
|
225
238
|
@connections.delete(connection)
|
|
226
239
|
else
|
|
227
240
|
resolve(connection, address["alias"])
|
|
228
|
-
@queries.delete(address["name"])
|
|
229
241
|
return
|
|
230
242
|
end
|
|
231
243
|
else
|
|
@@ -9,7 +9,7 @@ module HTTPX
|
|
|
9
9
|
include Callbacks
|
|
10
10
|
include Loggable
|
|
11
11
|
|
|
12
|
-
CHECK_IF_IP =
|
|
12
|
+
CHECK_IF_IP = lambda do |name|
|
|
13
13
|
begin
|
|
14
14
|
IPAddr.new(name)
|
|
15
15
|
true
|
|
@@ -55,6 +55,7 @@ module HTTPX
|
|
|
55
55
|
return if ips.empty?
|
|
56
56
|
|
|
57
57
|
ips.map { |ip| IPAddr.new(ip) }
|
|
58
|
+
rescue IOError
|
|
58
59
|
end
|
|
59
60
|
|
|
60
61
|
def emit_resolve_error(connection, hostname = connection.origin.host, ex = nil)
|
data/lib/httpx/response.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "objspace"
|
|
3
4
|
require "stringio"
|
|
4
5
|
require "tempfile"
|
|
5
6
|
require "fileutils"
|
|
@@ -13,6 +14,8 @@ module HTTPX
|
|
|
13
14
|
|
|
14
15
|
def_delegator :@body, :to_s
|
|
15
16
|
|
|
17
|
+
def_delegator :@body, :to_str
|
|
18
|
+
|
|
16
19
|
def_delegator :@body, :read
|
|
17
20
|
|
|
18
21
|
def_delegator :@body, :copy_to
|
|
@@ -44,7 +47,7 @@ module HTTPX
|
|
|
44
47
|
end
|
|
45
48
|
|
|
46
49
|
def content_type
|
|
47
|
-
ContentType.
|
|
50
|
+
@content_type ||= ContentType.new(@headers["content-type"])
|
|
48
51
|
end
|
|
49
52
|
|
|
50
53
|
def complete?
|
|
@@ -67,8 +70,31 @@ module HTTPX
|
|
|
67
70
|
raise HTTPError, self
|
|
68
71
|
end
|
|
69
72
|
|
|
73
|
+
def json(options = nil)
|
|
74
|
+
decode("json", options)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def form
|
|
78
|
+
decode("form")
|
|
79
|
+
end
|
|
80
|
+
|
|
70
81
|
private
|
|
71
82
|
|
|
83
|
+
def decode(format, options = nil)
|
|
84
|
+
# TODO: check if content-type is a valid format, i.e. "application/json" for json parsing
|
|
85
|
+
transcoder = Transcoder.registry(format)
|
|
86
|
+
|
|
87
|
+
raise Error, "no decoder available for \"#{format}\"" unless transcoder.respond_to?(:decode)
|
|
88
|
+
|
|
89
|
+
decoder = transcoder.decode(self)
|
|
90
|
+
|
|
91
|
+
raise Error, "no decoder available for \"#{format}\"" unless decoder
|
|
92
|
+
|
|
93
|
+
decoder.call(self, options)
|
|
94
|
+
rescue Registry::Error
|
|
95
|
+
raise Error, "no decoder available for \"#{format}\""
|
|
96
|
+
end
|
|
97
|
+
|
|
72
98
|
def no_data?
|
|
73
99
|
@status < 200 ||
|
|
74
100
|
@status == 204 ||
|
|
@@ -134,18 +160,26 @@ module HTTPX
|
|
|
134
160
|
end
|
|
135
161
|
|
|
136
162
|
def to_s
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
content = @buffer.read
|
|
163
|
+
case @buffer
|
|
164
|
+
when StringIO
|
|
140
165
|
begin
|
|
141
|
-
|
|
166
|
+
@buffer.string.force_encoding(@encoding)
|
|
167
|
+
rescue ArgumentError
|
|
168
|
+
@buffer.string
|
|
169
|
+
end
|
|
170
|
+
when Tempfile, File
|
|
171
|
+
rewind
|
|
172
|
+
content = _with_same_buffer_pos { @buffer.read }
|
|
173
|
+
begin
|
|
174
|
+
content.force_encoding(@encoding)
|
|
142
175
|
rescue ArgumentError # ex: unknown encoding name - utf
|
|
143
|
-
|
|
176
|
+
content
|
|
144
177
|
end
|
|
178
|
+
when nil
|
|
179
|
+
"".b
|
|
180
|
+
else
|
|
181
|
+
@buffer
|
|
145
182
|
end
|
|
146
|
-
"".b
|
|
147
|
-
ensure
|
|
148
|
-
close
|
|
149
183
|
end
|
|
150
184
|
alias_method :to_str, :to_s
|
|
151
185
|
|
|
@@ -177,7 +211,11 @@ module HTTPX
|
|
|
177
211
|
end
|
|
178
212
|
|
|
179
213
|
def ==(other)
|
|
180
|
-
|
|
214
|
+
if other.respond_to?(:read)
|
|
215
|
+
_with_same_buffer_pos { FileUtils.compare_stream(@buffer, other) }
|
|
216
|
+
else
|
|
217
|
+
to_s == other.to_s
|
|
218
|
+
end
|
|
181
219
|
end
|
|
182
220
|
|
|
183
221
|
# :nocov:
|
|
@@ -204,7 +242,7 @@ module HTTPX
|
|
|
204
242
|
@buffer = Tempfile.new("httpx", encoding: Encoding::BINARY, mode: File::RDWR)
|
|
205
243
|
else
|
|
206
244
|
@state = :memory
|
|
207
|
-
@buffer = StringIO.new("".b
|
|
245
|
+
@buffer = StringIO.new("".b)
|
|
208
246
|
end
|
|
209
247
|
when :memory
|
|
210
248
|
if @length > @threshold_size
|
|
@@ -222,6 +260,18 @@ module HTTPX
|
|
|
222
260
|
|
|
223
261
|
return unless %i[memory buffer].include?(@state)
|
|
224
262
|
end
|
|
263
|
+
|
|
264
|
+
def _with_same_buffer_pos
|
|
265
|
+
return yield unless @buffer && @buffer.respond_to?(:pos)
|
|
266
|
+
|
|
267
|
+
current_pos = @buffer.pos
|
|
268
|
+
@buffer.rewind
|
|
269
|
+
begin
|
|
270
|
+
yield
|
|
271
|
+
rescue StandardError
|
|
272
|
+
@buffer.pos = current_pos
|
|
273
|
+
end
|
|
274
|
+
end
|
|
225
275
|
end
|
|
226
276
|
end
|
|
227
277
|
|
|
@@ -229,30 +279,22 @@ module HTTPX
|
|
|
229
279
|
MIME_TYPE_RE = %r{^([^/]+/[^;]+)(?:$|;)}.freeze
|
|
230
280
|
CHARSET_RE = /;\s*charset=([^;]+)/i.freeze
|
|
231
281
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
def initialize(mime_type, charset)
|
|
235
|
-
@mime_type = mime_type
|
|
236
|
-
@charset = charset
|
|
282
|
+
def initialize(header_value)
|
|
283
|
+
@header_value = header_value
|
|
237
284
|
end
|
|
238
285
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
def parse(str)
|
|
242
|
-
new(mime_type(str), charset(str))
|
|
243
|
-
end
|
|
286
|
+
def mime_type
|
|
287
|
+
return @mime_type if defined?(@mime_type)
|
|
244
288
|
|
|
245
|
-
|
|
289
|
+
m = @header_value.to_s[MIME_TYPE_RE, 1]
|
|
290
|
+
m && @mime_type = m.strip.downcase
|
|
291
|
+
end
|
|
246
292
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
m && m.strip.downcase
|
|
250
|
-
end
|
|
293
|
+
def charset
|
|
294
|
+
return @charset if defined?(@charset)
|
|
251
295
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
m && m.strip.delete('"')
|
|
255
|
-
end
|
|
296
|
+
m = @header_value.to_s[CHARSET_RE, 1]
|
|
297
|
+
m && @charset = m.strip.delete('"')
|
|
256
298
|
end
|
|
257
299
|
end
|
|
258
300
|
|
|
@@ -286,14 +328,6 @@ module HTTPX
|
|
|
286
328
|
def raise_for_status
|
|
287
329
|
raise @error
|
|
288
330
|
end
|
|
289
|
-
|
|
290
|
-
# rubocop:disable Style/MissingRespondToMissing
|
|
291
|
-
def method_missing(meth, *, &block)
|
|
292
|
-
raise NoMethodError, "undefined response method `#{meth}' for error response" if @options.response_class.public_method_defined?(meth)
|
|
293
|
-
|
|
294
|
-
super
|
|
295
|
-
end
|
|
296
|
-
# rubocop:enable Style/MissingRespondToMissing
|
|
297
331
|
end
|
|
298
332
|
end
|
|
299
333
|
|