Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
创建接受HTTPS的Java代理服务器_Java_Ssl_Https_Proxy - Fatal编程技术网

创建接受HTTPS的Java代理服务器

创建接受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 {

我已经有了一个可以处理多个HTTP请求的HTTP代理服务器。现在我的问题是如何处理https请求

以下是我正在使用的简化代码:

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);