Как я могу сообщить об ошибке в середине фрагментированного http-отклика, если я хочу закрыть соединение? - PullRequest
1 голос
/ 10 октября 2008

(См. Связанный вопрос: Как мне сообщить об ошибке в середине фрагментированного http-отклика, не закрывая соединение? )

В моем случае, # 1 желает, чтобы браузер отображал сообщение об ошибке. Неважно, как малоинформативно.

Закрытие ServletResponse outputStream, очевидно, не работает. Также не выдает исключение, даже если я не закрываюсь первым (проверено на Tomcat 6.0.16). Я думаю, что мне нужен либо пакет RST, либо FIN в середине фрагмента, либо неправильно сформированные заголовки фрагментов.

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

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

Ответы [ 3 ]

1 голос
/ 16 октября 2008

Мой собственный ответ, после исследования.

Часть первая. Кажется, нет никакого способа убедить протестированные мной серверы приложений в том, что они выдавали ошибку на провод после фазы «фиксации». Следующий код сервлета приводит к допустимым заголовкам HTTP Chunked Transfer в сокете. Интересно, что в случае WebSphere сообщение об ошибке добавляется в конец потока перед отметкой конца.

public class Servlet extends HttpServlet {
    public static final int ARRAY_SIZE = 65536;
    private static final int SEND_COUNT = 100000;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException {

        String testData = "This is a fairly long piece of test text, running on and on and on, over and over.";

        final ServletOutputStream outputStream = response.getOutputStream();
        for (int i = 0; i < SEND_COUNT; ++i) {
            outputStream.println(testData);
        }
        throw new ServletException("Break it now");
    }
}

Часть вторая. Даже если сервер приложений захотел либо записать фиктивные данные в провод, либо закрыть сокет без закрывающего куска нулевой длины, обычные клиенты не сообщают об ошибке. IE7, FF3 и cURL не сообщают об ошибках в кодировании чанка. Это делает загрузку HTTP по своей сути ненадежной и противоречит духу, если не букве HTTP 1.1 RFC.

0 голосов
/ 16 октября 2008

API сервлета не позволяет этого. Как только ответ принят, код ответа был отправлен. Лучшее, что вы можете сделать, это закрыть соединение и зарегистрировать ошибку.

0 голосов
/ 10 октября 2008

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

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

<script type="text/javascript"> alert("Processing failed!"); </script>

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...