This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters. This comment has been minimized. Sign in to view. Copy link Quote reply. Excellent, thank you. Thanks, it's very helpful to me. A lot of load on server's memory. Sign up for free to join this conversation on GitHub.
Anthony Alberto Anthony Alberto I tried but i doesn't work, I'm sure I gettin something wrong. I did like you said, see in the edited question above — Barbared. Then try doc. I am using Carrierwave gem and when i download the file, if that file name contains space then it's converted into underscores. So how to remove that underscore from the filename while downloading it? Rasil Baidar Rasil Baidar 1. Sign up or log in Sign up using Google.
Sign up using Facebook. Sign up using Email and Password. Post as a guest Name. Email Required, but never shown. The Overflow Blog. Who owns this outage? Building intelligent escalation chains for modern SRE. Podcast Who is building clouds for the independent developer? We start by creating a request path that will handle streaming of our download.
To do so, we add a download route to the meeting resources that will use a custom controller:. When discussing downloading files of any kind, we need to touch on the subject of HTTP response headers and, in particular, the Content-Disposition header. The Content-Disposition response header tells the browser how to display the response content. If the browser knows how to handle the MIME type, the inline value displays the content as part of the web page.
Otherwise, the content is immediately downloaded. We can also instruct the browser to always download the content and save it locally. To do this, we use an attachment disposition. To change this, we can use filename attribute to name the downloaded file:. We also want to inform the browser about the content type. To help the user identify their download, we name our archived file by the meeting title using an easy to read slug identifier.
Putting it all together, we add the Content-Disposition and Content-Type response headers to the download action:. There are many quirks when dealing with the filename attribute of a Content-Disposition header. For starters, the filename may contain special characters that need escaping. So we ensure that the header is removed:. If our meeting app becomes widely successful, we want to be kind to our server resources and send a cached copy when possible.
It means that the server will perform validation before releasing a cached copy. For the server to perform cache validation, we need to provide a validator in our response as well. One choice is to use Last-Modified response header to validate the cached archive file.
We use the Time class httpdate method to provide the date and time in the expected format for when the archive was last modified:. Before we finish headers declaration, we need to deal with the HTTP server buffering problem. Web servers like Nginx perform buffering to reduce overhead with writing and reading streamed content. Unfortunately, this will make the browser wait for content.
To disable this behaviour, we can use the X-Accel-Buffering header to stop the Nginx from buffering:. Now, we can turn our attention to actually streaming the zip file content. To do this, we use the ZipTricks::BlockWriter that will be responsible for streaming chunks of the zip archive back to the browser.
Each time a writer receives a chunk of content, it will call a block and write the content directly onto the response stream:.
We use ZipTricks::Streamer and call the open method with a previously created writer to begin writing the zip archive. As we do so, we ensure that we close the stream when the streaming is done, otherwise the socket could be left open forever:. Next, one by one, we begin to retrieve meeting documents for streaming.
This method takes the document filename as an argument and yields back the previously created writer IO object that will serve for writing the document content:.
Thanks to ActiveStorage::Attachment association, we can access document metadata via the blob record. The ActiveStorage::Blob provides a download method which, when called with a block, will stream the file content in chunks.
Be careful here though, as calling this method without a block would read the entire file into memory before returning its content - not what we want. Unfortunately, calling response.
0コメント