Skip to content
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,11 @@
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.util.Assert;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.util.ContentCachingRequestWrapper;
import org.springframework.web.util.UriComponentsBuilder;
import org.springframework.web.util.WebUtils;

/**
Expand Down Expand Up @@ -99,6 +102,8 @@ public abstract class AbstractRequestLoggingFilter extends OncePerRequestFilter

private boolean includePayload = false;

private @Nullable Predicate<String> queryParamPredicate;

private @Nullable Predicate<String> headerPredicate;

private int maxPayloadLength = DEFAULT_MAX_PAYLOAD_LENGTH;
Expand Down Expand Up @@ -182,6 +187,30 @@ protected boolean isIncludePayload() {
return this.includePayload;
}

/**
* Configure a predicate for selecting which query params should be logged if
* {@link #setIncludeQueryString(boolean)} is set to {@code true}.
* <p>By default this is not set in which case all query params are logged
*
* <p>If there are multiple values for the same query param,
* the predicate will be applied once per query param name.
* As a result, the use of this predicate may result in a different query string
* than the one returned by {@link HttpServletRequest#getQueryString()}.
* @param queryParamPredicate the predicate to use
* @since 7.0
*/
public void setQueryParamPredicate(@Nullable Predicate<String> queryParamPredicate) {
this.queryParamPredicate = queryParamPredicate;
}

/**
* The configured {@link #setQueryParamPredicate(Predicate) queryParamPredicate}.
* @since 7.0
*/
protected @Nullable Predicate<String> getQueryParamPredicate() {
return this.queryParamPredicate;
}

/**
* Configure a predicate for selecting which headers should be logged if
* {@link #setIncludeHeaders(boolean)} is set to {@code true}.
Expand Down Expand Up @@ -326,6 +355,24 @@ protected String createMessage(HttpServletRequest request, String prefix, String
if (isIncludeQueryString()) {
String queryString = request.getQueryString();
if (queryString != null) {
if (getQueryParamPredicate() != null) {
MultiValueMap<String, String> queryParams = UriComponentsBuilder.fromUriString("?" + queryString)
.build()
.getQueryParams();

MultiValueMap<String, String> updatedQueryParams = new LinkedMultiValueMap<>(queryParams);
for (String name : queryParams.keySet()) {
if (!getQueryParamPredicate().test(name)) {
updatedQueryParams.set(name, "masked");
break;
}
}

queryString = UriComponentsBuilder.newInstance()
.queryParams(updatedQueryParams)
.build()
.getQuery();
}
msg.append('?').append(queryString);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,14 @@ void uri() throws Exception {

@Test
void queryStringIncluded() throws Exception {
request.setQueryString("booking=42");
request.setQueryString("booking=42&code=73&category=hotel&code=37&category=resort");
filter.setIncludeQueryString(true);
filter.setQueryParamPredicate(name -> !name.equals("code") && !name.equals("ignore"));

applyFilter();

assertThat(filter.beforeRequestMessage).contains("/hotels?booking=42");
assertThat(filter.afterRequestMessage).contains("/hotels?booking=42");
assertThat(filter.beforeRequestMessage).contains("/hotels?booking=42&code=masked&category=hotel&category=resort");
assertThat(filter.afterRequestMessage).contains("/hotels?booking=42&code=masked&category=hotel&category=resort");
}

@Test
Expand Down