Skip to content

Commit

Permalink
Adds RemoveContentLengthRequestHeadersFilter
Browse files Browse the repository at this point in the history
Removes workaround in RestClientProxyExchange and ClientHttpRequestFactoryProxyExchange

See gh-2949
  • Loading branch information
spencergibb committed Jul 12, 2023
1 parent b7d9662 commit 0655bdc
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.springframework.cloud.gateway.server.mvc.filter.ForwardedRequestHeadersFilter;
import org.springframework.cloud.gateway.server.mvc.filter.HttpHeadersFilter.RequestHttpHeadersFilter;
import org.springframework.cloud.gateway.server.mvc.filter.HttpHeadersFilter.ResponseHttpHeadersFilter;
import org.springframework.cloud.gateway.server.mvc.filter.RemoveContentLengthRequestHeadersFilter;
import org.springframework.cloud.gateway.server.mvc.filter.RemoveHopByHopRequestHeadersFilter;
import org.springframework.cloud.gateway.server.mvc.filter.RemoveHopByHopResponseHeadersFilter;
import org.springframework.cloud.gateway.server.mvc.filter.TransferEncodingNormalizationRequestHeadersFilter;
Expand Down Expand Up @@ -116,6 +117,12 @@ public ProxyExchangeHandlerFunction proxyExchangeHandlerFunction(ProxyExchange p
return new ProxyExchangeHandlerFunction(proxyExchange, requestHttpHeadersFilters, responseHttpHeadersFilters);
}

@Bean
@ConditionalOnMissingBean
public RemoveContentLengthRequestHeadersFilter removeContentLengthRequestHeadersFilter() {
return new RemoveContentLengthRequestHeadersFilter();
}

@Bean
@ConditionalOnMissingBean
public RemoveHopByHopRequestHeadersFilter removeHopByHopRequestHeadersFilter() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright 2013-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.cloud.gateway.server.mvc.filter;

import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.web.servlet.function.ServerRequest;

// jdk http clients seem to not like having this copied from the initial request.
// urlconnection fails with form url encoded
public class RemoveContentLengthRequestHeadersFilter implements HttpHeadersFilter.RequestHttpHeadersFilter, Ordered {

@Override
public int getOrder() {
return 1000;
}

@Override
public HttpHeaders apply(HttpHeaders input, ServerRequest request) {
if (input.containsKey(HttpHeaders.CONTENT_LENGTH)) {

HttpHeaders filtered = new HttpHeaders();
// avoids read only if input is read only
filtered.addAll(input);
filtered.remove(HttpHeaders.CONTENT_LENGTH);
return filtered;
}
return input;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ public ServerResponse exchange(Request request) {
try {
ClientHttpRequest clientHttpRequest = requestFactory.createRequest(request.getUri(), request.getMethod());
clientHttpRequest.getHeaders().putAll(request.getHeaders());
// TODO: why does this help form encoding?
clientHttpRequest.getHeaders().remove("content-length");
// copy body from request to clientHttpRequest
StreamUtils.copy(request.getServerRequest().servletRequest().getInputStream(), clientHttpRequest.getBody());
ClientHttpResponse clientHttpResponse = clientHttpRequest.execute();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,8 @@ public RestClientProxyExchange(RestClient restClient) {
@Override
public ServerResponse exchange(Request request) {
return restClient.method(request.getMethod()).uri(request.getUri())
.headers(httpHeaders -> request.getHeaders().forEach((header, values) -> {
// TODO: why does this help form encoding?
if (!header.equalsIgnoreCase("content-length")) {
httpHeaders.put(header, values);
}
})).body(outputStream -> copyBody(request, outputStream))
.headers(httpHeaders -> httpHeaders.putAll(request.getHeaders()))
.body(outputStream -> copyBody(request, outputStream))
.exchange((clientRequest, clientResponse) -> doExchange(request, clientResponse), false);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,16 @@
import static org.springframework.web.servlet.function.RequestPredicates.path;

@SuppressWarnings("unchecked")
@SpringBootTest(properties = {}, webEnvironment = WebEnvironment.RANDOM_PORT)
@SpringBootTest(properties = { "spring.cloud.gateway.mvc.http-client.type=jdk" },
webEnvironment = WebEnvironment.RANDOM_PORT)
@ContextConfiguration(initializers = HttpbinTestcontainers.class)
public class ServerMvcIntegrationTests {

static {
// if set type to autodetect above
System.setProperty("sun.net.http.allowRestrictedHeaders", "true");
}

@LocalServerPort
int port;

Expand Down

0 comments on commit 0655bdc

Please sign in to comment.