尝试创建代理,但不起作用

发布于 2024-11-03 03:50:08 字数 10068 浏览 1 评论 0原文

我有一个任务是编写一个代理服务器。简单的测试有效,但是当我将 Firefox 配置为使用代理时,响应输入流永远不会准备好。你能帮忙吗?

ProxyServer(重要方法)

public void start() {
        while (true) {
            Socket serverSocket;
            Socket clientSocket;
            BufferedWriter toClient;
            BufferedWriter toServer;
            try {
                //The client is meant to put data on the port, read the socket.
                clientSocket = listeningSocket.accept();
                Request request = new Request(clientSocket.getInputStream());
                System.out.println("Accepted a request!\n" + request);
                while(request.busy);
                //Make a connection to a real proxy.
                //Host & Port - should be read from the request
                URL url = null;
                try {
                    url = new URL(request.getRequestURL());
                } catch (MalformedURLException e){
                    url = new URL("http:\\"+request.getRequestHost()+request.getRequestURL());
                }

                //remove entry from cache if needed
                if (!request.getCacheControl().equals(CacheControl.CACHE) && cache.containsRequest(request)) {
                    cache.remove(request);
                }

                Response response = null;

                if (request.getRequestType() == RequestType.GET && request.getCacheControl().equals(CacheControl.CACHE) && cache.containsRequest(request)) {
                    response = cache.get(request);
                } else {
                    //Get the response from the destination
                    int remotePort = (url.getPort() == -1) ? 80 : url.getPort();
                    System.out.println("I am going to try to connect to: " + url.getHost() + " at port " + remotePort);
                    serverSocket = new Socket(url.getHost(), remotePort);
                    System.out.println("Connected.");

                    //write to the server - keep it open.
                    System.out.println("Writing to the server's buffer...");
                    toServer = new BufferedWriter(new OutputStreamWriter(serverSocket.getOutputStream()));
                    toServer.write(request.getFullRequest());
                    toServer.flush();
                    System.out.println("flushed.");

                    System.out.println("Getting a response...");
                    response = new Response(serverSocket.getInputStream());
                    System.out.println("Got a response!\n" + response);
                    //wait for the response
                    while(response.isBusy());   
                }

                if (request.getRequestType() == RequestType.GET && request.getCacheControl().equals(CacheControl.CACHE)) {
                    cache.put(request, response);
                }

                response = filter.filter(response);

                // Return the response to the client
                toClient = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
                toClient.write(response.getFullResponse());
                toClient.flush();
                toClient.close();

            } catch (IOException e) {
                e.printStackTrace();
                continue;
            }
        }
    }

ResponseRequest 类只是非常简单的 HTTP 请求/响应解析器。当我尝试通过代理加载网站时,我得到:


编辑 2

这是另一次尝试。 行之前添加了调试打印

Accepted a request!
Request
==============================

GET http://t2.technion.ac.il/~srachum/ HTTP/1.1
Host: t2.technion.ac.il
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:2.0) Gecko/20100101 Firefox/4.0
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
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Proxy-Connection: keep-alive


I am going to try to connect to: t2.technion.ac.il at port 80
Connected.
Writing to the server's buffer...
flushed.
Getting a response...
Got a response!
Response
==============================

HTTP/1.1 200 OK
Date: Sat, 23 Apr 2011 15:54:08 GMT
Server: Apache/2.0.52 (Red Hat)
Last-Modified: Fri, 18 Mar 2011 23:45:24 GMT
ETag: "14928fc-877-49eca5f29cd00"
Accept-Ranges: bytes
Content-Length: 2167
Connection: close
Content-Type: text/html
X-Pad: avoid browser bug

<html>
    ...
</html>


I am going to write the following response:

HTTP/1.1 200 OK
Date: Sat, 23 Apr 2011 15:54:08 GMT
Server: Apache/2.0.52 (Red Hat)
Last-Modified: Fri, 18 Mar 2011 23:45:24 GMT
ETag: "14928fc-877-49eca5f29cd00"
Accept-Ranges: bytes
Content-Length: 2167
Connection: close
Content-Type: text/html
X-Pad: avoid browser bug

