--- java/org/apache/tomcat/websocket/WsWebSocketContainer.java (revision 1485094) +++ java/org/apache/tomcat/websocket/WsWebSocketContainer.java (working copy) @@ -249,31 +249,43 @@ sm.getString("wsWebSocketContainer.pathNoHost")); } int port = path.getPort(); + if ("ws".equalsIgnoreCase(scheme)){ + if (port == -1) port = 80; + } else if ("wss".equalsIgnoreCase(scheme)){ + secure = true; + if (port == -1) port = 443; + } else{ + //we shouldn't be here as the scheme is already checked above + throw new DeploymentException( + sm.getString("wsWebSocketContainer.invalidScheme")); + } Map> reqHeaders = createRequestHeaders(host, port, clientEndpointConfiguration.getPreferredSubprotocols()); clientEndpointConfiguration.getConfigurator(). beforeRequest(reqHeaders); - + + //construct initial HTTP GET request ByteBuffer request = createRequest(path, reqHeaders); - - SocketAddress sa; - if (port == -1) { - if ("ws".equalsIgnoreCase(scheme)) { - sa = new InetSocketAddress(host, 80); - } else if ("wss".equalsIgnoreCase(scheme)) { - sa = new InetSocketAddress(host, 443); - secure = true; - } else { - throw new DeploymentException( - sm.getString("wsWebSocketContainer.invalidScheme")); - } - } else { - if ("wss".equalsIgnoreCase(scheme)) { - secure = true; - } - sa = new InetSocketAddress(host, port); + ByteBuffer proxyConnectRequest = null; + + boolean proxyIsSet = false; + if (System.getProperty("https.proxyHost")!=null && secure){ + proxyConnectRequest = createProxyConnect(host, port); + host = System.getProperty("https.proxyHost"); + port = Integer.valueOf(System.getProperty("https.proxyPort")); + proxyIsSet = true; } + if (System.getProperty("http.proxyHost")!=null && !secure){ + proxyConnectRequest = createProxyConnect(host, port); + host = System.getProperty("https.proxyHost"); + port = Integer.valueOf(System.getProperty("https.proxyPort")); + proxyIsSet = true; + } + + SocketAddress sa = new InetSocketAddress(host, port); + + AsynchronousSocketChannel socketChannel; try { socketChannel = @@ -283,8 +295,31 @@ "wsWebSocketContainer.asynchronousSocketChannelFail"), ioe); } + Future fConnect = socketChannel.connect(sa); - + try { + fConnect.get(); + + //if we are behind the proxy lets't do initial CONNECT + if (proxyIsSet && proxyConnectRequest != null){ + while (proxyConnectRequest.hasRemaining()){ + Futurefwrite = socketChannel.write(proxyConnectRequest); + fwrite.get(); + proxyConnectRequest.compact(); + proxyConnectRequest.flip(); + } + //let's read the response + proxyConnectRequest.clear(); + socketChannel.read(proxyConnectRequest).get(); + proxyConnectRequest.flip(); + byte[] res = new byte[proxyConnectRequest.limit()]; + proxyConnectRequest.get(res); + } + } catch (InterruptedException | ExecutionException e) { + throw new DeploymentException( + sm.getString("wsWebSocketContainer.httpRequestFailed"), e); + } + AsyncChannelWrapper channel; if (secure) { SSLEngine sslEngine = createSSLEngine( @@ -297,8 +332,6 @@ ByteBuffer response; String subProtocol; try { - fConnect.get(); - Future fHandshake = channel.handshake(); fHandshake.get(); @@ -360,7 +393,24 @@ } - protected void registerSession(Class endpoint, WsSession wsSession) { + private ByteBuffer createProxyConnect(String host, int port) { + //behind the proxy ('should send CONNECT request') + + ByteBuffer proxyRequest = ByteBuffer.allocate(4 * 1024); + proxyRequest.put(("CONNECT "+host+":"+port+" HTTP/1.1").getBytes(iso88591)); + proxyRequest.put(crlf); + proxyRequest.put(("Host: "+host).getBytes(iso88591)); + proxyRequest.put(crlf); + proxyRequest.put("Proxy-Connection: keep-alive".getBytes(iso88591)); + proxyRequest.put(crlf); + + proxyRequest.put(crlf); + proxyRequest.flip(); + return proxyRequest; + } + + + protected void registerSession(Class endpoint, WsSession wsSession) { if (!wsSession.isOpen()) { // The session was closed during onOpen. No need to register it. return;