Proxy 防波堤腹板箱代理

Proxy 防波堤腹板箱代理,proxy,websocket,jetty,Proxy,Websocket,Jetty,只是想知道是否有人尝试过使用嵌入式Jetty进行WebSocket代理(用于透明代理) 在使用Jetty 9.1.2.v20140210大约一天半之后,我能说的就是它不能以当前的形式代理WebSocket,添加这样的支持是一项非常重要的任务(至少是afaict) 基本上,Jetty ProxyServlet去掉了“升级”和“连接”头字段,而不管它是否来自WebSocket握手请求。如下所示,添加这些字段很容易。但是,当代理服务器返回带有HTTP代码101(交换协议)的响应时,代理服务器上不进行协

只是想知道是否有人尝试过使用嵌入式Jetty进行WebSocket代理(用于透明代理)

在使用Jetty 9.1.2.v20140210大约一天半之后,我能说的就是它不能以当前的形式代理WebSocket,添加这样的支持是一项非常重要的任务(至少是afaict)

基本上,Jetty ProxyServlet去掉了“升级”和“连接”头字段,而不管它是否来自WebSocket握手请求。如下所示,添加这些字段很容易。但是,当代理服务器返回带有HTTP代码101(交换协议)的响应时,代理服务器上不进行协议升级。因此,当第一个WebSocket数据包到达时,HttpParser会阻塞,并将其视为错误的HTTP请求

如果有人已经有了解决方案,或者熟悉Jetty,建议尝试什么,我们将不胜感激

下面是我实验中去掉不重要部分的代码:

public class ProxyServer
{
    public static void main(String[] args) throws Exception
    {
        Server server = new Server();
        ServerConnector connector = new ServerConnector(server);
        connector.setPort(8888);
        server.addConnector(connector);

        // Setup proxy handler to handle CONNECT methods
        ConnectHandler proxy = new ConnectHandler();
        server.setHandler(proxy);

        // Setup proxy servlet
        ServletContextHandler context = new ServletContextHandler(proxy, "/", ServletContextHandler.SESSIONS);
        ServletHolder proxyServlet = new ServletHolder(MyProxyServlet.class);
        context.addServlet(proxyServlet, "/*");

        server.start();
    }
}

@SuppressWarnings("serial")
public class MyProxyServlet extends ProxyServlet
{
    @Override
    protected void customizeProxyRequest(Request proxyRequest, HttpServletRequest request)
    {
        // Pass through the upgrade and connection header fields for websocket handshake request. 
        String upgradeValue = request.getHeader("Upgrade");
        if (upgradeValue != null && upgradeValue.compareToIgnoreCase("websocket") == 0)
        {
            setHeader(proxyRequest, "Upgrade", upgradeValue);
            setHeader(proxyRequest, "Connection", request.getHeader("Connection"));
        }
    }

    @Override
    protected void onResponseHeaders(HttpServletRequest request, HttpServletResponse response, Response proxyResponse)
    {
        super.onResponseHeaders(request, response, proxyResponse);

        // Restore the upgrade and connection header fields for websocket handshake request.
        HttpFields fields = proxyResponse.getHeaders();
        for (HttpField field : fields)
        {
            if (field.getName().compareToIgnoreCase("Upgrade") == 0)
            {
                String upgradeValue = field.getValue();
                if (upgradeValue != null && upgradeValue.compareToIgnoreCase("websocket") == 0)
                {
                    response.setHeader(field.getName(), upgradeValue);
                    for (HttpField searchField : fields)
                    {
                        if (searchField.getName().compareToIgnoreCase("Connection") == 0) {
                            response.setHeader(searchField.getName(), searchField.getValue());
                        }
                    }
                }
            }
        }
    }
}

让我们想象一下您试图构建的代理方案,我们有客户端A、服务器B和代理p。现在,让我们了解连接工作流: 1. A与代理建立TCP连接P(A-P) 2. A通过WebSocket握手发送连接地址(B)请求

这里有第一个问题,WS-handshake中使用的by头不是端到端头,因为对于HTTP来说,它们只在传输层(两个跃点之间)上有意义

  • P建立到B的TCP连接(P-B)
  • P将WS-handshake HTTP请求发送到B
  • B以HTTP->WS-upgrade响应(发送101)
  • 还有一个问题,在发送HTTP 101之后,服务器B和客户端A现在将只通过TCP进行通信,但jetty servlet不支持普通TCP数据包传播。换句话说,jetty代理servlet等待客户机A开始传输HTTP请求,这在A接收HTTP 101之后永远不会发生


    您需要使用WS-server和WS-client自己实现这一点

    我已经在嵌入式tomcat上试用过了,它正在工作。我在我的项目中使用了它。