-
Notifications
You must be signed in to change notification settings - Fork 21.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Encode Content-Disposition filenames on send_data and send_file #33829
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we remove ActiveStorage::Filename::Parameters
?
@@ -61,7 +61,7 @@ def sanitized | |||
end | |||
|
|||
def parameters #:nodoc: | |||
Parameters.new self | |||
ActionController::DataStreaming::DispositionFilenameParameters.new(sanitized) # :nodoc: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this :nodoc:
comment necessary? What is it excluding from the docs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, it's my bad
5e35120
to
4fb13b9
Compare
Thanks, @mtsmfm! A few more things:
|
4fb13b9
to
f6893aa
Compare
|
@@ -1,3 +1,7 @@ | |||
* Encode Content-Disposition filenames on `send_data` and `send_file`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅
f6893aa
to
1d3fa52
Compare
@@ -61,7 +59,7 @@ def sanitized | |||
end | |||
|
|||
def parameters #:nodoc: | |||
Parameters.new self | |||
ActionController::DataStreaming::DispositionFilenameParameters.new(sanitized) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't we need to require this file one? Also action_controller
because it is not in Active Storage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we don't have to require because this file is under app
and it's on Rails engine
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we avoid [internally] exposing this class entirely? AFAICS, this method's result is only used in:
(type.to_s.presence_in(%w( attachment inline )) || "inline") + "; #{filename.parameters}" |
(And that method seems to have more in common with the surrounding lines in send_file_headers!
, too.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we avoid [internally] exposing this class entirely?
Hmm, how can I avoid?
AFAIK, there's no way to share this logic across gems without exposing class/module
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think Matthew’s suggesting removing the parameters
method here and using the new class directly in ActiveStorage::Service#content_disposition_with
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gotcha
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking of something like ActionController::ContentDisposition.format(:inline, filename: "hello.jpg") # => "inline; filename=[...]"
So we still need to expose a constant (and following @rafaelfranca's suggestion to move it out of the DataStreaming namespace), but having it do the work internally, and just return a string. It just feels a bit odd to me that we're exposing the class instance, when all we want to do is call to_s
on it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool, I'll do that
|
||
module ActionController | ||
module DataStreaming | ||
class DispositionFilenameParameters # :nodoc: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we want to reuse inside Active Storage I don't think it should be inside DataStreaming
. ActionController:: DispositionFilename
is a better name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay, I'll rename
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, you also meant DispositionFilenameParameters
should be renamed to DispositionFilename
, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, but maybe DispositionFilenameParameter
is better.
ba2d8aa
to
60e29b5
Compare
seems failed test isn't related to this PR |
# frozen_string_literal: true | ||
|
||
module ActionController | ||
class ContentDisposition # :nodoc: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rafaelfranca Now I think this class should be put into the same place as ActionDispatch::Http::UploadedFile
.
It seems all helper stuff is placed in ActionDispatch
.
So I propose to rename this class to ActionDispatch::Http::ContentDisposition
.
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. Makes sense to me.
@@ -3,6 +3,7 @@ | |||
require "test_helper" | |||
require "database/setup" | |||
require "active_support/testing/method_call_assertions" | |||
require "action_controller/content_disposition" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This require should be probably inside lib/active_storage/service.rb
# frozen_string_literal: true | ||
|
||
module ActionController | ||
class ContentDisposition # :nodoc: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. Makes sense to me.
60e29b5
to
890485c
Compare
@georgeclaghorn @rafaelfranca @matthewd I fixed all points you reviewed. Can you review again, please? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👏
@georgeclaghorn Can I ask you to review? |
Thanks! |
`ActiveStorage::Filename#parameters` was removed by rails#33829.
Users downloading non-ASCII attachments would see garbled characters. When used with object storage, AWS S3 would return an InvalidArgument error: Header value cannot be represented using ISO-8859-1. Per RFC 5987 and RFC 6266, Content-Disposition should be encoded properly. This commit takes the Rails 6 implementation of ActiveSuppport::Http::ContentDisposition (rails/rails#33829) and ports it here. Closes https://gitlab.com/gitlab-org/gitlab-ce/issues/47673
Encode Content-Disposition filenames on send_data and send_file rails/rails#33829
* Update dependencies to support Rails 6 * Migrate /bin stubs to Rails 6 * Migrate /config files to Rails 6 * Migrate /public files to Rails 6 * Migrate /WcaOnRails files to Rails 6 * Migrate /app/views files to Rails 6 * Add Sprockets 4 manifest * Fix validator deprecation warnings * Update rspec Suite for Rails 6 compatibility * Fix update_attributes deprecation See rails/rails#31998 * Fix UTF-8 encoded Content-Disposition headers in tests See rails/rails#33829 * Hotfix for after_rollback trigger bug in Rails 6 See also rails/rails#36965 * Incorporate review comments
Summary
A few years ago, @stanhu tried to support non-ascii encodings for
send_data
andsend_file
.#21461
but it's still not merged because it lacks tests and some points to be fixed.
In the PR, @jeremy told us how he encodes and actually it's the same how activestorage encodes file name now
I changed
ActiveStorage::Filename::Parameters
toActionController::DataStreaming::DispositionFilenameParameters
to encode insend_data
andsend_file
and share the logic.I tested on Chrome, IE11, Safari and Firefox
Chrome
IE11
Safari
Firefox
Script
Other Information
I'm wondering if we can backport this change to older versions-> I created backport gem https://github.com/mtsmfm/action_dispatch-http-content_disposition