I am building a HTTP proxy with netty, which supports HTTP pipelining. Therefore I receive multiple HttpRequest
Objects on a single Channel and got the matching HttpResponse
Objects. The order of the HttpResponse
writes is the same than I got the HttpRequest
. If a HttpResponse
was written, the next one will be written when the HttpProxyHandler
receives a writeComplete
event.
The Pipeline should be convenient:
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());
Regarding this question only the order of the write calls should be important, but to be sure I build another Handler (HttpResponseWriteDelayHandler
) which suppresses the writeComplete
event until the whole response was written.
To test this I enabled network.http.proxy.pipelining
in Firefox and visited a page with many images and connections (a news page). The problem is, that the browser does not receive some responses in spite of the logs of the proxy consider them as sent successfully.
I have some findings:
- The problem only occurs if the connection from proxy to server is faster than the connection from proxy to browser.
- The problem occurs more often after sending a larger image on that connection, e.g. 20kB
- The problem does not occur if only
304 - Not Modified
responses were sent (refreshing the page considering browser cache) - Setting
bootstrap.setOption("sendBufferSize", 1048576);
or above does not help - Sleeping a timeframe dependent on the responses body size in before sending the
writeComplete
event inHttpResponseWriteDelayHandler
solves the problem, but is a very bad solution.