From 27d0c17dddc35c44b21e5d8cc7762d077cfb4eff Mon Sep 17 00:00:00 2001 From: kdelay Date: Tue, 6 Oct 2026 21:51:01 +0900 Subject: [PATCH] Read quoted and mixed-case charset parameters in FormEncoder FormEncoder looked for the charset with a case-sensitive pattern that did not accept a quoted value, so Content-Type headers such as 'Charset=ISO-8859-1' or 'charset="ISO-8859-1"' fell back to UTF-8 and the header was rewritten to charset=UTF-8. Parameter names are case-insensitive and values may be quoted (RFC 9110 8.3.1), and Response.charset() already reads both forms. Signed-off-by: kdelay --- .../src/main/java/feign/form/FormEncoder.java | 2 +- .../feign/form/FormEncoderCharsetTest.java | 30 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/form/src/main/java/feign/form/FormEncoder.java b/form/src/main/java/feign/form/FormEncoder.java index 19551b0fb..f35077f69 100644 --- a/form/src/main/java/feign/form/FormEncoder.java +++ b/form/src/main/java/feign/form/FormEncoder.java @@ -62,7 +62,7 @@ public class FormEncoder implements Encoder { static { CONTENT_TYPE_HEADER = "Content-Type"; - CHARSET_PATTERN = Pattern.compile("(?<=charset=)([\\w\\-]+)"); + CHARSET_PATTERN = Pattern.compile("(?<=charset=)\"?([\\w\\-]+)", Pattern.CASE_INSENSITIVE); } Encoder delegate; diff --git a/form/src/test/java/feign/form/FormEncoderCharsetTest.java b/form/src/test/java/feign/form/FormEncoderCharsetTest.java index d100fa65b..b3794b6ea 100644 --- a/form/src/test/java/feign/form/FormEncoderCharsetTest.java +++ b/form/src/test/java/feign/form/FormEncoderCharsetTest.java @@ -50,4 +50,34 @@ void unsupportedCharsetInContentTypeFallsBackToUtf8() { assertThat(new String(template.body(), StandardCharsets.UTF_8)).isEqualTo("foo=bar"); } + + @Test + void charsetParameterNameIsCaseInsensitive() { + RequestTemplate template = new RequestTemplate(); + template.header("Content-Type", "application/x-www-form-urlencoded; Charset=ISO-8859-1"); + + Map data = new LinkedHashMap<>(); + data.put("name", "é"); + + new FormEncoder().encode(data, Map.class, template); + + assertThat(new String(template.body(), StandardCharsets.ISO_8859_1)).isEqualTo("name=%E9"); + assertThat(template.headers().get("Content-Type")) + .containsExactly("application/x-www-form-urlencoded; charset=ISO-8859-1"); + } + + @Test + void quotedCharsetParameterIsHonored() { + RequestTemplate template = new RequestTemplate(); + template.header("Content-Type", "application/x-www-form-urlencoded; charset=\"ISO-8859-1\""); + + Map data = new LinkedHashMap<>(); + data.put("name", "é"); + + new FormEncoder().encode(data, Map.class, template); + + assertThat(new String(template.body(), StandardCharsets.ISO_8859_1)).isEqualTo("name=%E9"); + assertThat(template.headers().get("Content-Type")) + .containsExactly("application/x-www-form-urlencoded; charset=ISO-8859-1"); + } }