Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 22 additions & 4 deletions zap/src/main/java/org/parosproxy/paros/network/HttpMessage.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,15 @@
import java.net.HttpCookie;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.Vector;
Expand Down Expand Up @@ -156,6 +159,9 @@ public class HttpMessage implements Message {
*/
private boolean responseFromTargetHost = false;

private static final Set<String> WARNED_CONTENT_TYPE_VALUES =
Collections.synchronizedSet(new HashSet<>());

public HistoryReference getHistoryRef() {
return historyRef;
}
Expand Down Expand Up @@ -508,13 +514,25 @@ private static void setBodyCharset(HttpBody body, HttpHeader header) {
if (charset != null
&& !charset.equalsIgnoreCase(body.getCharset())
&& !isCharsetSupported(charset)) {
LOGGER.warn(
"Failed to set charset {} from content-type value: {}",
charset,
header.getNormalisedContentTypeValue());
String contentTypeValue = header.getNormalisedContentTypeValue();
if (WARNED_CONTENT_TYPE_VALUES.add(contentTypeValue)) {
LOGGER.warn(
"Failed to set charset {} from content-type value: {}",
charset,
header.getNormalisedContentTypeValue());
}
}
}

/**
* Resets the set of warned content-type values.
*
* <p><strong>Note:</strong> Not part of the public API.
*/
public static void resetWarnedContentTypeValues() {
WARNED_CONTENT_TYPE_VALUES.clear();
}

private static boolean isCharsetSupported(String charset) {
try {
return Charset.isSupported(charset);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import static java.util.Arrays.asList;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.equalTo;
Expand Down Expand Up @@ -72,6 +73,7 @@ class HttpMessageUnitTest {
@AfterEach
void cleanUp() throws Exception {
HttpMessage.setContentEncodingsHandler(null);
HttpMessage.resetWarnedContentTypeValues();
Configurator.reconfigure(getClass().getResource("/log4j2-test.properties").toURI());
}

Expand Down Expand Up @@ -624,6 +626,61 @@ void shouldUseDefaultAndWarnOnUnknownCharsetWhenSettingRequestBody(String charse
containsString("Failed to set charset"));
}

@Test
void shouldWarnOnceOnSameUnknownCharsetWhenSettingRequestBody() throws Exception {
// Given
HttpMessage message = new HttpMessage();
message.setRequestHeader(
new HttpRequestHeader(
"GET / HTTP/1.1\r\nContent-Type: text/plain; charset=1st_unknown"));
withLoggerAppender();
// When
message.setRequestBody("Body");
message.setRequestBody("Body");
message.setRequestHeader(
new HttpRequestHeader(
"GET / HTTP/1.1\r\nContent-Type: text/plain; charset=2nd_unknown"));
message.setRequestBody("Body");
message.setRequestBody("Body");
// Then
assertThat(testAppender.getLogEvents(), hasSize(2));
assertThat(
testAppender.getLogEvents().get(0).getMessage(),
allOf(
containsString("Failed to set charset"),
containsString("charset=1st_unknown")));
assertThat(
testAppender.getLogEvents().get(1).getMessage(),
allOf(
containsString("Failed to set charset"),
containsString("charset=2nd_unknown")));
}

@Test
void shouldWarnOnceAgainOnSameUnknownCharsetWhenSettingRequestBodyAfterResettingWarns()
throws Exception {
// Given
HttpMessage message = new HttpMessage();
message.setRequestHeader(
new HttpRequestHeader(
"GET / HTTP/1.1\r\nContent-Type: text/plain; charset=unknown"));
withLoggerAppender();
// When
message.setRequestBody("Body");
message.setRequestBody("Body");
HttpMessage.resetWarnedContentTypeValues();
message.setRequestBody("Body");
message.setRequestBody("Body");
// Then
assertThat(testAppender.getLogEvents(), hasSize(2));
assertThat(
testAppender.getLogEvents().get(0).getMessage(),
allOf(containsString("Failed to set charset"), containsString("charset=unknown")));
assertThat(
testAppender.getLogEvents().get(1).getMessage(),
allOf(containsString("Failed to set charset"), containsString("charset=unknown")));
}

static Stream<Arguments> setBodyData() {
String iso8851 = StandardCharsets.ISO_8859_1.name();
String utf8 = StandardCharsets.UTF_8.name();
Expand Down Expand Up @@ -681,6 +738,61 @@ void shouldUseDefaultAndWarnOnUnknownCharsetWhenSettingResponseBody(String chars
containsString("Failed to set charset"));
}

@Test
void shouldWarnOnceOnSameUnknownCharsetWhenSettingResponseBody() throws Exception {
// Given
HttpMessage message = new HttpMessage();
message.setResponseHeader(
new HttpResponseHeader(
"HTTP/1.1 200 OK\r\nContent-Type: text/plain; charset=1st_unknown"));
withLoggerAppender();
// When
message.setResponseBody("Body");
message.setResponseBody("Body");
message.setResponseHeader(
new HttpResponseHeader(
"HTTP/1.1 200 OK\r\nContent-Type: text/plain; charset=2nd_unknown"));
message.setResponseBody("Body");
message.setResponseBody("Body");
// Then
assertThat(testAppender.getLogEvents(), hasSize(2));
assertThat(
testAppender.getLogEvents().get(0).getMessage(),
allOf(
containsString("Failed to set charset"),
containsString("charset=1st_unknown")));
assertThat(
testAppender.getLogEvents().get(1).getMessage(),
allOf(
containsString("Failed to set charset"),
containsString("charset=2nd_unknown")));
}

@Test
void shouldWarnOnceAgainOnSameUnknownCharsetWhenSettingResponseBodyAfterResettingWarns()
throws Exception {
// Given
HttpMessage message = new HttpMessage();
message.setResponseHeader(
new HttpResponseHeader(
"HTTP/1.1 200 OK\r\nContent-Type: text/plain; charset=unknown"));
withLoggerAppender();
// When
message.setResponseBody("Body");
message.setResponseBody("Body");
HttpMessage.resetWarnedContentTypeValues();
message.setResponseBody("Body");
message.setResponseBody("Body");
// Then
assertThat(testAppender.getLogEvents(), hasSize(2));
assertThat(
testAppender.getLogEvents().get(0).getMessage(),
allOf(containsString("Failed to set charset"), containsString("charset=unknown")));
assertThat(
testAppender.getLogEvents().get(1).getMessage(),
allOf(containsString("Failed to set charset"), containsString("charset=unknown")));
}

private static HttpMessage newHttpMessage() throws Exception {
HttpMessage message =
new HttpMessage(
Expand Down
Loading