faraday-gzip 2.0.1 → 3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 44ad7c4e9c57927b182f8da9719aeb71455cd664607582af5be4440d660c9015
4
- data.tar.gz: cfd6528ad8d82ce76f1b62cddbd63e2af086dab192a62c1dc14e6603ae5f5a18
3
+ metadata.gz: 5a6ceb06f7b18d8d70a15a0a8ceda7cf7a2956df6653066f8ae0c84c0f1c832a
4
+ data.tar.gz: 9cde727357feea0a7efe5fe80a73c95942eb5fbcd0b21fa7a20c54d92acb91e8
5
5
  SHA512:
6
- metadata.gz: 61a096ffcf59316c2c7a1e9be64f159e879887a4a56dbfe495268d4c70a7636944885307277dd62c1a705df063676a6526921a65d01a0436cf01331349a01828
7
- data.tar.gz: 174bd0148dfcdc7e33acddb9c086629b37f8179905081c45ea4c35fb2e916c6f07c994a8065fce6b900aca34de1624e162330b185766f8c18a9d3edb6098c6f3
6
+ metadata.gz: 5ee966bedad1ea9379de2f5f8c971326488366d831df22e78c7f29557a41189befce5bf0be373482de72b441a94e3d435db7812c980f69258cdb8ca207decd08
7
+ data.tar.gz: '08f511d78ee79f136d2ba4d5770585ec4a146296e8d6b2c72bdf4efbba5e450fb8a84988872da4b7278c3bcd9b183b7c513e6e7880000052d33bed5bfd6dceac'
data/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.0.1 (01-Nov-2024)
4
+
5
+ * Minor fix in gemspec
6
+
7
+ ## 3.0.0 (29-Oct-2024)
8
+
9
+ * **Breaking change**: Drop support for Ruby 2, require 3.0+
10
+ * **Breaking change**: Drop support for Faraday v1. If you need to support Faraday v1, stay on [faraday-gzip version 2](https://github.com/bodrovis/faraday-gzip/tree/v2).
11
+ * Various code tweaks
12
+ * Remove JRuby 9.3 from CI matrix
13
+
3
14
  ## 2.0.1 (02-Jan-2024)
4
15
 
5
16
  * Handle cases when body is `nil` (thanks, @bendangelo)
data/README.md CHANGED
@@ -2,54 +2,58 @@
2
2
 
3
3
  ![CI](https://github.com/bodrovis/faraday-gzip/actions/workflows/ci.yaml/badge.svg)
4
4
  [![Gem](https://img.shields.io/gem/v/faraday-gzip.svg?style=flat-square)](https://rubygems.org/gems/faraday-gzip)
5
+ ![Gem Total Downloads](https://img.shields.io/gem/dt/faraday-gzip)
5
6
 
6
- The `Gzip` middleware for Faraday 1 and 2 adds the necessary `Accept-Encoding` headers and automatically decompresses the response. If the "Accept-Encoding" header wasn't set in the request, this sets it to "gzip,deflate" and appropriately handles the compressed response from the server. This resembles what Ruby does internally in Net::HTTP#get. If [Brotli](https://github.com/miyucy/brotli) is added to the Gemfile, it will also add "br" to the header.
7
+ The `Gzip` middleware for Faraday 1 and 2 adds the necessary `Accept-Encoding` headers and automatically decompresses the response. If the "Accept-Encoding" header isn't set in the request, it defaults to `gzip,deflate` and appropriately handles the server's compressed response. This functionality resembles what Ruby does internally in `Net::HTTP#get`. If [Brotli](https://github.com/miyucy/brotli) is included in your Gemfile, the middleware also adds `br` to the header for Brotli support.
7
8
 
8
9
  ## Prerequisites
9
10
 
10
- This gem is tested with Ruby 2.6+ and JRuby 9.3+. Faraday 1 and 2 is supported.
11
+ * faraday-gzip v3 supports only Faraday v2 and is tested with Ruby 3.0+ and JRuby 9.4
12
+ * [faraday-gzip v2](https://github.com/bodrovis/faraday-gzip/tree/v2) supports Faraday v1 and v2 and is tested with Ruby 2.7+ and JRuby 9.4.
11
13
 
12
14
  ## Installation
13
15
 
14
16
  Add this line to your application's Gemfile:
15
17
 
16
18
  ```ruby
17
- gem 'faraday-gzip'
19
+ gem 'faraday-gzip', '~> 3'
18
20
  ```
19
21
 
20
22
  And then execute:
21
23
 
22
- ```shell
24
+ ```
23
25
  bundle install
24
26
  ```
25
27
 
26
28
  Or install it yourself as:
27
29
 
28
- ```shell
30
+ ```
29
31
  gem install faraday-gzip
30
32
  ```
31
33
 
32
34
  ## Usage
33
35
 
36
+ To enable the middleware in your Faraday connection, add it as shown below:
37
+
34
38
  ```ruby
35
- require 'faraday/gzip' # <=== add this line
39
+ require 'faraday/gzip' # <=== Add this line
36
40
 
37
41
  conn = Faraday.new(...) do |f|
38
- f.request :gzip # <=== add this line
39
- #...
42
+ f.request :gzip # <=== Add this line
43
+ # Additional configuration...
40
44
  end
41
45
  ```
42
46
 
43
47
  ## Development
44
48
 
45
- After checking out the repo, run `bin/setup` to install dependencies.
46
-
47
- Then, run `bin/test` to run the tests.
48
-
49
- To install this gem onto your local machine, run `rake build`.
49
+ To contribute or make changes:
50
50
 
51
- To release a new version, make a commit with a message such as "Bumped to 0.0.2" and then run `rake release`.
52
- See how it works [here](https://bundler.io/guides/creating_gem.html#releasing-the-gem).
51
+ * Clone the repo
52
+ * Run `bundle` to install dependencies
53
+ * Implement your feature
54
+ * Write and run tests using `rspec .`
55
+ * Use rake build to build the gem locally if needed
56
+ * Create a new PR with your changes
53
57
 
54
58
  ## Contributing
55
59
 
@@ -57,4 +61,4 @@ Bug reports and pull requests are welcome on GitHub.
57
61
 
58
62
  ## License
59
63
 
60
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
64
+ This gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -2,15 +2,17 @@
2
2
 
3
3
  require 'zlib'
4
4
 
5
+ # Middleware to automatically decompress response bodies. If the
6
+ # "Accept-Encoding" header wasn't set in the request, this sets it to
7
+ # "gzip,deflate" and appropriately handles the compressed response from the
8
+ # server. This resembles what Ruby 1.9+ does internally in Net::HTTP#get.
9
+ # Based on https://github.com/lostisland/faraday_middleware/blob/main/lib/faraday_middleware/gzip.rb
5
10
  module Faraday
11
+ # Main module
6
12
  module Gzip
7
- # Middleware to automatically decompress response bodies. If the
8
- # "Accept-Encoding" header wasn't set in the request, this sets it to
9
- # "gzip,deflate" and appropriately handles the compressed response from the
10
- # server. This resembles what Ruby 1.9+ does internally in Net::HTTP#get.
11
- # Based on https://github.com/lostisland/faraday_middleware/blob/main/lib/faraday_middleware/gzip.rb
12
-
13
+ # Faraday middleware for decompression
13
14
  class Middleware < Faraday::Middleware
15
+ # System method required by Faraday
14
16
  def self.optional_dependency(lib = nil)
15
17
  lib ? require(lib) : yield
16
18
  true
@@ -20,6 +22,8 @@ module Faraday
20
22
 
21
23
  BROTLI_SUPPORTED = optional_dependency 'brotli'
22
24
 
25
+ # Returns supported encodings, adds brotli if the corresponding
26
+ # dependency is present
23
27
  def self.supported_encodings
24
28
  encodings = %w[gzip deflate]
25
29
  encodings << 'br' if BROTLI_SUPPORTED
@@ -31,37 +35,42 @@ module Faraday
31
35
  CONTENT_LENGTH = 'Content-Length'
32
36
  SUPPORTED_ENCODINGS = supported_encodings.join(',').freeze
33
37
 
38
+ # Main method to process the response
34
39
  def call(env)
35
40
  env[:request_headers][ACCEPT_ENCODING] ||= SUPPORTED_ENCODINGS
41
+
36
42
  @app.call(env).on_complete do |response_env|
37
- if empty_body?(response_env)
38
- reset_body(response_env) { |body| raw_body(body) }
39
- else
40
- case response_env[:response_headers][CONTENT_ENCODING]
41
- when 'gzip'
42
- reset_body(response_env) { |body| uncompress_gzip(body) }
43
- when 'deflate'
44
- reset_body(response_env) { |body| inflate(body) }
45
- when 'br'
46
- reset_body(response_env) { |body| brotli_inflate(body) }
47
- end
48
- end
43
+ reset_body(response_env, find_processor(response_env))
44
+ end
45
+ end
46
+
47
+ # Finds a proper processor
48
+ def find_processor(response_env)
49
+ if empty_body?(response_env)
50
+ ->(body) { raw_body(body) }
51
+ else
52
+ processors[response_env[:response_headers][CONTENT_ENCODING]]
49
53
  end
50
54
  end
51
55
 
52
- def reset_body(env)
53
- env[:body] = yield(env[:body])
56
+ # Calls the proper processor to decompress body
57
+ def reset_body(env, processor)
58
+ return if processor.nil?
59
+
60
+ env[:body] = processor.call(env[:body])
54
61
  env[:response_headers].delete(CONTENT_ENCODING)
55
62
 
56
63
  env[:response_headers][CONTENT_LENGTH] = env[:body].nil? ? 0 : env[:body].length
57
64
  end
58
65
 
66
+ # Process gzip
59
67
  def uncompress_gzip(body)
60
68
  io = StringIO.new(body)
61
69
  gzip_reader = Zlib::GzipReader.new(io, encoding: 'ASCII-8BIT')
62
70
  gzip_reader.read
63
71
  end
64
72
 
73
+ # Process deflate
65
74
  def inflate(body)
66
75
  # Inflate as a DEFLATE (RFC 1950+RFC 1951) stream
67
76
  Zlib::Inflate.inflate(body)
@@ -76,10 +85,12 @@ module Faraday
76
85
  end
77
86
  end
78
87
 
88
+ # Process brotli
79
89
  def brotli_inflate(body)
80
90
  Brotli.inflate(body)
81
91
  end
82
92
 
93
+ # Do not process anything, leave body as is
83
94
  def raw_body(body)
84
95
  body
85
96
  end
@@ -89,6 +100,15 @@ module Faraday
89
100
  def empty_body?(response_env)
90
101
  response_env[:body].nil? || response_env[:body].empty?
91
102
  end
103
+
104
+ # Method providing the processors
105
+ def processors
106
+ {
107
+ 'gzip' => ->(body) { uncompress_gzip(body) },
108
+ 'deflate' => ->(body) { inflate(body) },
109
+ 'br' => ->(body) { brotli_inflate(body) }
110
+ }
111
+ end
92
112
  end
93
113
  end
94
114
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Faraday
4
4
  module Gzip
5
- VERSION = '2.0.1'
5
+ VERSION = '3.0.1'
6
6
  end
7
7
  end
@@ -0,0 +1,179 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Faraday::Gzip::Middleware do
4
+ require 'brotli' if Faraday::Gzip::Middleware::BROTLI_SUPPORTED
5
+
6
+ subject(:middleware) do
7
+ described_class.new(->(env) { Faraday::Response.new(env) })
8
+ end
9
+
10
+ let(:headers) { {} }
11
+
12
+ def process(body, content_type = nil, options = {})
13
+ env = {
14
+ body: body, request: options,
15
+ request_headers: Faraday::Utils::Headers.new,
16
+ response_headers: Faraday::Utils::Headers.new(headers)
17
+ }
18
+ env[:response_headers]['content-type'] = content_type if content_type
19
+ yield(env) if block_given?
20
+ middleware.call(env)
21
+ end
22
+
23
+ context 'when request' do
24
+ it 'sets the Accept-Encoding request header' do
25
+ env = process('').env
26
+ encodings = Faraday::Gzip::Middleware::BROTLI_SUPPORTED ? 'gzip,deflate,br' : 'gzip,deflate'
27
+ expect(env[:request_headers][:accept_encoding]).to eq(encodings)
28
+ end
29
+
30
+ it 'doesnt overwrite existing Accept-Encoding request header' do
31
+ env = process('') do |e|
32
+ e[:request_headers][:accept_encoding] = 'zopfli'
33
+ end.env
34
+ expect(env[:request_headers][:accept_encoding]).to eq('zopfli')
35
+ end
36
+ end
37
+
38
+ context 'when response' do
39
+ let(:uncompressed_body) do
40
+ '<html><head><title>Rspec</title></head><body>Hello, spec!</body></html>'
41
+ end
42
+ let(:empty_body) { '' }
43
+ let(:gzipped_body) do
44
+ io = StringIO.new
45
+ gz = Zlib::GzipWriter.new(io)
46
+ gz.write(uncompressed_body)
47
+ gz.close
48
+ res = io.string
49
+ res.force_encoding('BINARY')
50
+ res
51
+ end
52
+ let(:deflated_body) do
53
+ Zlib::Deflate.deflate(uncompressed_body)
54
+ end
55
+ let(:raw_deflated_body) do
56
+ z = Zlib::Deflate.new(Zlib::DEFAULT_COMPRESSION, -Zlib::MAX_WBITS)
57
+ compressed_body = z.deflate(uncompressed_body, Zlib::FINISH)
58
+ z.close
59
+ compressed_body
60
+ end
61
+
62
+ if Faraday::Gzip::Middleware::BROTLI_SUPPORTED
63
+ let(:brotlied_body) do
64
+ Brotli.deflate(uncompressed_body)
65
+ end
66
+ end
67
+
68
+ shared_examples 'compressed response' do
69
+ it 'uncompresses the body' do
70
+ expect(process(body).body).to eq(uncompressed_body)
71
+ end
72
+
73
+ it 'sets the Content-Length' do
74
+ expect(process(body).headers['Content-Length']).to eq(uncompressed_body.length)
75
+ end
76
+
77
+ it 'removes the Content-Encoding' do
78
+ expect(process(body).headers['Content-Encoding']).to be_nil
79
+ end
80
+ end
81
+
82
+ context 'when gzipped response' do
83
+ let(:body) { gzipped_body }
84
+ let(:headers) { { 'Content-Encoding' => 'gzip', 'Content-Length' => body.length } }
85
+
86
+ it_behaves_like 'compressed response'
87
+ end
88
+
89
+ context 'when deflated response' do
90
+ let(:body) { deflated_body }
91
+ let(:headers) { { 'Content-Encoding' => 'deflate', 'Content-Length' => body.length } }
92
+
93
+ it_behaves_like 'compressed response'
94
+ end
95
+
96
+ context 'when raw deflated response' do
97
+ let(:body) { raw_deflated_body }
98
+ let(:headers) { { 'Content-Encoding' => 'deflate', 'Content-Length' => body.length } }
99
+
100
+ it_behaves_like 'compressed response'
101
+ end
102
+
103
+ if Faraday::Gzip::Middleware::BROTLI_SUPPORTED
104
+ context 'when brotlied response' do
105
+ let(:body) { brotlied_body }
106
+ let(:headers) { { 'Content-Encoding' => 'br', 'Content-Length' => body.length } }
107
+
108
+ it_behaves_like 'compressed response'
109
+ end
110
+ end
111
+
112
+ context 'when empty response' do
113
+ let(:body) { empty_body }
114
+ let(:headers) { { 'Content-Encoding' => 'gzip', 'Content-Length' => body.length } }
115
+
116
+ it 'sets the Content-Length' do
117
+ expect(process(body).headers['Content-Length']).to eq(empty_body.length)
118
+ end
119
+
120
+ it 'removes the Content-Encoding' do
121
+ expect(process(body).headers['Content-Encoding']).to be_nil
122
+ end
123
+ end
124
+
125
+ context 'when nil response' do
126
+ let(:body) { nil }
127
+ let(:headers) { { 'Content-Encoding' => 'gzip', 'Content-Length' => 0 } }
128
+
129
+ it 'sets the Content-Length' do
130
+ expect(process(body).headers['Content-Length']).to eq(0)
131
+ end
132
+
133
+ it 'removes the Content-Encoding' do
134
+ expect(process(body).headers['Content-Encoding']).to be_nil
135
+ end
136
+ end
137
+
138
+ context 'when identity response' do
139
+ let(:body) { uncompressed_body }
140
+
141
+ it 'does not modify the body' do
142
+ expect(process(body).body).to eq(uncompressed_body)
143
+ end
144
+ end
145
+
146
+ context 'when unsupported encoding response' do
147
+ let(:body) { 'unsupported' }
148
+ let(:headers) { { 'Content-Encoding' => 'unsupported' } }
149
+
150
+ it 'does not modify the body' do
151
+ expect(process(body).body).to eq(body)
152
+ end
153
+
154
+ it 'preserves the Content-Encoding header' do
155
+ expect(process(body).headers['Content-Encoding']).to eq('unsupported')
156
+ end
157
+ end
158
+
159
+ context 'when no Content-Encoding header' do
160
+ let(:body) { uncompressed_body }
161
+ let(:headers) { {} }
162
+
163
+ it 'does not modify the body' do
164
+ expect(process(body).body).to eq(uncompressed_body)
165
+ end
166
+
167
+ it 'does not add a Content-Encoding header' do
168
+ expect(process(body).headers['Content-Encoding']).to be_nil
169
+ end
170
+ end
171
+
172
+ context 'when Content-Length is a string' do
173
+ let(:body) { gzipped_body }
174
+ let(:headers) { { 'Content-Encoding' => 'gzip', 'Content-Length' => body.length.to_s } }
175
+
176
+ it_behaves_like 'compressed response'
177
+ end
178
+ end
179
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe 'Faraday::Gzip::VERSION' do
4
+ subject { Object.const_get(self.class.description) }
5
+
6
+ it { is_expected.to match(/^\d+\.\d+\.\d+(\.\w+(\.\d+)?)?$/) }
7
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'faraday'
4
+ require 'simplecov'
5
+
6
+ SimpleCov.start do
7
+ add_filter 'spec/'
8
+ add_filter '.github/'
9
+ end
10
+
11
+ require_relative '../lib/faraday/gzip'
12
+
13
+ RSpec.configure do |config|
14
+ # Enable flags like --only-failures and --next-failure
15
+ config.example_status_persistence_file_path = '.rspec_status'
16
+
17
+ # Disable RSpec exposing methods globally on `Module` and `main`
18
+ config.disable_monkey_patching!
19
+
20
+ config.expect_with :rspec do |c|
21
+ c.syntax = :expect
22
+ end
23
+
24
+ config.order = :random
25
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: faraday-gzip
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 3.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ilya Krukowski
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-02 00:00:00.000000000 Z
11
+ date: 2024-11-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -16,14 +16,20 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '1.0'
19
+ version: '2.0'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '3'
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
27
  - - ">="
25
28
  - !ruby/object:Gem::Version
26
- version: '1.0'
29
+ version: '2.0'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '3'
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: zlib
29
35
  requirement: !ruby/object:Gem::Requirement
@@ -142,14 +148,14 @@ dependencies:
142
148
  requirements:
143
149
  - - "~>"
144
150
  - !ruby/object:Gem::Version
145
- version: '2.11'
151
+ version: '3.0'
146
152
  type: :development
147
153
  prerelease: false
148
154
  version_requirements: !ruby/object:Gem::Requirement
149
155
  requirements:
150
156
  - - "~>"
151
157
  - !ruby/object:Gem::Version
152
- version: '2.11'
158
+ version: '3.0'
153
159
  description: 'Faraday plugin to automatically set compression headers (GZip, Deflate,
154
160
  Brotli) and decompress the response.
155
161
 
@@ -166,13 +172,16 @@ files:
166
172
  - lib/faraday/gzip.rb
167
173
  - lib/faraday/gzip/middleware.rb
168
174
  - lib/faraday/gzip/version.rb
175
+ - spec/faraday/gzip/middleware_spec.rb
176
+ - spec/faraday/gzip/version_spec.rb
177
+ - spec/spec_helper.rb
169
178
  homepage: https://github.com/bodrovis/faraday-gzip
170
179
  licenses:
171
180
  - MIT
172
181
  metadata:
173
182
  bug_tracker_uri: https://github.com/bodrovis/faraday-gzip/issues
174
183
  changelog_uri: https://github.com/bodrovis/faraday-gzip/blob/master/CHANGELOG.md
175
- documentation_uri: http://www.rubydoc.info/gems/faraday-gzip/2.0.1
184
+ documentation_uri: http://www.rubydoc.info/gems/faraday-gzip/3.0.1
176
185
  homepage_uri: https://github.com/bodrovis/faraday-gzip
177
186
  source_code_uri: https://github.com/bodrovis/faraday-gzip
178
187
  rubygems_mfa_required: 'true'
@@ -184,17 +193,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
184
193
  requirements:
185
194
  - - ">="
186
195
  - !ruby/object:Gem::Version
187
- version: '2.6'
188
- - - "<"
189
- - !ruby/object:Gem::Version
190
- version: '4'
196
+ version: '3.0'
191
197
  required_rubygems_version: !ruby/object:Gem::Requirement
192
198
  requirements:
193
199
  - - ">="
194
200
  - !ruby/object:Gem::Version
195
201
  version: '0'
196
202
  requirements: []
197
- rubygems_version: 3.5.3
203
+ rubygems_version: 3.5.22
198
204
  signing_key:
199
205
  specification_version: 4
200
206
  summary: Automatically sets compression headers and decompresses the response