<html>
    ...
</html>

我在行 toClient.write(response.getFullResponse()); EDIT 3:

Request

package cs236369.proxy;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import cs236369.proxy.types.CacheControl;
import cs236369.proxy.types.HttpPatterns;
import cs236369.proxy.types.RequestHeader;
import cs236369.proxy.types.RequestType;


public class Request {
    private String fullRequest = "";
    private BufferedReader reader;
    private RequestHeader requestHeader;
    private String requestHost;
    boolean busy = true;
    private CacheControl cacheControl = CacheControl.CACHE;

    public CacheControl getCacheControl() {
        return cacheControl;
    }

    Request(String request) {
        this(new ByteArrayInputStream(request.getBytes()));
    }

    Request(InputStream input){
        reader = new BufferedReader(new InputStreamReader(input));
        try {
            while(!reader.ready()); //wait for initialization.

            String line;
            while ((line = reader.readLine()) != null) {
                fullRequest += "\r\n" + line;

                if (HttpPatterns.CACHE_CONTROL.matches(line)) {
                    cacheControl = (CacheControl) HttpPatterns.RESPONSE_CODE.process(line);
                } else if (HttpPatterns.REQUEST_HEADER.matches(line)) {
                    requestHeader = (RequestHeader) HttpPatterns.REQUEST_HEADER.process(line);
                } else if (HttpPatterns.HOST.matches(line)) {
                    requestHost = (String) HttpPatterns.HOST.process(line);
                }
            }
            fullRequest = "\r\n" + fullRequest.trim() + "\r\n\r\n";
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        busy = false;
    }

    public String getFullRequest() {
        return fullRequest;
    }

    public RequestType getRequestType() {
        return requestHeader.type;
    }

    public String getRequestURL() {
        return requestHeader.url;
    }

    public String getRequestProtocol() {
        return requestHeader.protocol;
    }

    public String getRequestHost() {
        return requestHost;
    }

    public boolean isBusy() {
        return busy;
    }

    @Override
    public String toString() {
        return "Request\n==============================\n" + fullRequest;
    }
}

Response< /强>

package cs236369.proxy;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import cs236369.proxy.types.CacheControl;
import cs236369.proxy.types.HttpPatterns;

public class Response {
    private String fullResponse = "";
    private BufferedReader reader;
    private boolean busy = true;
    private int responseCode;
    private CacheControl cacheControl;

    public Response(String input) {
        this(new ByteArrayInputStream(input.getBytes()));
    }

