我正在开发一个项目,该项目在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调用。
答案 0 :(得分:0)
无论如何它都无法正常工作,因为嵌套的SSLSocket
会加密PROXY TCP4
请求。
您需要一个纯文本套接字,其中包含javax.net.ssl.SSLSocket
,并且您的代理SSL套接字就在其中。
我也会包装明文套接字,覆盖getOutputStream(),并在第一个输出上发送PROXY TCP4
行。