Skip to content

Commit 7a2381d

Browse files
fix: propagate WS subprotocols from sec-websocket-protocol header for V4 APIs
1 parent f6d484d commit 7a2381d

File tree

2 files changed

+29
-3
lines changed

2 files changed

+29
-3
lines changed

gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/src/main/java/io/gravitee/plugin/endpoint/http/proxy/connector/HttpConnector.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@ public class HttpConnector implements ProxyConnector {
8282
UPGRADE
8383
);
8484
private final String relativeTarget;
85-
private final String defaultHost;
86-
private final int defaultPort;
85+
protected final String defaultHost;
86+
protected final int defaultPort;
8787
private final boolean defaultSsl;
8888
private final MultiValueMap<String, String> targetParameters;
8989
protected final HttpProxyEndpointConnectorConfiguration configuration;

gravitee-apim-plugin/gravitee-apim-plugin-endpoint/gravitee-apim-plugin-endpoint-http-proxy/src/main/java/io/gravitee/plugin/endpoint/http/proxy/connector/WebSocketConnector.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,16 @@
3232
import io.gravitee.plugin.endpoint.http.proxy.client.HttpClientFactory;
3333
import io.gravitee.plugin.endpoint.http.proxy.configuration.HttpProxyEndpointConnectorConfiguration;
3434
import io.gravitee.plugin.endpoint.http.proxy.configuration.HttpProxyEndpointConnectorSharedConfiguration;
35+
import io.netty.handler.codec.http.HttpHeaderNames;
3536
import io.reactivex.rxjava3.core.Completable;
3637
import io.vertx.core.http.RequestOptions;
3738
import io.vertx.core.http.UpgradeRejectedException;
3839
import io.vertx.core.http.WebSocketConnectOptions;
3940
import io.vertx.rxjava3.core.http.ServerWebSocket;
41+
import java.util.Arrays;
42+
import java.util.List;
4043
import java.util.Set;
44+
import java.util.stream.Collectors;
4145

4246
/**
4347
* @author Guillaume LAMIRAND (guillaume.lamirand at graviteesource.com)
@@ -67,8 +71,14 @@ public Completable connect(final HttpExecutionContext ctx) {
6771
ObservableHttpClientRequest observableHttpClientRequest = new ObservableHttpClientRequest(options);
6872
Span httpRequestSpan = ctx.getTracer().startSpanFrom(observableHttpClientRequest);
6973

70-
ctx.metrics().setEndpoint(options.getURI());
74+
ctx.metrics().setEndpoint(buildWebSocketUri(options));
7175
WebSocketConnectOptions webSocketConnectOptions = new WebSocketConnectOptions(options.toJson());
76+
77+
// Add subprotocols: handle comma-separated values, trim whitespace, filter empty strings
78+
if (request.headers().contains(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL)) {
79+
webSocketConnectOptions.setSubProtocols(parseSubProtocols(request));
80+
}
81+
7282
return httpClientFactory
7383
.getOrBuildHttpClient(ctx, configuration, sharedConfiguration)
7484
.rxWebSocket(webSocketConnectOptions)
@@ -133,4 +143,20 @@ public Completable connect(final HttpExecutionContext ctx) {
133143
protected Set<CharSequence> hopHeaders() {
134144
return HOP_HEADERS;
135145
}
146+
147+
private String buildWebSocketUri(RequestOptions options) {
148+
String protocol = options.isSsl() ? "wss" : "ws";
149+
return protocol + "://" + defaultHost + ":" + defaultPort + options.getURI();
150+
}
151+
152+
private List<String> parseSubProtocols(HttpRequest request) {
153+
return request
154+
.headers()
155+
.getAll(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL)
156+
.stream()
157+
.flatMap(header -> Arrays.stream(header.split(",")))
158+
.map(String::trim)
159+
.filter(s -> !s.isEmpty())
160+
.collect(Collectors.toList());
161+
}
136162
}

0 commit comments

Comments
 (0)