création d'un serveur proxy Java qui accepte HTTPS


J'ai déjà un serveur proxy HTTP fonctionnel qui peut gérer plusieurs requêtes HTTP. maintenant, mon problème est de savoir comment gérer la demande https?

Voici un code simplifié que j'utilise:

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) { }
        }
    }

}

Et le 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 
            ...........
       }
}

}

J'ai vraiment essayé de chercher comment, j'ai rencontré SSL tunneling, certificate,handshaking, SSLSocket, SSLFactory, trustStore et etc. quelque chose comme ça, mais ne pouvait toujours pas le faire fonctionner.. J'ai juste besoin de savoir quelles sont les choses dont j'ai besoin et les étapes pour établir une connexion à un serveur Web compatible SSL.

Author: James G, 2012-02-20

3 answers

Je l'ai finalement eu.

Il me suffit d'utiliser un socket normal et d'envoyer un message au client indiquant qu'une connexion est établie. puis passez le tunnel.

Voici un code de travail:

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 
            ...........
       }

Voici une bonne explication sur la façon dont le serveur proxy gère la connexion. http://curl.haxx.se/rfc/draft-luotonen-web-proxy-tunneling-01.txt

 6
Author: James G, 2012-02-22 04:31:53

Veuillez trouver ci-dessous le code java pour créer un proxy HTTPS. Il ne modifie pas la réponse. Pour l'intégrer à HTTP, écrivez du code HTTP dans la clause else. Vous pouvez trouver le code HTTP pour proxy à un certain nombre d'endroits.

Fondamentalement, ce qui se passe, c'est lorsque le client envoie une requête HTTPS au proxy, il est livré avec le mot clé CONNECT. Vous devez envoyer HTTP / 1.1 200 OK au client après avoir établi la connexion avec le serveur en amont. Après cela vous devez fournir le flux d'entrée entrant du client sans en-têtes/hôte, etc. vers le serveur en amont et le flux entrant du serveur en amont vers le client.

Vous n'avez pas du tout besoin de penser à 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");
        }
    }
}
 2
Author: Sarvesh Agarwal, 2016-12-28 19:41:39

Google "serveur https en java" et vous pouvez trouver un tutoriel pertinent, un RFC connexe et une documentation standard . J'espère que cela aidera :).

 1
Author: Umer Hayat, 2012-02-20 07:48:09