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.
--- 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):
--- 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'