java實現http代理服務

y37f 9年前發布 | 3K 次閱讀 Java

    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> 




來自:http://chenyu-hz.iteye.com/blog/1493227

 本文由用戶 y37f 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!