Fix https transports, certificates etc.

Now we can serve https: the send_error() must be fixed so that
content-lenth is specified, certificates are configurable and
connections get properly shutdown so that the client won't wait
forever.

bzr revid: p_christ@hol.gr-20090831132956-00atxsfcy3qkdw4j
This commit is contained in:
P. Christeas 2009-08-31 16:29:56 +03:00
parent a267ef5d05
commit 0a838fba3a
2 changed files with 67 additions and 4 deletions

View File

@ -88,6 +88,12 @@ class SecureMultiHandler2(SecureMultiHTTPHandler):
def log_message(self, format, *args):
netsvc.Logger().notifyChannel('https',netsvc.LOG_DEBUG,format % args)
def getcert_fnames(self):
tc = tools.config
fcert = tc.get_misc('httpsd','sslcert', 'ssl/server.cert')
fkey = tc.get_misc('httpsd','sslkey', 'ssl/server.key')
return (fcert,fkey)
class HttpDaemon(threading.Thread, netsvc.Server):
def __init__(self, interface, port):
threading.Thread.__init__(self)
@ -141,6 +147,23 @@ class HttpSDaemon(threading.Thread, netsvc.Server):
netsvc.Logger().notifyChannel('httpd-ssl', netsvc.LOG_CRITICAL, "Error occur when starting the server daemon: %s" % (e,))
raise
def attach(self, path, gw):
pass
def stop(self):
self.running = False
if os.name != 'nt':
self.server.socket.shutdown( hasattr(socket, 'SHUT_RDWR') and socket.SHUT_RDWR or 2 )
self.server.socket.close()
def run(self):
#self.server.register_introspection_functions()
self.running = True
while self.running:
self.server.handle_request()
return True
httpd = None
httpsd = None
@ -175,7 +198,7 @@ def reg_http_service(hts, secure_only = False):
return
import SimpleXMLRPCServer
class XMLRPCRequestHandler(netsvc.OpenERPDispatcher,SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
class XMLRPCRequestHandler(netsvc.OpenERPDispatcher,FixSendError,SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
rpc_paths = []
protocol_version = 'HTTP/1.1'
def _dispatch(self, method, params):

View File

@ -146,7 +146,32 @@ class dummyconn:
def shutdown(self, tru):
pass
class MultiHTTPHandler(BaseHTTPRequestHandler):
def _quote_html(html):
return html.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")
class FixSendError:
def send_error(self, code, message=None):
#overriden from BaseHTTPRequestHandler, we also send the content-length
try:
short, long = self.responses[code]
except KeyError:
short, long = '???', '???'
if message is None:
message = short
explain = long
self.log_error("code %d, message %s", code, message)
# using _quote_html to prevent Cross Site Scripting attacks (see bug #1100201)
content = (self.error_message_format %
{'code': code, 'message': _quote_html(message), 'explain': explain})
self.send_response(code, message)
self.send_header("Content-Type", self.error_content_type)
self.send_header('Connection', 'close')
self.send_header('Content-Length', len(content) or 0)
self.end_headers()
if self.command != 'HEAD' and code >= 200 and code not in (204, 304):
self.wfile.write(content)
class MultiHTTPHandler(FixSendError,BaseHTTPRequestHandler):
""" this is a multiple handler, that will dispatch each request
to a nested handler, iff it matches
@ -304,17 +329,32 @@ class MultiHTTPHandler(BaseHTTPRequestHandler):
class SecureMultiHTTPHandler(MultiHTTPHandler):
def getcert_fnames(self):
""" Return a pair with the filenames of ssl cert,key
Override this to direct to other filenames
"""
return ('server.cert','server.key')
def setup(self):
import ssl
certfile, keyfile = self.getcert_fnames()
self.connection = ssl.wrap_socket(self.request,
server_side=True,
certfile="server.cert",
keyfile="server.key",
certfile=certfile,
keyfile=keyfile,
ssl_version=ssl.PROTOCOL_SSLv23)
self.rfile = self.connection.makefile('rb', self.rbufsize)
self.wfile = self.connection.makefile('wb', self.wbufsize)
self.log_message("Secure %s connection from %s",self.connection.cipher(),self.client_address)
def finish(self):
# With ssl connections, closing the filehandlers alone may not
# work because of ref counting. We explicitly tell the socket
# to shutdown.
MultiHTTPHandler.finish(self)
self.connection.shutdown(socket.SHUT_RDWR)
import threading
class ConnThreadingMixIn:
"""Mix-in class to handle each _connection_ in a new thread.