如何用Java实现HTTP代理服务器

发布时间:2025-05-18 03:23:30 作者:小樊
来源:亿速云 阅读:94

要用Java实现一个HTTP代理服务器,你可以使用Java的Socket编程来监听客户端的连接请求,并将请求转发到目标服务器。以下是一个简单的HTTP代理服务器的实现示例:

import java.io.*;
import java.net.*;

public class SimpleHttpProxyServer {
    private int port;

    public SimpleHttpProxyServer(int port) {
        this.port = port;
    }

    public void start() {
        try (ServerSocket serverSocket = new ServerSocket(port)) {
            System.out.println("HTTP Proxy Server is running on port: " + port);

            while (true) {
                Socket clientSocket = serverSocket.accept();
                new Thread(new ProxyHandler(clientSocket)).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static class ProxyHandler implements Runnable {
        private Socket clientSocket;

        public ProxyHandler(Socket clientSocket) {
            this.clientSocket = clientSocket;
        }

        @Override
        public void run() {
            try (
                BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                OutputStream out = clientSocket.getOutputStream()
            ) {
                String requestLine = in.readLine();
                if (requestLine == null) {
                    return;
                }

                // 解析请求行,获取请求方法、URL和HTTP版本
                String[] requestParts = requestLine.split(" ");
                String method = requestParts[0];
                String url = requestParts[1];

                // 处理CONNECT方法(用于HTTPS代理)
                if ("CONNECT".equalsIgnoreCase(method)) {
                    handleConnect(url, out);
                } else {
                    // 处理GET和POST方法
                    handleHttpRequest(url, method, in, out);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    clientSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        private void handleConnect(String url, OutputStream out) throws IOException {
            URL targetUrl = new URL(url);
            String host = targetUrl.getHost();
            int port = targetUrl.getPort() == -1 ? 443 : targetUrl.getPort();

            Socket targetSocket = new Socket(host, port);
            out.write(("HTTP/1.1 200 Connection Established\r\n\r\n").getBytes());

            // 将客户端和目标服务器的socket连接起来
            Thread clientToTarget = new Thread(() -> {
                try {
                    transferData(clientSocket.getInputStream(), targetSocket.getOutputStream());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });

            Thread targetToClient = new Thread(() -> {
                try {
                    transferData(targetSocket.getInputStream(), clientSocket.getOutputStream());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });

            clientToTarget.start();
            targetToClient.start();
        }

        private void handleHttpRequest(String url, String method, BufferedReader in, OutputStream out) throws IOException {
            URL targetUrl = new URL(url);
            String host = targetUrl.getHost();
            int port = targetUrl.getPort() == -1 ? 80 : targetUrl.getPort();

            HttpURLConnection connection = (HttpURLConnection) targetUrl.openConnection();
            connection.setRequestMethod(method);
            connection.setDoOutput(true);

            // 设置请求头
            for (int i = 1; ; i++) {
                String header = in.readLine();
                if (header == null || header.isEmpty()) {
                    break;
                }
                if ("Host".equalsIgnoreCase(header.split(":")[0])) {
                    connection.setRequestProperty("Host", header.split(":")[1]);
                }
            }

            // 发送请求体
            if ("POST".equalsIgnoreCase(method)) {
                String contentType = connection.getContentType();
                out.write(("POST " + url + " HTTP/1.1\r\n").getBytes());
                out.write(("Host: " + host + "\r\n").getBytes());
                out.write(("Content-Type: " + contentType + "\r\n").getBytes());
                out.write(("Content-Length: " + connection.getContentLength() + "\r\n").getBytes());
                out.write("\r\n".getBytes());
                byte[] body = new byte[connection.getContentLength()];
                in.readFully(body);
                out.write(body);
            } else {
                out.write(("GET " + url + " HTTP/1.1\r\n").getBytes());
                out.write(("Host: " + host + "\r\n").getBytes());
                out.write("\r\n".getBytes());
            }

            // 读取响应并转发给客户端
            transferData(connection.getInputStream(), out);

            // 关闭连接
            connection.disconnect();
        }

        private void transferData(InputStream in, OutputStream out) throws IOException {
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = in.read(buffer)) != -1) {
                out.write(buffer, 0, bytesRead);
            }
        }
    }

    public static void main(String[] args) {
        int port = 8080; // 代理服务器监听的端口
        SimpleHttpProxyServer proxyServer = new SimpleHttpProxyServer(port);
        proxyServer.start();
    }
}

说明:

  1. 监听端口:代理服务器在指定的端口上监听客户端的连接请求。
  2. 处理连接:当客户端连接时,创建一个新的线程来处理该连接。
  3. 解析请求:读取并解析HTTP请求行和请求头,获取请求方法、URL和HTTP版本。
  4. 处理CONNECT方法:用于HTTPS代理,建立与目标服务器的TCP连接,并将客户端和目标服务器的socket连接起来。
  5. 处理GET和POST方法:读取请求体并发送给目标服务器,然后将目标服务器的响应转发给客户端。
  6. 数据传输:使用transferData方法在两个socket之间传输数据。

注意事项:

你可以根据需要扩展这个示例,以满足更复杂的需求。

推荐阅读:
  1. Java类库在微服务灰度发布中的角色
  2. 高效模板渲染Java类库有哪些

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

java

上一篇:Java如何利用HTTP协议进行数据交换

下一篇:服务器运维中VLAN划分有哪些技巧

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》