diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar index 01e67997..bf82ff01 100644 Binary files a/.mvn/wrapper/maven-wrapper.jar and b/.mvn/wrapper/maven-wrapper.jar differ diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 71793467..6686a643 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1 +1,18 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.0/apache-maven-3.9.0-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/WebsocketRoutingFilter.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/WebsocketRoutingFilter.java index 50e27773..b5fd25ce 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/WebsocketRoutingFilter.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/WebsocketRoutingFilter.java @@ -32,6 +32,7 @@ import org.springframework.cloud.gateway.filter.headers.HttpHeadersFilter; import org.springframework.core.Ordered; import org.springframework.http.HttpHeaders; import org.springframework.util.StringUtils; +import org.springframework.web.reactive.socket.CloseStatus; import org.springframework.web.reactive.socket.WebSocketHandler; import org.springframework.web.reactive.socket.WebSocketMessage; import org.springframework.web.reactive.socket.WebSocketSession; @@ -201,12 +202,52 @@ public class WebsocketRoutingFilter implements GlobalFilter, Ordered { public Mono handle(WebSocketSession session) { // pass headers along so custom headers can be sent through return client.execute(url, this.headers, new WebSocketHandler() { + + private CloseStatus adaptCloseStatus(CloseStatus closeStatus) { + int code = closeStatus.getCode(); + if (code > 2999 && code < 5000) { + return closeStatus; + } + switch (code) { + case 1000: + case 1001: + case 1002: + case 1003: + case 1007: + case 1008: + case 1009: + case 1010: + case 1011: + return closeStatus; + case 1004: + // Should not be used in a close frame + // RESERVED; + case 1005: + // Should not be used in a close frame + // return CloseStatus.NO_STATUS_CODE; + case 1006: + // Should not be used in a close frame + // return CloseStatus.NO_CLOSE_FRAME; + case 1012: + // Not in RFC6455 + // return CloseStatus.SERVICE_RESTARTED; + case 1013: + // Not in RFC6455 + // return CloseStatus.SERVICE_OVERLOAD; + case 1015: + // Should not be used in a close frame + // return CloseStatus.TLS_HANDSHAKE_FAILURE; + default: + return CloseStatus.PROTOCOL_ERROR; + } + } + @Override public Mono handle(WebSocketSession proxySession) { Mono serverClose = proxySession.closeStatus().filter(__ -> session.isOpen()) - .flatMap(session::close); + .map(this::adaptCloseStatus).flatMap(session::close); Mono proxyClose = session.closeStatus().filter(__ -> proxySession.isOpen()) - .flatMap(proxySession::close); + .map(this::adaptCloseStatus).flatMap(proxySession::close); // Use retain() for Reactor Netty Mono proxySessionSend = proxySession .send(session.receive().doOnNext(WebSocketMessage::retain).doOnNext(webSocketMessage -> { diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/ipresolver/XForwardedRemoteAddressResolver.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/ipresolver/XForwardedRemoteAddressResolver.java index 5a816f21..f827f2c8 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/ipresolver/XForwardedRemoteAddressResolver.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/ipresolver/XForwardedRemoteAddressResolver.java @@ -125,11 +125,11 @@ public class XForwardedRemoteAddressResolver implements RemoteAddressResolver { log.warn("Multiple X-Forwarded-For headers found, discarding all"); return Collections.emptyList(); } - List values = Arrays.asList(xForwardedValues.get(0).split(", ")); - if (values.size() == 1 && !StringUtils.hasText(values.get(0))) { + String[] values = StringUtils.tokenizeToStringArray(xForwardedValues.get(0), ","); + if (values.length == 1 && !StringUtils.hasText(values[0])) { return Collections.emptyList(); } - return values; + return Arrays.asList(values); } } diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/handler/predicate/XForwardedRemoteAddrRoutePredicateFactoryTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/handler/predicate/XForwardedRemoteAddrRoutePredicateFactoryTests.java index 58c1b602..7f2c28c7 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/handler/predicate/XForwardedRemoteAddrRoutePredicateFactoryTests.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/handler/predicate/XForwardedRemoteAddrRoutePredicateFactoryTests.java @@ -56,7 +56,7 @@ public class XForwardedRemoteAddrRoutePredicateFactoryTests extends BaseWebClien @Test public void xForwardedRemoteAddrWorksUsingRightMostValueByDefault() { Mono result = webClient.get().uri("/xforwardfor") - .header("X-Forwarded-For", "99.99.99.99, 12.34.56.78").exchangeToMono(Mono::just); + .header("X-Forwarded-For", "99.99.99.99,12.34.56.78").exchangeToMono(Mono::just); StepVerifier.create(result).consumeNextWith(response -> assertStatus(response, HttpStatus.OK)).expectComplete() .verify(Duration.ofSeconds(20)); diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/support/ipresolver/XForwardedRemoteAddressResolverTest.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/support/ipresolver/XForwardedRemoteAddressResolverTest.java index 50e99c0d..8b3d41a9 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/support/ipresolver/XForwardedRemoteAddressResolverTest.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/support/ipresolver/XForwardedRemoteAddressResolverTest.java @@ -138,7 +138,7 @@ public class XForwardedRemoteAddressResolverTest { private MockServerHttpRequest.BaseBuilder oneTwoThreeBuilder() { return MockServerHttpRequest.get("someUrl").remoteAddress(remote0000Address).header("X-Forwarded-For", - "0.0.0.1, 0.0.0.2, 0.0.0.3"); + "0.0.0.1,0.0.0.2, 0.0.0.3"); } private ServerWebExchange buildExchange(MockServerHttpRequest.BaseBuilder requestBuilder) {