    public Response(InputStream input) {
        reader = new BufferedReader(new InputStreamReader(input));
        try {
            while (!reader.ready());//wait for initialization.

            String line;
            while ((line = reader.readLine()) != null) {
                fullResponse += "\r\n" + line;

                if (HttpPatterns.RESPONSE_CODE.matches(line)) {
                    responseCode = (Integer) HttpPatterns.RESPONSE_CODE.process(line);
                } else if (HttpPatterns.CACHE_CONTROL.matches(line)) {
                    cacheControl = (CacheControl) HttpPatterns.CACHE_CONTROL.process(line);
                }
            }
            reader.close();
            fullResponse = "\r\n" + fullResponse.trim() + "\r\n\r\n";
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        busy = false;
    }

    public CacheControl getCacheControl() {
        return cacheControl;
    }

    public String getFullResponse() {
        return fullResponse;
    }

    public boolean isBusy() {
        return busy;
    }

    public int getResponseCode() {
        return responseCode;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                + ((fullResponse == null) ? 0 : fullResponse.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (!(obj instanceof Response))
            return false;
        Response other = (Response) obj;
        if (fullResponse == null) {
            if (other.fullResponse != null)
                return false;
        } else if (!fullResponse.equals(other.fullResponse))
            return false;
        return true;
    }

    @Override
    public String toString() {
        return "Response\n==============================\n" + fullResponse;
    }
}

I have an assignment to write a proxy server. Simple tests work, but when I configure firefox to use the proxy, the response input stream is never ready. Can you help?

ProxyServer (the important method)

public void start() {
        while (true) {
            Socket serverSocket;
            Socket clientSocket;
            BufferedWriter toClient;
            BufferedWriter toServer;
            try {
                //The client is meant to put data on the port, read the socket.
                clientSocket = listeningSocket.accept();
                Request request = new Request(clientSocket.getInputStream());
                System.out.println("Accepted a request!\n" + request);
                while(request.busy);
                //Make a connection to a real proxy.
                //Host & Port - should be read from the request
                URL url = null;
                try {
                    url = new URL(request.getRequestURL());
                } catch (MalformedURLException e){
                    url = new URL("http:\\"+request.getRequestHost()+request.getRequestURL());
                }

                //remove entry from cache if needed
                if (!request.getCacheControl().equals(CacheControl.CACHE) && cache.containsRequest(request)) {
                    cache.remove(request);
                }

                Response response = null;

                if (request.getRequestType() == RequestType.GET && request.getCacheControl().equals(CacheControl.CACHE) && cache.containsRequest(request)) {
                    response = cache.get(request);
                } else {
                    //Get the response from the destination
                    int remotePort = (url.getPort() == -1) ? 80 : url.getPort();
                    System.out.println("I am going to try to connect to: " + url.getHost() + " at port " + remotePort);
                    serverSocket = new Socket(url.getHost(), remotePort);
                    System.out.println("Connected.");

                    //write to the server - keep it open.
                    System.out.println("Writing to the server's buffer...");
                    toServer = new BufferedWriter(new OutputStreamWriter(serverSocket.getOutputStream()));
                    toServer.write(request.getFullRequest());
                    toServer.flush();
                    System.out.println("flushed.");

                    System.out.println("Getting a response...");
                    response = new Response(serverSocket.getInputStream());
                    System.out.println("Got a response!\n" + response);
                    //wait for the response
                    while(response.isBusy());   
                }

                if (request.getRequestType() == RequestType.GET && request.getCacheControl().equals(CacheControl.CACHE)) {
                    cache.put(request, response);
                }

                response = filter.filter(response);

                // Return the response to the client
                toClient = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
                toClient.write(response.getFullResponse());
                toClient.flush();
                toClient.close();

            } catch (IOException e) {
                e.printStackTrace();
                continue;
            }
        }
    }

The Response and Request classes are just very simple parsers for HTTP requests/responses. When I try to load a website through the proxy, I get:


EDIT 2

Here's another attempt. I added a debug print just before the line toClient.write(response.getFullResponse());

Accepted a request!
Request
==============================

GET http://t2.technion.ac.il/~srachum/ HTTP/1.1
Host: t2.technion.ac.il
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:2.0) Gecko/20100101 Firefox/4.0
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
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Proxy-Connection: keep-alive


I am going to try to connect to: t2.technion.ac.il at port 80
Connected.
Writing to the server's buffer...
flushed.
Getting a response...
Got a response!
Response
==============================

HTTP/1.1 200 OK
Date: Sat, 23 Apr 2011 15:54:08 GMT
Server: Apache/2.0.52 (Red Hat)
Last-Modified: Fri, 18 Mar 2011 23:45:24 GMT
ETag: "14928fc-877-49eca5f29cd00"
Accept-Ranges: bytes
Content-Length: 2167
Connection: close
Content-Type: text/html
X-Pad: avoid browser bug

<html>
    ...
</html>


I am going to write the following response:

HTTP/1.1 200 OK
Date: Sat, 23 Apr 2011 15:54:08 GMT
Server: Apache/2.0.52 (Red Hat)
Last-Modified: Fri, 18 Mar 2011 23:45:24 GMT
ETag: "14928fc-877-49eca5f29cd00"
Accept-Ranges: bytes
Content-Length: 2167
Connection: close
Content-Type: text/html
X-Pad: avoid browser bug

<html>
    ...
</html>

EDIT 3:

Request

package cs236369.proxy;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import cs236369.proxy.types.CacheControl;
import cs236369.proxy.types.HttpPatterns;
import cs236369.proxy.types.RequestHeader;
import cs236369.proxy.types.RequestType;


public class Request {
    private String fullRequest = "";
    private BufferedReader reader;
    private RequestHeader requestHeader;
    private String requestHost;
    boolean busy = true;
    private CacheControl cacheControl = CacheControl.CACHE;

