Module: Zipline
- Defined in:
- lib/zipline.rb,
lib/zipline/version.rb,
lib/zipline/chunked_body.rb,
lib/zipline/tempfile_body.rb,
lib/zipline/zip_generator.rb
Overview
this class acts as a streaming body for rails initialize it with an array of the files you want to zip
Defined Under Namespace
Classes: Chunked, TempfileBody, ZipGenerator
Constant Summary collapse
- VERSION =
"1.6.0"
Instance Method Summary collapse
Instance Method Details
#zipline(files, zipname = 'zipline.zip', **kwargs_for_new) ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/zipline.rb', line 17 def zipline(files, zipname = 'zipline.zip', **kwargs_for_new) zip_generator = ZipGenerator.new(files, **kwargs_for_new) headers['Content-Disposition'] = ContentDisposition.format(disposition: 'attachment', filename: zipname) headers['Content-Type'] = Mime::Type.lookup_by_extension('zip').to_s response.sending_file = true response.cache_control[:public] ||= false # Disables Rack::ETag if it is enabled (prevent buffering) # see https://github.com/rack/rack/issues/1619#issuecomment-606315714 self.response.headers['Last-Modified'] = Time.now.httpdate if request.get_header("HTTP_VERSION") == "HTTP/1.0" # If HTTP/1.0 is used it is not possible to stream, and if that happens it usually will be # unclear why buffering is happening. Some info in the log is the least one can do. logger.warn { "The downstream HTTP proxy/LB insists on HTTP/1.0 protocol, ZIP response will be buffered." } if logger # If we use Rack::ContentLength it would run through our ZIP block twice - once to calculate the content length # of the response, and once - to serve. We can trade performance for disk space and buffer the response into a Tempfile # since we are already buffering. tempfile_body = TempfileBody.new(request.env, zip_generator) headers["Content-Length"] = tempfile_body.size.to_s headers["X-Zipline-Output"] = "buffered" self.response_body = tempfile_body else # Disable buffering for both nginx and Google Load Balancer, see # https://cloud.google.com/appengine/docs/flexible/how-requests-are-handled?tab=python#x-accel-buffering response.headers["X-Accel-Buffering"] = "no" # Make sure Rack::ContentLength does not try to compute a content length, # and remove the one already set headers.delete("Content-Length") # and send out in chunked encoding headers["Transfer-Encoding"] = "chunked" headers["X-Zipline-Output"] = "streamed" self.response_body = Chunked.new(zip_generator) end end |