zip_kit 6.4.0 → 6.4.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: 67a468ca21123613319181955fd418268f661dc8beaee1c5eab2054395759478
4
- data.tar.gz: 33047d74b3e2caaa47ce7ef1868bb5b2dba260e3dc97e116fa0b7fba4c6ec07d
3
+ metadata.gz: 0c9a2d7c76b813cfcbfb622fce1164f1566e42ef1487f8f44095d2464b76f282
4
+ data.tar.gz: 45ef948824bebe50569949c030cbf2d2c720568e5c87e011ac124d4dccaccc55
5
5
  SHA512:
6
- metadata.gz: 219f3a08a9413835762ee7af7108324e1d2819f3a4a4e4d35c1451b2ad60453f09b8e5783070c879fa644b87199c4e825d40978894489ded72f90ddc99b73a79
7
- data.tar.gz: 532ca543f7dc346385336ba11e876f14667825d5ef67b6bd1b308ef91c1306591a203adf638894b8a720e1d0abeed0af9ac66ff941dc5b41229261719d47fd21
6
+ metadata.gz: 45d55f2c2038c0d19c3da829a113b44c5cea973a9f54b7118b6c21c0a75f6edf14d6d31e55ce27c6713b4e7d04cab4e752fb1fd62264b72440e88147c0d9fd7c
7
+ data.tar.gz: 9740f7b322e6a6b32a3e1ff2c38e0b07fb20b92cdac2b30863c65bead2e04d05646d28c881edb993aee0b192009a38f30b04dd06ebb3174fc85bc31daf80f847
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  ## Unreleased
2
2
 
3
+ ## 6.4.1
4
+
5
+ * Use lowercase names for the HTTP headers ZipKit produces, since Rack 3 requires them (`Rack::Lint` rejects uppercase header names). `OutputEnumerator.streaming_http_headers` now returns `"content-type"`, `"last-modified"`, `"content-encoding"` and `"x-accel-buffering"`. This is a breaking change if you look those headers up or override them in the returned Hash using the capitalised names: `headers["Content-Type"]` is now `nil`, and `headers["Content-Type"] = "application/epub+zip"` adds a second content type instead of replacing ours. Use the lowercase names instead. `zip_kit_stream` in Rails is not affected: it now merges our headers into the response regardless of case, so headers Rails sets itself (like the content type) still take precedence and do not get sent twice.
6
+
7
+ ## 6.4.0
8
+
3
9
  * Add `Streamer.new(io, ocf: true)` for writing EPUB (OCF) and OpenDocument containers. The first entry must then be a stored `mimetype` file with its sizes in the local header, and `Streamer::OCFViolation` is raised otherwise. That entry is written without the extended timestamp extra field, which those formats forbid - before, they could not be produced with ZipKit at all. File names get checked against the OCF rules as well: valid UTF-8, no forbidden characters, segments of at most 255 bytes not ending with a `.`, and no two names in a directory which only differ by case or Unicode normalization.
4
10
  * Add `Streamer#write_mimetype_file` and `SizeEstimator#add_mimetype_entry`
5
11
  * Add the `extended_timestamp:` keyword argument to `ZipWriter#write_local_file_header` and `ZipWriter#write_central_directory_file_header`
data/README.md CHANGED
@@ -197,7 +197,7 @@ zip_body = ZipKit::OutputEnumerator.new do | zip |
197
197
  end
198
198
 
199
199
  hh = zip_body.streaming_http_headers
200
- hh["Content-Length"] = bytesize.to_s
200
+ hh["content-length"] = bytesize.to_s
201
201
 
202
202
  [200, hh, zip_body]
