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

Open
wants to merge 1 commit into
base: master
from

Conversation

Projects
None yet
5 participants
@mtsmfm
Contributor

mtsmfm commented Sep 9, 2018

Summary

A few years ago, @stanhu tried to support non-ascii encodings for send_data and send_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 to ActionController::DataStreaming::DispositionFilenameParameters to encode in send_data and send_file and share the logic.

I tested on Chrome, IE11, Safari and Firefox

Chrome

chrome

IE11

ie

Safari

safari

Firefox

firefox

Script

# 1. Put this file into the root of rails repo
# 2. `bundle exec rackup -b 0.0.0.0`
# 3. `open localhost:9292`
require 'rails/all'

tmpdir = Dir.mktmpdir
Dir.chdir(tmpdir)

ENV['DATABASE_URL'] = "sqlite3://#{File.join(tmpdir, 'database.sql')}"

class TestApp < Rails::Application
  secrets.secret_key_base = 'secret_key_base'
end

Rails.application.configure do
  config.load_defaults 5.2
  config.eager_load = true
  config.active_storage.service = :local
  config.logger = ActiveSupport::Logger.new(STDOUT)
  config.active_storage.service_configurations = {
    local: {
      service: 'Disk',
      root: tmpdir
    }
  }

  config.after_initialize do |app|
    ActiveRecord::Schema.define do
      create_table :users, force: true do |t|
      end

      load File.join(Bundler.rubygems.find_name('activestorage').first.full_gem_path, 'db/migrate/20170806125915_create_active_storage_tables.rb')

      CreateActiveStorageTables.new.change
    end

    class User < ActiveRecord::Base
      has_one_attached :avatar
    end

    class UsersController < ActionController::Base
      def index
        @user = User.new

        render inline: <<~ERB
          <%= form_with model: @user do |f| %>
            <%= f.file_field :avatar %>
            <%= f.submit %>
          <% end %>

          <ul>
            <%- User.all.each do |u| %>
              <li>
                <div>id: <%= u.id %></div>
                <%= link_to 'download via send_data', user_path(u.id) %>
                <%= link_to 'download via rails_blob_path', rails_blob_path(u.avatar, disposition: 'attachment') %>
              </li>
            <% end %>
          </ul>
        ERB
      end

      def create
        User.create!(params.require(:user).permit(:avatar))

        redirect_to users_path
      end

      def show
        user = User.find(params[:id])

        send_data user.avatar.download, disposition: 'attachment', filename: user.avatar.filename.to_s
      end
    end

    app.routes.prepend do
      root to: redirect('/users')
      resources :users
    end

    user = User.new
    user.avatar.attach(io: File.open(__FILE__), filename: %(あ"い"\\う/え'お.rb))
    user.save!
  end
end
Rails.application.initialize!
run Rails.application

at_exit do
  FileUtils.rm_rf(tmpdir)
end

Other Information

I'm wondering if we can backport this change to older versions

@georgeclaghorn

Can we remove ActiveStorage::Filename::Parameters?

@georgeclaghorn

This comment has been minimized.

Show comment
Hide comment
@georgeclaghorn

georgeclaghorn Sep 11, 2018

Member

Thanks, @mtsmfm! A few more things:

  1. We’re still requiring active_storage/filename/parameters here:

    require_dependency "active_storage/filename/parameters"

  2. There are ASt test failures like this:

    ArgumentError: wrong number of arguments (given 1, expected 0)
    

    I’m not immediately sure what’s causing them. Can you look into it?

  3. This needs a changelog entry.

  4. In response to the last paragraph of the PR description, I’m afraid we can’t backport this change, as it’s a new feature and not a bug fix. See the maintenance policy for more info.

Member

georgeclaghorn commented Sep 11, 2018

Thanks, @mtsmfm! A few more things:

  1. We’re still requiring active_storage/filename/parameters here:

    require_dependency "active_storage/filename/parameters"

  2. There are ASt test failures like this:

    ArgumentError: wrong number of arguments (given 1, expected 0)
    

    I’m not immediately sure what’s causing them. Can you look into it?

  3. This needs a changelog entry.

  4. In response to the last paragraph of the PR description, I’m afraid we can’t backport this change, as it’s a new feature and not a bug fix. See the maintenance policy for more info.

@mtsmfm

This comment has been minimized.

Show comment
Hide comment
@mtsmfm

mtsmfm Sep 11, 2018

Contributor
  1. Sorry, the cause is 1 🙇
  2. I thought it's kind of bug though, OK, I'll create a backport gem for older Rails.
Contributor

mtsmfm commented Sep 11, 2018

  1. Sorry, the cause is 1 🙇
  2. I thought it's kind of bug though, OK, I'll create a backport gem for older Rails.
@@ -1,3 +1,7 @@
* Encode Content-Disposition filenames on `send_data` and `send_file`.

This comment has been minimized.

@georgeclaghorn

georgeclaghorn Sep 11, 2018

Member

This merits more detail. At minimum, we ought to name the specifications implemented (RFCs 2231 and 5987) and provide examples.

@georgeclaghorn

georgeclaghorn Sep 11, 2018

Member

This merits more detail. At minimum, we ought to name the specifications implemented (RFCs 2231 and 5987) and provide examples.

This comment has been minimized.

@mtsmfm

mtsmfm Sep 12, 2018

Contributor

@mtsmfm

mtsmfm Sep 12, 2018

Contributor

@mtsmfm

This comment has been minimized.

Show comment
Hide comment
@mtsmfm

mtsmfm Sep 12, 2018

Contributor

Failed components: activesupport

seems failed test isn't related to this PR

Contributor

mtsmfm commented Sep 12, 2018

Failed components: activesupport

seems failed test isn't related to this PR

@mtsmfm

This comment has been minimized.

Show comment
Hide comment
@mtsmfm

mtsmfm Sep 13, 2018

Contributor

@georgeclaghorn @rafaelfranca @matthewd I fixed all points you reviewed. Can you review again, please?

Contributor

mtsmfm commented Sep 13, 2018

@georgeclaghorn @rafaelfranca @matthewd I fixed all points you reviewed. Can you review again, please?

@mtsmfm

This comment has been minimized.

Show comment
Hide comment
@mtsmfm

mtsmfm Sep 18, 2018

Contributor

@georgeclaghorn Can I ask you?

Contributor

mtsmfm commented Sep 18, 2018

@georgeclaghorn Can I ask you?

@jeremy

jeremy approved these changes Sep 18, 2018

👏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment