使用 org.apache.http.impl.client.ProxyClient 通过代理隧道访问 HTTPS Web 服务
Accessing HTTPS web services through proxy tunnel using org.apache.http.impl.client.ProxyClient
我需要通过 http 代理隧道访问一些 https soap 服务。所以我使用 org.apache.http.impl.client.ProxyClient 通过代理隧道连接到目标主机。其中returns我一个socket通过代理服务器连接到目标主机。返回的套接字已正确连接到目标系统。现在我需要调用目标系统中托管的 soap 服务。
但我不知道如何通过套接字访问这些 https 服务。下面是我的示例程序。
需要调用的服务示例url
https://XX.XX.XX.XX:44330/sampleService/1.0
public static void proxyTunnelDemo(String url,String soapRequestBody) throws IOException, HttpException {
ProxyClient proxyClient = new ProxyClient();
HttpHost target = new HttpHost("XX.XX.XX.XX", 44330);
HttpHost proxy = new HttpHost("YY.YY.YY.YY", 9293);
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("********", "********");
Socket socket = proxyClient.tunnel(proxy, target, credentials);
// Need to access Web service through socket .
// request method GET
// PORT = 44330
// url = https://XX.XX.XX.XX:44330/sampleService/1
//soapRequestBody = soap message needs to be sent.
String SOAP_CREDENTIALS = "*********";
SSLSocketFactory factory = (SSLSocketFactory)SSLSocketFactory.getDefault();
SSLSocket sslSocket = (SSLSocket)factory.createSocket(socket, target.getHostName(), target.getPort(), true);
sslSocket.startHandshake();
try {
//Send header
BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(sslSocket.getOutputStream(), StandardCharsets.UTF_8));
String authorization = new BASE64Encoder().encode(SOAP_CREDENTIALS.getBytes());
// You can use "UTF8" for compatibility with the Microsoft virtual machine.
wr.write("GET / HTTP/1.1\r\n");
wr.write("Host: "+target.getHostName()+"\r\n");
wr.write("Content-Length:"+ soapRequestBody.length() + "\r\n");
wr.write("Content-Type: text/html\"\r\n");
wr.write("SOAPAction:"+url+"\r\n");
wr.write("Authorization: Basic "+authorization+"\r\n");
wr.write("\r\n "); //Send data
wr.write(soapRequestBody);
wr.flush();
BufferedReader in = new BufferedReader(
new InputStreamReader(sslSocket.getInputStream(), StandardCharsets.UTF_8));
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
} finally {
socket.close();
sslSocket.close();
}
}
上面的代码得到下面的错误响应
HTTP/1.1 400 错误
X-Backside-Transport:失败失败
内容类型:text/xml
连接:关闭
您已经在端口 44330 上与 XX.XX.XX.XX 建立了连接。接下来您需要像这样将此套接字传递给 SSLSocket
SSLSocketFactory factory = (SSLSocketFactory)SSLSocketFactory.getDefault();
SSLSocket sslSocket = (SSLSocket)factory.createSocket(socket, host, port, true);
然后您可以与网络服务器进行 SSL 握手
socket.startHandShake();
然后使用 printwriter 从 socketread/write
https://docs.oracle.com/javase/tutorial/networking/sockets/readingWriting.html
这里有完整的例子:
我需要通过 http 代理隧道访问一些 https soap 服务。所以我使用 org.apache.http.impl.client.ProxyClient 通过代理隧道连接到目标主机。其中returns我一个socket通过代理服务器连接到目标主机。返回的套接字已正确连接到目标系统。现在我需要调用目标系统中托管的 soap 服务。 但我不知道如何通过套接字访问这些 https 服务。下面是我的示例程序。 需要调用的服务示例url https://XX.XX.XX.XX:44330/sampleService/1.0
public static void proxyTunnelDemo(String url,String soapRequestBody) throws IOException, HttpException {
ProxyClient proxyClient = new ProxyClient();
HttpHost target = new HttpHost("XX.XX.XX.XX", 44330);
HttpHost proxy = new HttpHost("YY.YY.YY.YY", 9293);
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("********", "********");
Socket socket = proxyClient.tunnel(proxy, target, credentials);
// Need to access Web service through socket .
// request method GET
// PORT = 44330
// url = https://XX.XX.XX.XX:44330/sampleService/1
//soapRequestBody = soap message needs to be sent.
String SOAP_CREDENTIALS = "*********";
SSLSocketFactory factory = (SSLSocketFactory)SSLSocketFactory.getDefault();
SSLSocket sslSocket = (SSLSocket)factory.createSocket(socket, target.getHostName(), target.getPort(), true);
sslSocket.startHandshake();
try {
//Send header
BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(sslSocket.getOutputStream(), StandardCharsets.UTF_8));
String authorization = new BASE64Encoder().encode(SOAP_CREDENTIALS.getBytes());
// You can use "UTF8" for compatibility with the Microsoft virtual machine.
wr.write("GET / HTTP/1.1\r\n");
wr.write("Host: "+target.getHostName()+"\r\n");
wr.write("Content-Length:"+ soapRequestBody.length() + "\r\n");
wr.write("Content-Type: text/html\"\r\n");
wr.write("SOAPAction:"+url+"\r\n");
wr.write("Authorization: Basic "+authorization+"\r\n");
wr.write("\r\n "); //Send data
wr.write(soapRequestBody);
wr.flush();
BufferedReader in = new BufferedReader(
new InputStreamReader(sslSocket.getInputStream(), StandardCharsets.UTF_8));
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
} finally {
socket.close();
sslSocket.close();
}
}
上面的代码得到下面的错误响应
HTTP/1.1 400 错误
X-Backside-Transport:失败失败
内容类型:text/xml
连接:关闭
您已经在端口 44330 上与 XX.XX.XX.XX 建立了连接。接下来您需要像这样将此套接字传递给 SSLSocket
SSLSocketFactory factory = (SSLSocketFactory)SSLSocketFactory.getDefault();
SSLSocket sslSocket = (SSLSocket)factory.createSocket(socket, host, port, true);
然后您可以与网络服务器进行 SSL 握手
socket.startHandShake();
然后使用 printwriter 从 socketread/write
https://docs.oracle.com/javase/tutorial/networking/sockets/readingWriting.html
这里有完整的例子: