Ошибка при записи в обработку выходного потока

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

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

Изящным способом я имею в виду отображение или перенаправление пользователя на страницу с ошибкой «Внутренняя ошибка сервера».

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

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


person Mikey S.    schedule 17.08.2011    source источник


Ответы (2)


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

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

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

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

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

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

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

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

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

person Artefacto    schedule 17.08.2011
comment
Понятно ... Спасибо за информацию :) - person Mikey S.; 17.08.2011

Изящно я имею в виду отображение или перенаправление пользователя на страницу с ошибкой «Внутренняя ошибка сервера».

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

person user207421    schedule 17.08.2011