Affects: \5.3.3


In spring, one can add an undertow websocket extension by:  

@Bean
    public WebServerFactoryCustomizer<UndertowServletWebServerFactory> deploymentCustomizer() {
        return factory -> {
            UndertowDeploymentInfoCustomizer customizer = deploymentInfo -> {

                WebSocketDeploymentInfo webSocketDeploymentInfo = new WebSocketDeploymentInfo();
                webSocketDeploymentInfo.addExtension(new PerMessageDeflateHandshake());
                deploymentInfo.addServletContextAttribute(WebSocketDeploymentInfo.ATTRIBUTE_NAME, webSocketDeploymentInfo);
            };
            factory.addDeploymentInfoCustomizers(customizer); 
        };
    }

But that extension does not work when processing requests. I have found that spring wraps extensions in org.springframework.web.socket.server.standard.AbstractStandardUpgradeStrategy.getInstalledExtensions(...)

protected List<WebSocketExtension> getInstalledExtensions(WebSocketContainer container) {
        List<WebSocketExtension> result = new ArrayList<>();
        for (Extension extension : container.getInstalledExtensions()) {
            result.add(new StandardToWebSocketExtensionAdapter(extension));
        }
        return result;
    }

which breaks the extension matching in 

org.springframework.web.socket.server.support.filterRequestedExtensions(...)

protected List<WebSocketExtension> filterRequestedExtensions(ServerHttpRequest request,
            List<WebSocketExtension> requestedExtensions, List<WebSocketExtension> supportedExtensions) {

        List<WebSocketExtension> result = new ArrayList<>(requestedExtensions.size());
        for (WebSocketExtension extension : requestedExtensions) {
            if (supportedExtensions.contains(extension)) {
                result.add(extension);
            }
        }
        return result;
    }

I have been unable to find a workaround for this, and I am not sure what an appropriate fix would be.

Comment From: rstoyanchev

How does it break? Does it not find the installed extensions or something in the equals() of the wrapper?

Comment From: piotrblasiak

@rstoyanchev it finds the installed extension but it wraps it in a StandardToWebSocketExtensionAdapter, which makes the filterRequestedExtensions method not include it in the final list of extensions to apply to the request. I am thinking perhaps it should not be wrapped or the filterRequestedExtensions could be changed to filter by name and not Collection.contains().

Comment From: rstoyanchev

Okay so WebSocketExtension has an equals method but the getClass() check would fail to match, WebSocketExtension for the requested vs StandardToWebSocketExtensionAdapter for the installed.

Comment From: rstoyanchev

I'll add a fix. A workaround could be to override getInstalledExtensions and return WebSocketExtension instances and plug the RequestUpgradeStrategy into the DefaultHandshakeHandler.

Comment From: rstoyanchev

@piotrblasiak I've committed a fix if you'd like to check it with a 5.3.4-SNAPSHOT in your codebase.

Comment From: piotrblasiak

@rstoyanchev I can confirm it has been fixed and it is now working as expected. Thank you!

Comment From: rstoyanchev

Great, thanks for testing it! I will now backport it to 5.2.x.