203
203
  ```
@@ -56,7 +56,7 @@ class ZipDownload
56
56
  # and return the response, adding the Content-Length we have computed earlier
57
57
  [
58
58
  200,
59
- {"Content-Length" => size.to_s, "Content-Disposition" => content_disposition},
59
+ {"content-length" => size.to_s, "content-disposition" => content_disposition},
60
60
  zip_response_body
61
61
  ]
62
62
  end
@@ -114,15 +114,18 @@ class ZipKit::OutputEnumerator
114
114
  #
115
115
  # More value, however, is in the "technical" headers this method will provide. It will take the following steps to make sure streaming works correctly.
116
116
  #
117
- # * `Last-Modified` will be set to "now" so that the response is considered "fresh" by `Rack::ETag`. This is done so that `Rack::ETag` won't try to
117
+ # * `last-modified` will be set to "now" so that the response is considered "fresh" by `Rack::ETag`. This is done so that `Rack::ETag` won't try to
118
118
  # calculate a lax ETag value and thus won't start buffering your response out of nowhere
119
- # * `Content-Encoding` will be set to `identity`. This is so that proxies or the Rack middleware that applies compression to the response (like gzip)
119
+ # * `content-encoding` will be set to `identity`. This is so that proxies or the Rack middleware that applies compression to the response (like gzip)
120
120
  # is not going to try to compress your response. It also tells the receiving browsers (or downstream proxies) that they should not attempt to
121
121
  # open or uncompress the response before saving it or passing it onwards.
122
- # * `X-Accel-Buffering` will be set to 'no` - this tells both nginx and the Google Cloud load balancer that the response should not be buffered
122
+ # * `x-accel-buffering` will be set to `no` - this tells both nginx and the Google Cloud load balancer that the response should not be buffered
123
123
  #
124
124
  # These header values are known to get as close as possible to guaranteeing streaming on most environments where Ruby web applications may be hosted.
125
125
  #
126
+ # The header names are lowercase, as Rack 3 requires. If you look headers up in the returned Hash
127
+ # or add your own, use lowercase names too (`"content-type"`, not `"Content-Type"`).
128
+ #
126
129
  # @return [Hash]
127
130
  def self.streaming_http_headers
128
131
  _headers = {
@@ -130,16 +133,16 @@ class ZipKit::OutputEnumerator
130
133
  # https://github.com/rack/rack/issues/1619#issuecomment-606315714
131
134
  # Set this even when not streaming for consistency. The fact that there would be
132
135
  # a weak ETag generated would mean that the middleware buffers, so we have tests for that.
133
- "Last-Modified" => Time.now.httpdate,
136
+ "last-modified" => Time.now.httpdate,
134
137
  # Make sure Rack::Deflater does not touch our response body either, see
135
138
  # https://github.com/felixbuenemann/xlsxtream/issues/14#issuecomment-529569548
136
- "Content-Encoding" => "identity",
139
+ "content-encoding" => "identity",
137
140
  # Disable buffering for both nginx and Google Load Balancer, see
138
141
  # https://cloud.google.com/appengine/docs/flexible/how-requests-are-handled?tab=python#x-accel-buffering
139
- "X-Accel-Buffering" => "no",
142
+ "x-accel-buffering" => "no",
140
143
  # Set the correct content type. This should be overridden if you need to
141
144
  # serve things such as EPubs and other derived ZIP formats.
142
- "Content-Type" => "application/zip"
145
+ "content-type" => "application/zip"
143
146
  }
144
147
  end
145
148
 
@@ -39,11 +39,14 @@ module ZipKit::RailsStreaming
39
39
  logger&.warn { "The downstream HTTP proxy/LB insists on HTTP/1.0 protocol, ZIP response will be buffered." }
40
40
  end
41
41
 
42
- headers = ZipKit::OutputEnumerator.streaming_http_headers
43
-
44
42
  # Allow Rails headers to override ours. This is important if, for example, a content type gets
45
- # set to something else than "application/zip"
46
- response.headers.reverse_merge!(headers)
43
+ # set to something else than "application/zip". Before 7.1 Rails keeps the headers in a
44
+ # case-sensitive Hash with names like "Content-Type", so a reverse_merge! of our lowercase
45
+ # names would send some headers twice
46
+ present_header_names = response.headers.keys.map(&:downcase)
47
+ ZipKit::OutputEnumerator.streaming_http_headers.each_pair do |name, value|
48
+ response.headers[name] = value unless present_header_names.include?(name)
49
+ end
47
50
 
48
51
  # The output enumerator yields chunks of bytes generated from the Streamer,
49
52
  # with some buffering. See OutputEnumerator docs for more.
@@ -59,7 +62,7 @@ module ZipKit::RailsStreaming
59
62
  # some especially pesky Rack middleware that just would not cooperate. Those include
60
63
  # Rack::MiniProfiler and the above-mentioned Rack::ContentLength.
61
64
  if use_chunked_transfer_encoding
