http 5.0.0.pre2 → 5.0.2
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/layout.yml +8 -0
- data/.rubocop/style.yml +32 -0
- data/.rubocop.yml +7 -124
- data/.rubocop_todo.yml +192 -0
- data/CHANGES.md +114 -1
- data/Gemfile +18 -11
- data/LICENSE.txt +1 -1
- data/README.md +13 -16
- data/Rakefile +2 -10
- data/http.gemspec +3 -3
- data/lib/http/chainable.rb +15 -14
- data/lib/http/client.rb +26 -15
- 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/auto_inflate.rb +0 -2
- 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/writer.rb +5 -1
- data/lib/http/request.rb +22 -5
- data/lib/http/response/body.rb +5 -4
- data/lib/http/response/inflater.rb +1 -1
- data/lib/http/response/parser.rb +74 -62
- data/lib/http/response/status.rb +2 -2
- data/lib/http/response.rb +22 -4
- data/lib/http/timeout/global.rb +41 -35
- data/lib/http/timeout/null.rb +2 -1
- data/lib/http/timeout/per_operation.rb +56 -59
- data/lib/http/version.rb +1 -1
- data/spec/lib/http/client_spec.rb +109 -41
- data/spec/lib/http/features/auto_inflate_spec.rb +0 -1
- data/spec/lib/http/features/instrumentation_spec.rb +21 -16
- data/spec/lib/http/features/logging_spec.rb +2 -5
- data/spec/lib/http/headers_spec.rb +3 -3
- data/spec/lib/http/redirector_spec.rb +44 -0
- data/spec/lib/http/request/writer_spec.rb +12 -1
- data/spec/lib/http/response/body_spec.rb +5 -5
- data/spec/lib/http/response/parser_spec.rb +30 -1
- data/spec/lib/http/response_spec.rb +62 -10
- 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/servlet.rb +14 -2
- data/spec/support/dummy_server.rb +1 -1
- data/spec/support/fuubar.rb +21 -0
- data/spec/support/simplecov.rb +19 -0
- metadata +23 -17
- data/.coveralls.yml +0 -1
- data/.travis.yml +0 -38
data/CHANGES.md
CHANGED
|
@@ -1,4 +1,77 @@
|
|
|
1
|
-
##
|
|
1
|
+
## 5.0.2 (2021-09-10)
|
|
2
|
+
|
|
3
|
+
* [#686](https://github.com/httprb/http/pull/686)
|
|
4
|
+
Correctly reset the parser.
|
|
5
|
+
([@bryanp])
|
|
6
|
+
|
|
7
|
+
* [#684](https://github.com/httprb/http/pull/684)
|
|
8
|
+
Don't set Content-Length for GET, HEAD, DELETE, or CONNECT requests without a BODY.
|
|
9
|
+
([@jyn514])
|
|
10
|
+
|
|
11
|
+
* [#679](https://github.com/httprb/http/pull/679)
|
|
12
|
+
Use features on redirected requests.
|
|
13
|
+
([@nomis])
|
|
14
|
+
|
|
15
|
+
* [#678](https://github.com/schwern)
|
|
16
|
+
Restore `HTTP::Response` `:uri` option for backwards compatibility.
|
|
17
|
+
([@schwern])
|
|
18
|
+
|
|
19
|
+
* [#676](https://github.com/httprb/http/pull/676)
|
|
20
|
+
Update addressable because of CVE-2021-32740.
|
|
21
|
+
([@matheussilvasantos])
|
|
22
|
+
|
|
23
|
+
* [#653](https://github.com/httprb/http/pull/653)
|
|
24
|
+
Avoid force encodings on frozen strings.
|
|
25
|
+
([@bvicenzo])
|
|
26
|
+
|
|
27
|
+
* [#638](https://github.com/httprb/http/pull/638)
|
|
28
|
+
DNS failover handling.
|
|
29
|
+
([@midnight-wonderer])
|
|
30
|
+
|
|
31
|
+
## 5.0.1 (2021-06-26)
|
|
32
|
+
|
|
33
|
+
* [#670](https://github.com/httprb/http/pull/670)
|
|
34
|
+
Revert `Response#parse` behavior introduced in [#540].
|
|
35
|
+
([@DannyBen])
|
|
36
|
+
|
|
37
|
+
* [#669](https://github.com/httprb/http/pull/669)
|
|
38
|
+
Prevent bodies from being resubmitted when following unsafe redirects.
|
|
39
|
+
([@odinhb])
|
|
40
|
+
|
|
41
|
+
* [#664](https://github.com/httprb/http/pull/664)
|
|
42
|
+
Bump llhttp-ffi to 0.3.0.
|
|
43
|
+
([@bryanp])
|
|
44
|
+
|
|
45
|
+
## 5.0.0 (2021-05-12)
|
|
46
|
+
|
|
47
|
+
* [#656](https://github.com/httprb/http/pull/656)
|
|
48
|
+
Handle connection timeouts in `Features`
|
|
49
|
+
([@semenyukdmitry])
|
|
50
|
+
|
|
51
|
+
* [#651](https://github.com/httprb/http/pull/651)
|
|
52
|
+
Replace `http-parser` with `llhttp`
|
|
53
|
+
([@bryanp])
|
|
54
|
+
|
|
55
|
+
* [#647](https://github.com/httprb/http/pull/647)
|
|
56
|
+
Add support for `MKCALENDAR` HTTP verb
|
|
57
|
+
([@meanphil])
|
|
58
|
+
|
|
59
|
+
* [#632](https://github.com/httprb/http/pull/632)
|
|
60
|
+
Respect the SSL context's `verify_hostname` value
|
|
61
|
+
([@colemannugent])
|
|
62
|
+
|
|
63
|
+
* [#625](https://github.com/httprb/http/pull/625)
|
|
64
|
+
Fix inflator with empty responses
|
|
65
|
+
([@LukaszMaslej])
|
|
66
|
+
|
|
67
|
+
* [#599](https://github.com/httprb/http/pull/599)
|
|
68
|
+
Allow passing `HTTP::FormData::{Multipart,UrlEncoded}` object directly.
|
|
69
|
+
([@ixti])
|
|
70
|
+
|
|
71
|
+
* [#593](https://github.com/httprb/http/pull/593)
|
|
72
|
+
[#592](https://github.com/httprb/http/issues/592)
|
|
73
|
+
Support informational (1XX) responses.
|
|
74
|
+
([@ixti])
|
|
2
75
|
|
|
3
76
|
* [#590](https://github.com/httprb/http/pull/590)
|
|
4
77
|
[#589](https://github.com/httprb/http/issues/589)
|
|
@@ -24,6 +97,12 @@
|
|
|
24
97
|
Preserve header names casing.
|
|
25
98
|
([@joshuaflanagan])
|
|
26
99
|
|
|
100
|
+
* [#540](https://github.com/httprb/http/pull/540)
|
|
101
|
+
[#538](https://github.com/httprb/http/issues/538)
|
|
102
|
+
**BREAKING CHANGE**
|
|
103
|
+
Require explicit MIME type for Response#parse
|
|
104
|
+
([@ixti])
|
|
105
|
+
|
|
27
106
|
* [#532](https://github.com/httprb/http/pull/532)
|
|
28
107
|
Fix pipes support in request bodies.
|
|
29
108
|
([@ixti])
|
|
@@ -50,6 +129,27 @@
|
|
|
50
129
|
Drop Ruby 2.3.x support.
|
|
51
130
|
([@ixti])
|
|
52
131
|
|
|
132
|
+
* [3ed0c31](https://github.com/httprb/http/commit/3ed0c318eab6a8c390654cda17bf6df9e963c7d6)
|
|
133
|
+
Drop Ruby 2.4.x support.
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
## 4.4.0 (2020-03-25)
|
|
137
|
+
|
|
138
|
+
* Backport [#587](https://github.com/httprb/http/pull/587)
|
|
139
|
+
Fix redirections when server responds with multiple Location headers.
|
|
140
|
+
([@ixti])
|
|
141
|
+
|
|
142
|
+
* Backport [#599](https://github.com/httprb/http/pull/599)
|
|
143
|
+
Allow passing HTTP::FormData::{Multipart,UrlEncoded} object directly.
|
|
144
|
+
([@ixti])
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
## 4.3.0 (2020-01-09)
|
|
148
|
+
|
|
149
|
+
* Backport [#581](https://github.com/httprb/http/pull/581)
|
|
150
|
+
Add Ruby-2.7 compatibility.
|
|
151
|
+
([@ixti], [@janko])
|
|
152
|
+
|
|
53
153
|
|
|
54
154
|
## 4.2.0 (2019-10-22)
|
|
55
155
|
|
|
@@ -835,3 +935,16 @@ end
|
|
|
835
935
|
[@mamoonraja]: https://github.com/mamoonraja
|
|
836
936
|
[@joshuaflanagan]: https://github.com/joshuaflanagan
|
|
837
937
|
[@antonvolkoff]: https://github.com/antonvolkoff
|
|
938
|
+
[@LukaszMaslej]: https://github.com/LukaszMaslej
|
|
939
|
+
[@colemannugent]: https://github.com/colemannugent
|
|
940
|
+
[@semenyukdmitry]: https://github.com/semenyukdmitry
|
|
941
|
+
[@bryanp]: https://github.com/bryanp
|
|
942
|
+
[@meanphil]: https://github.com/meanphil
|
|
943
|
+
[@odinhb]: https://github.com/odinhb
|
|
944
|
+
[@DannyBen]: https://github.com/DannyBen
|
|
945
|
+
[@jyn514]: https://github.com/jyn514
|
|
946
|
+
[@bvicenzo]: https://github.com/bvicenzo
|
|
947
|
+
[@nomis]: https://github.com/nomis
|
|
948
|
+
[@midnight-wonderer]: https://github.com/midnight-wonderer
|
|
949
|
+
[@schwern]: https://github.com/schwern
|
|
950
|
+
[@matheussilvasantos]: https://github.com/matheussilvasantos
|
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/LICENSE.txt
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Copyright (c) 2011-
|
|
1
|
+
Copyright (c) 2011-2021 Tony Arcieri, Erik Michaels-Ober, Alexey V. Zapparov, Zachary Anker
|
|
2
2
|
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
4
|
a copy of this software and associated documentation files (the
|
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,10 +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
|
-
* JRuby 9.2
|
|
165
|
+
* Ruby 2.6
|
|
166
|
+
* Ruby 2.7
|
|
167
|
+
* Ruby 3.0
|
|
168
|
+
* JRuby 9.2
|
|
172
169
|
|
|
173
170
|
If something doesn't work on one of these versions, it's a bug.
|
|
174
171
|
|
|
@@ -198,5 +195,5 @@ dropped.
|
|
|
198
195
|
|
|
199
196
|
## Copyright
|
|
200
197
|
|
|
201
|
-
Copyright (c) 2011-
|
|
198
|
+
Copyright (c) 2011-2021 Tony Arcieri, Alexey V. Zapparov, Erik Michaels-Ober, Zachary Anker.
|
|
202
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
|
-
gem.add_runtime_dependency "addressable", "~> 2.
|
|
30
|
+
gem.add_runtime_dependency "addressable", "~> 2.8"
|
|
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.4.0"
|
|
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,19 +25,19 @@ 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)
|
|
32
32
|
return res unless opts.follow
|
|
33
33
|
|
|
34
34
|
Redirector.new(opts.follow).perform(req, res) do |request|
|
|
35
|
-
perform(request, opts)
|
|
35
|
+
perform(wrap_request(request, opts), opts)
|
|
36
36
|
end
|
|
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)
|
|
@@ -52,9 +52,7 @@ module HTTP
|
|
|
52
52
|
:body => body
|
|
53
53
|
)
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
feature.wrap_request(request)
|
|
57
|
-
end
|
|
55
|
+
wrap_request(req, opts)
|
|
58
56
|
end
|
|
59
57
|
|
|
60
58
|
# @!method persistent?
|
|
@@ -68,9 +66,9 @@ module HTTP
|
|
|
68
66
|
|
|
69
67
|
@state = :dirty
|
|
70
68
|
|
|
71
|
-
@connection ||= HTTP::Connection.new(req, options)
|
|
72
|
-
|
|
73
69
|
begin
|
|
70
|
+
@connection ||= HTTP::Connection.new(req, options)
|
|
71
|
+
|
|
74
72
|
unless @connection.failed_proxy_connect?
|
|
75
73
|
@connection.send_request(req)
|
|
76
74
|
@connection.read_headers!
|
|
@@ -97,13 +95,19 @@ module HTTP
|
|
|
97
95
|
end
|
|
98
96
|
|
|
99
97
|
def close
|
|
100
|
-
@connection
|
|
98
|
+
@connection&.close
|
|
101
99
|
@connection = nil
|
|
102
100
|
@state = :clean
|
|
103
101
|
end
|
|
104
102
|
|
|
105
103
|
private
|
|
106
104
|
|
|
105
|
+
def wrap_request(req, opts)
|
|
106
|
+
opts.features.inject(req) do |request, (_name, feature)|
|
|
107
|
+
feature.wrap_request(request)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
107
111
|
def build_response(req, options)
|
|
108
112
|
Response.new(
|
|
109
113
|
:status => @connection.status_code,
|
|
@@ -120,15 +124,15 @@ module HTTP
|
|
|
120
124
|
def verify_connection!(uri)
|
|
121
125
|
if default_options.persistent? && uri.origin != default_options.persistent
|
|
122
126
|
raise StateError, "Persistence is enabled for #{default_options.persistent}, but we got #{uri.origin}"
|
|
127
|
+
end
|
|
128
|
+
|
|
123
129
|
# We re-create the connection object because we want to let prior requests
|
|
124
130
|
# lazily load the body as long as possible, and this mimics prior functionality.
|
|
125
|
-
|
|
126
|
-
|
|
131
|
+
return close if @connection && (!@connection.keep_alive? || @connection.expired?)
|
|
132
|
+
|
|
127
133
|
# If we get into a bad state (eg, Timeout.timeout ensure being killed)
|
|
128
134
|
# close the connection to prevent potential for mixed responses.
|
|
129
|
-
|
|
130
|
-
close
|
|
131
|
-
end
|
|
135
|
+
return close if @state == :dirty
|
|
132
136
|
end
|
|
133
137
|
|
|
134
138
|
# Merges query params if needed
|
|
@@ -175,7 +179,7 @@ module HTTP
|
|
|
175
179
|
when opts.body
|
|
176
180
|
opts.body
|
|
177
181
|
when opts.form
|
|
178
|
-
form =
|
|
182
|
+
form = make_form_data(opts.form)
|
|
179
183
|
headers[Headers::CONTENT_TYPE] ||= form.content_type
|
|
180
184
|
form
|
|
181
185
|
when opts.json
|
|
@@ -184,5 +188,12 @@ module HTTP
|
|
|
184
188
|
body
|
|
185
189
|
end
|
|
186
190
|
end
|
|
191
|
+
|
|
192
|
+
def make_form_data(form)
|
|
193
|
+
return form if form.is_a? HTTP::FormData::Multipart
|
|
194
|
+
return form if form.is_a? HTTP::FormData::Urlencoded
|
|
195
|
+
|
|
196
|
+
HTTP::FormData.create(form)
|
|
197
|
+
end
|
|
187
198
|
end
|
|
188
199
|
end
|