Spring Boot 如何在Sping Boot 中禁用Tomcat的permessage-deflate WebSocket压缩?

s71maibg  于 2023-10-16  发布在  Spring
关注(0)|答案(2)|浏览(155)

我有一个Sping Boot 服务器,我希望能够与无法或不愿意处理 permessage-deflate 压缩消息的WebSocket客户端进行通信。我从这两个类似的问题(下面的链接)中知道,我可以添加VM参数-Dorg.apache.tomcat.websocket.DISABLE_BUILTIN_EXTENSIONS=true来禁用Tomcat的默认deflate压缩。

然而,我计划做一个程序,它将被分发,以便其他人可以运行它,并且不得不强迫人们记住总是包括一个特定的VM参数,只是为了改变一个设置,这似乎是相当粗糙的。
有没有其他方法可以禁用Tomcat的WebSocket压缩,而不需要用户在运行时指定VM参数,也许可以使用Spring的Java配置或自定义WebSocket握手拦截器?

lf5gs5x2

lf5gs5x21#

您不仅可以使用JVM参数设置属性,还可以使用System.setProperty以编程方式设置属性,如下所示:

System.setProperty("org.apache.tomcat.websocket.DISABLE_BUILTIN_EXTENSIONS",String.valueOf(true));

如果您使用嵌入式tomcat将项目导出为JAR文件,则可以在执行SpringApplication.run之前在main中运行它:

public static void main(String[] args) {
    System.setProperty("org.apache.tomcat.websocket.DISABLE_BUILTIN_EXTENSIONS",String.valueOf(true));
    SpringApplication.run(YourApplicationClass.class,args);
}

如果您将应用程序打包到WAR文件中,您可以尝试以下操作:

@SpringBootApplication
public class YourApplicationClass extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        System.setProperty("org.apache.tomcat.websocket.DISABLE_BUILTIN_EXTENSIONS",String.valueOf(true));
        return application.sources(YourApplicationClass.class);
    } 
}
gudnpqoy

gudnpqoy2#

在Tomcat 10.1中,DISABLE_BUILTIN_EXTENSIONS选项是removed,因此dan1st的答案不再有效。
我设法通过使用过滤器从请求头中删除permessage-deflate来禁用压缩:

@Component
public class WebSocketHeaderFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;

        HttpServletRequest req = new HttpServletRequestWrapper((HttpServletRequest) request) {
            @Override
            public String getHeader(String name) {
                if ("Sec-WebSocket-Extensions".equalsIgnoreCase(name)) {
                    return "";
                }
                return super.getHeader(name);
            }

            @Override
            public Enumeration<String> getHeaders(String name) {

                if ("Sec-WebSocket-Extensions".equalsIgnoreCase(name)) {
                    return Collections.enumeration(Collections.emptyList());
                }
                return super.getHeaders(name);
            }
        };

        chain.doFilter(req, httpResponse);
    
    }
}

在我的例子中,简单地清除头的值就足够了。但由于客户端可能会请求其他WebSocket扩展,因此最好从头文件中删除permessage-deflate

相关问题