0

I'm writting my own Java Proxy Server. 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. 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){}
            }
        }
    }
}

1 Answer 1

1

You made simple tcp proxy with predefined hardcoded target: host:remote_port

It is not a HTTP proxy.

So your solution should work in case:

  1. you are running squid or some proper HTTP proxy on localhost:9001.
  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).

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 (i.e. http or 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.

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.