mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
202 lines
6.1 KiB
Ruby
202 lines
6.1 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "abstract_unit"
|
|
|
|
class MultipartParamsParsingTest < ActionDispatch::IntegrationTest
|
|
class TestController < ActionController::Base
|
|
class << self
|
|
attr_accessor :last_request_parameters, :last_parameters
|
|
end
|
|
|
|
def parse
|
|
self.class.last_request_parameters = begin
|
|
request.request_parameters
|
|
rescue EOFError
|
|
{}
|
|
end
|
|
self.class.last_parameters = request.parameters
|
|
head :ok
|
|
end
|
|
|
|
def read
|
|
render plain: "File: #{params[:uploaded_data].read}"
|
|
end
|
|
end
|
|
|
|
FIXTURE_PATH = File.expand_path("../../fixtures/multipart", __dir__)
|
|
|
|
def teardown
|
|
TestController.last_request_parameters = nil
|
|
end
|
|
|
|
test "parses single parameter" do
|
|
assert_equal({ "foo" => "bar" }, parse_multipart("single_parameter"))
|
|
end
|
|
|
|
test "parses bracketed parameters" do
|
|
assert_equal({ "foo" => { "baz" => "bar" } }, parse_multipart("bracketed_param"))
|
|
end
|
|
|
|
test "parse single utf8 parameter" do
|
|
assert_equal({ "Iñtërnâtiônàlizætiøn_name" => "Iñtërnâtiônàlizætiøn_value" },
|
|
parse_multipart("single_utf8_param"), "request.request_parameters")
|
|
assert_equal(
|
|
"Iñtërnâtiônàlizætiøn_value",
|
|
TestController.last_parameters["Iñtërnâtiônàlizætiøn_name"], "request.parameters")
|
|
end
|
|
|
|
test "parse bracketed utf8 parameter" do
|
|
assert_equal({ "Iñtërnâtiônàlizætiøn_name" => {
|
|
"Iñtërnâtiônàlizætiøn_nested_name" => "Iñtërnâtiônàlizætiøn_value" } },
|
|
parse_multipart("bracketed_utf8_param"), "request.request_parameters")
|
|
assert_equal(
|
|
{ "Iñtërnâtiônàlizætiøn_nested_name" => "Iñtërnâtiônàlizætiøn_value" },
|
|
TestController.last_parameters["Iñtërnâtiônàlizætiøn_name"], "request.parameters")
|
|
end
|
|
|
|
test "parses text file" do
|
|
params = parse_multipart("text_file")
|
|
assert_equal %w(file foo), params.keys.sort
|
|
assert_equal "bar", params["foo"]
|
|
|
|
file = params["file"]
|
|
assert_equal "file.txt", file.original_filename
|
|
assert_equal "text/plain", file.content_type
|
|
assert_equal "contents", file.read
|
|
end
|
|
|
|
test "parses utf8 filename with percent character" do
|
|
params = parse_multipart("utf8_filename")
|
|
assert_equal %w(file foo), params.keys.sort
|
|
assert_equal "bar", params["foo"]
|
|
|
|
file = params["file"]
|
|
assert_equal "ファイル%名.txt", file.original_filename
|
|
assert_equal "text/plain", file.content_type
|
|
assert_equal "contents", file.read
|
|
end
|
|
|
|
test "parses boundary problem file" do
|
|
params = parse_multipart("boundary_problem_file")
|
|
assert_equal %w(file foo), params.keys.sort
|
|
|
|
file = params["file"]
|
|
foo = params["foo"]
|
|
|
|
assert_equal "file.txt", file.original_filename
|
|
assert_equal "text/plain", file.content_type
|
|
|
|
assert_equal "bar", foo
|
|
end
|
|
|
|
test "parses large text file" do
|
|
params = parse_multipart("large_text_file")
|
|
assert_equal %w(file foo), params.keys.sort
|
|
assert_equal "bar", params["foo"]
|
|
|
|
file = params["file"]
|
|
|
|
assert_equal "file.txt", file.original_filename
|
|
assert_equal "text/plain", file.content_type
|
|
assert_equal(("a" * 20480), file.read)
|
|
end
|
|
|
|
test "parses binary file" do
|
|
params = parse_multipart("binary_file")
|
|
assert_equal %w(file flowers foo), params.keys.sort
|
|
assert_equal "bar", params["foo"]
|
|
|
|
file = params["file"]
|
|
assert_equal "file.csv", file.original_filename
|
|
assert_nil file.content_type
|
|
assert_equal "contents", file.read
|
|
|
|
file = params["flowers"]
|
|
assert_equal "flowers.jpg", file.original_filename
|
|
assert_equal "image/jpeg", file.content_type
|
|
assert_equal 19512, file.size
|
|
end
|
|
|
|
test "parses mixed files" do
|
|
params = parse_multipart("mixed_files")
|
|
assert_equal %w(files foo), params.keys.sort
|
|
assert_equal "bar", params["foo"]
|
|
|
|
# Rack doesn't handle multipart/mixed for us.
|
|
files = params["files"]
|
|
assert_equal 19756, files.bytesize
|
|
end
|
|
|
|
test "does not create tempfile if no file has been selected" do
|
|
params = parse_multipart("none")
|
|
assert_equal %w(submit-name), params.keys.sort
|
|
assert_equal "Larry", params["submit-name"]
|
|
assert_nil params["files"]
|
|
end
|
|
|
|
test "parses empty upload file" do
|
|
params = parse_multipart("empty")
|
|
assert_equal %w(files submit-name), params.keys.sort
|
|
assert_equal "Larry", params["submit-name"]
|
|
assert params["files"]
|
|
assert_equal "", params["files"].read
|
|
end
|
|
|
|
test "uploads and reads binary file" do
|
|
with_test_routing do
|
|
fixture = FIXTURE_PATH + "/ruby_on_rails.jpg"
|
|
params = { uploaded_data: fixture_file_upload(fixture, "image/jpg") }
|
|
post "/read", params: params
|
|
end
|
|
end
|
|
|
|
test "uploads and reads file" do
|
|
with_test_routing do
|
|
post "/read", params: { uploaded_data: fixture_file_upload(FIXTURE_PATH + "/hello.txt", "text/plain") }
|
|
assert_equal "File: Hello", response.body
|
|
end
|
|
end
|
|
|
|
# This can happen in Internet Explorer when redirecting after multipart form submit.
|
|
test "does not raise EOFError on GET request with multipart content-type" do
|
|
with_routing do |set|
|
|
set.draw do
|
|
ActiveSupport::Deprecation.silence do
|
|
get ":action", controller: "multipart_params_parsing_test/test"
|
|
end
|
|
end
|
|
headers = { "CONTENT_TYPE" => "multipart/form-data; boundary=AaB03x" }
|
|
get "/parse", headers: headers
|
|
assert_response :ok
|
|
end
|
|
end
|
|
|
|
private
|
|
def fixture(name)
|
|
File.open(File.join(FIXTURE_PATH, name), "rb") do |file|
|
|
{ "rack.input" => file.read,
|
|
"CONTENT_TYPE" => "multipart/form-data; boundary=AaB03x",
|
|
"CONTENT_LENGTH" => file.stat.size.to_s }
|
|
end
|
|
end
|
|
|
|
def parse_multipart(name)
|
|
with_test_routing do
|
|
headers = fixture(name)
|
|
post "/parse", params: headers.delete("rack.input"), headers: headers
|
|
assert_response :ok
|
|
TestController.last_request_parameters
|
|
end
|
|
end
|
|
|
|
def with_test_routing
|
|
with_routing do |set|
|
|
set.draw do
|
|
ActiveSupport::Deprecation.silence do
|
|
post ":action", controller: "multipart_params_parsing_test/test"
|
|
end
|
|
end
|
|
yield
|
|
end
|
|
end
|
|
end
|