From 0633a9230fd3663915f013f26bb821dd266c260e Mon Sep 17 00:00:00 2001 From: Armin Date: Tue, 3 Jun 2025 09:36:29 +0200 Subject: [PATCH 1/4] Make use to #media_type instead of #content_type to avoid false negatives (e.g., multipart/form-data; boundary=...) --- lib/hanami/action/mime.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/hanami/action/mime.rb b/lib/hanami/action/mime.rb index 56706d7a..bffba066 100644 --- a/lib/hanami/action/mime.rb +++ b/lib/hanami/action/mime.rb @@ -222,11 +222,11 @@ def enforce_accept(request, config) # @since 2.0.0 # @api private def enforce_content_type(request, config) - content_type = request.content_type + media_type = request.media_type - return if content_type.nil? + return if media_type.nil? - return if accepted_mime_type?(content_type, config) + return if accepted_mime_type?(media_type, config) yield end From e4e0c1ce7dd97f31fdc51ff35c6e10b4e0d8c50a Mon Sep 17 00:00:00 2001 From: Armin Date: Tue, 3 Jun 2025 09:41:10 +0200 Subject: [PATCH 2/4] Clarify media type comparison in enforce_content_type with a comment --- lib/hanami/action/mime.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/hanami/action/mime.rb b/lib/hanami/action/mime.rb index bffba066..f4d74734 100644 --- a/lib/hanami/action/mime.rb +++ b/lib/hanami/action/mime.rb @@ -222,6 +222,8 @@ def enforce_accept(request, config) # @since 2.0.0 # @api private def enforce_content_type(request, config) + # Compare media type (without parameters) instead of full Content-Type header + # to avoid false negatives (e.g., multipart/form-data; boundary=...) media_type = request.media_type return if media_type.nil? From 52c9c85f4baea67eb7ab58e887f19ddbaee6087f Mon Sep 17 00:00:00 2001 From: wuarmin Date: Tue, 3 Jun 2025 21:04:46 +0200 Subject: [PATCH 3/4] Add spec for the enforce_content_type-fix. --- spec/integration/hanami/controller/mime_type_spec.rb | 9 +++++++++ spec/support/fixtures.rb | 11 +++++++++++ 2 files changed, 20 insertions(+) diff --git a/spec/integration/hanami/controller/mime_type_spec.rb b/spec/integration/hanami/controller/mime_type_spec.rb index 9cccc1fd..40e85ff1 100644 --- a/spec/integration/hanami/controller/mime_type_spec.rb +++ b/spec/integration/hanami/controller/mime_type_spec.rb @@ -58,6 +58,15 @@ end end + context "when uploading a file to an action with format multipart/form-data configured" do + it "does not return 415 for multipart/form-data with a boundary parameter" do + response = app.post("/upload", "CONTENT_TYPE" => "multipart/form-data; boundary=----abc123") + + expect(response.status).to eq(200) + expect(response.body).to eq("multipart/form-data; boundary=----abc123") + end + end + context "when Content-Type are sent and formats are configured to accept all" do it "accepts the request with a custom content type" do response = app.get("/relaxed", "CONTENT_TYPE" => "application/custom") diff --git a/spec/support/fixtures.rb b/spec/support/fixtures.rb index 7d5f1013..763f8b0f 100644 --- a/spec/support/fixtures.rb +++ b/spec/support/fixtures.rb @@ -1597,6 +1597,16 @@ def handle(*, res) end end + class UploadAction < Hanami::Action + config.formats.add :multipart, "multipart/form-data" + config.format :multipart + + def handle(req, res) + res.format = :txt + res.body = req.content_type + end + end + class Restricted < Hanami::Action config.formats.add :custom, "application/custom" @@ -1641,6 +1651,7 @@ def initialize get "/custom_from_accept", to: Mimes::CustomFromAccept.new get "/strict", to: Mimes::Strict.new get "/relaxed", to: Mimes::Relaxed.new + post "/upload", to: Mimes::UploadAction.new end end From 405af041371904c995c00d93f7a339b58f30557e Mon Sep 17 00:00:00 2001 From: wuarmin Date: Tue, 3 Jun 2025 21:10:15 +0200 Subject: [PATCH 4/4] Improve spec-text. --- spec/integration/hanami/controller/mime_type_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/integration/hanami/controller/mime_type_spec.rb b/spec/integration/hanami/controller/mime_type_spec.rb index 40e85ff1..9d0ef213 100644 --- a/spec/integration/hanami/controller/mime_type_spec.rb +++ b/spec/integration/hanami/controller/mime_type_spec.rb @@ -59,7 +59,7 @@ end context "when uploading a file to an action with format multipart/form-data configured" do - it "does not return 415 for multipart/form-data with a boundary parameter" do + it "does not return 415 for valid multipart/form-data request with boundary" do response = app.post("/upload", "CONTENT_TYPE" => "multipart/form-data; boundary=----abc123") expect(response.status).to eq(200)