java實現http代理服務
package httpProxy;
/** 一個基礎的代理服務器類 ************************************* */ import java.net.*; import java.io.*; public class HttpProxy extends Thread { static public int CONNECT_RETRIES = 5; static public int CONNECT_PAUSE = 5; static public int TIMEOUT = 50; static public int BUFSIZ = 1024; static public boolean logging = false; static public OutputStream log = null; // 傳入數據用的Socket static public Socket socket; // 上級代理服務器,可選 static private String parent = null; static private int parentPort = -1; static public void setParentProxy(String name, int pport) { parent = name; parentPort = pport; } // 在給定Socket上創建一個代理線程。 public HttpProxy(Socket s) { socket = s; start(); } public void writeLog(int c, boolean browser) throws IOException { log.write(c); } public void writeLog(byte[] bytes, int offset, int len, boolean browser) throws IOException { for (int i = 0; i < len; i++) writeLog((int) bytes[offset + i], browser); } // 默認情況下,日志信息輸出到 // 標準輸出設備 // 派生類可以覆蓋它 public String processHostName(String url, String host, int port, Socket sock) { java.text.DateFormat cal = java.text.DateFormat.getDateTimeInstance(); System.out.println(cal.format(new java.util.Date()) + " - " + url + " " + sock.getInetAddress() + "\n"); return host; } // 執行操作的線程 public void run() { String line; String host; int port = 80; Socket outbound = null; try { socket.setSoTimeout(TIMEOUT); InputStream is = socket.getInputStream(); OutputStream os = null; try { // 獲取請求行的內容 line = ""; host = ""; int state = 0; boolean space; while (true) { int c = is.read(); if (c == -1) break; if (logging) writeLog(c, true); space = Character.isWhitespace((char) c); switch (state) { case 0: if (space) continue; state = 1; case 1: if (space) { state = 2; continue; } line = line + (char) c; break; case 2: if (space) continue; // 跳過多個空白字符 state = 3; case 3: if (space) { state = 4; // 只取出主機名稱部分 String host0 = host; int n; n = host.indexOf("//"); if (n != -1) host = host.substring(n + 2); n = host.indexOf('/'); if (n != -1) host = host.substring(0, n); // 分析可能存在的端口號 n = host.indexOf(":"); if (n != -1) { port = Integer.parseInt(host.substring(n + 1)); host = host.substring(0, n); } host = processHostName(host0, host, port, socket); if (parent != null) { host = parent; port = parentPort; } int retry = CONNECT_RETRIES; while (retry-- != 0) { try { outbound = new Socket(host, port); break; } catch (Exception e) { } // 等待 Thread.sleep(CONNECT_PAUSE); } if (outbound == null) break; outbound.setSoTimeout(TIMEOUT); os = outbound.getOutputStream(); os.write(line.getBytes()); os.write(' '); os.write(host0.getBytes()); os.write(' '); pipe(is, outbound.getInputStream(), os, socket.getOutputStream()); break; } host = host + (char) c; break; } } } catch (IOException e) { } } catch (Exception e) { } finally { try { socket.close(); } catch (Exception e1) { } try { outbound.close(); } catch (Exception e2) { } } } void pipe(InputStream is0, InputStream is1, OutputStream os0, OutputStream os1) throws IOException { try { int ir; byte bytes[] = new byte[BUFSIZ]; while (true) { try { if ((ir = is0.read(bytes)) > 0) { os0.write(bytes, 0, ir); if (logging) writeLog(bytes, 0, ir, true); } else if (ir < 0) break; } catch (InterruptedIOException e) { } try { if ((ir = is1.read(bytes)) > 0) { os1.write(bytes, 0, ir); if (logging) writeLog(bytes, 0, ir, false); } else if (ir < 0) break; } catch (InterruptedIOException e) { } } } catch (Exception e0) { System.out.println("Pipe異常: " + e0); } } static public void startProxy(int port, Class clobj) { ServerSocket ssock; try { ssock = new ServerSocket(port); while (true) { Class[] sarg = new Class[1]; Object[] arg = new Object[1]; sarg[0] = Socket.class; try { java.lang.reflect.Constructor cons = clobj .getDeclaredConstructor(sarg); arg[0] = ssock.accept(); cons.newInstance(arg); // 創建HttpProxy或其派生類的實例 } catch (Exception e) { Socket esock = (Socket) arg[0]; try { esock.close(); } catch (Exception ec) { } } } } catch (IOException e) { } } static public void stopProxy(){ try { if(null!=HttpProxy.socket) HttpProxy.socket.close(); } catch (IOException e) { e.printStackTrace(); } } // 測試用的簡單main方法 static public void main(String args[]) { System.out.println("在端口808啟動代理服務器\n"); HttpProxy.log = System.out; HttpProxy.logging = false; HttpProxy.startProxy(808, HttpProxy.class); } } </pre>
本文由用戶 y37f 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!