    public CacheControl getCacheControl() {
        return cacheControl;
    }

    Request(String request) {
        this(new ByteArrayInputStream(request.getBytes()));
    }

    Request(InputStream input){
        reader = new BufferedReader(new InputStreamReader(input));
        try {
            while(!reader.ready()); //wait for initialization.

            String line;
            while ((line = reader.readLine()) != null) {
                fullRequest += "\r\n" + line;

                if (HttpPatterns.CACHE_CONTROL.matches(line)) {
                    cacheControl = (CacheControl) HttpPatterns.RESPONSE_CODE.process(line);
                } else if (HttpPatterns.REQUEST_HEADER.matches(line)) {
                    requestHeader = (RequestHeader) HttpPatterns.REQUEST_HEADER.process(line);
                } else if (HttpPatterns.HOST.matches(line)) {
                    requestHost = (String) HttpPatterns.HOST.process(line);
                }
            }
            fullRequest = "\r\n" + fullRequest.trim() + "\r\n\r\n";
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        busy = false;
    }

    public String getFullRequest() {
        return fullRequest;
    }

    public RequestType getRequestType() {
        return requestHeader.type;
    }

    public String getRequestURL() {
        return requestHeader.url;
    }

    public String getRequestProtocol() {
        return requestHeader.protocol;
    }

    public String getRequestHost() {
        return requestHost;
    }

    public boolean isBusy() {
        return busy;
    }

    @Override
    public String toString() {
        return "Request\n==============================\n" + fullRequest;
    }
}

Response

package cs236369.proxy;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import cs236369.proxy.types.CacheControl;
import cs236369.proxy.types.HttpPatterns;

public class Response {
    private String fullResponse = "";
    private BufferedReader reader;
    private boolean busy = true;
    private int responseCode;
    private CacheControl cacheControl;

    public Response(String input) {
        this(new ByteArrayInputStream(input.getBytes()));
    }

