NiceLeeのBlog 用爱发电 bilibili~

Java Http/Https代理Demo (下)

2019-02-13
nIceLee

阅读:


上一篇实现了中间人代理Http服务,接下来完成隧道方式代理Https请求。

写在前面

  • HTTP 代理原理及实现
  • 目标是通过中间人代理的方式代理普通Http请求, 使用隧道代理方式代理Https请求。

思考

  • 本文考虑隧道代理方式
  • 明白了原理,隧道代理方式其实比前者更加简单。
    • 通俗来说,我收到了connect连接请求,根据这个请求建立对服务器的TCP连接,然后回复客户端OK。
    • 然后啥事不用管,客户端数据来了转发服务器,服务器数据来了转发客户端。

实现

其实明白了原理,似乎也没啥好bb的。。
创建到服务器的TCP连接,打开面向服务器的监听线程,专用于转发数据给客户端

private void connecToServer(HttpRequest httpRequest) throws IOException {
    //默认ip:port参数
    String dstIp = httpRequest.host;
    int dstPort = 80;
    // connect方法, 从首行url获取目的参数
    if (httpRequest.method.toLowerCase().equals("connect")) {
        dstPort = 443;
        dstIp = httpRequest.url;
    }
    // dstIp 若为ip:port形式,更新参数
    Matcher matcher = HttpResource.patternHost.matcher(dstIp);
    if (matcher.find()) {
        dstIp = matcher.group(1);
        dstPort = Integer.parseInt(matcher.group(2));
    }

    if (socketServer == null) {
        socketServer = new Socket();
        socketServer.connect(new InetSocketAddress(dstIp, dstPort));
        // 获取服务器之间的输入输出流
        inFromSever = new StreamReader(monitor, socketServer,
                new BufferedInputStream(socketServer.getInputStream()));
        outToServer = new BufferedOutputStream(socketServer.getOutputStream());

        // 打开面向服务器的监听线程,专用于转发数据给客户端
        ProxyDealer proxyDealer = new ProxyDealer(this);
        SocketServer.httpProxyThreadPool.execute(proxyDealer);
    }
}

处理客户端的消息,构造Http请求发送给服务器

private void doProxyConnect(HttpRequest httpRequest) throws IOException {
    // System.out.println("调用的是connect 方法");
    connecToServer(httpRequest);
    out.write("HTTP/1.1 200 Connection Established\r\n\r\n".getBytes());
    out.flush();
}

源代码


内容
隐藏