diff --git a/zap/src/main/java/org/parosproxy/paros/network/HttpMessage.java b/zap/src/main/java/org/parosproxy/paros/network/HttpMessage.java index 4ace36efe4b..b8c79009717 100644 --- a/zap/src/main/java/org/parosproxy/paros/network/HttpMessage.java +++ b/zap/src/main/java/org/parosproxy/paros/network/HttpMessage.java @@ -129,7 +129,11 @@ public class HttpMessage implements Message { body.setContentEncodings(encodings); }; + private static final CharsetProvider DEFAULT_CHARSET_PROVIDER = + (header, body) -> header.getCharset(); + private static HttpEncodingsHandler contentEncodingsHandler; + private static CharsetProvider charsetProvider; private HttpRequestHeader mReqHeader = new HttpRequestHeader(); private HttpRequestBody mReqBody = new HttpRequestBody(); @@ -508,7 +512,7 @@ public void setRequestBody(byte[] body) { } private static void setBodyCharset(HttpBody body, HttpHeader header) { - String charset = header.getCharset(); + String charset = getCharset(header, body); body.setCharset(charset); if (charset != null @@ -524,6 +528,25 @@ private static void setBodyCharset(HttpBody body, HttpHeader header) { } } + /** + * Sets the provider of charset. + * + *

Note: Not part of the public API. + * + * @param provider the provider. + */ + public static void setCharsetProvider(CharsetProvider provider) { + charsetProvider = provider; + } + + private static String getCharset(HttpHeader header, HttpBody body) { + var localProvider = charsetProvider; + if (localProvider == null) { + localProvider = DEFAULT_CHARSET_PROVIDER; + } + return localProvider.get(header, body); + } + /** * Resets the set of warned content-type values. * @@ -1327,4 +1350,9 @@ public interface HttpEncodingsHandler { void handle(HttpHeader header, HttpBody body); } + + /** Note: Not part of the public API. */ + public interface CharsetProvider { + String get(HttpHeader header, HttpBody body); + } } diff --git a/zap/src/test/java/org/parosproxy/paros/network/HttpMessageUnitTest.java b/zap/src/test/java/org/parosproxy/paros/network/HttpMessageUnitTest.java index 36dc3071fb4..dd652abbe82 100644 --- a/zap/src/test/java/org/parosproxy/paros/network/HttpMessageUnitTest.java +++ b/zap/src/test/java/org/parosproxy/paros/network/HttpMessageUnitTest.java @@ -73,6 +73,7 @@ class HttpMessageUnitTest { @AfterEach void cleanUp() throws Exception { HttpMessage.setContentEncodingsHandler(null); + HttpMessage.setCharsetProvider(null); HttpMessage.resetWarnedContentTypeValues(); Configurator.reconfigure(getClass().getResource("/log4j2-test.properties").toURI()); } @@ -586,6 +587,19 @@ void shouldNotBeWebSocketUpgradeIfResponseMissUpgradeHeader() throws Exception { assertThat(webSocketUpgrade, is(equalTo(false))); } + @Test + void shouldUseCharsetProviderWhenSettingRequestBody() { + // Given + HttpMessage.setCharsetProvider((header, body) -> "UTF-16BE"); + HttpMessage message = new HttpMessage(); + withLoggerAppender(); + // When + message.setRequestBody(""); + // Then + assertThat(message.getRequestBody().getCharset(), is(equalTo("UTF-16BE"))); + assertThat(testAppender.getLogEvents(), hasSize(0)); + } + @ParameterizedTest @MethodSource(value = "setBodyData") void shouldUseContentTypeCharsetWhenSettingRequestBody( @@ -698,6 +712,19 @@ static Stream getNonPostMethods() { .map(Arguments::arguments); } + @Test + void shouldUseCharsetProviderWhenSettingResponseBody() { + // Given + HttpMessage.setCharsetProvider((header, body) -> "UTF-16LE"); + HttpMessage message = new HttpMessage(); + withLoggerAppender(); + // When + message.setResponseBody(""); + // Then + assertThat(message.getResponseBody().getCharset(), is(equalTo("UTF-16LE"))); + assertThat(testAppender.getLogEvents(), hasSize(0)); + } + @ParameterizedTest @MethodSource(value = "setBodyData") void shouldUseContentTypeCharsetWhenSettingResponseBody(