summaryrefslogtreecommitdiff
path: root/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/mercurial/hgweb/server.py
diff options
context:
space:
mode:
Diffstat (limited to 'eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/mercurial/hgweb/server.py')
-rw-r--r--eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/mercurial/hgweb/server.py309
1 files changed, 0 insertions, 309 deletions
diff --git a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/mercurial/hgweb/server.py b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/mercurial/hgweb/server.py
deleted file mode 100644
index fa31afa..0000000
--- a/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/mercurial/hgweb/server.py
+++ /dev/null
@@ -1,309 +0,0 @@
-# hgweb/server.py - The standalone hg web server.
-#
-# Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
-# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-import os, sys, errno, urllib, BaseHTTPServer, socket, SocketServer, traceback
-from mercurial import util, error
-from mercurial.i18n import _
-
-def _splitURI(uri):
- """ Return path and query splited from uri
-
- Just like CGI environment, the path is unquoted, the query is
- not.
- """
- if '?' in uri:
- path, query = uri.split('?', 1)
- else:
- 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(self, str):
- self.writelines(str.split('\n'))
- def writelines(self, seq):
- for msg in seq:
- self.handler.log_error("HG error: %s", msg)
-
-class _httprequesthandler(BaseHTTPServer.BaseHTTPRequestHandler):
-
- url_scheme = 'http'
-
- @staticmethod
- def preparehttpserver(httpserver, ssl_cert):
- """Prepare .socket of new HTTPServer instance"""
- pass
-
- def __init__(self, *args, **kargs):
- self.protocol_version = 'HTTP/1.1'
- BaseHTTPServer.BaseHTTPRequestHandler.__init__(self, *args, **kargs)
-
- def _log_any(self, fp, format, *args):
- fp.write("%s - - [%s] %s\n" % (self.client_address[0],
- self.log_date_time_string(),
- format % args))
- fp.flush()
-
- def log_error(self, format, *args):
- self._log_any(self.server.errorlog, format, *args)
-
- def log_message(self, format, *args):
- self._log_any(self.server.accesslog, format, *args)
-
- def do_write(self):
- try:
- self.do_hgweb()
- except socket.error, inst:
- if inst[0] != errno.EPIPE:
- raise
-
- def do_POST(self):
- try:
- self.do_write()
- except StandardError:
- self._start_response("500 Internal Server Error", [])
- self._write("Internal Server Error")
- tb = "".join(traceback.format_exception(*sys.exc_info()))
- self.log_error("Exception happened during processing "
- "request '%s':\n%s", self.path, tb)
-
- def do_GET(self):
- self.do_POST()
-
- def do_hgweb(self):
- path, query = _splitURI(self.path)
-
- env = {}
- env['GATEWAY_INTERFACE'] = 'CGI/1.1'
- env['REQUEST_METHOD'] = self.command
- env['SERVER_NAME'] = self.server.server_name
- env['SERVER_PORT'] = str(self.server.server_port)
- env['REQUEST_URI'] = self.path
- env['SCRIPT_NAME'] = self.server.prefix
- env['PATH_INFO'] = path[len(self.server.prefix):]
- env['REMOTE_HOST'] = self.client_address[0]
- env['REMOTE_ADDR'] = self.client_address[0]
- if query:
- env['QUERY_STRING'] = query
-
- if self.headers.typeheader is None:
- env['CONTENT_TYPE'] = self.headers.type
- else:
- env['CONTENT_TYPE'] = self.headers.typeheader
- length = self.headers.getheader('content-length')
- if length:
- env['CONTENT_LENGTH'] = length
- for header in [h for h in self.headers.keys()
- if h not in ('content-type', 'content-length')]:
- hkey = 'HTTP_' + header.replace('-', '_').upper()
- hval = self.headers.getheader(header)
- hval = hval.replace('\n', '').strip()
- if hval:
- env[hkey] = hval
- env['SERVER_PROTOCOL'] = self.request_version
- env['wsgi.version'] = (1, 0)
- env['wsgi.url_scheme'] = self.url_scheme
- 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
-
- self.close_connection = True
- self.saved_status = None
- self.saved_headers = []
- self.sent_headers = False
- self.length = None
- for chunk in self.server.application(env, self._start_response):
- self._write(chunk)
-
- 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)
- should_close = True
- for h in self.saved_headers:
- self.send_header(*h)
- if h[0].lower() == 'content-length':
- should_close = False
- self.length = int(h[1])
- # The value of the Connection header is a list of case-insensitive
- # tokens separated by commas and optional whitespace.
- if 'close' in [token.strip().lower() for token in
- self.headers.get('connection', '').split(',')]:
- should_close = True
- if should_close:
- self.send_header('Connection', 'close')
- self.close_connection = should_close
- 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
- bad_headers = ('connection', 'transfer-encoding')
- self.saved_headers = [h for h in headers
- if h[0].lower() not in bad_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()
- if self.length is not None:
- if len(data) > self.length:
- raise AssertionError("Content-length header sent, but more "
- "bytes than specified are being written.")
- self.length = self.length - len(data)
- self.wfile.write(data)
- self.wfile.flush()
-
-class _httprequesthandleropenssl(_httprequesthandler):
- """HTTPS handler based on pyOpenSSL"""
-
- url_scheme = 'https'
-
- @staticmethod
- def preparehttpserver(httpserver, ssl_cert):
- try:
- import OpenSSL
- OpenSSL.SSL.Context
- except ImportError:
- raise util.Abort(_("SSL support is unavailable"))
- ctx = OpenSSL.SSL.Context(OpenSSL.SSL.SSLv23_METHOD)
- ctx.use_privatekey_file(ssl_cert)
- ctx.use_certificate_file(ssl_cert)
- sock = socket.socket(httpserver.address_family, httpserver.socket_type)
- httpserver.socket = OpenSSL.SSL.Connection(ctx, sock)
- httpserver.server_bind()
- httpserver.server_activate()
-
- def setup(self):
- self.connection = self.request
- self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
- self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)
-
- def do_write(self):
- import OpenSSL
- try:
- _httprequesthandler.do_write(self)
- except OpenSSL.SSL.SysCallError, inst:
- if inst.args[0] != errno.EPIPE:
- raise
-
- def handle_one_request(self):
- import OpenSSL
- try:
- _httprequesthandler.handle_one_request(self)
- except (OpenSSL.SSL.SysCallError, OpenSSL.SSL.ZeroReturnError):
- self.close_connection = True
- pass
-
-class _httprequesthandlerssl(_httprequesthandler):
- """HTTPS handler based on Pythons ssl module (introduced in 2.6)"""
-
- url_scheme = 'https'
-
- @staticmethod
- def preparehttpserver(httpserver, ssl_cert):
- try:
- import ssl
- ssl.wrap_socket
- except ImportError:
- raise util.Abort(_("SSL support is unavailable"))
- httpserver.socket = ssl.wrap_socket(httpserver.socket, server_side=True,
- certfile=ssl_cert, ssl_version=ssl.PROTOCOL_SSLv23)
-
- def setup(self):
- self.connection = self.request
- self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
- self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)
-
-try:
- from threading import activeCount
- _mixin = SocketServer.ThreadingMixIn
-except ImportError:
- if hasattr(os, "fork"):
- _mixin = SocketServer.ForkingMixIn
- else:
- class _mixin:
- pass
-
-def openlog(opt, default):
- if opt and opt != '-':
- return open(opt, 'a')
- return default
-
-class MercurialHTTPServer(object, _mixin, BaseHTTPServer.HTTPServer):
-
- # SO_REUSEADDR has broken semantics on windows
- if os.name == 'nt':
- allow_reuse_address = 0
-
- def __init__(self, ui, app, addr, handler, **kwargs):
- BaseHTTPServer.HTTPServer.__init__(self, addr, handler, **kwargs)
- self.daemon_threads = True
- self.application = app
-
- handler.preparehttpserver(self, ui.config('web', 'certificate'))
-
- prefix = ui.config('web', 'prefix', '')
- if prefix:
- prefix = '/' + prefix.strip('/')
- self.prefix = prefix
-
- alog = openlog(ui.config('web', 'accesslog', '-'), sys.stdout)
- elog = openlog(ui.config('web', 'errorlog', '-'), sys.stderr)
- self.accesslog = alog
- self.errorlog = elog
-
- self.addr, self.port = self.socket.getsockname()[0:2]
- self.fqaddr = socket.getfqdn(addr[0])
-
-class IPv6HTTPServer(MercurialHTTPServer):
- address_family = getattr(socket, 'AF_INET6', None)
- def __init__(self, *args, **kwargs):
- if self.address_family is None:
- raise error.RepoError(_('IPv6 is not available on this system'))
- super(IPv6HTTPServer, self).__init__(*args, **kwargs)
-
-def create_server(ui, app):
-
- if ui.config('web', 'certificate'):
- if sys.version_info >= (2, 6):
- handler = _httprequesthandlerssl
- else:
- handler = _httprequesthandleropenssl
- else:
- handler = _httprequesthandler
-
- if ui.configbool('web', 'ipv6'):
- cls = IPv6HTTPServer
- else:
- cls = MercurialHTTPServer
-
- # ugly hack due to python issue5853 (for threaded use)
- import mimetypes; mimetypes.init()
-
- address = ui.config('web', 'address', '')
- port = util.getport(ui.config('web', 'port', 8000))
- try:
- return cls(ui, app, (address, port), handler)
- except socket.error, inst:
- raise util.Abort(_("cannot start server at '%s:%d': %s")
- % (address, port, inst.args[1]))