0
  • 課題として、私は ServerSocket と Socket クラスのみを使用することを許可されています。また、シングルスレッドでもある必要があります。

私は Java で HTTP プロキシ サーバーを実装しています。最初にクライアントから要求をフェッチし、次にサーバーにプッシュしてから、応答をクライアントにプッシュします。

問題

問題は、リクエストを正常に取得し、それをエンドサーバーに送信して、適切な HTTP 応答を取得したことです。console で応答を出力することもできますしかし、clientServer.outputstream に応答を送信すると、スタックしてしまいました。Firefox (使用が要求された、HTTP 1.0、キープアライブが要求されていない) は永遠にロードされているようで、何も表示されず、Firefox が私のプログラムからも応答を受け取りませんでした。

デバッグ時に検査するもの

ページのロードが開始されるたびに (FF 要求)、常に 2 つのクライアント ソケットがあります。最初のソケットには null リクエストが含まれ、2 番目のソケットには適切なリクエストが含まれます。私が期待していたのは、Firefox からの適切な HTTP リクエストは 1 つだけだったということです。それは奇妙な行動ですか?

例:

/0:0:0:0:0:0:0:1:65194
[null request]

/0:0:0:0:0:0:0:1:65195
GET http://www.microsoft.com/ HTTP/1.0
Host: www.microsoft.com
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:15.0) Gecko/20100101 Firefox/15.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Proxy-Connection: close
Cookie: viewkey=lightweight; WT_FPC=id=269eb0e7618962f93a81347585923074:lv=1349229942007:ss=1349229580158; WT_NVR_RU=0=technet|msdn:1=:2=; omniID=c736269c_f430_4e9b_a42a_23a0c965c60a; MUID=212A1766CFE761423CD014BDCBE76158&TUID=1; MC1=GUID=08600fba7f5c5f409e67980d8a027593&HASH=ba0f&LV=20129&V=4&LU=1347643534618; A=I&I=AxUFAAAAAADGBwAA8ezRtqBBHjk3++mP1Bwj9w!!&V=4&CS=119EQ5002j10100; msdn=L=en-US

コード

ServerSocket serverSocket;
try {
    serverSocket = new ServerSocket(60000);
    while (true) {
            clientSocket = serverSocket.accept();
            [...]
            // Extract request, and push to end-server
            // Fetch response from end-server to client, using flush() already
            // Close all input, output
            // Close all sockets
} catch {[...]}

どんな助けでも大歓迎です、ありがとう!

要求された完全なコード、私は PrintWriter を使用しますが、その前に Byte を使用しても違いはありません (効率は気にしません)。

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

public class Proxy {

    static String separator = System.getProperty("line.separator");

    public static void main(String args[]) {
        //int port = Integer.parseInt(args[0]); 
        start(60000);
    }

    public static void start(int port) {
        ServerSocket serverSocket;
        try {
            serverSocket = new ServerSocket(port);
            Socket clientSocket = null;
            while (true) {
                clientSocket = serverSocket.accept();

                System.out.println(clientSocket.getRemoteSocketAddress() + "\n" + clientSocket.getLocalSocketAddress() + "\n" + clientSocket.getInetAddress());

                BufferedReader inStreamFromClient = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

                String inLine;
                Vector<String> clientRequestHeader = new Vector<String>();
                String rawRequest = "";

                while ((inLine = inStreamFromClient.readLine()) != null) {
                    if (!inLine.isEmpty()) {
                        clientRequestHeader.add(inLine);
                        rawRequest = rawRequest.concat(inLine + separator);
                    } else break;
                }

                while ((inLine = inStreamFromClient.readLine()) != null) 
                    rawRequest = rawRequest.concat(inLine + separator);

                System.out.println(rawRequest);

                if (!rawRequest.isEmpty()) {
                    handleRequest(clientSocket, clientRequestHeader, rawRequest);
                } else {
                    //clientSocket.close();
                                    // Not sure how to handle null request
                }

            }
        } catch (Exception e) {e.printStackTrace();}

    }

    public static void handleRequest(Socket clientSocket, Vector<String> clientRequestHeader, String rawRequest) {
        HTTPRequest request = new HTTPRequest(clientRequestHeader, rawRequest);
        try {
            //System.out.println(rawRequest);

            // Send request to end-server
            Socket endServerSocket = new Socket(request.getHost(), 80);

            PrintWriter outStreamToEndServer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(endServerSocket.getOutputStream())));
            BufferedReader stringReader = new BufferedReader(new StringReader(rawRequest));
            String inLine;
            while ((inLine = stringReader.readLine())!= null) {
                outStreamToEndServer.println(inLine);
            }
            outStreamToEndServer.println();
            outStreamToEndServer.flush();


            // Read response header from end-server
            String responseHeader = "";
            BufferedReader inStreamFromEndServer = new BufferedReader(new InputStreamReader(endServerSocket.getInputStream())); 
            while (!(inLine = inStreamFromEndServer.readLine()).isEmpty()) {
                responseHeader = responseHeader.concat(inLine + separator);
            }

            // Send response header to client
            PrintWriter outStreamToClient = new PrintWriter(new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream())));
            outStreamToClient.println(responseHeader);
            outStreamToClient.flush();

            // Send response body to client
            String responseBody = "";
            while ((inLine = inStreamFromEndServer.readLine()) != null) {
                responseBody = responseBody.concat(inLine + separator);
            }
            outStreamToClient.println(responseBody);
            outStreamToClient.flush();

            endServerSocket.shutdownInput();
            clientSocket.shutdownOutput();
            clientSocket.close();
            endServerSocket.close();

            //endServerSocket = null;
        } catch (Exception e) {
            e.printStackTrace();
        } 
    }

}
4

1 に答える 1