Я создаю HTTP-прокси с помощью netty, который поддерживает конвейерную обработку HTTP. Поэтому я получаю несколько объектов HttpRequest
на одном канале и получаю соответствующие объекты HttpResponse
. Порядок записи HttpResponse
такой же, как у HttpRequest
. Если было записано HttpResponse
, следующее будет записано, когда HttpProxyHandler
получит событие writeComplete
.
Pipeline должен быть удобным:
final ChannelPipeline pipeline = Channels.pipeline();
pipeline.addLast("decoder", new HttpRequestDecoder());
pipeline.addLast("encoder", new HttpResponseEncoder());
pipeline.addLast("writer", new HttpResponseWriteDelayHandler());
pipeline.addLast("deflater", new HttpContentCompressor(9));
pipeline.addLast("handler", new HttpProxyHandler());
Относительно этого вопроса важен только порядок вызовов записи, но для верности я создаю еще один обработчик (HttpResponseWriteDelayHandler
), который подавляет событие writeComplete
до тех пор, пока не будет записан весь ответ.
Чтобы проверить это, я включил network.http.proxy.pipelining
в Firefox и посетил страницу с большим количеством изображений и ссылок (страница новостей). Проблема в том, что браузер не получает некоторые ответы, несмотря на то, что логи прокси считают их успешно отправленными.
У меня есть некоторые выводы:
- Проблема возникает только в том случае, если соединение прокси-сервера с сервером быстрее, чем соединение прокси-сервера с браузером.
- Проблема возникает чаще после отправки большего изображения по этому соединению, например. 20 КБ
- Проблема не возникает, если было отправлено только
304 - Not Modified
ответов (обновление страницы с учетом кеша браузера) - Установка
bootstrap.setOption("sendBufferSize", 1048576);
или выше не помогает - Задержка периода времени, зависящего от размера тела ответа, перед отправкой события
writeComplete
вHttpResponseWriteDelayHandler
решает проблему, но это очень плохое решение.