Прокси-сервер не может отправить ответ клиенту - PullRequest
0 голосов
/ 20 декабря 2018

Я создаю прокси-сервер, используя Java, в то время как мой клиент и сервер оба написаны на NodeJS.Как клиент может отправить несколько запросов, так что я создаю поток для каждого запроса клиента на прокси-сервер.Теперь, когда я получаю ответ от сервера (целочисленное значение), я хочу отправить те же данные клиенту с моего прокси-сервера.Но мой прокси-сервер не может этого сделать.

Клиент ожидает ответа в течение 100 мс.Итак, я установил свойство подключения и считывания времени ожидания.Если я не получу ответ в течение этого времени, я хочу ответить клиенту целым числом 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();
}

Задача.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();
            }   
        }
    }
}

1 Ответ

0 голосов
/ 20 декабря 2018

Особая проблема, с которой вы сталкиваетесь сейчас, это, вероятно, то, что клиент получает ноль и говорит: «Это не полный HTTP-ответ, и я ожидаю полного HTTP-ответа, поэтому должно поступить больше данных»,поэтому он ожидает больше данных

Поскольку клиент говорит только HTTP, а вы не отправляете HTTP клиенту в случае тайм-аута, почему вы ожидаете, что он будет работать?

Вы на самом деле неделать это даже в случае успеха!Вы подключили HTTP-декодер к исходящему соединению и передаете вывод декодированного клиенту.Но клиент ожидает, что raw HTTP.

Существует множество способов, которые могут вас укусить.Скажем, заголовки прокси-ответа указывают на чанкированное кодированиеВам нужно либо изменить эти заголовки, либо отправить данные клиенту с помощью chunked-кодировки, потому что ваш код для получения ответа прокси-сервера декодирует chunked-кодировку.Где код для этого?

Вам необходимо правильно обрабатывать постоянство HTTP-соединения.Вам необходимо определить, поддерживает ли клиент его и совместим ли с ним прокси-ответ, чтобы знать, как обрабатывать клиентское соединение после того, как вы проксируете ответ.Вы должны закрыть это?Если вы попытаетесь получить другой ответ по тому же соединению?Это зависит от нескольких факторов: где находится код, позволяющий принять правильное решение?

Есть и другие проблемы с вашим кодом.Вы должны посмотреть на код для существующих HTTP прокси и понять, как они работают.Существует большое количество проблем, которые вы должны решить, чтобы действительный HTTP-прокси работал, и вы не обратились к ним.

Существуют некоторые возможные хаки, которые могут заставить этот подход работать так, что вы можетебыть в состоянии выдать это, как сделано.Но если это важное приложение, которое должно быть надежным, это неправильный подход.HTTP прокси большие, сложные вещи.Этот код не один.

Посмотрите, как найти простейший код для работающего реального HTTP-прокси, который вы можете использовать.Прочитайте спецификацию HTTP и внимательно изучите требования к прокси.Это минное поле, и вы действительно должны начать с HTTP-прокси, который, как известно, работает, и изменять его по мере необходимости.

...