fix double encoding websocket upgrade url (#1731)

This commit is contained in:
Nikita Konev
2020-07-28 20:18:33 +03:00
committed by GitHub
parent 93a87dc507
commit 9ddfb8b703
2 changed files with 27 additions and 2 deletions

View File

@@ -41,12 +41,14 @@ import org.springframework.web.util.UriComponentsBuilder;
import static org.springframework.cloud.gateway.filter.headers.HttpHeadersFilter.filterRequest;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.containsEncodedParts;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.isAlreadyRouted;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.setAlreadyRouted;
import static org.springframework.util.StringUtils.commaDelimitedListToStringArray;
/**
* @author Spencer Gibb
* @author Nikita Konev
*/
public class WebsocketRoutingFilter implements GlobalFilter, Ordered {
@@ -132,7 +134,7 @@ public class WebsocketRoutingFilter implements GlobalFilter, Ordered {
return this.headersFilters;
}
private void changeSchemeIfIsWebSocketUpgrade(ServerWebExchange exchange) {
static void changeSchemeIfIsWebSocketUpgrade(ServerWebExchange exchange) {
// Check the Upgrade
URI requestUrl = exchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR);
String scheme = requestUrl.getScheme().toLowerCase();
@@ -141,8 +143,9 @@ public class WebsocketRoutingFilter implements GlobalFilter, Ordered {
if ("WebSocket".equalsIgnoreCase(upgrade)
&& ("http".equals(scheme) || "https".equals(scheme))) {
String wsScheme = convertHttpToWs(scheme);
boolean encoded = containsEncodedParts(requestUrl);
URI wsRequestUrl = UriComponentsBuilder.fromUri(requestUrl).scheme(wsScheme)
.build().toUri();
.build(encoded).toUri();
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, wsRequestUrl);
if (log.isTraceEnabled()) {
log.trace("changeSchemeTo:[" + wsRequestUrl + "]");

View File

@@ -16,10 +16,19 @@
package org.springframework.cloud.gateway.filter;
import java.net.URI;
import org.junit.Test;
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
import org.springframework.mock.web.server.MockServerWebExchange;
import org.springframework.web.server.ServerWebExchange;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.cloud.gateway.filter.WebsocketRoutingFilter.changeSchemeIfIsWebSocketUpgrade;
import static org.springframework.cloud.gateway.filter.WebsocketRoutingFilter.convertHttpToWs;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
import static org.springframework.http.HttpHeaders.UPGRADE;
public class WebsocketRoutingFilterTests {
@@ -32,4 +41,17 @@ public class WebsocketRoutingFilterTests {
assertThat(convertHttpToWs("tcp")).isEqualTo("tcp");
}
@Test
public void testEncodedUrl() {
MockServerHttpRequest request = MockServerHttpRequest
.get("http://not-matters-that").header(UPGRADE, "WebSocket").build();
ServerWebExchange exchange = MockServerWebExchange.from(request);
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR,
URI.create("http://microservice/my-service/websocket%20upgrade"));
changeSchemeIfIsWebSocketUpgrade(exchange);
URI wsRequestUrl = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);
assertThat(wsRequestUrl).isEqualTo(
URI.create("ws://microservice/my-service/websocket%20upgrade"));
}
}