# HG changeset patch # User Augie Fackler # Date 1287268144 18000 # Node ID 8dcd3203a2614286458f8db6dc794c76ea75f6f8 # Parent e9733f96b38bb03895c832ffebb482f0e781a776 hgweb: don't send a body or illegal headers during 304 response Without this fix, mod_wsgi and spawning get in a wedged state after sending a 304 response. Not sending a body fixed that problem. The header change was discovered by using wsgiref.validate.validator to check for other errors. diff -r e9733f96b38b -r 8dcd3203a261 mercurial/hgweb/hgweb_mod.py --- a/mercurial/hgweb/hgweb_mod.py Sat Oct 16 22:40:46 2010 +0200 +++ b/mercurial/hgweb/hgweb_mod.py Sat Oct 16 17:29:04 2010 -0500 @@ -9,7 +9,8 @@ import os from mercurial import ui, hg, hook, error, encoding, templater from common import get_mtime, ErrorResponse, permhooks, caching -from common import HTTP_OK, HTTP_BAD_REQUEST, HTTP_NOT_FOUND, HTTP_SERVER_ERROR +from common import HTTP_OK, HTTP_NOT_MODIFIED, HTTP_BAD_REQUEST +from common import HTTP_NOT_FOUND, HTTP_SERVER_ERROR from request import wsgirequest import webcommands, protocol, webutil @@ -202,6 +203,9 @@ return tmpl('error', error=str(inst)) except ErrorResponse, inst: req.respond(inst, ctype) + if inst.code == HTTP_NOT_MODIFIED: + # Not allowed to return a body on a 304 + return [''] return tmpl('error', error=inst.message) def templater(self, req): diff -r e9733f96b38b -r 8dcd3203a261 mercurial/hgweb/request.py --- a/mercurial/hgweb/request.py Sat Oct 16 22:40:46 2010 +0200 +++ b/mercurial/hgweb/request.py Sat Oct 16 17:29:04 2010 -0500 @@ -8,7 +8,7 @@ import socket, cgi, errno from mercurial import util -from common import ErrorResponse, statusmessage +from common import ErrorResponse, statusmessage, HTTP_NOT_MODIFIED shortcuts = { 'cl': [('cmd', ['changelog']), ('rev', None)], @@ -83,6 +83,13 @@ if isinstance(status, ErrorResponse): self.header(status.headers) + if status.code == HTTP_NOT_MODIFIED: + # RFC 2616 Section 10.3.5: 304 Not Modified has cases where + # it MUST NOT include any headers other than these and no + # body + self.headers = [(k, v) for (k, v) in self.headers if + k in ('Date', 'ETag', 'Expires', + 'Cache-Control', 'Vary')] status = statusmessage(status.code, status.message) elif status == 200: status = '200 Script output follows'