httpi 3.0.1 → 4.0.1
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/.devcontainer/devcontainer.json +22 -0
- data/.github/workflows/development.yml +4 -3
- data/CHANGELOG.md +21 -0
- data/Gemfile +1 -1
- data/README.md +13 -2
- data/UPDATING.md +4 -0
- data/httpi.gemspec +14 -4
- data/lib/httpi/adapter.rb +2 -0
- data/lib/httpi/request.rb +2 -2
- data/lib/httpi/response.rb +1 -1
- data/lib/httpi/utils.rb +238 -0
- data/lib/httpi/version.rb +1 -1
- data/lib/httpi.rb +7 -1
- data/spec/httpi/adapter/httpclient_spec.rb +2 -1
- data/spec/httpi/httpi_spec.rb +24 -0
- data/spec/httpi/request_spec.rb +4 -4
- data/spec/httpi/response_spec.rb +2 -2
- data/spec/integration/net_http_spec.rb +6 -3
- data/spec/integration/support/server.rb +1 -1
- metadata +67 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 70c75f8e865f40f9218b34d091ab64aad2656467fff356ac18e2530b70dc52d7
|
|
4
|
+
data.tar.gz: fb86901d88b603911f98d1dbcad0132a0c3f6c28ce3d7b1640ce5b84f7524659
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4eddf2bd30c64892ec8bc478e5774382030a829b58450a7e0b2266ebdba4f7b01ead27315253c56ba454addc9c7a6112b77f553684e35d143e06397c51de5389
|
|
7
|
+
data.tar.gz: 5b497936201359ed9b45df8486875bb6be8706fedeeed5ec7d7b43a0c15555cff46e3a7fc48a50b1970a76e2dae202eef591ccf74325caf8d5faf77a09f46789
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
|
2
|
+
// README at: https://github.com/devcontainers/templates/tree/main/src/ruby
|
|
3
|
+
{
|
|
4
|
+
"name": "Ruby",
|
|
5
|
+
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
|
|
6
|
+
"image": "mcr.microsoft.com/devcontainers/ruby:1-3.2-bullseye"
|
|
7
|
+
|
|
8
|
+
// Features to add to the dev container. More info: https://containers.dev/features.
|
|
9
|
+
// "features": {},
|
|
10
|
+
|
|
11
|
+
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
|
12
|
+
// "forwardPorts": [],
|
|
13
|
+
|
|
14
|
+
// Use 'postCreateCommand' to run commands after the container is created.
|
|
15
|
+
// "postCreateCommand": "ruby --version",
|
|
16
|
+
|
|
17
|
+
// Configure tool-specific properties.
|
|
18
|
+
// "customizations": {},
|
|
19
|
+
|
|
20
|
+
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
|
|
21
|
+
// "remoteUser": "root"
|
|
22
|
+
}
|
|
@@ -14,9 +14,10 @@ jobs:
|
|
|
14
14
|
- ubuntu
|
|
15
15
|
|
|
16
16
|
ruby:
|
|
17
|
-
- "2.6"
|
|
18
|
-
- "2.7"
|
|
19
17
|
- "3.0"
|
|
18
|
+
- "3.1"
|
|
19
|
+
- "3.2"
|
|
20
|
+
- "3.3"
|
|
20
21
|
|
|
21
22
|
experimental: [false]
|
|
22
23
|
env: [""]
|
|
@@ -33,7 +34,7 @@ jobs:
|
|
|
33
34
|
experimental: true
|
|
34
35
|
|
|
35
36
|
steps:
|
|
36
|
-
- uses: actions/checkout@
|
|
37
|
+
- uses: actions/checkout@v4
|
|
37
38
|
|
|
38
39
|
- name: Install dependencies
|
|
39
40
|
run: sudo apt-get install libcurl4-openssl-dev
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
### Unreleased
|
|
2
|
+
|
|
3
|
+
* Add your changelog entry here
|
|
4
|
+
|
|
5
|
+
### 4.0.1 (2024-02-16)
|
|
6
|
+
|
|
7
|
+
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.
|
|
8
|
+
|
|
9
|
+
* Adds support for rack 3.0.
|
|
10
|
+
* 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.
|
|
11
|
+
|
|
12
|
+
### 4.0.0 (yanked)
|
|
13
|
+
|
|
14
|
+
Yanked due to a bug when used with rack 2.
|
|
15
|
+
|
|
16
|
+
### 3.0.2 (2024-02-10)
|
|
17
|
+
|
|
18
|
+
* Improvement: [#237](https://github.com/savonrb/httpi/pull/237) Implemented `adapter_client_setup`.
|
|
19
|
+
* Add support for ruby 3.1, 3.2, 3.3. Drop support for ruby 2.7 and below.
|
|
20
|
+
* Pin to rack version < 3, HTTPI is not tested with rack 3 yet.
|
|
21
|
+
|
|
1
22
|
### 3.0.1 (2021-12-17)
|
|
2
23
|
|
|
3
24
|
* Fix: [#230](https://github.com/savonrb/httpi/pull/230) Make rack a runtime dependency.
|
data/Gemfile
CHANGED
|
@@ -10,7 +10,7 @@ gem 'httpclient', '~> 2.3', :require => false
|
|
|
10
10
|
gem 'curb', '~> 0.8', :require => false, :platforms => [:ruby]
|
|
11
11
|
gem 'em-http-request', :require => false, :platforms => [:ruby]
|
|
12
12
|
gem 'em-synchrony', :require => false, :platforms => [:ruby, :jruby]
|
|
13
|
-
gem 'excon', '~> 0.
|
|
13
|
+
gem 'excon', '~> 0.71', :require => false, :platforms => [:ruby, :jruby]
|
|
14
14
|
gem 'net-http-persistent', '~> 4.0', :require => false
|
|
15
15
|
gem 'http', :require => false
|
|
16
16
|
|
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
|
@@ -8,23 +8,33 @@ Gem::Specification.new do |s|
|
|
|
8
8
|
s.version = HTTPI::VERSION
|
|
9
9
|
s.authors = ['Daniel Harrington', 'Martin Tepper']
|
|
10
10
|
s.email = 'me@rubiii.com'
|
|
11
|
-
s.homepage = "
|
|
11
|
+
s.homepage = "https://github.com/savonrb/httpi"
|
|
12
12
|
s.summary = "Common interface for Ruby's HTTP libraries"
|
|
13
13
|
s.description = s.summary
|
|
14
|
+
s.metadata = { 'bug_tracker_uri' => 'https://github.com/savonrb/httpi/issues',
|
|
15
|
+
'changelog_uri' => 'https://github.com/savonrb/httpi/blob/master/CHANGELOG.md',
|
|
16
|
+
'source_code_uri' => s.homepage,
|
|
17
|
+
'wiki_uri' => 'https://github.com/savonrb/httpi/wiki',
|
|
18
|
+
'documentation_uri' => 'https://www.rubydoc.info/gems/httpi' }
|
|
14
19
|
|
|
15
|
-
s.required_ruby_version = '>=
|
|
20
|
+
s.required_ruby_version = '>= 3.0'
|
|
16
21
|
|
|
17
22
|
s.license = 'MIT'
|
|
18
23
|
|
|
19
|
-
s.add_dependency 'rack'
|
|
24
|
+
s.add_dependency 'rack', '>= 2.0', '< 3.1'
|
|
25
|
+
s.add_dependency 'nkf'
|
|
26
|
+
s.add_dependency 'base64'
|
|
27
|
+
s.add_dependency 'mutex_m'
|
|
20
28
|
|
|
21
29
|
s.add_development_dependency 'rubyntlm', '~> 0.3.2'
|
|
22
30
|
s.add_development_dependency 'rake', '~> 13.0'
|
|
23
31
|
s.add_development_dependency 'rspec', '~> 3.5'
|
|
24
32
|
s.add_development_dependency 'mocha', '~> 0.13'
|
|
25
|
-
s.add_development_dependency 'puma', '~>
|
|
33
|
+
s.add_development_dependency 'puma', '~> 6.0'
|
|
26
34
|
s.add_development_dependency 'webmock'
|
|
27
35
|
|
|
36
|
+
s.metadata["rubygems_mfa_required"] = "true"
|
|
37
|
+
|
|
28
38
|
s.files = `git ls-files`.split("\n")
|
|
29
39
|
s.require_path = 'lib'
|
|
30
40
|
end
|
data/lib/httpi/adapter.rb
CHANGED
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,238 @@
|
|
|
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
|
+
# HTTPI::Utils::Headers is a Hash subclass that downcases all keys.
|
|
7
|
+
class Headers < Hash
|
|
8
|
+
KNOWN_HEADERS = {}
|
|
9
|
+
%w(
|
|
10
|
+
Accept-CH
|
|
11
|
+
Accept-Patch
|
|
12
|
+
Accept-Ranges
|
|
13
|
+
Access-Control-Allow-Credentials
|
|
14
|
+
Access-Control-Allow-Headers
|
|
15
|
+
Access-Control-Allow-Methods
|
|
16
|
+
Access-Control-Allow-Origin
|
|
17
|
+
Access-Control-Expose-Headers
|
|
18
|
+
Access-Control-Max-Age
|
|
19
|
+
Age
|
|
20
|
+
Allow
|
|
21
|
+
Alt-Svc
|
|
22
|
+
Cache-Control
|
|
23
|
+
Connection
|
|
24
|
+
Content-Disposition
|
|
25
|
+
Content-Encoding
|
|
26
|
+
Content-Language
|
|
27
|
+
Content-Length
|
|
28
|
+
Content-Location
|
|
29
|
+
Content-MD5
|
|
30
|
+
Content-Range
|
|
31
|
+
Content-Security-Policy
|
|
32
|
+
Content-Security-Policy-Report-Only
|
|
33
|
+
Content-Type
|
|
34
|
+
Date
|
|
35
|
+
Delta-Base
|
|
36
|
+
ETag
|
|
37
|
+
Expect-CT
|
|
38
|
+
Expires
|
|
39
|
+
Feature-Policy
|
|
40
|
+
IM
|
|
41
|
+
Last-Modified
|
|
42
|
+
Link
|
|
43
|
+
Location
|
|
44
|
+
NEL
|
|
45
|
+
P3P
|
|
46
|
+
Permissions-Policy
|
|
47
|
+
Pragma
|
|
48
|
+
Preference-Applied
|
|
49
|
+
Proxy-Authenticate
|
|
50
|
+
Public-Key-Pins
|
|
51
|
+
Referrer-Policy
|
|
52
|
+
Refresh
|
|
53
|
+
Report-To
|
|
54
|
+
Retry-After
|
|
55
|
+
Server
|
|
56
|
+
Set-Cookie
|
|
57
|
+
Status
|
|
58
|
+
Strict-Transport-Security
|
|
59
|
+
Timing-Allow-Origin
|
|
60
|
+
Tk
|
|
61
|
+
Trailer
|
|
62
|
+
Transfer-Encoding
|
|
63
|
+
Upgrade
|
|
64
|
+
Vary
|
|
65
|
+
Via
|
|
66
|
+
WWW-Authenticate
|
|
67
|
+
Warning
|
|
68
|
+
X-Cascade
|
|
69
|
+
X-Content-Duration
|
|
70
|
+
X-Content-Security-Policy
|
|
71
|
+
X-Content-Type-Options
|
|
72
|
+
X-Correlation-ID
|
|
73
|
+
X-Correlation-Id
|
|
74
|
+
X-Download-Options
|
|
75
|
+
X-Frame-Options
|
|
76
|
+
X-Permitted-Cross-Domain-Policies
|
|
77
|
+
X-Powered-By
|
|
78
|
+
X-Redirect-By
|
|
79
|
+
X-Request-ID
|
|
80
|
+
X-Request-Id
|
|
81
|
+
X-Runtime
|
|
82
|
+
X-UA-Compatible
|
|
83
|
+
X-WebKit-CS
|
|
84
|
+
X-XSS-Protection
|
|
85
|
+
).each do |str|
|
|
86
|
+
downcased = str.downcase.freeze
|
|
87
|
+
KNOWN_HEADERS[str] = KNOWN_HEADERS[downcased] = downcased
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def self.[](*items)
|
|
91
|
+
if items.length % 2 != 0
|
|
92
|
+
if items.length == 1 && items.first.is_a?(Hash)
|
|
93
|
+
new.merge!(items.first)
|
|
94
|
+
else
|
|
95
|
+
raise ArgumentError, "odd number of arguments for Utils::Headers"
|
|
96
|
+
end
|
|
97
|
+
else
|
|
98
|
+
hash = new
|
|
99
|
+
loop do
|
|
100
|
+
break if items.length == 0
|
|
101
|
+
key = items.shift
|
|
102
|
+
value = items.shift
|
|
103
|
+
hash[key] = value
|
|
104
|
+
end
|
|
105
|
+
hash
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def [](key)
|
|
110
|
+
super(downcase_key(key))
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def []=(key, value)
|
|
114
|
+
super(KNOWN_HEADERS[key] || key.downcase.freeze, value)
|
|
115
|
+
end
|
|
116
|
+
alias store []=
|
|
117
|
+
|
|
118
|
+
def assoc(key)
|
|
119
|
+
super(downcase_key(key))
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def compare_by_identity
|
|
123
|
+
raise TypeError, "Utils::Headers cannot compare by identity, use regular Hash"
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def delete(key)
|
|
127
|
+
super(downcase_key(key))
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def dig(key, *a)
|
|
131
|
+
super(downcase_key(key), *a)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def fetch(key, *default, &block)
|
|
135
|
+
key = downcase_key(key)
|
|
136
|
+
super
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def fetch_values(*a)
|
|
140
|
+
super(*a.map!{|key| downcase_key(key)})
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def has_key?(key)
|
|
144
|
+
super(downcase_key(key))
|
|
145
|
+
end
|
|
146
|
+
alias include? has_key?
|
|
147
|
+
alias key? has_key?
|
|
148
|
+
alias member? has_key?
|
|
149
|
+
|
|
150
|
+
def invert
|
|
151
|
+
hash = self.class.new
|
|
152
|
+
each{|key, value| hash[value] = key}
|
|
153
|
+
hash
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def merge(hash, &block)
|
|
157
|
+
dup.merge!(hash, &block)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def reject(&block)
|
|
161
|
+
hash = dup
|
|
162
|
+
hash.reject!(&block)
|
|
163
|
+
hash
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def replace(hash)
|
|
167
|
+
clear
|
|
168
|
+
update(hash)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def select(&block)
|
|
172
|
+
hash = dup
|
|
173
|
+
hash.select!(&block)
|
|
174
|
+
hash
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def to_proc
|
|
178
|
+
lambda{|x| self[x]}
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def transform_values(&block)
|
|
182
|
+
dup.transform_values!(&block)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def update(hash, &block)
|
|
186
|
+
hash.each do |key, value|
|
|
187
|
+
self[key] = if block_given? && include?(key)
|
|
188
|
+
block.call(key, self[key], value)
|
|
189
|
+
else
|
|
190
|
+
value
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
self
|
|
194
|
+
end
|
|
195
|
+
alias merge! update
|
|
196
|
+
|
|
197
|
+
def values_at(*keys)
|
|
198
|
+
keys.map{|key| self[key]}
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# :nocov:
|
|
202
|
+
if RUBY_VERSION >= '2.5'
|
|
203
|
+
# :nocov:
|
|
204
|
+
def slice(*a)
|
|
205
|
+
h = self.class.new
|
|
206
|
+
a.each{|k| h[k] = self[k] if has_key?(k)}
|
|
207
|
+
h
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def transform_keys(&block)
|
|
211
|
+
dup.transform_keys!(&block)
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def transform_keys!
|
|
215
|
+
hash = self.class.new
|
|
216
|
+
each do |k, v|
|
|
217
|
+
hash[yield k] = v
|
|
218
|
+
end
|
|
219
|
+
replace(hash)
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
# :nocov:
|
|
224
|
+
if RUBY_VERSION >= '3.0'
|
|
225
|
+
# :nocov:
|
|
226
|
+
def except(*a)
|
|
227
|
+
super(*a.map!{|key| downcase_key(key)})
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
private
|
|
232
|
+
|
|
233
|
+
def downcase_key(key)
|
|
234
|
+
key.is_a?(String) ? KNOWN_HEADERS[key] || key.downcase : key
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
end
|
data/lib/httpi/version.rb
CHANGED
data/lib/httpi.rb
CHANGED
|
@@ -3,6 +3,7 @@ require "httpi/version"
|
|
|
3
3
|
require "httpi/logger"
|
|
4
4
|
require "httpi/request"
|
|
5
5
|
require "httpi/query_builder"
|
|
6
|
+
require "httpi/utils"
|
|
6
7
|
|
|
7
8
|
require "httpi/adapter/httpclient"
|
|
8
9
|
require "httpi/adapter/curb"
|
|
@@ -154,7 +155,8 @@ module HTTPI
|
|
|
154
155
|
# Executes an HTTP request for the given +method+.
|
|
155
156
|
def request(method, request, adapter = nil, redirects = 0)
|
|
156
157
|
adapter_class = load_adapter(adapter, request)
|
|
157
|
-
|
|
158
|
+
|
|
159
|
+
Adapter.client_setup_block.call(adapter_class.client) if Adapter.client_setup_block
|
|
158
160
|
yield adapter_class.client if block_given?
|
|
159
161
|
log_request(method, request, Adapter.identify(adapter_class.class))
|
|
160
162
|
|
|
@@ -174,6 +176,10 @@ module HTTPI
|
|
|
174
176
|
Adapter.use = adapter
|
|
175
177
|
end
|
|
176
178
|
|
|
179
|
+
def adapter_client_setup=(block)
|
|
180
|
+
Adapter.client_setup_block = block
|
|
181
|
+
end
|
|
182
|
+
|
|
177
183
|
private
|
|
178
184
|
|
|
179
185
|
def request_and_adapter_from(args)
|
|
@@ -215,7 +215,8 @@ describe HTTPI::Adapter::HTTPClient do
|
|
|
215
215
|
end
|
|
216
216
|
end
|
|
217
217
|
|
|
218
|
-
|
|
218
|
+
# TODO: ntlm_openssl3 https://github.com/WinRb/rubyntlm/issues/57
|
|
219
|
+
xit "supports NTLM authentication" do
|
|
219
220
|
request = HTTPI::Request.new(@server.url + "ntlm-auth")
|
|
220
221
|
|
|
221
222
|
request.auth.ntlm("tester", "vReqSoafRe5O")
|
data/spec/httpi/httpi_spec.rb
CHANGED
|
@@ -33,6 +33,18 @@ describe HTTPI do
|
|
|
33
33
|
end
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
+
describe ".adapter_client_setup=" do
|
|
37
|
+
after do
|
|
38
|
+
HTTPI.adapter_client_setup = nil
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "sets the adapter client setup block" do
|
|
42
|
+
block = proc { }
|
|
43
|
+
HTTPI.adapter_client_setup = block
|
|
44
|
+
expect(HTTPI::Adapter.client_setup_block).to eq(block)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
36
48
|
describe ".query_builder" do
|
|
37
49
|
it "gets flat builder by default" do
|
|
38
50
|
expect(client.query_builder).to eq(HTTPI::QueryBuilder::Flat)
|
|
@@ -281,6 +293,18 @@ describe HTTPI do
|
|
|
281
293
|
|
|
282
294
|
client.request(:custom, request, :httpclient)
|
|
283
295
|
end
|
|
296
|
+
|
|
297
|
+
describe "client setup block present" do
|
|
298
|
+
around do |example|
|
|
299
|
+
HTTPI::Adapter.client_setup_block = proc { |client| client.base_url = 'https://google.com' }
|
|
300
|
+
example.run
|
|
301
|
+
HTTPI::Adapter.client_setup_block = nil
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
it 'calls client setup block' do
|
|
305
|
+
client.request(:get, request, :httpclient) { |client| expect(client.base_url).to eq('https://google.com') }
|
|
306
|
+
end
|
|
307
|
+
end
|
|
284
308
|
end
|
|
285
309
|
|
|
286
310
|
HTTPI::REQUEST_METHODS.each do |method|
|
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,7 @@ 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
120
|
end
|
|
121
121
|
end
|
|
122
122
|
|
|
@@ -138,7 +138,8 @@ describe HTTPI::Adapter::NetHTTP do
|
|
|
138
138
|
to raise_error(HTTPI::NotSupportedError, /does not support HTTP digest authentication/)
|
|
139
139
|
end
|
|
140
140
|
|
|
141
|
-
|
|
141
|
+
# TODO: ntlm_openssl3 https://github.com/WinRb/rubyntlm/issues/57
|
|
142
|
+
xit "supports ntlm authentication" do
|
|
142
143
|
request = HTTPI::Request.new(@server.url + "ntlm-auth")
|
|
143
144
|
request.auth.ntlm("tester", "vReqSoafRe5O")
|
|
144
145
|
|
|
@@ -166,7 +167,8 @@ describe HTTPI::Adapter::NetHTTP do
|
|
|
166
167
|
HTTPI::Adapter::NetHTTP.any_instance.unstub(:check_net_ntlm_version!)
|
|
167
168
|
end
|
|
168
169
|
|
|
169
|
-
|
|
170
|
+
# TODO: ntlm_openssl3 https://github.com/WinRb/rubyntlm/issues/57
|
|
171
|
+
xit "does check ntlm when ntlm authentication is requested" do
|
|
170
172
|
request = HTTPI::Request.new(@server.url + "ntlm-auth")
|
|
171
173
|
request.auth.ntlm("tester", "vReqSoafRe5O")
|
|
172
174
|
|
|
@@ -183,7 +185,8 @@ describe HTTPI::Adapter::NetHTTP do
|
|
|
183
185
|
HTTPI::Adapter::NetHTTP.any_instance.unstub(:ntlm_version)
|
|
184
186
|
end
|
|
185
187
|
|
|
186
|
-
|
|
188
|
+
# TODO: ntlm_openssl3 https://github.com/WinRb/rubyntlm/issues/57
|
|
189
|
+
xit "does not crash when authenticate header is missing (on second request)" do
|
|
187
190
|
request = HTTPI::Request.new(@server.url + "ntlm-auth")
|
|
188
191
|
request.auth.ntlm("tester", "vReqSoafRe5O")
|
|
189
192
|
|
metadata
CHANGED
|
@@ -1,18 +1,66 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: httpi
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 4.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Daniel Harrington
|
|
8
8
|
- Martin Tepper
|
|
9
|
-
autorequire:
|
|
9
|
+
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date:
|
|
12
|
+
date: 2024-02-16 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: rack
|
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
|
17
|
+
requirements:
|
|
18
|
+
- - ">="
|
|
19
|
+
- !ruby/object:Gem::Version
|
|
20
|
+
version: '2.0'
|
|
21
|
+
- - "<"
|
|
22
|
+
- !ruby/object:Gem::Version
|
|
23
|
+
version: '3.1'
|
|
24
|
+
type: :runtime
|
|
25
|
+
prerelease: false
|
|
26
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
27
|
+
requirements:
|
|
28
|
+
- - ">="
|
|
29
|
+
- !ruby/object:Gem::Version
|
|
30
|
+
version: '2.0'
|
|
31
|
+
- - "<"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '3.1'
|
|
34
|
+
- !ruby/object:Gem::Dependency
|
|
35
|
+
name: nkf
|
|
36
|
+
requirement: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
41
|
+
type: :runtime
|
|
42
|
+
prerelease: false
|
|
43
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">="
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
- !ruby/object:Gem::Dependency
|
|
49
|
+
name: base64
|
|
50
|
+
requirement: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ">="
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
type: :runtime
|
|
56
|
+
prerelease: false
|
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ">="
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
- !ruby/object:Gem::Dependency
|
|
63
|
+
name: mutex_m
|
|
16
64
|
requirement: !ruby/object:Gem::Requirement
|
|
17
65
|
requirements:
|
|
18
66
|
- - ">="
|
|
@@ -87,14 +135,14 @@ dependencies:
|
|
|
87
135
|
requirements:
|
|
88
136
|
- - "~>"
|
|
89
137
|
- !ruby/object:Gem::Version
|
|
90
|
-
version: '
|
|
138
|
+
version: '6.0'
|
|
91
139
|
type: :development
|
|
92
140
|
prerelease: false
|
|
93
141
|
version_requirements: !ruby/object:Gem::Requirement
|
|
94
142
|
requirements:
|
|
95
143
|
- - "~>"
|
|
96
144
|
- !ruby/object:Gem::Version
|
|
97
|
-
version: '
|
|
145
|
+
version: '6.0'
|
|
98
146
|
- !ruby/object:Gem::Dependency
|
|
99
147
|
name: webmock
|
|
100
148
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -115,6 +163,7 @@ executables: []
|
|
|
115
163
|
extensions: []
|
|
116
164
|
extra_rdoc_files: []
|
|
117
165
|
files:
|
|
166
|
+
- ".devcontainer/devcontainer.json"
|
|
118
167
|
- ".github/workflows/development.yml"
|
|
119
168
|
- ".gitignore"
|
|
120
169
|
- ".rspec"
|
|
@@ -145,6 +194,7 @@ files:
|
|
|
145
194
|
- lib/httpi/query_builder.rb
|
|
146
195
|
- lib/httpi/request.rb
|
|
147
196
|
- lib/httpi/response.rb
|
|
197
|
+
- lib/httpi/utils.rb
|
|
148
198
|
- lib/httpi/version.rb
|
|
149
199
|
- spec/fixtures/attachment.gif
|
|
150
200
|
- spec/fixtures/client_cert.pem
|
|
@@ -187,11 +237,17 @@ files:
|
|
|
187
237
|
- spec/support/error_helper.rb
|
|
188
238
|
- spec/support/fixture.rb
|
|
189
239
|
- spec/support/matchers.rb
|
|
190
|
-
homepage:
|
|
240
|
+
homepage: https://github.com/savonrb/httpi
|
|
191
241
|
licenses:
|
|
192
242
|
- MIT
|
|
193
|
-
metadata:
|
|
194
|
-
|
|
243
|
+
metadata:
|
|
244
|
+
bug_tracker_uri: https://github.com/savonrb/httpi/issues
|
|
245
|
+
changelog_uri: https://github.com/savonrb/httpi/blob/master/CHANGELOG.md
|
|
246
|
+
source_code_uri: https://github.com/savonrb/httpi
|
|
247
|
+
wiki_uri: https://github.com/savonrb/httpi/wiki
|
|
248
|
+
documentation_uri: https://www.rubydoc.info/gems/httpi
|
|
249
|
+
rubygems_mfa_required: 'true'
|
|
250
|
+
post_install_message:
|
|
195
251
|
rdoc_options: []
|
|
196
252
|
require_paths:
|
|
197
253
|
- lib
|
|
@@ -199,15 +255,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
199
255
|
requirements:
|
|
200
256
|
- - ">="
|
|
201
257
|
- !ruby/object:Gem::Version
|
|
202
|
-
version: '
|
|
258
|
+
version: '3.0'
|
|
203
259
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
204
260
|
requirements:
|
|
205
261
|
- - ">="
|
|
206
262
|
- !ruby/object:Gem::Version
|
|
207
263
|
version: '0'
|
|
208
264
|
requirements: []
|
|
209
|
-
rubygems_version: 3.
|
|
210
|
-
signing_key:
|
|
265
|
+
rubygems_version: 3.4.10
|
|
266
|
+
signing_key:
|
|
211
267
|
specification_version: 4
|
|
212
268
|
summary: Common interface for Ruby's HTTP libraries
|
|
213
269
|
test_files: []
|