httpi 3.0.2 → 4.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cd06f829b3d33418dfe3ef465949f504f6acde0e9f5988edea9615e700bb8f23
4
- data.tar.gz: '00197cf31c50d34768c76325d42cc8dc325774ffe5a2ecaf6feb33f7d22c382c'
3
+ metadata.gz: bb83de56d8f0e1b609e317db0a889b669290c6888b2ef4a41efe682bcd092ec3
4
+ data.tar.gz: a2ec713acb8c51714850de1490c2b247d10fdd0ada7227fbd89ec4cdfb3c7963
5
5
  SHA512:
6
- metadata.gz: 81a2a86d8a7784711c0a72995a21262c7bcdfb17d9127a06a9573c50f7eaffde7e544c07b332e905da3fb1b177d867d34c2b59a75f0605182a6d278db9eda4a6
7
- data.tar.gz: e59a0468efe743db6a4b4d7eff007714cb739e928396b7ff8797896a346e7808a2635185ccf1a9eb53db64d149626782a4f3dc530f3e9644c21923ce6a4a0f3d
6
+ metadata.gz: bd35a2d65bc74884715d763c2790aa0567355c84337f17459fc6d0956b2f019fc6c82dba220bd3fd707b1e1837dcf6b264395ef109251196211d700b76e9f66e
7
+ data.tar.gz: f965bcc58b97d692f295408058bbf2ee3cf70d7b19221cc892aa4bdd250aa177bedc1303efc172c1e953ec7c44327cb026ca044fbf32144b4bb1bf1c435ebb17
@@ -34,7 +34,7 @@ jobs:
34
34
  experimental: true
35
35
 
36
36
  steps:
37
- - uses: actions/checkout@v3
37
+ - uses: actions/checkout@v4
38
38
 
39
39
  - name: Install dependencies
40
40
  run: sudo apt-get install libcurl4-openssl-dev
data/CHANGELOG.md CHANGED
@@ -1,10 +1,27 @@
1
1
  ### Unreleased
2
2
 
3
- * Improvement: [#237](https://github.com/savonrb/httpi/pull/237) Implemented `adapter_client_setup`.
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
@@ -15,7 +15,7 @@ gem 'net-http-persistent', '~> 4.0', :require => false
15
15
  gem 'http', :require => false
16
16
 
17
17
  # adapter extensions
18
- gem 'rack', '< 3'
18
+ gem 'rack'
19
19
  gem 'socksify'
20
20
 
21
21
  # coverage
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', '~> 3.0.0'
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.3.2'
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', '~> 5.0'
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 ||= Rack::Utils::HeaderHash.new
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 = Rack::Utils::HeaderHash.new(headers)
72
+ @headers = HTTPI::Utils::Headers.new.merge(headers)
73
73
  end
74
74
 
75
75
  # Adds a header information to accept gzipped content.
@@ -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 = Rack::Utils::HeaderHash.new(headers)
23
+ self.headers = HTTPI::Utils::Headers.new.merge(headers)
24
24
  self.raw_body = body
25
25
  end
26
26
 
@@ -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
@@ -1,3 +1,3 @@
1
1
  module HTTPI
2
- VERSION = '3.0.2'
2
+ VERSION = '4.0.2'
3
3
  end
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"
@@ -215,8 +215,7 @@ describe HTTPI::Adapter::HTTPClient do
215
215
  end
216
216
  end
217
217
 
218
- # TODO: ntlm_openssl3 https://github.com/WinRb/rubyntlm/issues/57
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")
@@ -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[]=nested&q[]=query")
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[]=nested&q[]=query")
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[]=foo", "baz[]=tst"])
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
@@ -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
- # TODO: ntlm_openssl3 https://github.com/WinRb/rubyntlm/issues/57
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
- # TODO: ntlm_openssl3 https://github.com/WinRb/rubyntlm/issues/57
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
- # TODO: ntlm_openssl3 https://github.com/WinRb/rubyntlm/issues/57
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
 
@@ -57,7 +57,7 @@ class IntegrationServer
57
57
  private
58
58
 
59
59
  def events
60
- Puma::Events.new($stdout, $stderr)
60
+ Puma::Events.new
61
61
  end
62
62
 
63
63
  def add_tcp_listener
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: 3.0.2
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-02-11 00:00:00.000000000 Z
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.3.2
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.3.2
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: '5.0'
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: '5.0'
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.10
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