我正在制作一个依赖于设置http.proxyPort和的Java应用程序http.proxyHost.有两个过程:一个是常规程序,另一个是代理.我有一个简单的套接字监听器http.proxyPort(我控制).这很简单
while (true) {
try {
Socket connection = server.accept();
Handler handler = new Handler(connection);
handler.start();
} catch (Exception ex) {
ex.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
所以每当"进程1"发出一个http请求时 - 就像
URL yahoo = new URL("http://www.google.ca/");
URLConnection yc = yahoo.openConnection();
System.out.println(yc.getClass().getName());
BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
Run Code Online (Sandbox Code Playgroud)
它通过代理.现在如果客户端使用HTTPS协议怎么办?喜欢用https://google.ca吗?有一个属性https.proxyPort和https.proxyHost,但我从字面上一直试图个月(开启和关闭,这不是太重要),没有运气.我已经阅读了一堆线程(我会在最后列出一些,所以你知道我已经做了一些事情).
我迄今为止最接近的尝试:服务器
try {
System.setProperty("javax.net.ssl.keyStore", "test.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "2520xe");
SSLServerSocketFactory sslserversocketfactory =
(SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
SSLServerSocket sslserversocket =
(SSLServerSocket) sslserversocketfactory.createServerSocket(9999);
System.out.println("Ready");
SSLSocket sslsocket = (SSLSocket) sslserversocket.accept();
InputStream inputstream = sslsocket.getInputStream();
InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
OutputStream toClient = sslsocket.getOutputStream();
toClient.write(("HTTP/1.0 200 Connection established\n" +
"Content-Length: " + "Shut down!".getBytes().length
+ "\r\n").getBytes("utf-8"));
toClient.write("Shut down!".getBytes("utf-8"));
toClient.close();
} catch (Exception exception) {
exception.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)
客户
try {
System.setProperty("https.proxyHost", "127.0.0.1");
System.setProperty("https.proxyPort", "9999");
URL yahoo = new URL("https://www.google.ca/");
URLConnection yc = yahoo.openConnection();
System.out.println(yc.getClass().getName());
BufferedReader in = new BufferedReader(
new InputStreamReader(
yc.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
} catch (Exception ex) {
ex.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)
我得到了这个错误,javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?我用谷歌搜索它,但提出了一些邮件.
基本上,我需要创建一个java代理服务器,通过https.proxyPort和https.proxyHost标志设置到客户端,并可以将数据发送回客户端应用程序,这可能不会以任何方式进行修改(它只是使用URL connection = new URL("https://..."))
我试过的几个网站......
正如auntyellow评论的那样:你不需要自己做任何SSL摆弄.基本上,https-proxying是关于在两方之间转发二进制数据.
引用draft-luotonen-web-proxy-tunneling-01.txt:
Run Code Online (Sandbox Code Playgroud)CLIENT -> SERVER SERVER -> CLIENT -------------------------------------- ----------------------------------- CONNECT home.netscape.com:443 HTTP/1.0 User-agent: Mozilla/4.0 <<< empty line >>> HTTP/1.0 200 Connection established Proxy-agent: Netscape-Proxy/1.1 <<< empty line >>> <<< data tunneling to both directions begins >>>
所以基本上你需要确保你信任你的客户足以从你的代理防火墙位置连接到给定的主机和端口.由于这种常见做法是将允许端口限制为443,拒绝与localhost和"不可信"方的连接.
这是一个"简单"的服务器,https.proxy如果你不相信,它可以像Java 一样使用:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Created for http://stackoverflow.com/q/16351413/1266906.
*/
public class Server extends Thread {
public static void main(String[] args) {
(new Server()).run();
}
public Server() {
super("Server Thread");
}
@Override
public void run() {
try (ServerSocket serverSocket = new ServerSocket(9999)) {
Socket socket;
try {
while ((socket = serverSocket.accept()) != null) {
(new Handler(socket)).start();
}
} catch (IOException e) {
e.printStackTrace(); // TODO: implement catch
}
} catch (IOException e) {
e.printStackTrace(); // TODO: implement catch
return;
}
}
public static class Handler extends Thread {
public static final Pattern CONNECT_PATTERN = Pattern.compile("CONNECT (.+):(.+) HTTP/(1\\.[01])",
Pattern.CASE_INSENSITIVE);
private final Socket clientSocket;
private boolean previousWasR = false;
public Handler(Socket clientSocket) {
this.clientSocket = clientSocket;
}
@Override
public void run() {
try {
String request = readLine(clientSocket);
System.out.println(request);
Matcher matcher = CONNECT_PATTERN.matcher(request);
if (matcher.matches()) {
String header;
do {
header = readLine(clientSocket);
} while (!"".equals(header));
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(clientSocket.getOutputStream(),
"ISO-8859-1");
final Socket forwardSocket;
try {
forwardSocket = new Socket(matcher.group(1), Integer.parseInt(matcher.group(2)));
System.out.println(forwardSocket);
} catch (IOException | NumberFormatException e) {
e.printStackTrace(); // TODO: implement catch
outputStreamWriter.write("HTTP/" + matcher.group(3) + " 502 Bad Gateway\r\n");
outputStreamWriter.write("Proxy-agent: Simple/0.1\r\n");
outputStreamWriter.write("\r\n");
outputStreamWriter.flush();
return;
}
try {
outputStreamWriter.write("HTTP/" + matcher.group(3) + " 200 Connection established\r\n");
outputStreamWriter.write("Proxy-agent: Simple/0.1\r\n");
outputStreamWriter.write("\r\n");
outputStreamWriter.flush();
Thread remoteToClient = new Thread() {
@Override
public void run() {
forwardData(forwardSocket, clientSocket);
}
};
remoteToClient.start();
try {
if (previousWasR) {
int read = clientSocket.getInputStream().read();
if (read != -1) {
if (read != '\n') {
forwardSocket.getOutputStream().write(read);
}
forwardData(clientSocket, forwardSocket);
} else {
if (!forwardSocket.isOutputShutdown()) {
forwardSocket.shutdownOutput();
}
if (!clientSocket.isInputShutdown()) {
clientSocket.shutdownInput();
}
}
} else {
forwardData(clientSocket, forwardSocket);
}
} finally {
try {
remoteToClient.join();
} catch (InterruptedException e) {
e.printStackTrace(); // TODO: implement catch
}
}
} finally {
forwardSocket.close();
}
}
} catch (IOException e) {
e.printStackTrace(); // TODO: implement catch
} finally {
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace(); // TODO: implement catch
}
}
}
private static void forwardData(Socket inputSocket, Socket outputSocket) {
try {
InputStream inputStream = inputSocket.getInputStream();
try {
OutputStream outputStream = outputSocket.getOutputStream();
try {
byte[] buffer = new byte[4096];
int read;
do {
read = inputStream.read(buffer);
if (read > 0) {
outputStream.write(buffer, 0, read);
if (inputStream.available() < 1) {
outputStream.flush();
}
}
} while (read >= 0);
} finally {
if (!outputSocket.isOutputShutdown()) {
outputSocket.shutdownOutput();
}
}
} finally {
if (!inputSocket.isInputShutdown()) {
inputSocket.shutdownInput();
}
}
} catch (IOException e) {
e.printStackTrace(); // TODO: implement catch
}
}
private String readLine(Socket socket) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int next;
readerLoop:
while ((next = socket.getInputStream().read()) != -1) {
if (previousWasR && next == '\n') {
previousWasR = false;
continue;
}
previousWasR = false;
switch (next) {
case '\r':
previousWasR = true;
break readerLoop;
case '\n':
break readerLoop;
default:
byteArrayOutputStream.write(next);
break;
}
}
return byteArrayOutputStream.toString("ISO-8859-1");
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
30774 次 |
| 最近记录: |