httpi 3.0.2 → 4.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/development.yml +1 -1
- data/CHANGELOG.md +18 -1
- data/Gemfile +1 -1
- data/README.md +13 -2
- data/UPDATING.md +4 -0
- data/httpi.gemspec +3 -3
- data/lib/httpi/request.rb +2 -2
- data/lib/httpi/response.rb +1 -1
- data/lib/httpi/utils.rb +95 -0
- data/lib/httpi/version.rb +1 -1
- data/lib/httpi.rb +1 -0
- data/spec/httpi/adapter/httpclient_spec.rb +1 -2
- data/spec/httpi/request_spec.rb +4 -4
- data/spec/httpi/response_spec.rb +6 -2
- data/spec/integration/net_http_spec.rb +3 -6
- data/spec/integration/support/server.rb +1 -1
- metadata +16 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bb83de56d8f0e1b609e317db0a889b669290c6888b2ef4a41efe682bcd092ec3
|
4
|
+
data.tar.gz: a2ec713acb8c51714850de1490c2b247d10fdd0ada7227fbd89ec4cdfb3c7963
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bd35a2d65bc74884715d763c2790aa0567355c84337f17459fc6d0956b2f019fc6c82dba220bd3fd707b1e1837dcf6b264395ef109251196211d700b76e9f66e
|
7
|
+
data.tar.gz: f965bcc58b97d692f295408058bbf2ee3cf70d7b19221cc892aa4bdd250aa177bedc1303efc172c1e953ec7c44327cb026ca044fbf32144b4bb1bf1c435ebb17
|
data/CHANGELOG.md
CHANGED
@@ -1,10 +1,27 @@
|
|
1
1
|
### Unreleased
|
2
2
|
|
3
|
-
*
|
3
|
+
* Add your changelog entry here
|
4
|
+
|
5
|
+
### 4.0.2 (2024-06-13)
|
6
|
+
|
7
|
+
* Don't change http header casing by @pcai in https://github.com/savonrb/httpi/pull/249
|
8
|
+
|
9
|
+
### 4.0.1 (2024-02-16)
|
10
|
+
|
11
|
+
HTTPI is officially in maintenance mode. Our emphasis will now be on bugs, security fixes, and compatibility with the wider ecosystem. See [this issue](https://github.com/savonrb/httpi/issues/238) for details.
|
12
|
+
|
13
|
+
* Adds support for rack 3.0.
|
14
|
+
* POTENTIAL BREAKING CHANGE: `HTTPI::Request#headers` and `HTTPI::Response#headers` now return `HTTPI::Utils::Headers` instead of `Rack::Utils::HeaderHash`. This change will prevent HTTPI from breaking or changing its public API whenever rack rearranges its classes. If you were relying on the `Rack::Utils::HeaderHash` implementation, you will need to update your code to use `HTTPI::Utils::Headers` instead.
|
15
|
+
|
16
|
+
### 4.0.0 (yanked)
|
17
|
+
|
18
|
+
Yanked due to a bug when used with rack 2.
|
4
19
|
|
5
20
|
### 3.0.2 (2024-02-10)
|
6
21
|
|
22
|
+
* Improvement: [#237](https://github.com/savonrb/httpi/pull/237) Implemented `adapter_client_setup`.
|
7
23
|
* Add support for ruby 3.1, 3.2, 3.3. Drop support for ruby 2.7 and below.
|
24
|
+
* Pin to rack version < 3, HTTPI is not tested with rack 3 yet.
|
8
25
|
|
9
26
|
### 3.0.1 (2021-12-17)
|
10
27
|
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# HTTPI
|
2
2
|
|
3
|
-
A common interface for Ruby's HTTP libraries.
|
3
|
+
A common interface for Ruby's HTTP libraries. This project is now in maintenance mode. For new projects, we recommend [faraday](https://github.com/lostisland/faraday).
|
4
4
|
|
5
5
|
[Documentation](https://www.rubydoc.info/gems/httpi)
|
6
6
|
|
@@ -14,7 +14,7 @@ HTTPI is available through [Rubygems](https://rubygems.org/gems/httpi) and can b
|
|
14
14
|
|
15
15
|
or add it to your Gemfile like this:
|
16
16
|
|
17
|
-
gem 'httpi', '~>
|
17
|
+
gem 'httpi', '~> 4.0.0'
|
18
18
|
|
19
19
|
## Usage example
|
20
20
|
|
@@ -36,6 +36,17 @@ HTTPI.adapter = :httpclient
|
|
36
36
|
|
37
37
|
# and execute arbitary requests
|
38
38
|
HTTPI.request(:custom, request)
|
39
|
+
|
40
|
+
# add a client setup block that will be called before each request
|
41
|
+
HTTPI.adapter = :httpclient
|
42
|
+
HTTPI.adapter_client_setup = proc do |x|
|
43
|
+
x.ssl_config.set_default_paths
|
44
|
+
x.force_basic_auth = true
|
45
|
+
end
|
46
|
+
# ...
|
47
|
+
HTTPI.get(request) do |x|
|
48
|
+
x.force_basic_auth = false
|
49
|
+
end
|
39
50
|
```
|
40
51
|
|
41
52
|
### SOCKS Proxy Support
|
data/UPDATING.md
CHANGED
@@ -5,3 +5,7 @@
|
|
5
5
|
BREAKING CHANGE: the [#255](https://github.com/savonrb/httpi/pull/225) made the gem socksify and rack gems optional dependencies.
|
6
6
|
|
7
7
|
In order to restore the old behavior, see the README section "SOCKS Proxy Support" and "Rack Mock Adapter".
|
8
|
+
|
9
|
+
## From 3.x to 4.x
|
10
|
+
|
11
|
+
POTENTIAL BREAKING CHANGE: `HTTPI::Request#headers` and `HTTPI::Response#headers` now return `HTTPI::Utils::Headers` instead of `Rack::Utils::HeaderHash`. This change will prevent HTTPI from breaking or changing its public API whenever rack rearranges its classes. If you were relying on the `Rack::Utils::HeaderHash` implementation, you will need to update your code to use `HTTPI::Utils::Headers` instead.
|
data/httpi.gemspec
CHANGED
@@ -21,16 +21,16 @@ Gem::Specification.new do |s|
|
|
21
21
|
|
22
22
|
s.license = 'MIT'
|
23
23
|
|
24
|
-
s.add_dependency 'rack', '< 3'
|
24
|
+
s.add_dependency 'rack', '>= 2.0', '< 3.1'
|
25
25
|
s.add_dependency 'nkf'
|
26
26
|
s.add_dependency 'base64'
|
27
27
|
s.add_dependency 'mutex_m'
|
28
28
|
|
29
|
-
s.add_development_dependency 'rubyntlm', '~> 0.
|
29
|
+
s.add_development_dependency 'rubyntlm', '~> 0.6.4'
|
30
30
|
s.add_development_dependency 'rake', '~> 13.0'
|
31
31
|
s.add_development_dependency 'rspec', '~> 3.5'
|
32
32
|
s.add_development_dependency 'mocha', '~> 0.13'
|
33
|
-
s.add_development_dependency 'puma', '~>
|
33
|
+
s.add_development_dependency 'puma', '~> 6.0'
|
34
34
|
s.add_development_dependency 'webmock'
|
35
35
|
|
36
36
|
s.metadata["rubygems_mfa_required"] = "true"
|
data/lib/httpi/request.rb
CHANGED
@@ -64,12 +64,12 @@ module HTTPI
|
|
64
64
|
|
65
65
|
# Returns a Hash of HTTP headers. Defaults to return an empty Hash.
|
66
66
|
def headers
|
67
|
-
@headers ||=
|
67
|
+
@headers ||= HTTPI::Utils::Headers.new
|
68
68
|
end
|
69
69
|
|
70
70
|
# Sets the Hash of HTTP headers.
|
71
71
|
def headers=(headers)
|
72
|
-
@headers =
|
72
|
+
@headers = HTTPI::Utils::Headers.new.merge(headers)
|
73
73
|
end
|
74
74
|
|
75
75
|
# Adds a header information to accept gzipped content.
|
data/lib/httpi/response.rb
CHANGED
@@ -20,7 +20,7 @@ module HTTPI
|
|
20
20
|
# Initializer expects an HTTP response +code+, +headers+ and +body+.
|
21
21
|
def initialize(code, headers, body)
|
22
22
|
self.code = code.to_i
|
23
|
-
self.headers =
|
23
|
+
self.headers = HTTPI::Utils::Headers.new.merge(headers)
|
24
24
|
self.raw_body = body
|
25
25
|
end
|
26
26
|
|
data/lib/httpi/utils.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
# mostly verbatim from: https://github.com/rack/rack/blob/main/lib/rack/headers.rb
|
2
|
+
# Because this is part of httpi's public API, its better not to load an external
|
3
|
+
# library for it.
|
4
|
+
module HTTPI
|
5
|
+
module Utils
|
6
|
+
# A case-insensitive Hash that preserves the original case of a
|
7
|
+
# header when set.
|
8
|
+
#
|
9
|
+
class Headers < Hash
|
10
|
+
def self.[](headers)
|
11
|
+
if headers.is_a?(Headers) && !headers.frozen?
|
12
|
+
return headers
|
13
|
+
else
|
14
|
+
return self.new(headers)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(hash = {})
|
19
|
+
super()
|
20
|
+
@names = {}
|
21
|
+
hash.each { |k, v| self[k] = v }
|
22
|
+
end
|
23
|
+
|
24
|
+
# on dup/clone, we need to duplicate @names hash
|
25
|
+
def initialize_copy(other)
|
26
|
+
super
|
27
|
+
@names = other.names.dup
|
28
|
+
end
|
29
|
+
|
30
|
+
# on clear, we need to clear @names hash
|
31
|
+
def clear
|
32
|
+
super
|
33
|
+
@names.clear
|
34
|
+
end
|
35
|
+
|
36
|
+
def each
|
37
|
+
super do |k, v|
|
38
|
+
yield(k, v.respond_to?(:to_ary) ? v.to_ary.join("\n") : v)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_hash
|
43
|
+
hash = {}
|
44
|
+
each { |k, v| hash[k] = v }
|
45
|
+
hash
|
46
|
+
end
|
47
|
+
|
48
|
+
def [](k)
|
49
|
+
super(k) || super(@names[k.downcase])
|
50
|
+
end
|
51
|
+
|
52
|
+
def []=(k, v)
|
53
|
+
canonical = k.downcase.freeze
|
54
|
+
delete k if @names[canonical] && @names[canonical] != k # .delete is expensive, don't invoke it unless necessary
|
55
|
+
@names[canonical] = k
|
56
|
+
super k, v
|
57
|
+
end
|
58
|
+
|
59
|
+
def delete(k)
|
60
|
+
canonical = k.downcase
|
61
|
+
result = super @names.delete(canonical)
|
62
|
+
result
|
63
|
+
end
|
64
|
+
|
65
|
+
def include?(k)
|
66
|
+
super || @names.include?(k.downcase)
|
67
|
+
end
|
68
|
+
|
69
|
+
alias_method :has_key?, :include?
|
70
|
+
alias_method :member?, :include?
|
71
|
+
alias_method :key?, :include?
|
72
|
+
|
73
|
+
def merge!(other)
|
74
|
+
other.each { |k, v| self[k] = v }
|
75
|
+
self
|
76
|
+
end
|
77
|
+
|
78
|
+
def merge(other)
|
79
|
+
hash = dup
|
80
|
+
hash.merge! other
|
81
|
+
end
|
82
|
+
|
83
|
+
def replace(other)
|
84
|
+
clear
|
85
|
+
other.each { |k, v| self[k] = v }
|
86
|
+
self
|
87
|
+
end
|
88
|
+
|
89
|
+
protected
|
90
|
+
def names
|
91
|
+
@names
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
data/lib/httpi/version.rb
CHANGED
data/lib/httpi.rb
CHANGED
@@ -215,8 +215,7 @@ describe HTTPI::Adapter::HTTPClient do
|
|
215
215
|
end
|
216
216
|
end
|
217
217
|
|
218
|
-
|
219
|
-
xit "supports NTLM authentication" do
|
218
|
+
it "supports NTLM authentication" do
|
220
219
|
request = HTTPI::Request.new(@server.url + "ntlm-auth")
|
221
220
|
|
222
221
|
request.auth.ntlm("tester", "vReqSoafRe5O")
|
data/spec/httpi/request_spec.rb
CHANGED
@@ -92,11 +92,11 @@ describe HTTPI::Request do
|
|
92
92
|
after { HTTPI.query_builder = :flat }
|
93
93
|
|
94
94
|
it "lets you specify query parameter as Hash" do
|
95
|
-
expect(request.url.to_s).to eq("http://example.com?q
|
95
|
+
expect(request.url.to_s).to eq("http://example.com?q%5B%5D=nested&q%5B%5D=query")
|
96
96
|
end
|
97
97
|
|
98
98
|
it "getter return String for query parameter as Hash" do
|
99
|
-
expect(request.query).to eq("q
|
99
|
+
expect(request.query).to eq("q%5B%5D=nested&q%5B%5D=query")
|
100
100
|
end
|
101
101
|
end
|
102
102
|
end
|
@@ -149,7 +149,7 @@ describe HTTPI::Request do
|
|
149
149
|
describe "#headers" do
|
150
150
|
it "lets you specify a Hash of HTTP request headers" do
|
151
151
|
request.headers = { "Accept-Encoding" => "gzip" }
|
152
|
-
expect(request.headers).to eq({ "Accept-Encoding" => "gzip" })
|
152
|
+
expect(request.headers).to eq HTTPI::Utils::Headers.new.merge({ "Accept-Encoding" => "gzip" })
|
153
153
|
end
|
154
154
|
|
155
155
|
it "defaults to return an empty Hash" do
|
@@ -235,7 +235,7 @@ describe HTTPI::Request do
|
|
235
235
|
end
|
236
236
|
it "request body using a Hash with Array" do
|
237
237
|
request.body = {:foo => :bar, :baz => [:foo, :tst]}
|
238
|
-
expect(request.body.split("&")).to match_array(["foo=bar", "baz
|
238
|
+
expect(request.body.split("&")).to match_array(["foo=bar", "baz%5B%5D=foo", "baz%5B%5D=tst"])
|
239
239
|
end
|
240
240
|
end
|
241
241
|
end
|
data/spec/httpi/response_spec.rb
CHANGED
@@ -88,7 +88,7 @@ describe HTTPI::Response do
|
|
88
88
|
|
89
89
|
describe "#headers" do
|
90
90
|
it "returns the HTTP response headers" do
|
91
|
-
expect(response.headers).to eq({ "Content-Encoding" => "gzip" })
|
91
|
+
expect(response.headers).to eq HTTPI::Utils::Headers.new.merge({ "Content-Encoding" => "gzip" })
|
92
92
|
end
|
93
93
|
end
|
94
94
|
|
@@ -116,7 +116,11 @@ describe HTTPI::Response do
|
|
116
116
|
|
117
117
|
describe "#headers" do
|
118
118
|
it "returns the HTTP response headers" do
|
119
|
-
expect(response.headers).to eq({ "Content-Type" => "application/dime" })
|
119
|
+
expect(response.headers).to eq HTTPI::Utils::Headers.new.merge({ "Content-Type" => "application/dime" })
|
120
|
+
end
|
121
|
+
|
122
|
+
it "preserves casing" do
|
123
|
+
expect(response.headers.keys).to eq ["Content-Type"]
|
120
124
|
end
|
121
125
|
end
|
122
126
|
|
@@ -138,8 +138,7 @@ describe HTTPI::Adapter::NetHTTP do
|
|
138
138
|
to raise_error(HTTPI::NotSupportedError, /does not support HTTP digest authentication/)
|
139
139
|
end
|
140
140
|
|
141
|
-
|
142
|
-
xit "supports ntlm authentication" do
|
141
|
+
it "supports ntlm authentication" do
|
143
142
|
request = HTTPI::Request.new(@server.url + "ntlm-auth")
|
144
143
|
request.auth.ntlm("tester", "vReqSoafRe5O")
|
145
144
|
|
@@ -167,8 +166,7 @@ describe HTTPI::Adapter::NetHTTP do
|
|
167
166
|
HTTPI::Adapter::NetHTTP.any_instance.unstub(:check_net_ntlm_version!)
|
168
167
|
end
|
169
168
|
|
170
|
-
|
171
|
-
xit "does check ntlm when ntlm authentication is requested" do
|
169
|
+
it "does check ntlm when ntlm authentication is requested" do
|
172
170
|
request = HTTPI::Request.new(@server.url + "ntlm-auth")
|
173
171
|
request.auth.ntlm("tester", "vReqSoafRe5O")
|
174
172
|
|
@@ -185,8 +183,7 @@ describe HTTPI::Adapter::NetHTTP do
|
|
185
183
|
HTTPI::Adapter::NetHTTP.any_instance.unstub(:ntlm_version)
|
186
184
|
end
|
187
185
|
|
188
|
-
|
189
|
-
xit "does not crash when authenticate header is missing (on second request)" do
|
186
|
+
it "does not crash when authenticate header is missing (on second request)" do
|
190
187
|
request = HTTPI::Request.new(@server.url + "ntlm-auth")
|
191
188
|
request.auth.ntlm("tester", "vReqSoafRe5O")
|
192
189
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: httpi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 4.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Harrington
|
@@ -9,22 +9,28 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2024-
|
12
|
+
date: 2024-06-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
+
- - ">="
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '2.0'
|
18
21
|
- - "<"
|
19
22
|
- !ruby/object:Gem::Version
|
20
|
-
version: '3'
|
23
|
+
version: '3.1'
|
21
24
|
type: :runtime
|
22
25
|
prerelease: false
|
23
26
|
version_requirements: !ruby/object:Gem::Requirement
|
24
27
|
requirements:
|
28
|
+
- - ">="
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '2.0'
|
25
31
|
- - "<"
|
26
32
|
- !ruby/object:Gem::Version
|
27
|
-
version: '3'
|
33
|
+
version: '3.1'
|
28
34
|
- !ruby/object:Gem::Dependency
|
29
35
|
name: nkf
|
30
36
|
requirement: !ruby/object:Gem::Requirement
|
@@ -73,14 +79,14 @@ dependencies:
|
|
73
79
|
requirements:
|
74
80
|
- - "~>"
|
75
81
|
- !ruby/object:Gem::Version
|
76
|
-
version: 0.
|
82
|
+
version: 0.6.4
|
77
83
|
type: :development
|
78
84
|
prerelease: false
|
79
85
|
version_requirements: !ruby/object:Gem::Requirement
|
80
86
|
requirements:
|
81
87
|
- - "~>"
|
82
88
|
- !ruby/object:Gem::Version
|
83
|
-
version: 0.
|
89
|
+
version: 0.6.4
|
84
90
|
- !ruby/object:Gem::Dependency
|
85
91
|
name: rake
|
86
92
|
requirement: !ruby/object:Gem::Requirement
|
@@ -129,14 +135,14 @@ dependencies:
|
|
129
135
|
requirements:
|
130
136
|
- - "~>"
|
131
137
|
- !ruby/object:Gem::Version
|
132
|
-
version: '
|
138
|
+
version: '6.0'
|
133
139
|
type: :development
|
134
140
|
prerelease: false
|
135
141
|
version_requirements: !ruby/object:Gem::Requirement
|
136
142
|
requirements:
|
137
143
|
- - "~>"
|
138
144
|
- !ruby/object:Gem::Version
|
139
|
-
version: '
|
145
|
+
version: '6.0'
|
140
146
|
- !ruby/object:Gem::Dependency
|
141
147
|
name: webmock
|
142
148
|
requirement: !ruby/object:Gem::Requirement
|
@@ -188,6 +194,7 @@ files:
|
|
188
194
|
- lib/httpi/query_builder.rb
|
189
195
|
- lib/httpi/request.rb
|
190
196
|
- lib/httpi/response.rb
|
197
|
+
- lib/httpi/utils.rb
|
191
198
|
- lib/httpi/version.rb
|
192
199
|
- spec/fixtures/attachment.gif
|
193
200
|
- spec/fixtures/client_cert.pem
|
@@ -255,7 +262,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
255
262
|
- !ruby/object:Gem::Version
|
256
263
|
version: '0'
|
257
264
|
requirements: []
|
258
|
-
rubygems_version: 3.4.
|
265
|
+
rubygems_version: 3.4.19
|
259
266
|
signing_key:
|
260
267
|
specification_version: 4
|
261
268
|
summary: Common interface for Ruby's HTTP libraries
|