试图创建代理,不起作用 [英] Trying to create a proxy, doesn't work

查看:80
本文介绍了试图创建代理,不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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(重要的方法)

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;
            }
        }
    }

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

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:

编辑2

这是另一次尝试。我在行 toClient.write(response.getFullResponse())之前添加了一个调试打印;

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>






编辑3:

请求

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;
    }
}

响应

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;
    }
}


推荐答案

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

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();

此代码有效。乍一看,它看起来像你的。您可以尝试将两者结合起来,并观察问题何时开始发生。你的 Response 解析器可能有问题吗?

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。您确定从浏览器获得的原始请求以两个换行符结束吗?在您发布的日志中,似乎只有一个空白行...

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...

编辑:我编译了您的代码并进行了少量修改,它工作正常。我做的事情:

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


  • 关于CacheControl,过滤和RequestHeader的注释,因为我没有这些类的来源;

  • 添加了URL和主机的简单解析,因为没有它们将无法正常工作;

  • 添加了检查以删除 Accept-Encoding 因为许多服务器使用的gzip在这个程序中被破坏了;

  • 添加了一个检查,在两次换行后停止解析请求。

  • 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.

此程序用作Firefox的代理服务器,可以正常使用HTML代码。请编译我的版本并尝试它是否适合您。可能与Firefox设置有关吗?

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?

请注意,此代理服务器正在破坏二进制数据,如图像和gzip压缩包。这必须是由InputStreamReader和OutputStreamWriter的使用引起的;它们将字节转换为字符,反之亦然,这对文本很有用,但对于二进制数据,最好按原样使用InputStream和OutputStream。

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;
        }
    }

}

这篇关于试图创建代理,不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