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:
parent
a267ef5d05
commit
0a838fba3a
|
@ -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):
|
||||
|
|
|
@ -146,7 +146,32 @@ class dummyconn:
|
|||
def shutdown(self, tru):
|
||||
pass
|
||||
|
||||
class MultiHTTPHandler(BaseHTTPRequestHandler):
|
||||
def _quote_html(html):
|
||||
return html.replace("&", "&").replace("<", "<").replace(">", ">")
|
||||
|
||||
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.
|
||||
|
|
Loading…
Reference in New Issue