如何使用Java中的套接字(HTTP / HTTPS代理)正确拦截HTTP和HTTPS请求?

时间:2019-06-23 17:54:44

标签: java sockets proxy

对我来说,这是一个非常重要的项目。我想用Java创建一个代理,该代理使我能够拦截用户从其浏览器发出的所有HTTP和HTTPS请求(一旦配置了该请求,表示将在地址localhost和端口8080中使用代理)。一旦被拦截,我希望能够处理请求的某些部分(例如,User-agent标头),并将它们发送到相应的主机后,获得响应,并能够对其进行处理,并且将其发送到用户的浏览器。

我已经使用套接字(ServerSocket和Socket)实现了上述目标。但是,存在一个严重的问题:

当我拦截对启用了SSL的服务器(即HTTPS)的请求时,我只能看到使用CONNECT方法的请求,而看不到使用GET或POST方法的请求,如下所示:< / p>

CONNECT img.youtube.com:443 HTTP / 1.1 用户代理:Mozilla / 5.0(Windows NT 10.0; Win64; x64; rv:67.0)Gecko / 20100101 Firefox / 67.0 代理连接:保持活动状态 连接:保持活动状态 主持人:img.youtube.com:443

以上是我的应用程序从Sockets信息中显示的内容。另一方面,Burp Suite工具还显示以下信息:

GET /image.jpeg HTTP / 1.1 主持人:img.youtube.com 用户代理:Mozilla / 5.0(Windows NT 10.0; Win64; x64; rv:67.0)Gecko / 20100101 Firefox / 67.0 接受:* / * 接受语言:en-us,en:q = 0.5 接受编码:gzip,放气 缓存控制:无缓存 语法:无缓存

上述问题是我的代理服务器也应该显示Burp Suite工具显示的内容,但事实并非如此。 是否需要SSL证书之类的问题?我的代理服务器仅使用Socket和ServerSocket,而不使用SSLSocket。

以下是其中的一些代码段:

步骤1-我创建了一个侦听端口的ServerSocket:


ServerSocket serverSocket=null;
        try {
            serverSocket = new ServerSocket( ProxyConfig.getInstance().getLocalPort() );
        } catch (IOException e1) {
            e1.printStackTrace();
        }

        Socket socket;
        Connection connectionCreator;
        try {
            while ( (socket = serverSocket.accept() ) != null) {
                connectionCreator = new ConnectionImpl( new ClientConnectionImpl(socket) );
                connectionCreator.start();
            }
        } catch (IOException e) {
            e.printStackTrace(); 
        }

第2步-我打印套接字内容(以下代码仅打印第一行,类似于“ CONNECT img.youtube.com:443 HTTP / 1.1”):

int characterRead;
        boolean endOfLine = false;
        ByteArrayOutputStream contentClientRequest = new ByteArrayOutputStream();

        while (( (characterRead = getClientSocket().getInputStream().read()) != -1) && !endOfLine) {
            switch (characterRead)
            {
                case '\n':
                    endOfLine=true;
                    break;
                case '\r':
                    endOfLine=true;
                    break;
                default:
                    contentClientRequest.write( characterRead );
                    break;
            }
        }

        System.out.println( contentClientRequest.toString() );

        return contentClientRequest.toString( getISO() );

注意:在上面的代码中,“ getClientSocket()”表示在步骤1中接受的套接字(“ socket = serverSocket.accept()”)

第3步-将响应发送到用户的浏览器(在第1步和第2步所示的套接字中写入字节)。

感谢您的回答,并告诉我是否需要更多信息。

0 个答案:

没有答案