62
- response.headers["Transfer-Encoding"] = "chunked"
65
+ response.headers["transfer-encoding"] = "chunked"
63
66
  rack_zip_body = ZipKit::RackChunkedBody.new(rack_zip_body)
64
67
  end
65
68
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ZipKit
4
- VERSION = "6.4.0"
4
+ VERSION = "6.4.1"
5
5
  end
data/rbi/zip_kit.rbi CHANGED
@@ -2299,14 +2299,17 @@ end, T.untyped)
2299
2299
  #
2300
2300
  # More value, however, is in the "technical" headers this method will provide. It will take the following steps to make sure streaming works correctly.
2301
2301
  #
2302
- # * `Last-Modified` will be set to "now" so that the response is considered "fresh" by `Rack::ETag`. This is done so that `Rack::ETag` won't try to
2302
+ # * `last-modified` will be set to "now" so that the response is considered "fresh" by `Rack::ETag`. This is done so that `Rack::ETag` won't try to
2303
2303
  # calculate a lax ETag value and thus won't start buffering your response out of nowhere
2304
- # * `Content-Encoding` will be set to `identity`. This is so that proxies or the Rack middleware that applies compression to the response (like gzip)
2304
+ # * `content-encoding` will be set to `identity`. This is so that proxies or the Rack middleware that applies compression to the response (like gzip)
2305
2305
  # is not going to try to compress your response. It also tells the receiving browsers (or downstream proxies) that they should not attempt to
2306
2306
  # open or uncompress the response before saving it or passing it onwards.
2307
- # * `X-Accel-Buffering` will be set to 'no` - this tells both nginx and the Google Cloud load balancer that the response should not be buffered
2307
+ # * `x-accel-buffering` will be set to `no` - this tells both nginx and the Google Cloud load balancer that the response should not be buffered
2308
2308
  #
2309
2309
  # These header values are known to get as close as possible to guaranteeing streaming on most environments where Ruby web applications may be hosted.
2310
+ #
2311
+ # The header names are lowercase, as Rack 3 requires. If you look headers up in the returned Hash
2312
+ # or add your own, use lowercase names too (`"content-type"`, not `"Content-Type"`).
2310
2313
  sig { returns(T::Hash[T.untyped, T.untyped]) }
2311
2314
  def self.streaming_http_headers; end
2312
2315
 
data/rbi/zip_kit.rbs CHANGED
@@ -2018,14 +2018,17 @@ module ZipKit
2018
2018
  #
2019
2019
  # More value, however, is in the "technical" headers this method will provide. It will take the following steps to make sure streaming works correctly.
2020
2020
  #
2021
- # * `Last-Modified` will be set to "now" so that the response is considered "fresh" by `Rack::ETag`. This is done so that `Rack::ETag` won't try to
2021
+ # * `last-modified` will be set to "now" so that the response is considered "fresh" by `Rack::ETag`. This is done so that `Rack::ETag` won't try to
2022
2022
  # calculate a lax ETag value and thus won't start buffering your response out of nowhere
2023
- # * `Content-Encoding` will be set to `identity`. This is so that proxies or the Rack middleware that applies compression to the response (like gzip)
2023
+ # * `content-encoding` will be set to `identity`. This is so that proxies or the Rack middleware that applies compression to the response (like gzip)
2024
2024
  # is not going to try to compress your response. It also tells the receiving browsers (or downstream proxies) that they should not attempt to
2025
2025
  # open or uncompress the response before saving it or passing it onwards.
2026
- # * `X-Accel-Buffering` will be set to 'no` - this tells both nginx and the Google Cloud load balancer that the response should not be buffered
2026
+ # * `x-accel-buffering` will be set to `no` - this tells both nginx and the Google Cloud load balancer that the response should not be buffered
2027
2027
  #
2028
2028
  # These header values are known to get as close as possible to guaranteeing streaming on most environments where Ruby web applications may be hosted.
2029
+ #
2030
+ # The header names are lowercase, as Rack 3 requires. If you look headers up in the returned Hash
2031
+ # or add your own, use lowercase names too (`"content-type"`, not `"Content-Type"`).
2029
2032
  def self.streaming_http_headers: () -> ::Hash[untyped, untyped]
2030
2033
 
2031
2034
  # Returns a Hash of HTTP response headers for this particular response. This used to contain "Content-Length" for
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zip_kit
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.4.0
4
+ version: 6.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julik Tarkhanov