我正在一个正在连接到服务器的项目中,期望在SSL握手之前使用明文PROXY protocol行。服务器端要求该行存在,没有它就无法正确握手。为了避免在客户端和服务器之间使用其他软件(例如haproxy),我选择尝试扩展javax.net.ssl.SSLSocket类(和SSLProtocolSocketFactory类)。我已经能够验证我的班级是正在创建和访问的班级。它是this class(SSLSocketWrapper)的略微修改版本。

我现在遇到的问题是,似乎未调用javax.net.ssl.SSLSocket中存在的startHandshake方法。我试过调试断点,它们甚至不触发startHandshake。我一直暂停该过程,并逐步使用调试器,我可以看到当Axis2发送请求时,HTTP类肯定是在使用我的Socket类。

我想知道是否通过尝试覆盖startHandshake完全树错了树。也许我正在重新发明轮子(尽管我还没有发现其他人这样做过)。任何帮助,将不胜感激

这是工厂代码:

import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;

import org.apache.commons.httpclient.ConnectTimeoutException;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.protocol.SSLProtocolSocketFactory;

public class ProxyProtoSSLProtocolSocketFactory extends
SSLProtocolSocketFactory {

@Override
public Socket createSocket(Socket socket, String host, int port,
        boolean autoClose) throws IOException, UnknownHostException {
    return new ProxySSLSocketWrapper((SSLSocket) super.createSocket(socket, host, port, autoClose));
}

@Override
public Socket createSocket(String arg0, int arg1, InetAddress arg2,
        int arg3, HttpConnectionParams arg4) throws IOException,
        UnknownHostException, ConnectTimeoutException {
    // TODO Auto-generated method stub
    return new ProxySSLSocketWrapper((SSLSocket)super.createSocket(arg0, arg1, arg2, arg3, arg4));
}

@Override
public Socket createSocket(String host, int port, InetAddress clientHost,
        int clientPort) throws IOException, UnknownHostException {
    // TODO Auto-generated method stub
    return new ProxySSLSocketWrapper((SSLSocket) super.createSocket(host, port, clientHost, clientPort));
}

@Override
public Socket createSocket(String host, int port) throws IOException,
        UnknownHostException {
    return new ProxySSLSocketWrapper((SSLSocket) super.createSocket(host, port));
}
}


这是我从上面链接的SSLSocketWrapper类更改的部分。我刚刚发布了已更改的部分,因为它已接近385行,对于内联来说有点多了。在这一点上,它实际上与上面的没有什么不同,我只是在startHandshake中添加了一个断点,以进行完整性检查,以确保尚未调用它。

public class ProxySSLSocketWrapper extends SSLSocket {
private SSLSocket s;

public ProxySSLSocketWrapper(SSLSocket s) {
    this.s = s;
}

/* javax.net.ssl.SSLSocket */

/**
 * Start handshake after sending over PROXY protocol line.
 */
@Override
public void startHandshake() throws IOException {
  s.startHandshake();
  /*
   if (s instanceof SSLSocket) {
     InetAddress dest = s.getInetAddress();
     InetAddress local = s.getLocalAddress();
     int localPort = s.getLocalPort();
     int destPort = s.getPort();
     String proxyLine = String.format("PROXY TCP4 %s %s %d %d\r\n", local.getHostAddress(), dest.getHostAddress(), localPort, destPort);
     System.err.print("Proxy line written: " + proxyLine);
     System.err.flush();
     OutputStream out = s.getOutputStream();
     OutputStreamWriter writer = new OutputStreamWriter(out);
     writer.write(proxyLine);
     writer.flush();
       ((SSLSocket) s).startHandshake();
   }
   */


}

尝试进行的连接调用只是试图通过Axis2生成的存根进行SOAP调用。

最佳答案

无论如何它都不会起作用,因为嵌套的SSLSocket将加密PROXY TCP4请求。

您需要一个纯文本套接字,并在其周围包裹一个javax.net.ssl.SSLSocket,并在其周围包裹一个代理SSL套接字。

我也将包装纯文本套接字,重写getOutputStream(),并在第一个输出上发送PROXY TCP4行。

关于java - 尝试覆盖SSLSocket的startHandshake以与Axis2一起使用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18111122/

10-11 20:38