Details
-
Suggestion
-
Resolution: Won't Fix
-
None
-
None
Description
Under certain circumstances on some application servers (this was observed on
WebLogic 8.1), a 304 response can be closely followed by an empty content
packet:
"0000\r\n\r\n". For some reason, sometimes - not always, but reproducibly often
enough - this gets interpretted as a 200 (as shown in LiveHeaders), and the
browser then waits for the rest of the content. There is no further content
coming and eventually the server closes the socket, leaving the browser
displaying the following (the bit in between the lines):
----------------------------
0000
HTTP/1.1 304 Not Modified
Date: Wed, 20 Dec 2006 06:24:02 GMT
0000
----------------------------
The server response is made up of two TCP packets, the first containing the 304
and the second containing the empty content. If they are a single packet, the
problem cannot be reproduced. Turning off keep-alive and switching to HTTP 1.0
also appear to fix this (at least make it no longer visible!)
BTW. I tried to file this on Mozilla core, but couldn't find the Bugzilla
product. Please move over to there and to the Network:HTTP component if
possible.
I am going on holiday over christmas, any urgent follow up should be cc'd to
dylan@atlassian.com
Reproducible: Sometimes
Steps to Reproduce:
1. make request to dodgy web-server.
2. web-server responds with 304 and then empty content packet.
Actual Results:
Client waits for server until socket is closed (20+ seconds), then shows the
304 and content responses and as though they were the page content. If the
request were for an image or javascript, the server tries to interpret them as
such.
Expected Results:
Client properly uses cached version of resource.
This was initially found in Firefox 2 on Ubuntu and Red Hat, confirmed on
Windows in both version 2 and Minefield 3.0a1.
The following Java class acts as a very simple web-server hanging on port 8070
and reproduces the problem. To use, point the browser to this port and then
refresh. For my Windows browser in VMWare, this could be reproduced after only
a couple of refreshes, on the Ubuntu host, it took up to 20 refreshes before
being seen, but was still always reproducible.
---------------
/** * Simple server that returns an HTTP Response 200 on a socket and subsequently returns 304s with a follow-up empty * chunk. This reproduces a bug in Firefox that is seen with some content served from WebLogic. */ public class WebServerTest { public static void main(String[] args) throws Exception { new WebServerTest().run(); } static String getResponse() { StringBuilder builder = new StringBuilder("HTTP/1.1 200 OK\r\nDate: Wed, 20 Dec 2006 06:24:02 GMT\r\nContent-Length: "); String content = "<html><head><title>Test Page</title></head><body><h1>Some Content</h1>This is content</body></html>"; builder.append(content.length()); builder.append("\r\nLast-Modified: Tue, 19 Dec 2006 00:37:34 GMT\r\n\r\n"); builder.append(content); builder.append("\r\n\r\n"); return builder.toString(); } static void copy(String string, OutputStream stream) throws IOException { final int bufferSize = 8 * 1024; final Reader input = new StringReader(string); final Writer output = new OutputStreamWriter(stream); final char[] buffer = new char[bufferSize]; int n = 0; while (-1 != (n = input.read(buffer))) { output.write(buffer, 0, n); } output.flush(); } private final Executor executor = Executors.newCachedThreadPool(); private final ServerSocket serverSocket; private final String response = getResponse(); private final String notModified = "HTTP/1.1 304 Not Modified\r\nDate: Wed, 20 Dec 2006 06:24:02 GMT\r\n\r\n"; private final String emptyContent = "0000\r\n\r\n"; public WebServerTest() { try { this.serverSocket = new ServerSocket(8070); } catch (UnknownHostException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } } public void run() { while (true) { try { executor.execute(new RequestHandler(serverSocket.accept())); } catch (IOException e) { throw new RuntimeException(e); } } } class RequestHandler implements Runnable { private final Socket socket; boolean newSocket = true; RequestHandler(Socket socket) { this.socket = socket; } public void run() { while (true) { try { getInput(socket); } catch (TimeoutException e) { try { socket.close(); } catch (IOException ignore) {} return; } try { final OutputStream outputStream = socket.getOutputStream(); if (newSocket) { copy(response, outputStream); newSocket = false; } else { copy(notModified, outputStream); // send a second chunk, an empty content packet that fools firefox // into thinking more is on the way copy(emptyContent, outputStream); } outputStream.flush(); } catch (IOException e) { throw new RuntimeException(e); } } } String getInput(Socket socket) throws TimeoutException { final int WAIT_TIME = 10; final int TEN_SECONDS = 10000; int waitedFor = 0; StringBuilder buffer; try { final InputStream inputStream = socket.getInputStream(); while (inputStream.available() == 0) { Thread.sleep(WAIT_TIME); waitedFor = waitedFor + WAIT_TIME; if (waitedFor > TEN_SECONDS) { socket.close(); throw new TimeoutException(); } } buffer = new StringBuilder(inputStream.available()); while (inputStream.available() > 0) { buffer.append((char) inputStream.read()); } } catch (IOException e) { throw new RuntimeException(e); } catch (InterruptedException e) { throw new RuntimeException(e); } return buffer.toString(); } } }
Attachments
Issue Links
- is related to
-
JRASERVER-14474 When viewing issues, JIRA hangs for 30s, then renders page without stylesheets when using GZip compression, mod_jk / mod_proxy_ajp and SSL
- Closed