http 5.0.0.pre3 → 5.0.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/.github/workflows/ci.yml +65 -0
- data/.gitignore +6 -10
- data/.rspec +0 -4
- data/.rubocop.yml +7 -124
- data/.rubocop/layout.yml +8 -0
- data/.rubocop/style.yml +32 -0
- data/.rubocop_todo.yml +192 -0
- data/CHANGES.md +48 -1
- data/Gemfile +18 -11
- data/README.md +13 -17
- data/Rakefile +2 -10
- data/http.gemspec +2 -2
- data/lib/http/chainable.rb +15 -14
- data/lib/http/client.rb +18 -11
- data/lib/http/connection.rb +7 -3
- data/lib/http/content_type.rb +10 -5
- data/lib/http/feature.rb +1 -1
- data/lib/http/features/instrumentation.rb +1 -1
- data/lib/http/features/logging.rb +19 -21
- data/lib/http/headers.rb +3 -3
- data/lib/http/mime_type/adapter.rb +2 -0
- data/lib/http/options.rb +2 -2
- data/lib/http/redirector.rb +1 -1
- data/lib/http/request.rb +7 -4
- data/lib/http/response/body.rb +1 -2
- data/lib/http/response/inflater.rb +1 -1
- data/lib/http/response/parser.rb +72 -64
- data/lib/http/response/status.rb +2 -2
- data/lib/http/timeout/global.rb +16 -28
- data/lib/http/timeout/null.rb +2 -1
- data/lib/http/timeout/per_operation.rb +31 -55
- data/lib/http/version.rb +1 -1
- data/spec/lib/http/client_spec.rb +75 -41
- data/spec/lib/http/features/instrumentation_spec.rb +21 -15
- data/spec/lib/http/features/logging_spec.rb +2 -4
- data/spec/lib/http/headers_spec.rb +3 -3
- data/spec/lib/http/response/parser_spec.rb +2 -2
- data/spec/lib/http_spec.rb +20 -2
- data/spec/spec_helper.rb +21 -21
- data/spec/support/black_hole.rb +1 -1
- data/spec/support/dummy_server.rb +1 -1
- data/spec/support/dummy_server/servlet.rb +14 -2
- data/spec/support/fuubar.rb +21 -0
- data/spec/support/simplecov.rb +19 -0
- metadata +21 -16
- data/.coveralls.yml +0 -1
- data/.travis.yml +0 -38
data/CHANGES.md
CHANGED
|
@@ -1,4 +1,28 @@
|
|
|
1
|
-
##
|
|
1
|
+
## 5.0.0 (2021-05-12)
|
|
2
|
+
|
|
3
|
+
* [#656](https://github.com/httprb/http/pull/656)
|
|
4
|
+
Handle connection timeouts in `Features`
|
|
5
|
+
([@semenyukdmitry])
|
|
6
|
+
|
|
7
|
+
* [#651](https://github.com/httprb/http/pull/651)
|
|
8
|
+
Replace `http-parser` with `llhttp`
|
|
9
|
+
([@bryanp])
|
|
10
|
+
|
|
11
|
+
* [#647](https://github.com/httprb/http/pull/647)
|
|
12
|
+
Add support for `MKCALENDAR` HTTP verb
|
|
13
|
+
([@meanphil])
|
|
14
|
+
|
|
15
|
+
* [#632](https://github.com/httprb/http/pull/632)
|
|
16
|
+
Respect the SSL context's `verify_hostname` value
|
|
17
|
+
([@colemannugent])
|
|
18
|
+
|
|
19
|
+
* [#625](https://github.com/httprb/http/pull/625)
|
|
20
|
+
Fix inflator with empty responses
|
|
21
|
+
([@LukaszMaslej])
|
|
22
|
+
|
|
23
|
+
* [#599](https://github.com/httprb/http/pull/599)
|
|
24
|
+
Allow passing `HTTP::FormData::{Multipart,UrlEncoded}` object directly.
|
|
25
|
+
([@ixti])
|
|
2
26
|
|
|
3
27
|
* [#593](https://github.com/httprb/http/pull/593)
|
|
4
28
|
[#592](https://github.com/httprb/http/issues/592)
|
|
@@ -56,6 +80,24 @@
|
|
|
56
80
|
([@ixti])
|
|
57
81
|
|
|
58
82
|
|
|
83
|
+
## 4.4.0 (2020-03-25)
|
|
84
|
+
|
|
85
|
+
* Backport [#587](https://github.com/httprb/http/pull/587)
|
|
86
|
+
Fix redirections when server responds with multiple Location headers.
|
|
87
|
+
([@ixti])
|
|
88
|
+
|
|
89
|
+
* Backport [#599](https://github.com/httprb/http/pull/599)
|
|
90
|
+
Allow passing HTTP::FormData::{Multipart,UrlEncoded} object directly.
|
|
91
|
+
([@ixti])
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
## 4.3.0 (2020-01-09)
|
|
95
|
+
|
|
96
|
+
* Backport [#581](https://github.com/httprb/http/pull/581)
|
|
97
|
+
Add Ruby-2.7 compatibility.
|
|
98
|
+
([@ixti], [@janko])
|
|
99
|
+
|
|
100
|
+
|
|
59
101
|
## 4.2.0 (2019-10-22)
|
|
60
102
|
|
|
61
103
|
* Backport [#489](https://github.com/httprb/http/pull/489)
|
|
@@ -840,3 +882,8 @@ end
|
|
|
840
882
|
[@mamoonraja]: https://github.com/mamoonraja
|
|
841
883
|
[@joshuaflanagan]: https://github.com/joshuaflanagan
|
|
842
884
|
[@antonvolkoff]: https://github.com/antonvolkoff
|
|
885
|
+
[@LukaszMaslej]: https://github.com/LukaszMaslej
|
|
886
|
+
[@colemannugent]: https://github.com/colemannugent
|
|
887
|
+
[@semenyukdmitry]: https://github.com/semenyukdmitry
|
|
888
|
+
[@bryanp]: https://github.com/bryanp
|
|
889
|
+
[@meanphil]: https://github.com/meanphil
|
data/Gemfile
CHANGED
|
@@ -5,32 +5,39 @@ ruby RUBY_VERSION
|
|
|
5
5
|
|
|
6
6
|
gem "rake"
|
|
7
7
|
|
|
8
|
+
# Ruby 3.0 does not ship it anymore.
|
|
9
|
+
# TODO: We should probably refactor specs to avoid need for it.
|
|
10
|
+
gem "webrick"
|
|
11
|
+
|
|
8
12
|
group :development do
|
|
9
13
|
gem "guard-rspec", :require => false
|
|
10
14
|
gem "nokogiri", :require => false
|
|
11
15
|
gem "pry", :require => false
|
|
12
16
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
17
|
+
# RSpec formatter
|
|
18
|
+
gem "fuubar", :require => false
|
|
19
|
+
|
|
20
|
+
platform :mri do
|
|
21
|
+
gem "pry-byebug"
|
|
16
22
|
end
|
|
17
23
|
end
|
|
18
24
|
|
|
19
25
|
group :test do
|
|
20
|
-
gem "
|
|
21
|
-
gem "certificate_authority", :require => false
|
|
26
|
+
gem "certificate_authority", "~> 1.0", :require => false
|
|
22
27
|
|
|
23
28
|
gem "backports"
|
|
24
29
|
|
|
25
|
-
gem "
|
|
26
|
-
gem "
|
|
30
|
+
gem "rubocop"
|
|
31
|
+
gem "rubocop-performance"
|
|
32
|
+
gem "rubocop-rake"
|
|
33
|
+
gem "rubocop-rspec"
|
|
34
|
+
|
|
35
|
+
gem "simplecov", :require => false
|
|
36
|
+
gem "simplecov-lcov", :require => false
|
|
27
37
|
|
|
28
|
-
gem "rspec", "~> 3.
|
|
38
|
+
gem "rspec", "~> 3.10"
|
|
29
39
|
gem "rspec-its"
|
|
30
40
|
|
|
31
|
-
gem "rubocop", "= 0.68.1"
|
|
32
|
-
gem "rubocop-performance"
|
|
33
|
-
|
|
34
41
|
gem "yardstick"
|
|
35
42
|
end
|
|
36
43
|
|
data/README.md
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
# 
|
|
2
2
|
|
|
3
|
-
[](https://rubygems.org/gems/http)
|
|
4
|
+
[](https://github.com/httprb/http/actions?query=workflow:CI)
|
|
5
5
|
[](https://codeclimate.com/github/httprb/http)
|
|
6
|
-
[](https://coveralls.io/r/httprb/http)
|
|
7
6
|
[](https://github.com/httprb/http/blob/master/LICENSE.txt)
|
|
8
7
|
|
|
9
8
|
[Documentation]
|
|
@@ -18,14 +17,12 @@ HTTP (The Gem! a.k.a. http.rb) is an easy-to-use client library for making reque
|
|
|
18
17
|
from Ruby. It uses a simple method chaining system for building requests, similar to
|
|
19
18
|
Python's [Requests].
|
|
20
19
|
|
|
21
|
-
Under the hood,
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
natively and outsources the parsing to native extensions.
|
|
20
|
+
Under the hood, http.rb uses the [llhttp] parser, a fast HTTP parsing native extension.
|
|
21
|
+
This library isn't just yet another wrapper around `Net::HTTP`. It implements the HTTP
|
|
22
|
+
protocol natively and outsources the parsing to native extensions.
|
|
25
23
|
|
|
26
24
|
[requests]: http://docs.python-requests.org/en/latest/
|
|
27
|
-
[
|
|
28
|
-
[http-parser-ffi]: https://github.com/cotag/http-parser
|
|
25
|
+
[llhttp]: https://llhttp.org/
|
|
29
26
|
|
|
30
27
|
|
|
31
28
|
## Another Ruby HTTP library? Why should I care?
|
|
@@ -115,8 +112,8 @@ for more detailed documentation and usage notes.
|
|
|
115
112
|
|
|
116
113
|
The following API documentation is also available:
|
|
117
114
|
|
|
118
|
-
* [YARD API documentation](
|
|
119
|
-
* [Chainable module (all chainable methods)](
|
|
115
|
+
* [YARD API documentation](https://www.rubydoc.info/github/httprb/http)
|
|
116
|
+
* [Chainable module (all chainable methods)](https://www.rubydoc.info/github/httprb/http/HTTP/Chainable)
|
|
120
117
|
|
|
121
118
|
[documentation]: https://github.com/httprb/http/wiki
|
|
122
119
|
|
|
@@ -165,11 +162,10 @@ and call `#readpartial` on it repeatedly until it returns `nil`:
|
|
|
165
162
|
This library aims to support and is [tested against][travis] the following Ruby
|
|
166
163
|
versions:
|
|
167
164
|
|
|
168
|
-
* Ruby 2.
|
|
169
|
-
* Ruby 2.
|
|
170
|
-
* Ruby
|
|
171
|
-
*
|
|
172
|
-
* JRuby 9.2.x.x
|
|
165
|
+
* Ruby 2.6
|
|
166
|
+
* Ruby 2.7
|
|
167
|
+
* Ruby 3.0
|
|
168
|
+
* JRuby 9.2
|
|
173
169
|
|
|
174
170
|
If something doesn't work on one of these versions, it's a bug.
|
|
175
171
|
|
|
@@ -199,5 +195,5 @@ dropped.
|
|
|
199
195
|
|
|
200
196
|
## Copyright
|
|
201
197
|
|
|
202
|
-
Copyright (c) 2011-
|
|
198
|
+
Copyright (c) 2011-2021 Tony Arcieri, Alexey V. Zapparov, Erik Michaels-Ober, Zachary Anker.
|
|
203
199
|
See LICENSE.txt for further details.
|
data/Rakefile
CHANGED
|
@@ -35,7 +35,7 @@ task :generate_status_codes do
|
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
File.open("./lib/http/response/status/reasons.rb", "w") do |io|
|
|
38
|
-
io.puts
|
|
38
|
+
io.puts <<~TPL
|
|
39
39
|
# AUTO-GENERATED FILE, DO NOT CHANGE IT MANUALLY
|
|
40
40
|
|
|
41
41
|
require "delegate"
|
|
@@ -61,12 +61,4 @@ task :generate_status_codes do
|
|
|
61
61
|
end
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
task :default => %i[spec rubocop verify_measurements]
|
|
66
|
-
else
|
|
67
|
-
case ENV["SUITE"]
|
|
68
|
-
when "rubocop" then task :default => :rubocop
|
|
69
|
-
when "yardstick" then task :default => :verify_measurements
|
|
70
|
-
else task :default => :spec
|
|
71
|
-
end
|
|
72
|
-
end
|
|
64
|
+
task :default => %i[spec rubocop verify_measurements]
|
data/http.gemspec
CHANGED
|
@@ -25,12 +25,12 @@ Gem::Specification.new do |gem|
|
|
|
25
25
|
gem.require_paths = ["lib"]
|
|
26
26
|
gem.version = HTTP::VERSION
|
|
27
27
|
|
|
28
|
-
gem.required_ruby_version = ">= 2.
|
|
28
|
+
gem.required_ruby_version = ">= 2.5"
|
|
29
29
|
|
|
30
30
|
gem.add_runtime_dependency "addressable", "~> 2.3"
|
|
31
31
|
gem.add_runtime_dependency "http-cookie", "~> 1.0"
|
|
32
32
|
gem.add_runtime_dependency "http-form_data", "~> 2.2"
|
|
33
|
-
gem.add_runtime_dependency "
|
|
33
|
+
gem.add_runtime_dependency "llhttp-ffi", "~> 0.0.1"
|
|
34
34
|
|
|
35
35
|
gem.add_development_dependency "bundler", "~> 2.0"
|
|
36
36
|
|
data/lib/http/chainable.rb
CHANGED
|
@@ -9,63 +9,63 @@ module HTTP
|
|
|
9
9
|
# Request a get sans response body
|
|
10
10
|
# @param uri
|
|
11
11
|
# @option options [Hash]
|
|
12
|
-
def head(uri, options = {})
|
|
12
|
+
def head(uri, options = {})
|
|
13
13
|
request :head, uri, options
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
# Get a resource
|
|
17
17
|
# @param uri
|
|
18
18
|
# @option options [Hash]
|
|
19
|
-
def get(uri, options = {})
|
|
19
|
+
def get(uri, options = {})
|
|
20
20
|
request :get, uri, options
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
# Post to a resource
|
|
24
24
|
# @param uri
|
|
25
25
|
# @option options [Hash]
|
|
26
|
-
def post(uri, options = {})
|
|
26
|
+
def post(uri, options = {})
|
|
27
27
|
request :post, uri, options
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
# Put to a resource
|
|
31
31
|
# @param uri
|
|
32
32
|
# @option options [Hash]
|
|
33
|
-
def put(uri, options = {})
|
|
33
|
+
def put(uri, options = {})
|
|
34
34
|
request :put, uri, options
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
# Delete a resource
|
|
38
38
|
# @param uri
|
|
39
39
|
# @option options [Hash]
|
|
40
|
-
def delete(uri, options = {})
|
|
40
|
+
def delete(uri, options = {})
|
|
41
41
|
request :delete, uri, options
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
# Echo the request back to the client
|
|
45
45
|
# @param uri
|
|
46
46
|
# @option options [Hash]
|
|
47
|
-
def trace(uri, options = {})
|
|
47
|
+
def trace(uri, options = {})
|
|
48
48
|
request :trace, uri, options
|
|
49
49
|
end
|
|
50
50
|
|
|
51
51
|
# Return the methods supported on the given URI
|
|
52
52
|
# @param uri
|
|
53
53
|
# @option options [Hash]
|
|
54
|
-
def options(uri, options = {})
|
|
54
|
+
def options(uri, options = {})
|
|
55
55
|
request :options, uri, options
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
# Convert to a transparent TCP/IP tunnel
|
|
59
59
|
# @param uri
|
|
60
60
|
# @option options [Hash]
|
|
61
|
-
def connect(uri, options = {})
|
|
61
|
+
def connect(uri, options = {})
|
|
62
62
|
request :connect, uri, options
|
|
63
63
|
end
|
|
64
64
|
|
|
65
65
|
# Apply partial modifications to a resource
|
|
66
66
|
# @param uri
|
|
67
67
|
# @option options [Hash]
|
|
68
|
-
def patch(uri, options = {})
|
|
68
|
+
def patch(uri, options = {})
|
|
69
69
|
request :patch, uri, options
|
|
70
70
|
end
|
|
71
71
|
|
|
@@ -148,7 +148,7 @@ module HTTP
|
|
|
148
148
|
|
|
149
149
|
yield p_client
|
|
150
150
|
ensure
|
|
151
|
-
p_client
|
|
151
|
+
p_client&.close
|
|
152
152
|
end
|
|
153
153
|
|
|
154
154
|
# Make a request through an HTTP proxy
|
|
@@ -173,7 +173,7 @@ module HTTP
|
|
|
173
173
|
# @param options
|
|
174
174
|
# @return [HTTP::Client]
|
|
175
175
|
# @see Redirector#initialize
|
|
176
|
-
def follow(options = {})
|
|
176
|
+
def follow(options = {})
|
|
177
177
|
branch default_options.with_follow options
|
|
178
178
|
end
|
|
179
179
|
|
|
@@ -211,10 +211,11 @@ module HTTP
|
|
|
211
211
|
# @option opts [#to_s] :user
|
|
212
212
|
# @option opts [#to_s] :pass
|
|
213
213
|
def basic_auth(opts)
|
|
214
|
-
user
|
|
215
|
-
pass
|
|
214
|
+
user = opts.fetch(:user)
|
|
215
|
+
pass = opts.fetch(:pass)
|
|
216
|
+
creds = "#{user}:#{pass}"
|
|
216
217
|
|
|
217
|
-
auth("Basic
|
|
218
|
+
auth("Basic #{Base64.strict_encode64(creds)}")
|
|
218
219
|
end
|
|
219
220
|
|
|
220
221
|
# Get options for HTTP
|
data/lib/http/client.rb
CHANGED
|
@@ -25,7 +25,7 @@ module HTTP
|
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
# Make an HTTP request
|
|
28
|
-
def request(verb, uri, opts = {})
|
|
28
|
+
def request(verb, uri, opts = {})
|
|
29
29
|
opts = @default_options.merge(opts)
|
|
30
30
|
req = build_request(verb, uri, opts)
|
|
31
31
|
res = perform(req, opts)
|
|
@@ -37,7 +37,7 @@ module HTTP
|
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
# Prepare an HTTP request
|
|
40
|
-
def build_request(verb, uri, opts = {})
|
|
40
|
+
def build_request(verb, uri, opts = {})
|
|
41
41
|
opts = @default_options.merge(opts)
|
|
42
42
|
uri = make_request_uri(uri, opts)
|
|
43
43
|
headers = make_request_headers(opts)
|
|
@@ -68,9 +68,9 @@ module HTTP
|
|
|
68
68
|
|
|
69
69
|
@state = :dirty
|
|
70
70
|
|
|
71
|
-
@connection ||= HTTP::Connection.new(req, options)
|
|
72
|
-
|
|
73
71
|
begin
|
|
72
|
+
@connection ||= HTTP::Connection.new(req, options)
|
|
73
|
+
|
|
74
74
|
unless @connection.failed_proxy_connect?
|
|
75
75
|
@connection.send_request(req)
|
|
76
76
|
@connection.read_headers!
|
|
@@ -97,7 +97,7 @@ module HTTP
|
|
|
97
97
|
end
|
|
98
98
|
|
|
99
99
|
def close
|
|
100
|
-
@connection
|
|
100
|
+
@connection&.close
|
|
101
101
|
@connection = nil
|
|
102
102
|
@state = :clean
|
|
103
103
|
end
|
|
@@ -120,15 +120,15 @@ module HTTP
|
|
|
120
120
|
def verify_connection!(uri)
|
|
121
121
|
if default_options.persistent? && uri.origin != default_options.persistent
|
|
122
122
|
raise StateError, "Persistence is enabled for #{default_options.persistent}, but we got #{uri.origin}"
|
|
123
|
+
end
|
|
124
|
+
|
|
123
125
|
# We re-create the connection object because we want to let prior requests
|
|
124
126
|
# lazily load the body as long as possible, and this mimics prior functionality.
|
|
125
|
-
|
|
126
|
-
|
|
127
|
+
return close if @connection && (!@connection.keep_alive? || @connection.expired?)
|
|
128
|
+
|
|
127
129
|
# If we get into a bad state (eg, Timeout.timeout ensure being killed)
|
|
128
130
|
# close the connection to prevent potential for mixed responses.
|
|
129
|
-
|
|
130
|
-
close
|
|
131
|
-
end
|
|
131
|
+
return close if @state == :dirty
|
|
132
132
|
end
|
|
133
133
|
|
|
134
134
|
# Merges query params if needed
|
|
@@ -175,7 +175,7 @@ module HTTP
|
|
|
175
175
|
when opts.body
|
|
176
176
|
opts.body
|
|
177
177
|
when opts.form
|
|
178
|
-
form =
|
|
178
|
+
form = make_form_data(opts.form)
|
|
179
179
|
headers[Headers::CONTENT_TYPE] ||= form.content_type
|
|
180
180
|
form
|
|
181
181
|
when opts.json
|
|
@@ -184,5 +184,12 @@ module HTTP
|
|
|
184
184
|
body
|
|
185
185
|
end
|
|
186
186
|
end
|
|
187
|
+
|
|
188
|
+
def make_form_data(form)
|
|
189
|
+
return form if form.is_a? HTTP::FormData::Multipart
|
|
190
|
+
return form if form.is_a? HTTP::FormData::Urlencoded
|
|
191
|
+
|
|
192
|
+
HTTP::FormData.create(form)
|
|
193
|
+
end
|
|
187
194
|
end
|
|
188
195
|
end
|
data/lib/http/connection.rb
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
require "forwardable"
|
|
4
4
|
|
|
5
5
|
require "http/headers"
|
|
6
|
-
require "http/response/parser"
|
|
7
6
|
|
|
8
7
|
module HTTP
|
|
9
8
|
# A connection to the HTTP server
|
|
@@ -68,8 +67,13 @@ module HTTP
|
|
|
68
67
|
# @param [Request] req Request to send to the server
|
|
69
68
|
# @return [nil]
|
|
70
69
|
def send_request(req)
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
if @pending_response
|
|
71
|
+
raise StateError, "Tried to send a request while one is pending already. Make sure you read off the body."
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
if @pending_request
|
|
75
|
+
raise StateError, "Tried to send a request while a response is pending. Make sure you read off the body."
|
|
76
|
+
end
|
|
73
77
|
|
|
74
78
|
@pending_request = true
|
|
75
79
|
|
data/lib/http/content_type.rb
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module HTTP
|
|
4
|
-
ContentType
|
|
4
|
+
class ContentType
|
|
5
5
|
MIME_TYPE_RE = %r{^([^/]+/[^;]+)(?:$|;)}.freeze
|
|
6
6
|
CHARSET_RE = /;\s*charset=([^;]+)/i.freeze
|
|
7
7
|
|
|
8
|
+
attr_accessor :mime_type, :charset
|
|
9
|
+
|
|
8
10
|
class << self
|
|
9
11
|
# Parse string and return ContentType struct
|
|
10
12
|
def parse(str)
|
|
@@ -15,15 +17,18 @@ module HTTP
|
|
|
15
17
|
|
|
16
18
|
# :nodoc:
|
|
17
19
|
def mime_type(str)
|
|
18
|
-
|
|
19
|
-
m && m.strip.downcase
|
|
20
|
+
str.to_s[MIME_TYPE_RE, 1]&.strip&.downcase
|
|
20
21
|
end
|
|
21
22
|
|
|
22
23
|
# :nodoc:
|
|
23
24
|
def charset(str)
|
|
24
|
-
|
|
25
|
-
m && m.strip.delete('"')
|
|
25
|
+
str.to_s[CHARSET_RE, 1]&.strip&.delete('"')
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
|
+
|
|
29
|
+
def initialize(mime_type = nil, charset = nil)
|
|
30
|
+
@mime_type = mime_type
|
|
31
|
+
@charset = charset
|
|
32
|
+
end
|
|
28
33
|
end
|
|
29
34
|
end
|