    public Response(InputStream input) {
        reader = new BufferedReader(new InputStreamReader(input));
        try {
            while (!reader.ready());//wait for initialization.

            String line;
            while ((line = reader.readLine()) != null) {
                fullResponse += "\r\n" + line;

                if (HttpPatterns.RESPONSE_CODE.matches(line)) {
                    responseCode = (Integer) HttpPatterns.RESPONSE_CODE.process(line);
                } else if (HttpPatterns.CACHE_CONTROL.matches(line)) {
                    cacheControl = (CacheControl) HttpPatterns.CACHE_CONTROL.process(line);
                }
            }
            reader.close();
            fullResponse = "\r\n" + fullResponse.trim() + "\r\n\r\n";
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        busy = false;
    }

    public CacheControl getCacheControl() {
        return cacheControl;
    }

    public String getFullResponse() {
        return fullResponse;
    }

    public boolean isBusy() {
        return busy;
    }

    public int getResponseCode() {
        return responseCode;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                + ((fullResponse == null) ? 0 : fullResponse.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (!(obj instanceof Response))
            return false;
        Response other = (Response) obj;
        if (fullResponse == null) {
            if (other.fullResponse != null)
                return false;
        } else if (!fullResponse.equals(other.fullResponse))
            return false;
        return true;
    }

    @Override
    public String toString() {
        return "Response\n==============================\n" + fullResponse;
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

溇涏 2024-11-10 03:50:09

有一次我正在编写一个发送 HTTP 请求的程序...我的代码是这样的:

String host="www.google.com";
String request="GET / HTTP/1.0\r\nHost: "+host+"\r\nAccept-Encoding: gzip\r\n\r\n";
System.out.println(request);
Socket sock=new Socket(host,80);
InputStream inp=sock.getInputStream();
OutputStream outp=sock.getOutputStream();
outp.write(request.getBytes());
byte[] buff=new byte[999];
while(true){
    int n=inp.read(buff);
    if(n<0) break;
    System.out.println(new String(buff,0,n));
}
inp.close();
outp.close();
sock.close();

这段代码有效。乍一看,它看起来像你的。您可以尝试将两者结合起来并观察问题何时开始出现。也许您的 Response 解析器有问题?

PS 您确定从浏览器收到的原始请求以两个换行符结尾吗?在您发布的日志中,似乎只有一个空行...

编辑:我通过较小的修改编译了您的代码,并且工作正常。我所做的事情:

  • 注释掉有关 CacheControl、过滤和 RequestHeader 的所有内容,因为我没有这些类的源代码;
  • 添加了对 URL 和主机的简单解析,因为没有它们就无法工作;
  • 添加了一项检查以删除 Accept-Encoding,因为许多服务器使用 gzip,该程序在此程序中会损坏;
  • 添加了一项检查,以在两行换行后停止解析请求。

该程序充当 Firefox 的代理服务器,并且可以很好地处理 HTML 代码。请编译我的版本并尝试它是否适合您。可能与 Firefox 设置有关?

请注意,此代理服务器会损坏二进制数据,例如图像和 gzip 压缩的 HTML。这肯定是使用了InputStreamReader和OutputStreamWriter造成的;它们将字节转换为字符,反之亦然,这对于文本很有用,但对于二进制数据,您最好“按原样”使用 InputStream 和 OutputStream。

public class AmirRachum {

    public static void main(String[] args) {
        try{
            int port=38824;

            ServerSocket listeningSocket=new ServerSocket(port);
            System.out.println("Socket created");

            while (true) {
                Socket serverSocket;
                Socket clientSocket;
                BufferedWriter toClient;
                BufferedWriter toServer;
                try {
                    //The client is meant to put data on the port, read the socket.
                    clientSocket = listeningSocket.accept();
                    Request request = new Request(clientSocket.getInputStream());
                    System.out.println("Accepted a request!\n" + request);
                    while(request.busy);
                    //Make a connection to a real proxy.
                    //Host & Port - should be read from the request
                    URL url = null;
                    try {
                        url = new URL(request.getRequestURL());
                    } catch (MalformedURLException e){
                        url = new URL("http:\\"+request.getRequestHost()+request.getRequestURL());
                    }

                    //remove entry from cache if needed
             /*       if (!request.getCacheControl().equals(CacheControl.CACHE) && cache.containsRequest(request)) {
                        cache.remove(request);
                    }*/

                    Response response = null;

             /*       if (request.getRequestType() == RequestType.GET && request.getCacheControl().equals(CacheControl.CACHE) && cache.containsRequest(request)) {
                        response = cache.get(request);
                    } else*/ {
                        //Get the response from the destination
                        int remotePort = (url.getPort() == -1) ? 80 : url.getPort();
                        System.out.println("I am going to try to connect to: " + url.getHost() + " at port " + remotePort);
                        serverSocket = new Socket(url.getHost(), remotePort);
                        System.out.println("Connected.");

                        //write to the server - keep it open.
                        System.out.println("Writing to the server's buffer...");
                        toServer = new BufferedWriter(new OutputStreamWriter(serverSocket.getOutputStream()));
                        toServer.write(request.getFullRequest());
                        toServer.flush();
                        System.out.println("flushed.");

                        System.out.println("Getting a response...");
                        response = new Response(serverSocket.getInputStream());
                        System.out.println("Got a response!\n" + response);
                        //wait for the response
                        while(response.isBusy());   
                    }

            /*        if (request.getRequestType() == RequestType.GET && request.getCacheControl().equals(CacheControl.CACHE)) {
                        cache.put(request, response);
                    }

                    response = filter.filter(response);*/

                    // Return the response to the client
                    toClient = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
                    toClient.write(response.getFullResponse());
                    toClient.flush();
                    toClient.close();

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

    public static class Request {
        private String fullRequest = "";
        private BufferedReader reader;
    //    private RequestHeader requestHeader;
        private String requestHost;
        private String requestURL;
        boolean busy = true;
    //    private CacheControl cacheControl = CacheControl.CACHE;

     /*   public CacheControl getCacheControl() {
            return cacheControl;
        }*/

        Request(String request) {
            this(new ByteArrayInputStream(request.getBytes()));
        }

        Request(InputStream input){
            reader = new BufferedReader(new InputStreamReader(input));
            try {
                while(!reader.ready()); //wait for initialization.

                String line;
                while ((line = reader.readLine()) != null) {
                    if(!line.startsWith("Accept-Encoding:")) fullRequest += "\r\n" + line;

                /*    if (HttpPatterns.CACHE_CONTROL.matches(line)) {
                        cacheControl = (CacheControl) HttpPatterns.RESPONSE_CODE.process(line);
                    } else if (HttpPatterns.REQUEST_HEADER.matches(line)) {
                        requestHeader = (RequestHeader) HttpPatterns.REQUEST_HEADER.process(line);
                    } else if (HttpPatterns.HOST.matches(line)) {
                        requestHost = (String) HttpPatterns.HOST.process(line);
                    }*/
                    if(line.startsWith("GET ")){requestURL=line.split(" ")[1];System.out.println("url \""+requestURL+"\"");}
                    if(line.startsWith("Host:")){requestHost=line.substring(6);System.out.println("Host \""+requestHost+"\"");}
                    if(line.length()==0){System.out.println("empty line");break;}
                }
                fullRequest = "\r\n" + fullRequest.trim() + "\r\n\r\n";
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            busy = false;
        }

        public String getFullRequest() {
            return fullRequest;
        }

    /*    public RequestType getRequestType() {
            return requestHeader.type;
        }*/

        public String getRequestURL() {
            return requestURL;
        }

    /*    public String getRequestProtocol() {
            return requestHeader.protocol;
        }*/

        public String getRequestHost() {
            return requestHost;
        }

        public boolean isBusy() {
            return busy;
        }

        //@Override
        public String toString() {
            return "Request\n==============================\n" + fullRequest;
        }
    }

    public static class Response {
        private String fullResponse = "";
        private BufferedReader reader;
        private boolean busy = true;
    //    private int responseCode;
    //    private CacheControl cacheControl;

        public Response(String input) {
            this(new ByteArrayInputStream(input.getBytes()));
        }

        public Response(InputStream input) {
            reader = new BufferedReader(new InputStreamReader(input));
            try {
                while (!reader.ready());//wait for initialization.

                String line;
                while ((line = reader.readLine()) != null) {
                    fullResponse += "\r\n" + line;

               /*     if (HttpPatterns.RESPONSE_CODE.matches(line)) {
                        responseCode = (Integer) HttpPatterns.RESPONSE_CODE.process(line);
                    }/* else if (HttpPatterns.CACHE_CONTROL.matches(line)) {
                        cacheControl = (CacheControl) HttpPatterns.CACHE_CONTROL.process(line);
                    }*/
                }
                reader.close();
                fullResponse = "\r\n" + fullResponse.trim() + "\r\n\r\n";
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } 
            busy = false;
        }

    /*    public CacheControl getCacheControl() {
            return cacheControl;
        }*/

        public String getFullResponse() {
            return fullResponse;
        }

        public boolean isBusy() {
            return busy;
        }

     /*   public int getResponseCode() {
            return responseCode;
        }*/

        //@Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result
                    + ((fullResponse == null) ? 0 : fullResponse.hashCode());
            return result;
        }

        //@Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (!(obj instanceof Response))
                return false;
            Response other = (Response) obj;
            if (fullResponse == null) {
                if (other.fullResponse != null)
                    return false;
            } else if (!fullResponse.equals(other.fullResponse))
                return false;
            return true;
        }

        //@Override
        public String toString() {
            return "Response\n==============================\n" + fullResponse;
        }
    }

}

Once I was writing a program to send HTTP requests... My code was like this:

String host="www.google.com";
String request="GET / HTTP/1.0\r\nHost: "+host+"\r\nAccept-Encoding: gzip\r\n\r\n";
System.out.println(request);
Socket sock=new Socket(host,80);
InputStream inp=sock.getInputStream();
OutputStream outp=sock.getOutputStream();
outp.write(request.getBytes());
byte[] buff=new byte[999];
while(true){
    int n=inp.read(buff);
    if(n<0) break;
    System.out.println(new String(buff,0,n));
}
inp.close();
outp.close();
sock.close();

This code works. At first sight, it looks like yours. You can try combining the two and watch when problems start to occur. Maybe there is something wrong in your Response parser?

P.S. Are you sure that the original request you got from the browser ends with two line breaks? In the log you posted it seems that there is only one blank line...

EDIT: I compiled your code with minor modifications, and it works fine. The things I did:

  • Commented out everything about CacheControl, filtering and RequestHeader because I don't have sources for these classes;
  • Added simple parsing of URL and host because it won't work without them;
  • Added a check to remove Accept-Encoding because many servers use gzip which gets corrupted in this program;
  • Added a check to stop parsing the request after two line breaks.

This program serves as a proxy server for Firefox and works fine with HTML code. Please compile my version and try whether it works for you. Probably there is something to do with Firefox settings?

Please note that this proxy server is corrupting binary data such as images and gzipped HTML. This must be caused by the usage of InputStreamReader and OutputStreamWriter; they convert bytes to characters and vice versa, this is good for text but for binary data you'd better use InputStream and OutputStream "as is".

public class AmirRachum {

    public static void main(String[] args) {
        try{
            int port=38824;

            ServerSocket listeningSocket=new ServerSocket(port);
            System.out.println("Socket created");

            while (true) {
                Socket serverSocket;
                Socket clientSocket;
                BufferedWriter toClient;
                BufferedWriter toServer;
                try {
                    //The client is meant to put data on the port, read the socket.
                    clientSocket = listeningSocket.accept();
                    Request request = new Request(clientSocket.getInputStream());
                    System.out.println("Accepted a request!\n" + request);
                    while(request.busy);
                    //Make a connection to a real proxy.
                    //Host & Port - should be read from the request
                    URL url = null;
                    try {
                        url = new URL(request.getRequestURL());
                    } catch (MalformedURLException e){
                        url = new URL("http:\\"+request.getRequestHost()+request.getRequestURL());
                    }

                    //remove entry from cache if needed
             /*       if (!request.getCacheControl().equals(CacheControl.CACHE) && cache.containsRequest(request)) {
                        cache.remove(request);
                    }*/

                    Response response = null;

             /*       if (request.getRequestType() == RequestType.GET && request.getCacheControl().equals(CacheControl.CACHE) && cache.containsRequest(request)) {
                        response = cache.get(request);
                    } else*/ {
                        //Get the response from the destination
                        int remotePort = (url.getPort() == -1) ? 80 : url.getPort();
                        System.out.println("I am going to try to connect to: " + url.getHost() + " at port " + remotePort);
                        serverSocket = new Socket(url.getHost(), remotePort);
                        System.out.println("Connected.");

                        //write to the server - keep it open.
                        System.out.println("Writing to the server's buffer...");
                        toServer = new BufferedWriter(new OutputStreamWriter(serverSocket.getOutputStream()));
                        toServer.write(request.getFullRequest());
                        toServer.flush();
                        System.out.println("flushed.");

                        System.out.println("Getting a response...");
                        response = new Response(serverSocket.getInputStream());
                        System.out.println("Got a response!\n" + response);
                        //wait for the response
                        while(response.isBusy());   
                    }

            /*        if (request.getRequestType() == RequestType.GET && request.getCacheControl().equals(CacheControl.CACHE)) {
                        cache.put(request, response);
                    }

                    response = filter.filter(response);*/

                    // Return the response to the client
                    toClient = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
                    toClient.write(response.getFullResponse());
                    toClient.flush();
                    toClient.close();

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

    public static class Request {
        private String fullRequest = "";
        private BufferedReader reader;
    //    private RequestHeader requestHeader;
        private String requestHost;
        private String requestURL;
        boolean busy = true;
    //    private CacheControl cacheControl = CacheControl.CACHE;

     /*   public CacheControl getCacheControl() {
            return cacheControl;
        }*/

        Request(String request) {
            this(new ByteArrayInputStream(request.getBytes()));
        }

        Request(InputStream input){
            reader = new BufferedReader(new InputStreamReader(input));
            try {
                while(!reader.ready()); //wait for initialization.

                String line;
                while ((line = reader.readLine()) != null) {
                    if(!line.startsWith("Accept-Encoding:")) fullRequest += "\r\n" + line;

                /*    if (HttpPatterns.CACHE_CONTROL.matches(line)) {
                        cacheControl = (CacheControl) HttpPatterns.RESPONSE_CODE.process(line);
                    } else if (HttpPatterns.REQUEST_HEADER.matches(line)) {
                        requestHeader = (RequestHeader) HttpPatterns.REQUEST_HEADER.process(line);
                    } else if (HttpPatterns.HOST.matches(line)) {
                        requestHost = (String) HttpPatterns.HOST.process(line);
                    }*/
                    if(line.startsWith("GET ")){requestURL=line.split(" ")[1];System.out.println("url \""+requestURL+"\"");}
                    if(line.startsWith("Host:")){requestHost=line.substring(6);System.out.println("Host \""+requestHost+"\"");}
                    if(line.length()==0){System.out.println("empty line");break;}
                }
                fullRequest = "\r\n" + fullRequest.trim() + "\r\n\r\n";
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            busy = false;
        }

        public String getFullRequest() {
            return fullRequest;
        }

    /*    public RequestType getRequestType() {
            return requestHeader.type;
        }*/

        public String getRequestURL() {
            return requestURL;
        }

    /*    public String getRequestProtocol() {
            return requestHeader.protocol;
        }*/

        public String getRequestHost() {
            return requestHost;
        }

        public boolean isBusy() {
            return busy;
        }

        //@Override
        public String toString() {
            return "Request\n==============================\n" + fullRequest;
        }
    }

    public static class Response {
        private String fullResponse = "";
        private BufferedReader reader;
        private boolean busy = true;
    //    private int responseCode;
    //    private CacheControl cacheControl;

        public Response(String input) {
            this(new ByteArrayInputStream(input.getBytes()));
        }

        public Response(InputStream input) {
            reader = new BufferedReader(new InputStreamReader(input));
            try {
                while (!reader.ready());//wait for initialization.

                String line;
                while ((line = reader.readLine()) != null) {
                    fullResponse += "\r\n" + line;

               /*     if (HttpPatterns.RESPONSE_CODE.matches(line)) {
                        responseCode = (Integer) HttpPatterns.RESPONSE_CODE.process(line);
                    }/* else if (HttpPatterns.CACHE_CONTROL.matches(line)) {
                        cacheControl = (CacheControl) HttpPatterns.CACHE_CONTROL.process(line);
                    }*/
                }
                reader.close();
                fullResponse = "\r\n" + fullResponse.trim() + "\r\n\r\n";
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } 
            busy = false;
        }

    /*    public CacheControl getCacheControl() {
            return cacheControl;
        }*/

        public String getFullResponse() {
            return fullResponse;
        }

        public boolean isBusy() {
            return busy;
        }

     /*   public int getResponseCode() {
            return responseCode;
        }*/

        //@Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result
                    + ((fullResponse == null) ? 0 : fullResponse.hashCode());
            return result;
        }

        //@Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (!(obj instanceof Response))
                return false;
            Response other = (Response) obj;
            if (fullResponse == null) {
                if (other.fullResponse != null)
                    return false;
            } else if (!fullResponse.equals(other.fullResponse))
                return false;
            return true;
        }

        //@Override
        public String toString() {
            return "Response\n==============================\n" + fullResponse;
        }
    }

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文