spring-cloud-gateway icon indicating copy to clipboard operation
spring-cloud-gateway copied to clipboard

Add a condition 'DoNotReplaceQueryParams' paramerter for ProxyExchangeHandlerFunction in GatewayMvc

Open sunhao1256 opened this issue 1 year ago • 0 comments

Is your feature request related to a problem? Please describe. In my scenario, my request uri is "http://fool?key1=value1@%26@&key2=value2" , it wiil proxy for another server. i use embed jetty, i will auto decode uri parameters to compose HttpServletRequest. so the parametersMap in HttpServletRequest becomes {key1=value1@&@,key2=value2} , that's not my aim. the character '@%26@' is special for another server , i don't want any change in query parameters until another server received.

ProxyExchangeHandlerFunction

the method Handle, will replaceQueryParams from uri parameters to serverRequest params .

	public ServerResponse handle(ServerRequest serverRequest) {
		URI uri = uriResolver.apply(serverRequest);
		boolean encoded = containsEncodedQuery(serverRequest.uri());
		// @formatter:off
		URI url = UriComponentsBuilder.fromUri(serverRequest.uri())
				.scheme(uri.getScheme())
				.host(uri.getHost())
				.port(uri.getPort())
                              // should not replace in every scenario
				.replaceQueryParams(serverRequest.params())
				.build(encoded)
				.toUri();
		// @formatter:on

		// TODO: Streams.collect()?
		HttpHeaders filteredRequestHeaders = filterHeaders(
				this.requestHttpHeadersFilters.orderedStream().map(Function.identity()),
				serverRequest.headers().asHttpHeaders(), serverRequest);

		boolean preserveHost = (boolean) serverRequest.attributes()
				.getOrDefault(MvcUtils.PRESERVE_HOST_HEADER_ATTRIBUTE, false);
		if (preserveHost) {
			filteredRequestHeaders.set(HttpHeaders.HOST, serverRequest.headers().firstHeader(HttpHeaders.HOST));
		}
		else {
			filteredRequestHeaders.remove(HttpHeaders.HOST);
		}

		// @formatter:off
		ProxyExchange.Request proxyRequest = proxyExchange.request(serverRequest).uri(url)
				.headers(filteredRequestHeaders)
				// TODO: allow injection of ResponseConsumer
				.responseConsumer((response, serverResponse) -> {
					HttpHeaders httpHeaders = filterHeaders(this.responseHttpHeadersFilters.orderedStream()
							.map(Function.identity()), response.getHeaders(), serverResponse);
					serverResponse.headers().putAll(httpHeaders);
				})
				.build();
		// @formatter:on
		return proxyExchange.exchange(proxyRequest);
	}

Describe the solution you'd like i don't want any change in query parameters until another server received.

Describe alternatives you've considered we could add a condition 'DoNotReplaceQueryParams' for ProxyExchangeHandlerFunction constructer parameter

Additional context None

sunhao1256 avatar Feb 01 '24 02:02 sunhao1256