Exclude query from URI in WebClient checkpoints

See gh-31992
This commit is contained in:
Aaron Rosser 2024-01-09 23:35:54 +00:00 committed by rstoyanchev
parent 79cc0ec4aa
commit 1e49334209
3 changed files with 55 additions and 16 deletions

View File

@ -195,6 +195,18 @@ final class DefaultWebClient implements WebClient {
return response.releaseBody().onErrorComplete().then(Mono.error(ex));
}
private static URI getUriToLog(URI uri) {
if (StringUtils.hasText(uri.getQuery())) {
try {
uri = new URI(uri.getScheme(), null, uri.getHost(), uri.getPort(), uri.getPath(), null, null);
}
catch (URISyntaxException ex) {
// ignore
}
}
return uri;
}
private class DefaultRequestBodyUriSpec implements RequestBodyUriSpec {
@ -457,7 +469,7 @@ final class DefaultWebClient implements WebClient {
observationContext.setRequest(request);
Mono<ClientResponse> responseMono = filterFunction.apply(exchangeFunction)
.exchange(request)
.checkpoint("Request to " + this.httpMethod.name() + " " + this.uri + " [DefaultWebClient]")
.checkpoint("Request to " + this.httpMethod.name() + " " + getUriToLog(request.url()) + " [DefaultWebClient]")
.switchIfEmpty(NO_HTTP_CLIENT_RESPONSE_ERROR);
if (this.contextModifier != null) {
responseMono = responseMono.contextWrite(this.contextModifier);
@ -698,18 +710,6 @@ final class DefaultWebClient implements WebClient {
return null;
}
private static URI getUriToLog(URI uri) {
if (StringUtils.hasText(uri.getQuery())) {
try {
uri = new URI(uri.getScheme(), null, uri.getHost(), uri.getPort(), uri.getPath(), null, null);
}
catch (URISyntaxException ex) {
// ignore
}
}
return uri;
}
private static class StatusHandler {

View File

@ -16,6 +16,8 @@
package org.springframework.web.reactive.function.client;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.List;
@ -30,6 +32,7 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Exceptions that contain actual HTTP response data.
@ -99,7 +102,19 @@ public class WebClientResponseException extends WebClientException {
private static String initMessage(HttpStatusCode status, String reasonPhrase, @Nullable HttpRequest request) {
return status.value() + " " + reasonPhrase +
(request != null ? " from " + request.getMethod() + " " + request.getURI() : "");
(request != null ? " from " + request.getMethod() + " " + getUriToLog(request.getURI()) : "");
}
private static URI getUriToLog(URI uri) {
if (StringUtils.hasText(uri.getQuery())) {
try {
uri = new URI(uri.getScheme(), null, uri.getHost(), uri.getPort(), uri.getPath(), null, null);
}
catch (URISyntaxException ex) {
// ignore
}
}
return uri;
}
/**

View File

@ -17,6 +17,7 @@
package org.springframework.web.reactive.function.client;
import java.net.InetSocketAddress;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
@ -34,7 +35,9 @@ import org.springframework.core.codec.StringDecoder;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpRange;
import org.springframework.http.HttpRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.MediaType;
@ -43,6 +46,7 @@ import org.springframework.http.ResponseEntity;
import org.springframework.http.client.reactive.ClientHttpResponse;
import org.springframework.http.codec.DecoderHttpMessageReader;
import org.springframework.http.codec.json.Jackson2JsonDecoder;
import org.springframework.lang.Nullable;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
@ -67,13 +71,16 @@ class DefaultClientResponseTests {
private final ExchangeStrategies mockExchangeStrategies = mock();
@Nullable
private HttpRequest httpRequest = null;
private DefaultClientResponse defaultClientResponse;
@BeforeEach
void configureMocks() {
given(mockResponse.getHeaders()).willReturn(this.httpHeaders);
defaultClientResponse = new DefaultClientResponse(mockResponse, mockExchangeStrategies, "", "", () -> null);
defaultClientResponse = new DefaultClientResponse(mockResponse, mockExchangeStrategies, "", "", () -> httpRequest);
}
@ -302,13 +309,30 @@ class DefaultClientResponseTests {
given(mockResponse.getStatusCode()).willReturn(HttpStatus.NOT_FOUND);
given(mockResponse.getBody()).willReturn(Flux.just(dataBuffer));
httpRequest = new HttpRequest() {
@Override
public HttpMethod getMethod() {
return HttpMethod.valueOf("UNKNOWN");
}
@Override
public URI getURI() {
return URI.create("https://user:pass@example.org:9999/app/path?token=secret#fragment");
}
@Override
public HttpHeaders getHeaders() {
return HttpHeaders.EMPTY;
}
};
given(mockExchangeStrategies.messageReaders()).willReturn(
List.of(new DecoderHttpMessageReader<>(new ByteArrayDecoder())));
Mono<WebClientResponseException> resultMono = defaultClientResponse.createException();
WebClientResponseException exception = resultMono.block();
assertThat(exception.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
assertThat(exception.getMessage()).isEqualTo("404 Not Found");
assertThat(exception.getMessage()).isEqualTo("404 Not Found from UNKNOWN https://example.org:9999/app/path");
assertThat(exception.getHeaders()).containsExactly(entry("Content-Type", List.of("text/plain")));
assertThat(exception.getResponseBodyAsByteArray()).isEqualTo(bytes);
}