3

GET 要求と POST 要求の両方を受け入れる単純な Web プロキシを Java で作成しようとしています。次のコードを書きました。

import java.net.*;
import java.io.*;
import java.nio.CharBuffer;
import java.util.logging.Level;
import java.util.logging.Logger;

public class InterceptionProxy2 {

    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = null;
        boolean listening = true;
        int port = 1234;
        try {
            serverSocket = new ServerSocket(port);
        } catch (IOException e) {
            System.out.println("Port Error");
            System.exit(-1);
        }
        while (listening) {
            new ProxyThread2(serverSocket.accept()).start();
        }
        serverSocket.close();
    }
}

class ProxyThread2 extends Thread {

    private Socket clientSocket = null;
    private Socket serverSocket = null;

    public ProxyThread2(Socket socket) {
        super("ProxyThread2");
        this.clientSocket = socket;
    }

    public void run() {
        //Stream to put data to the browser
        PrintWriter outGoing = null;
        try {
            outGoing = new PrintWriter(clientSocket.getOutputStream(), true);

            //Stream to get data from the browser
            BufferedReader inComing = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

            String incomingRequest;
            String url = "";
            String request = "";
            String response = "";
            //Take the incoming request
            char[] buf = new char[8196];        //8196 is the default max size for GET requests in Apache
            int bytesRead = inComing.read(buf);   //BytesRead need to be calculated if the char buffer contains too many values
            request = new String(buf, 0, bytesRead);

            System.out.println("Request");
            System.out.println(request);

            //Create a new socket for connecting to destination server
            serverSocket = new Socket("localhost", 80);
            PrintWriter pOut = new PrintWriter(serverSocket.getOutputStream(), true);

            //Reader for response from destination server
            BufferedReader pIn = new BufferedReader(new InputStreamReader(serverSocket.getInputStream()));

            //Put data into the new socket(to the apache server) and receive its output
            pOut.print(request);
            pOut.flush();
            bytesRead = pIn.read(buf);

            //Check if data is read
            if (bytesRead > 0) {
                response = new String(buf, 0, bytesRead);
            }
            System.out.println("Response");
            System.out.println(response);

            //Put data back into the original client socket
            outGoing.write(response);
        } catch (IOException ex) {
            Logger.getLogger(ProxyThread2.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            outGoing.close();
        }
    }
}

システムは要求と応答を出力として適切に出力しますが、プロキシは応答をブラウザーに返しません。outGoing ストリームの定義に問題はありますか? または、ブラウザにデータを送り返すために新しいソケットを作成する必要がありますか?

4

2 に答える 2

8

の別のインスタンスを作成する必要はありませんjava.net.ServerSocket。port に接続する必要があるため80、あなたはクライアントです。

Socket socket = new Socket("localhost", 80);

例えば:

class ProxyThread extends Thread {

    private final Socket clientSocket;

    public ProxyThread(Socket socket) {
        this.clientSocket = socket;
    }

    public void run() {
        try {
            // Read request
            InputStream incommingIS = clientSocket.getInputStream();
            byte[] b = new byte[8196];
            int len = incommingIS.read(b);

            if (len > 0) {
                System.out.println("REQUEST"
                        + System.getProperty("line.separator") + "-------");
                System.out.println(new String(b, 0, len));

                // Write request
                Socket socket = new Socket("localhost", 80);
                OutputStream outgoingOS = socket.getOutputStream();
                outgoingOS.write(b, 0, len);

                // Copy response
                OutputStream incommingOS = clientSocket.getOutputStream();
                InputStream outgoingIS = socket.getInputStream();
                for (int length; (length = outgoingIS.read(b)) != -1;) {
                    incommingOS.write(b, 0, length);
                }

                incommingOS.close();
                outgoingIS.close();
                outgoingOS.close();
                incommingIS.close();

                socket.close();
            } else {
                incommingIS.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
于 2013-09-19T15:17:25.517 に答える
1

単純なテキスト ファイルまたは html で動作するコード。問題は 1 つだけです。HTTP ヘッダーだけがテキスト データであり、HTTP メッセージの本文はすべて画像のような単純なバイト データである可能性があります。

PrintWriter や Strings を使用して応答を変換しないでください。サーバーから取得するバイト バッファを単純に転送する必要があります。HTTP メッセージを表示したい場合にのみ、バイト バッファを変換します。

于 2013-09-19T15:35:26.430 に答える