diff --git a/core/src/main/java/feign/FeignException.java b/core/src/main/java/feign/FeignException.java index 1582a3f36..327095918 100644 --- a/core/src/main/java/feign/FeignException.java +++ b/core/src/main/java/feign/FeignException.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 The Feign Authors + * Copyright 2012-2024 The Feign Authors * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at @@ -21,6 +21,7 @@ import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; +import java.nio.charset.IllegalCharsetNameException; import java.util.Collection; import java.util.Collections; import java.util.Map; @@ -29,6 +30,7 @@ import java.util.regex.Pattern; import static feign.Util.*; import static java.lang.String.format; +import static java.util.regex.Pattern.CASE_INSENSITIVE; /** * Origin exception type for all Http Apis. @@ -519,14 +521,18 @@ private static Charset getResponseCharset(Map> header return null; } - Pattern pattern = Pattern.compile(".*charset=([^\\s|^;]+).*"); + Pattern pattern = Pattern.compile(".*charset=\"?([^\\s|^;|^\"]+).*", CASE_INSENSITIVE); Matcher matcher = pattern.matcher(strings.iterator().next()); if (!matcher.lookingAt()) { return null; } String group = matcher.group(1); - if (!Charset.isSupported(group)) { + try { + if (!Charset.isSupported(group)) { + return null; + } + } catch (IllegalCharsetNameException ex) { return null; } return Charset.forName(group); diff --git a/core/src/test/java/feign/FeignExceptionTest.java b/core/src/test/java/feign/FeignExceptionTest.java index ea49a77d1..1aef7d6d1 100644 --- a/core/src/test/java/feign/FeignExceptionTest.java +++ b/core/src/test/java/feign/FeignExceptionTest.java @@ -24,6 +24,8 @@ import java.util.HashMap; import java.util.Map; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; class FeignExceptionTest { @@ -76,6 +78,32 @@ void createFeignExceptionWithCorrectCharsetResponse() { .isEqualTo("[400] during [GET] to [/home] [methodKey]: [response]"); } + @ParameterizedTest + @ValueSource(strings = { + "application/json;charset=\"UTF-16BE\"", + "application/json; charset=UTF-16BE", + "application/json; charset=\"UTF-16BE\"", + "application/json;charset=UTF-16BE" + }) + void createFeignExceptionWithCorrectCharsetResponseButDifferentContentTypeFormats(String contentType) { + Map> map = new HashMap<>(); + map.put("connection", new ArrayList<>(Collections.singletonList("keep-alive"))); + map.put("content-length", new ArrayList<>(Collections.singletonList("100"))); + map.put("content-type", + new ArrayList<>(Collections.singletonList(contentType))); + + Request request = Request.create(Request.HttpMethod.GET, "/home", Collections.emptyMap(), + "data".getBytes(StandardCharsets.UTF_16BE), StandardCharsets.UTF_16BE, null); + + Response response = + Response.builder().status(400).body("response".getBytes(StandardCharsets.UTF_16BE)) + .headers(map).request(request).build(); + + FeignException exception = FeignException.errorStatus("methodKey", response); + assertThat(exception.getMessage()) + .isEqualTo("[400] during [GET] to [/home] [methodKey]: [response]"); + } + @Test void createFeignExceptionWithErrorCharsetResponse() { Map> map = new HashMap<>();