--- a/mercurial/hgweb/server.py Tue Jun 27 00:09:31 2006 -0700
+++ b/mercurial/hgweb/server.py Tue Jun 27 00:09:33 2006 -0700
@@ -10,7 +10,7 @@
import os, sys, errno
demandload(globals(), "urllib BaseHTTPServer socket SocketServer")
demandload(globals(), "mercurial:ui,hg,util,templater")
-demandload(globals(), "hgweb_mod:hgweb hgwebdir_mod:hgwebdir request:hgrequest")
+demandload(globals(), "hgweb_mod:hgweb hgwebdir_mod:hgwebdir request:wsgiapplication")
from mercurial.i18n import gettext as _
def _splitURI(uri):
@@ -25,6 +25,17 @@
path, query = uri, ''
return urllib.unquote(path), query
+class _error_logger(object):
+ def __init__(self, handler):
+ self.handler = handler
+ def flush(self):
+ pass
+ def write(str):
+ self.writelines(str.split('\n'))
+ def writelines(seq):
+ for msg in seq:
+ self.handler.log_error("HG error: %s", msg)
+
class _hgwebhandler(object, BaseHTTPServer.BaseHTTPRequestHandler):
def __init__(self, *args, **kargs):
self.protocol_version = 'HTTP/1.1'
@@ -84,10 +95,50 @@
if hval:
env[hkey] = hval
env['SERVER_PROTOCOL'] = self.request_version
+ env['wsgi.version'] = (1, 0)
+ env['wsgi.url_scheme'] = 'http'
+ env['wsgi.input'] = self.rfile
+ env['wsgi.errors'] = _error_logger(self)
+ env['wsgi.multithread'] = isinstance(self.server,
+ SocketServer.ThreadingMixIn)
+ env['wsgi.multiprocess'] = isinstance(self.server,
+ SocketServer.ForkingMixIn)
+ env['wsgi.run_once'] = 0
- req = hgrequest(self.rfile, self.wfile, env)
- self.send_response(200, "Script output follows")
- self.close_connection = self.server.make_and_run_handler(req)
+ self.close_connection = True
+ self.saved_status = None
+ self.saved_headers = []
+ self.sent_headers = False
+ req = self.server.reqmaker(env, self._start_response)
+ for data in req:
+ if data:
+ self._write(data)
+
+ def send_headers(self):
+ if not self.saved_status:
+ raise AssertionError("Sending headers before start_response() called")
+ saved_status = self.saved_status.split(None, 1)
+ saved_status[0] = int(saved_status[0])
+ self.send_response(*saved_status)
+ for h in self.saved_headers:
+ self.send_header(*h)
+ self.end_headers()
+ self.sent_headers = True
+
+ def _start_response(self, http_status, headers, exc_info=None):
+ code, msg = http_status.split(None, 1)
+ code = int(code)
+ self.saved_status = http_status
+ self.saved_headers = headers
+ return self._write
+
+ def _write(self, data):
+ if not self.saved_status:
+ raise AssertionError("data written before start_response() called")
+ elif not self.sent_headers:
+ self.send_headers()
+ self.wfile.write(data)
+ self.wfile.flush()
def create_server(ui, repo):
use_threads = True
@@ -127,8 +178,9 @@
self.webdir_conf = webdir_conf
self.webdirmaker = hgwebdir
self.repoviewmaker = hgweb
+ self.reqmaker = wsgiapplication(self.make_handler)
- def make_and_run_handler(self, req):
+ def make_handler(self):
if self.webdir_conf:
hgwebobj = self.webdirmaker(self.webdir_conf)
elif self.repo is not None:
@@ -136,8 +188,7 @@
repo.origroot))
else:
raise hg.RepoError(_('no repo found'))
- hgwebobj.run(req)
- return req.will_close
+ return hgwebobj
class IPv6HTTPServer(MercurialHTTPServer):
address_family = getattr(socket, 'AF_INET6', None)