默认端口:8888
javac RuphyHttpProxy.java
java RuphyHttpProxy 11111
import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.regex.Matcher; import java.util.regex.Pattern; public class RuphyHttpProxy extends Thread { private final ServerSocket server; private final int port; public RuphyHttpProxy(int port) throws IOException { this.port = port; server = new ServerSocket(port); System.out.println("代理端口:" + this.port); } public static void main(String[] args) throws IOException { int port = 8888; if (args != null && args.length > 0 && args[0].matches("\\d+")) { port = Integer.parseInt(args[0]); } new RuphyHttpProxy(port).start(); } @Override public void run() { // 线程运行函数 while (true) { try { Socket client = server.accept(); //使用线程处理收到的请求 new HttpConnectThread(client).start(); } catch (Exception e) { e.printStackTrace(); } } } private static class HttpConnectThread extends Thread { private Socket client; byte clientInputBuffer[] = new byte[1024 * 1024 * 4]; private int clientReadLength, port = 80; private String host = null; private Socket server = null; private DataInputStream clientInputStream = null; //客户端输入流 private DataInputStream serverInputStream = null; //服务端输入流 private DataOutputStream clientOutputStream = null; //客户端输出流 private DataOutputStream serverOutputStream = null; //服务端输出流 public HttpConnectThread(Socket client) { this.client = client; } @Override public void run() { try { clientInputStream = new DataInputStream(client.getInputStream()); clientOutputStream = new DataOutputStream(client.getOutputStream()); if (clientInputStream != null && clientOutputStream != null) { clientReadLength = clientInputStream.read(clientInputBuffer, 0, clientInputBuffer.length); // 从客户端读数据 if (clientReadLength > 0) { // 读到数据 String clientInputString = new String(clientInputBuffer, 0, clientReadLength); if (clientInputString.contains("\n")) { clientInputString = clientInputString.substring(0, clientInputString.indexOf("\n")); System.out.println(clientInputString); } if (clientInputString.contains("CONNECT ")) { Pattern pattern = Pattern.compile("CONNECT ([^ ]+) HTTP/"); Matcher matcher = pattern.matcher(clientInputString); if (matcher.find()) { host = matcher.group(1); if (host.contains(":")) { port = Integer.parseInt(host.substring(host.indexOf(":") + 1)); host = host.substring(0, host.indexOf(":")); } } } if (clientInputString.contains("http://") && clientInputString.contains("HTTP/")) { // 从所读数据中取域名和端口号 Pattern pattern = Pattern.compile("http://([^/]+)/"); Matcher matcher = pattern.matcher(clientInputString + "/"); if (matcher.find()) { host = matcher.group(1); if (host.contains(":")) { port = Integer.parseInt(host.substring(host.indexOf(":") + 1)); host = host.substring(0, host.indexOf(":")); } } } if (host != null) { server = new Socket(host, port); // 根据读到的域名和端口号建立套接字 serverInputStream = new DataInputStream(server.getInputStream()); serverOutputStream = new DataOutputStream(server.getOutputStream()); if (serverInputStream != null && serverOutputStream != null && server != null) { if (clientInputString.contains("GET ")) { doGet(); } if (clientInputString.contains("CONNECT ")) { doConnect(); } if (clientInputString.contains("POST ")) { doPost(); } } } } } } catch (IOException e) { e.printStackTrace(); closeAll(); } } /** * 处理POST请求 * * @throws IOException */ private void doPost() throws IOException { write(clientInputBuffer, clientReadLength, serverOutputStream); // 建立线程 , 用于从外网读数据 , 并返回给内网 new HttpChannel(serverInputStream, clientOutputStream).start(); // 建立线程 , 用于从内网读数据 , 并返回给外网 new HttpChannel(clientInputStream, serverOutputStream).start(); } /** * 写数据 * * @param buf 缓冲区 * @param length 读取的偏移量 * @param outputStream 输出流 * @throws IOException */ private void write(byte[] buf, int length, DataOutputStream outputStream) throws IOException { outputStream.write(buf, 0, length); outputStream.flush(); } /** * 处理连接请求 * * @return */ private void doConnect() throws IOException { String ack = "HTTP/1.0 200 Connection established\r\n"; ack = ack + "Proxy-agent: proxy\r\n\r\n"; clientOutputStream.write(ack.getBytes()); clientOutputStream.flush(); // 建立线程 , 用于从外网读数据 , 并返回给内网 new HttpChannel(serverInputStream, clientOutputStream).start(); // 建立线程 , 用于从内网读数据 , 并返回给外网 new HttpChannel(clientInputStream, serverOutputStream).start(); } /** * 处理GET请求 * * @return * @throws IOException */ private void doGet() throws IOException { write(clientInputBuffer, clientReadLength, serverOutputStream); new HttpChannel(serverInputStream, clientOutputStream).start(); } /** * 异常关闭所有流 */ private void closeAll() { if (serverInputStream != null) { try { serverInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if (serverOutputStream != null) { try { serverOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if (server != null) { try { server.close(); } catch (IOException e) { e.printStackTrace(); } } if (clientInputStream != null) { try { clientInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if (clientOutputStream != null) { try { clientOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if (client != null) { try { client.close(); } catch (IOException e) { e.printStackTrace(); } } } } private static class HttpChannel extends Thread { private DataInputStream in; private DataOutputStream out; public HttpChannel(DataInputStream in, DataOutputStream out) { this.in = in; this.out = out; } @Override public void run() { int len; byte buf[] = new byte[10240]; try { while ((len = in.read(buf, 0, buf.length)) != -1) { out.write(buf, 0, len); out.flush(); } } catch (Exception e) { e.printStackTrace(); } finally { try { in.close(); } catch (IOException e) { e.printStackTrace(); } try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
原文:https://www.cnblogs.com/muphy/p/14210917.html