简体   繁体   中英

Proxy server can not send response back to client

I am creating a proxy server using Java while my client and server both are written in NodeJS. As client can send multiple request, so I am creating thread for each client request to proxy server. Now when I get response back from server (an integer value), I want to send the same data back to the client from my proxy server. But my proxy server is unable to do so.

Client expects a response within 100ms. So I have set connect and read time out property. If I do not receive response within this time then, I want to respond to the client with integer 0.

SocketServer.java

private int portNo;
private ServerSocket serverSocket = null;

public SocketServer(int portNo) {
    this.portNo = portNo;
    try {
        serverSocket = new ServerSocket(this.portNo);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public void runServer() {
    while(true) {
        try {
            Socket clientSocket = serverSocket.accept();
            new Thread(new Task(clientSocket)).start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

public static void main(String args[]) {
    SocketServer socketServer = new SocketServer(3000);
    socketServer.runServer();
}

Task.java

public class Task implements Runnable {

    Socket socket = null;

    public Task(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            String dataFromClient = in.readLine(); // this is the url from client
            String partOfLink = dataFromClient.substring(5, 9);

            URL url = new URL("http://localhost:3001/" + partOfLink);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setDoOutput(true);
            conn.setConnectTimeout(80);
            conn.setReadTimeout(80);

            // Get the response
            BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = rd.readLine()) != null) {
                out.write(line);
            }

        } catch (IOException e) {
            //e.printStackTrace();
            try {
                BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                out.write(0);
            } catch (IOException e1) {
                e1.printStackTrace();
            }   
        }
    }
}

The specific issue that you're hitting right now is probably that the client receives the zero and says "this isn't a complete HTTP reply and I'm expecting a complete HTTP reply, so more data must be coming", so it waits for more data

Since the client only speaks HTTP and you are not sending HTTP to the client in the timeout case, why would you expect it to work?

You are actually not doing this even in the success case! You have attached an HTTP decoder to the outbound connection and are relaying the decoded output to the client. But the client expects raw HTTP.

There are lots of ways this can bite you. Say the proxied response headers indicate chunked encoding. You either need to modify those headers or send the data to the client with chunked encoding too because your code to receive the proxy response decodes chunked encoding. Where is the code for this?

You need to correctly handle HTTP connection persistence. You need to detect whether the client supports it and whether the proxied reply is compatible with it to know how to handle the client connection after you proxy the reply. Should you close it? Should you try to receive another reply on the same connection? It depends on several factors -- where is the code to make this decision correctly?

There are lots of other issues with your code too. You should look at code for existing HTTP proxies that work and understand how they work. There are a large number of issues you must get right for a real HTTP proxy to work and you haven't addressed them.

There are some possible hacks that might get this approach to seem to work enough that you may be able to pass it off as done. But if this is an important application that has to be reliable, this is the wrong approach. HTTP proxies are big, complicated things. This code is not one.

Look at finding the simplest code for a working real HTTP proxy that you can use. Read the HTTP specification and look closely at the requirements for proxies. This is a minefield and you really should start with an HTTP proxy that's known to work and modify it as you need.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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