简体   繁体   English

Java HTTP/HTTPS 代理服务器

[英]Java HTTP/HTTPS Proxy Server

I'm writting my own Java Proxy Server.我正在编写自己的 Java 代理服务器。 When I try to use it, I have the correct output (I see all commands that are going through the proxy server), but any website I want to visit doesn't work at all and I have the following error in my browser: ERR_TUNNEL_CONNECTION_FAILED.当我尝试使用它时,我有正确的输出(我看到所有通过代理服务器的命令),但是我想访问的任何网站都无法正常工作,并且我的浏览器中出现以下错误:ERR_TUNNEL_CONNECTION_FAILED . I don't actually good at network questions and there are some things I don't understand.我实际上并不擅长网络问题,有些事情我不明白。 So, there is my code below and I'll be really glad if someone tell me where is the problem:所以,下面是我的代码,如果有人告诉我问题出在哪里,我会很高兴:

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

public class ProxyServer
{
    private String host;
    private int localPort;
    private int remotePort;
    private ProxyServer(String host, int localPort, int remotePort)
    {
        this.host=host;
        this.localPort=localPort;
        this.remotePort=remotePort;
    }
    public static void main(String[] args) throws IOException
    {
        new ProxyServer("localhost", 8080, 9001).start();
    }
    public void start() throws IOException
    {
        System.out.println("Starting the proxy server for "+this.host+":"+this.localPort+"...");
        ServerSocket ss=new ServerSocket(this.localPort);
        final byte[] request=new byte[4096];
        byte[] response=new byte[4096];
        while(true)
        {
            Socket client=null;
            Socket server=null;
            try
            {
                client=ss.accept();
                final InputStream streamFromClient=client.getInputStream();
                OutputStream streamToClient=client.getOutputStream();
                System.out.println(new BufferedReader(new InputStreamReader(streamFromClient)).readLine());
                try
                {
                    server=new Socket(host, this.remotePort);
                }
                catch(IOException exc)
                {
                    PrintWriter out=new PrintWriter(streamToClient);
                    out.println("Proxy server cannot connect to "+host+":"+this.remotePort+"\n"+exc);
                    out.flush();
                    client.close();
                    continue;
                }
                InputStream streamFromServer=server.getInputStream();
                final OutputStream streamToServer=server.getOutputStream();
                System.out.println(new BufferedReader(new InputStreamReader(streamFromServer)).readLine());
                new Thread
                (
                    ()->
                    {
                        int bytesRead;
                        try
                        {
                            while((bytesRead=streamFromClient.read(request))!=-1)
                            {
                                streamToServer.write(request, 0, bytesRead);
                                streamToServer.flush();
                            }
                        }
                        catch(IOException exc){}
                        try
                        {
                            streamToServer.close();
                        }
                        catch(IOException exc){}
                    }
                ).start();
                int bytesRead;
                try
                {
                    while((bytesRead=streamFromServer.read(response))!=-1)
                    {
                        streamToClient.write(response, 0, bytesRead);
                        streamToClient.flush();
                    }
                }
                catch(IOException exc){}
                streamToClient.close();
            }
            catch(IOException exc)
            {
                System.out.println(exc.getMessage());
            }
            finally
            {
                try
                {
                    if(server!=null) server.close();
                    if(client!=null) client.close();
                }
                catch(IOException exc){}
            }
        }
    }
}

You made simple tcp proxy with predefined hardcoded target: host:remote_port您使用预定义的硬编码目标制作了简单的 tcp 代理:host:remote_port

It is not a HTTP proxy.它不是 HTTP 代理。

So your solution should work in case:因此,您的解决方案应该适用于以下情况:

  1. you are running squid or some proper HTTP proxy on localhost:9001.您正在 localhost:9001 上运行 squid 或一些适当的 HTTP 代理。
  2. And use it as HTTP proxy only (I mean that when you configure browser you should not tell it that your app is https proxy).并且仅将其用作 HTTP 代理(我的意思是,当您配置浏览器时,您不应该告诉它您的应用程序是 https 代理)。

If you plan to make standalone proxy then you need to analyze HTTP request and get host, port and protocol from request to know what server should you connect (including port) and which protocol you should use (ie http or https).如果您打算制作独立代理,那么您需要分析 HTTP 请求并从请求中获取主机、端口和协议,以了解您应该连接哪个服务器(包括端口)以及您应该使用哪个协议(即 http 或 https)。 When browser request service directly (without proxy) it sends URI only and when browser sends request through proxy then it uses full URL in a request.当浏览器直接请求服务(没有代理)时,它只发送 URI,当浏览器通过代理发送请求时,它会在请求中使用完整的 URL。

so first line in a request will be something like that:所以请求中的第一行将是这样的:

GET http://google.com[:80]/blah-blah-blah HTTP/1.1
...headers here...

Your proxy need to analyze URL and get host, port and URI out of it.您的代理需要分析 URL 并从中获取主机、端口和 URI。 So you would need to resolve domain name and connect to the host to required port with modified first line.因此,您需要解析域名并使用修改后的第一行将主机连接到所需的端口。 It would look like:它看起来像:

GET /blah-blah-blah HTTP/1.1
...headers here...

And if you use extra http proxy server which listens on 9001 port then please check if it is in operational state.如果您使用额外的 http 代理服务器侦听 9001 端口,请检查它是否处于运行状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM