Proxy websocket wss:// to ws:// spring cloud gateway
500 Server Error for HTTP GET "/stomp" I have an instance of Unsecured ActiveMQ-5.16.0 and I want to route secured websocket to ActiveMQ using Spring Cloud Gateway. I have tried the solution using the documentation from Spring Cloud and I get the following issue:
500 Server Error for HTTP GET "/stomp".
Any idea why I am getting java.lang.ClassCastException
Route builder config code snippet
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class BeanConfig {
@Bean
public RouteLocator gatewayRoutes(RouteLocatorBuilder builder) {
return builder.routes()
.route(r -> r.path("/stomp/**")
.filters(f -> f
.rewritePath("/stomp/?(?<segment>.*)", "/$\\{segment}")
.addRequestHeader("Sec-WebSocket-Protocol", "v10.stomp, v11.stomp")
)
.uri("ws://localhost:61614"))
.build();
}
}
Stacktrace:
2021-11-03 07:08:27.245 ERROR 5200 --- [io-8443-exec-10] a.w.r.e.AbstractErrorWebExceptionHandler : [d9a04a] 500 Server Error for HTTP GET "/stomp"
java.lang.ClassCastException: org.apache.catalina.connector.ResponseFacade cannot be cast to reactor.netty.http.server.HttpServerResponse
at org.springframework.web.reactive.socket.server.upgrade.ReactorNettyRequestUpgradeStrategy.getNativeResponse(ReactorNettyRequestUpgradeStrategy.java:93) ~[spring-webflux-5.2.3.RELEASE.jar:5.2.3.RELEASE]
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
|_ checkpoint ? org.springframework.cloud.gateway.filter.WeightCalculatorWebFilter [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.security.web.server.authorization.AuthorizationWebFilter [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.security.web.server.authorization.ExceptionTranslationWebFilter [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.security.web.server.authentication.logout.LogoutWebFilter [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.security.web.server.savedrequest.ServerRequestCacheWebFilter [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.security.web.server.context.SecurityContextServerWebExchangeWebFilter [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.security.web.server.ui.LogoutPageGeneratingWebFilter [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.security.web.server.ui.LoginPageGeneratingWebFilter [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.security.web.server.authentication.AuthenticationWebFilter [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.security.web.server.authentication.AuthenticationWebFilter [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.security.web.server.context.ReactorContextWebFilter [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.security.web.server.csrf.CsrfWebFilter [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.security.web.server.header.HttpHeaderWriterWebFilter [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.security.config.web.server.ServerHttpSecurity$ServerWebExchangeReactorContextWebFilter [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.security.web.server.WebFilterChainProxy [DefaultWebFilterChain]
|_ checkpoint ? org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter [DefaultWebFilterChain]
|_ checkpoint ? HTTP GET "/stomp" [ExceptionHandlingWebHandler]
Stack trace:
at org.springframework.web.reactive.socket.server.upgrade.ReactorNettyRequestUpgradeStrategy.getNativeResponse(ReactorNettyRequestUpgradeStrategy.java:93) ~[spring-webflux-5.2.3.RELEASE.jar:5.2.3.RELEASE]
at org.springframework.web.reactive.socket.server.upgrade.ReactorNettyRequestUpgradeStrategy.upgrade(ReactorNettyRequestUpgradeStrategy.java:77) ~[spring-webflux-5.2.3.RELEASE.jar:5.2.3.RELEASE]
at org.springframework.web.reactive.socket.server.support.HandshakeWebSocketService.lambda$handleRequest$1(HandshakeWebSocketService.java:235) ~[spring-webflux-5.2.3.RELEASE.jar:5.2.3.RELEASE]
at reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:151) ~[reactor-core-3.3.2.RELEASE.jar:3.3.2.RELEASE]
at reactor.core.publisher.MonoFlatMap.subscribeOrReturn(MonoFlatMap.java:53) ~[reactor-core-3.3.2.RELEASE.jar:3.3.2.RELEASE]
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:48) ~[reactor-core-3.3.2.RELEASE.jar:3.3.2.RELEASE]
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) ~[reactor-core-3.3.2.RELEASE.jar:3.3.2.RELEASE]
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) ~[reactor-core-3.3.2.RELEASE.jar:3.3.2.RELEASE]
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) ~[reactor-core-3.3.2.RELEASE.jar:3.3.2.RELEASE]
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) ~[reactor-core-3.3.2.RELEASE.jar:3.3.2.RELEASE]
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) ~[reactor-core-3.3.2.RELEASE.jar:3.3.2.RELEASE]
Can you describe your setup more? Where does org.apache.catalina.connector.ResponseFacade come from?
@spencergibb the org.apache.catalina.connector.ResponseFacade is coming from Active MQ 5.16.0 and I tried even using a simple java websocket server custom app, the outcome is the same.
I am using Active MQ 5.16.0 standalone server for my web socket [ws://localhost:61614/stomp/queue/test]. I used the sample provided by Active MQ stomp example.
I use spring-cloud-gateway to proxy the unsecured Active MQ standalone behind the secured gateway. I then route the wss:// to ws:// using spring cloud.
I have a simple HTTPS client running on https://localhost:8443/index.html which try to connect to Active MQ ws://localhost:61614/stomp/queue/test through the proxy at wss://localhost:8443/
I have created a repo of this sample code: https://github.com/intumba/spring-cloud-gateway and I got this sample code from the github repos.
Hope this describes my use case.
I am facing the exact same issue.
Sorry for the late reply. If this still happens with Spring Boot 3.2 and Cloud 2023.0 we can reopen and assess.