创建接受HTTPS的Java代理服务器
我已经有了一个可以处理多个HTTP请求的HTTP代理服务器。现在我的问题是如何处理https请求 以下是我正在使用的简化代码:创建接受HTTPS的Java代理服务器,java,ssl,https,proxy,Java,Ssl,Https,Proxy,我已经有了一个可以处理多个HTTP请求的HTTP代理服务器。现在我的问题是如何处理https请求 以下是我正在使用的简化代码: class Daemon { public static void main(String[] args) { ServerSocket cDaemonSocket = new ServerSocket(3128); while(true) { try {
class Daemon
{
public static void main(String[] args)
{
ServerSocket cDaemonSocket = new ServerSocket(3128);
while(true)
{
try
{
Socket ClientSocket = cDaemonSocket.accept();
(new ClientHandler(ClientSocket )).start();
}catch(Exception e) { }
}
}
}
还有ClientHandler
class ClientHandler extends Thread
{
private Socket socket = null;
private Socket remoteSocket = null;
private HTTPReqHeader request = null;
ClientHandler(Socket socket)
{
this.socket = socket;
request = new HTTPReqHeader();
request.parse(socket); // I read and parse the HTTP request here
}
public void run()
{
if(!request.isSecure() )
{
remoteSocket = new Socket(request.url,request.port);
}
else
{
// now what should I do to established a secured socket?
}
// start connecting remoteSocket and clientSocket
...........
}
}
}
我真的尝试过搜索,我遇到了SSL隧道、证书、握手、SSLSocket、SSLFactory、trustStore等类似的东西,但仍然无法让它工作。。我只需要知道我需要什么,以及与启用SSL的web服务器建立连接的步骤。谷歌“java中的https服务器”,您可以找到,和。我希望这会有帮助:)。我终于找到了
我只需要使用普通套接字并向客户端发送一条消息,表明已建立连接。然后继续挖掘隧道
以下是工作代码:
private Socket socket = null;
private Socket remoteSocket = null;
private HTTPReqHeader request = null;
ClientHandler(Socket socket)
{
this.socket = socket;
request = new HTTPReqHeader();
request.parse(socket); // I read and parse the HTTP request here
}
public void run()
{
remoteSocket = new Socket(request.url,request.port);
if(request.isSecure() )
{
// send ok message to client
String ConnectResponse = "HTTP/1.0 200 Connection established\n" +
"Proxy-agent: ProxyServer/1.0\n" +
"\r\n";
try
{
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
out.writeByte(ConnectResponse);
out.flush();
} catch(Exception e) {}
}
// start connecting remoteSocket and clientSocket
...........
}
下面是关于代理服务器如何处理连接的一个很好的解释。
请找到下面的java代码来创建HTTPS代理。它不会修改响应。要将其与HTTP集成,请在else子句中编写HTTP代码。您可以在许多地方找到代理的HTTP代码 基本上,当客户端向代理发送一个HTTPS请求时,就会发生连接关键字。在与上游服务器建立连接后,必须向客户端发送HTTP/1.1 200 OK。之后,您必须向上游服务器提供客户端的传入输入流(不带头/主机等),并从上游服务器向客户端提供传入流 您根本不需要考虑SSL
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");
}
}
}
import java.io.*;
导入java.net.ServerSocket;
导入java.net.Socket;
导入java.util.regex.Matcher;
导入java.util.regex.Pattern;
/**
*创建用于http://stackoverflow.com/q/16351413/1266906.
*/
公共类服务器扩展线程{
公共静态void main(字符串[]args){
(新服务器()).run();
}
公共服务器(){
超级(“服务器线程”);
}
@凌驾
公开募捐{
try(ServerSocket-ServerSocket=newserversocket(9999)){
插座;
试一试{
而((socket=serverSocket.accept())!=null){
(新处理程序(套接字)).start();
}
}捕获(IOE异常){
e、 printStackTrace();//TODO:实现捕获
}
}捕获(IOE异常){
e、 printStackTrace();//TODO:实现捕获
返回;
}
}
公共静态类处理程序扩展线程{
公共静态最终模式CONNECT_Pattern=Pattern.compile(“CONNECT(++):(++)HTTP/(1\\[01]),
模式(不区分大小写);
私有最终套接字clientSocket;
私有布尔值previousWasR=false;
公共处理程序(套接字客户端套接字){
this.clientSocket=clientSocket;
}
@凌驾
公开募捐{
试一试{
字符串请求=readLine(clientSocket);
系统输出打印项次(请求);
Matcher Matcher=CONNECT\u PATTERN.Matcher(请求);
if(matcher.matches()){
字符串头;
做{
header=readLine(clientSocket);
}而(!“”.equals(header));
OutputStreamWriter OutputStreamWriter=新的OutputStreamWriter(clientSocket.getOutputStream(),
“ISO-8859-1”);
最终插座和前插座;
试一试{
forwardSocket=新套接字(matcher.group(1),Integer.parseInt(matcher.group(2));
System.out.println(forwardSocket);
}捕获(IOException | NumberFormatException e){
e、 printStackTrace();//TODO:实现捕获
outputStreamWriter.write(“HTTP/”+matcher.group(3)+“502坏网关\r\n”);
outputStreamWriter.write(“代理:简单/0.1\r\n”);
outputStreamWriter.write(“\r\n”);
outputStreamWriter.flush();
返回;
}
试一试{
outputStreamWriter.write(“HTTP/”+matcher.group(3)+“200连接已建立\r\n”);
outputStreamWriter.write(“代理:简单/0.1\r\n”);
outputStreamWriter.write(“\r\n”);
outputStreamWriter.flush();
线程remoteToClient=新线程(){
@凌驾
公开募捐{
forwardData(forwardSocket、clientSocket);
}
};
remoteToClient.start();
试一试{
if(先前的wasr){
int read=clientSocket.getInputStream().read();
如果(读取!=-1){
如果(读取!='\n'){
forwardSocket.getOutputStream().write(read);
}
forwardData(clientSocket,forwardSocket);
}否则{
如果(!forwardSocket.isOutputShutdown()){
forwardSocket.shutdownOutput();
}
如果(!clientSocket.isInputShutdown()){
clientSocket.shutdownInput();
}
}
}否则{
forwardData(clientSocket,forwardSocket);