Skip to content

Commit 2452f03

Browse files
kubav182Jakub Venglar
andauthored
Fixed extracting charset from response. (OpenFeign#2545)
While building FeignException, ignore quotes in regexp, ignore case and catch IllegalCharsetNameException to be sure it does not raise in other cases. These content types are all valid and results in utf-8: text/html;charset=utf-8 text/html;charset=UTF-8 Text/HTML;Charset="utf-8" text/html; charset="utf-8" Fixes OpenFeign#2540 Co-authored-by: Jakub Venglar <venglar@rixo.cz>
1 parent ec7febe commit 2452f03

3 files changed

Lines changed: 49 additions & 4 deletions

File tree

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
qprxi7sg7jh57ear2tgbtqkl5q
1+
dm4ytkvb7jhsbbokecdbdaq3ku

core/src/main/java/feign/FeignException.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 The Feign Authors
2+
* Copyright 2012-2024 The Feign Authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
55
* in compliance with the License. You may obtain a copy of the License at
@@ -15,6 +15,7 @@
1515

1616
import static feign.Util.*;
1717
import static java.lang.String.format;
18+
import static java.util.regex.Pattern.CASE_INSENSITIVE;
1819

1920
import java.io.ByteArrayInputStream;
2021
import java.io.IOException;
@@ -24,6 +25,7 @@
2425
import java.nio.ByteBuffer;
2526
import java.nio.CharBuffer;
2627
import java.nio.charset.Charset;
28+
import java.nio.charset.IllegalCharsetNameException;
2729
import java.util.Collection;
2830
import java.util.Collections;
2931
import java.util.Map;
@@ -530,14 +532,18 @@ private static Charset getResponseCharset(Map<String, Collection<String>> header
530532
return null;
531533
}
532534

533-
Pattern pattern = Pattern.compile(".*charset=([^\\s|^;]+).*");
535+
Pattern pattern = Pattern.compile(".*charset=\"?([^\\s|^;|^\"]+).*", CASE_INSENSITIVE);
534536
Matcher matcher = pattern.matcher(strings.iterator().next());
535537
if (!matcher.lookingAt()) {
536538
return null;
537539
}
538540

539541
String group = matcher.group(1);
540-
if (!Charset.isSupported(group)) {
542+
try {
543+
if (!Charset.isSupported(group)) {
544+
return null;
545+
}
546+
} catch (IllegalCharsetNameException ex) {
541547
return null;
542548
}
543549
return Charset.forName(group);

core/src/test/java/feign/FeignExceptionTest.java

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import java.util.HashMap;
2626
import java.util.Map;
2727
import org.junit.jupiter.api.Test;
28+
import org.junit.jupiter.params.ParameterizedTest;
29+
import org.junit.jupiter.params.provider.ValueSource;
2830

2931
class FeignExceptionTest {
3032

@@ -103,6 +105,43 @@ void createFeignExceptionWithCorrectCharsetResponse() {
103105
.isEqualTo("[400] during [GET] to [/home] [methodKey]: [response]");
104106
}
105107

108+
@ParameterizedTest
109+
@ValueSource(
110+
strings = {
111+
"application/json;charset=\"UTF-16BE\"",
112+
"application/json; charset=UTF-16BE",
113+
"application/json; charset=\"UTF-16BE\"",
114+
"application/json;charset=UTF-16BE"
115+
})
116+
void createFeignExceptionWithCorrectCharsetResponseButDifferentContentTypeFormats(
117+
String contentType) {
118+
Map<String, Collection<String>> map = new HashMap<>();
119+
map.put("connection", new ArrayList<>(Collections.singletonList("keep-alive")));
120+
map.put("content-length", new ArrayList<>(Collections.singletonList("100")));
121+
map.put("content-type", new ArrayList<>(Collections.singletonList(contentType)));
122+
123+
Request request =
124+
Request.create(
125+
Request.HttpMethod.GET,
126+
"/home",
127+
Collections.emptyMap(),
128+
"data".getBytes(StandardCharsets.UTF_16BE),
129+
StandardCharsets.UTF_16BE,
130+
null);
131+
132+
Response response =
133+
Response.builder()
134+
.status(400)
135+
.body("response".getBytes(StandardCharsets.UTF_16BE))
136+
.headers(map)
137+
.request(request)
138+
.build();
139+
140+
FeignException exception = FeignException.errorStatus("methodKey", response);
141+
assertThat(exception.getMessage())
142+
.isEqualTo("[400] during [GET] to [/home] [methodKey]: [response]");
143+
}
144+
106145
@Test
107146
void createFeignExceptionWithErrorCharsetResponse() {
108147
Map<String, Collection<String>> map = new HashMap<>();

0 commit comments

Comments
 (0)