Самостоятельно созданный http-сервер не может обработать запрос почтальона - PullRequest
0 голосов
/ 15 октября 2018

Я пытаюсь реализовать простой http-сервер на Java, чтобы понять, как работает http-сервер.Теперь я могу отправить запрос из любого браузера и получить правильный ответ, однако, когда я пытаюсь смоделировать запрос от Почтальона, он всегда выдает java.net.SocketException: Broken pipe (Write failed) исключение.

Мой http-сервер очень прост: после получения запроса, отправьте сообщение отправителю.

Реализация выглядит следующим образом: Исходный код

package com.ont.http;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class SingleThreadHttpServer implements HttpServer {

    public void run(int port) throws IOException {
        ServerSocket serverSocket = new ServerSocket(port);
        try {
            while (true) {
                Socket socket = serverSocket.accept();

                BufferedReader inBufferReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                StringBuilder stringBuffer = new StringBuilder();

                String inputLine;
                while ((inputLine = inBufferReader.readLine()) != null && !inputLine.equals("")) {
                    stringBuffer.append(inputLine);
                    stringBuffer.append("\r\n");
                }

                System.out.println(stringBuffer.toString());

                OutputStream outStream = socket.getOutputStream();
                BufferedReader bufferedReader = new BufferedReader(new StringReader("A Message from server."));

                // Header should be ended with '\r\n' at each line.
                outStream.write("HTTP/1.1 200 OK\r\n".getBytes());
                outStream.write("Main: OneServer 0.1\r\n".getBytes());
                outStream.write("Content-length: 22\r\n".getBytes()); // if text/plain the length is required
                outStream.write("Content-Type: text/plain\r\n".getBytes());

                // An empty line is required after the header
                outStream.write("\r\n".getBytes());

                String line;
                while ((line = bufferedReader.readLine()) != null) {
                    outStream.write(line.getBytes());
                }

                inBufferReader.close();
                bufferedReader.close();
                outStream.flush();
                outStream.close(); // Socket will close automatically once output stream is closed.
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Любые типы запросов, отправленных почтальоном, будут немедленновызвать это исключение, и debug сообщает, что соединение с сокетом было потеряно во время outStream.write(...).если я отправляю из браузера, это никогда не вызовет этой проблемы.

Чего я не понимаю, так это того, что к Почтальону не должны применяться какие-либо настройки, потому что, когда я пытаюсь смоделировать запрос к своему коту, он обрабатывает все как талисман, должно быть что-то пропалоне так с моим кодом, но я не знаю, где и почему.

Буду признателен за любые подсказки или подсказки, спасибо.

----- Обновления ----

С консоли почтальона я вижу это исключение,

Error: read ECONNRESET
Request Headers:
accept:"text/plain"
cache-control:"no-cache"

Если я оставил только outStream.write("HTTP/1.1 200 OK\r\n".getBytes()) эту строку и удалил все остальные outStream.write..., и браузеры, и почтальон работают как шарм.это действительно тянет меня за волосы, но почему?

1 Ответ

0 голосов
/ 15 октября 2018

Исключение означает, что другая сторона уже закрыла соединение, пока вы все еще пытаетесь записать в него.

На данный момент это всего лишь предположение, но, возможно, Почтальону не нравится ответ, который он получает, и он просто сдается.Браузер может по-прежнему принимать то, что вы делаете, изо всех сил, но это не обязательно означает, что ответ правильный.Я не знаю всю http спецификацию по голове, поэтому я не мог сразу сказать вам, если это так.Чтобы продолжить, возможно, вы могли бы взглянуть на такой инструмент, как Fiddler, и посмотреть, что обычно возвращается с http-сервера после базового запроса, а затем посмотреть, что вы что-то упустили.

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

...