Ошибка в середине записи в обработку выходного потока - PullRequest
4 голосов
/ 17 августа 2011

Я создаю http-сервер как часть моего академического курса Java, Сервер должен поддерживать только базовые запросы GET и POST.

Мне было интересно, существует ли элегантный способ обработки ошибки, которая происходит в середине записи содержимого потока файла html (и после того, как я уже отправил заголовки ответа) в выходной поток HttpServer .

Под элегантным способом я имею в виду показ или перенаправление пользователя на страницу ошибки «Внутренняя ошибка сервера».

Я попытался повторно отправить заголовки ответа http с кодом ошибки 501, но java выдает исключение, которое утверждает, что заголовки уже отправлены ...

Одним из исправлений было бы чтение содержимого файла в память и только затем отправка заголовков и содержимого, но могут возникнуть другие проблемы, и, кроме того, я не хочу загружать огромные файлы в память перед их отправкой в ответ.

Ответы [ 2 ]

4 голосов
/ 17 августа 2011

После отправки статуса ответа по проводам его нельзя изменить. Таким образом, если вы отправили ответ 200 OK, вы не сможете передумать впоследствии. Как вы обнаружили, это создает проблему в случае ошибок, возникающих в середине ответа.

Насколько я знаю, единственная мысль, которую вы можете сделать, - это отправить частичный ответ. См. Раздел 3.6.1 RFC 2616:

Кодированная часть изменяет тело сообщения, чтобы передать его как последовательность кусков, каждый со своим собственным индикатором размера, сопровождаемый ДОПОЛНИТЕЛЬНЫМ трейлером, содержащим поля заголовка объекта. это позволяет динамически создаваемый контент передаваться вместе с информация, необходимая получателю для подтверждения того, что он получил полное сообщение.

Цель этого трейлера - предоставить информацию об теле сущности, которую невозможно рассчитать до отправки тела сущности. Тем не менее, раздел 7.1 позволяет включать в этот трейлер любой заголовок:

Механизм расширения заголовка допускает дополнительные поля заголовка объекта быть определенным без изменения протокола, но эти поля не могут быть признанным получателем узнаваемым. Нераспознанный заголовок поля ДОЛЖНЫ игнорироваться получателем и ДОЛЖНЫ быть перенаправлены прозрачные прокси.

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

Преждевременное завершение соединения в сообщении с заголовком Content-length - это опция, но она явно запрещена:

Когда в сообщении указана длина содержимого, а тело сообщения разрешено, значение его поля ДОЛЖНО точно соответствовать количеству OCTET в тело сообщения. HTTP / 1.1 пользовательские агенты ДОЛЖНЫ уведомлять пользователя, когда получена и обнаружена неверная длина.

Тем не менее, хотя сервер не должен отправлять сообщение короче, чем он рекламирует, клиент должен проверить это условие ошибки и сообщить об этом (а прокси-сервер может даже кэшировать этот частичный ответ).

0 голосов
/ 17 августа 2011

Под элегантным способом я имею в виду показ или перенаправление пользователя на страницу ошибки «Внутренняя ошибка сервера».

Если вы не можете отправить ответ «успех», как вы?собираетесь отправить другой ответ?Все, что вы можете сделать, это войти в систему и забыть об этом.

...