import logging
import os
import signal
+import socket
import sys
import threading
import traceback
return [response]
def xmlrpc_handle_exception(e):
- if isinstance(e, openerp.osv.osv.except_osv): # legacy
+ if isinstance(e, openerp.osv.orm.except_orm): # legacy
fault = xmlrpclib.Fault(RPC_FAULT_CODE_WARNING, openerp.tools.ustr(e.value))
response = xmlrpclib.dumps(fault, allow_none=False, encoding=None)
- elif isinstance(e, openerp.exceptions.Warning):
+ elif isinstance(e, openerp.exceptions.Warning) or isinstance(e, openerp.exceptions.RedirectWarning):
fault = xmlrpclib.Fault(RPC_FAULT_CODE_WARNING, str(e))
response = xmlrpclib.dumps(fault, allow_none=False, encoding=None)
elif isinstance (e, openerp.exceptions.AccessError):
return response
def xmlrpc_handle_exception_legacy(e):
- if isinstance(e, openerp.osv.osv.except_osv):
+ if isinstance(e, openerp.osv.orm.except_orm):
fault = xmlrpclib.Fault('warning -- ' + e.name + '\n\n' + e.value, '')
response = xmlrpclib.dumps(fault, allow_none=False, encoding=None)
elif isinstance(e, openerp.exceptions.Warning):
handler.auth_provider.checkRequest(handler, path)
except websrv_lib.AuthRequiredExc, ae:
# Darwin 9.x.x webdav clients will report "HTTP/1.0" to us, while they support (and need) the
- # authorisation features of HTTP/1.1
+ # authorisation features of HTTP/1.1
if request_version != 'HTTP/1.1' and ('Darwin/9.' not in handler.headers.get('User-Agent', '')):
start_response("403 Forbidden", [])
return []
# WSGI handlers registered through the register_wsgi_handler() function below.
module_handlers = []
+# RPC endpoints registered through the register_rpc_endpoint() function below.
+rpc_handlers = {}
def register_wsgi_handler(handler):
""" Register a WSGI handler.
"""
module_handlers.append(handler)
+def register_rpc_endpoint(endpoint, handler):
+ """ Register a handler for a given RPC enpoint.
+ """
+ rpc_handlers[endpoint] = handler
+
def application_unproxied(environ, start_response):
""" WSGI entry point."""
openerp.service.start_internal()
# The WSGI server, started by start_server(), stopped by stop_server().
httpd = None
-def serve():
+def serve(interface, port, threaded):
""" Serve HTTP requests via werkzeug development server.
- If werkzeug can not be imported, we fall back to wsgiref's simple_server.
-
Calling this function is blocking, you might want to call it in its own
thread.
"""
global httpd
-
- # TODO Change the xmlrpc_* options to http_*
- interface = config['xmlrpc_interface'] or '0.0.0.0'
- port = config['xmlrpc_port']
- if not openerp.tools.config.options["gevent"]:
- httpd = werkzeug.serving.make_server(interface, port, application, threaded=True)
+ if not openerp.evented:
+ httpd = werkzeug.serving.make_server(interface, port, application, threaded=threaded)
else:
from gevent.wsgi import WSGIServer
httpd = WSGIServer((interface, port), application)
- _logger.info('HTTP service (werkzeug) running on %s:%s', interface, port)
httpd.serve_forever()
-def start_server():
+def start_service():
""" Call serve() in its own thread.
The WSGI server can be shutdown with stop_server() below.
"""
- threading.Thread(target=serve).start()
+ # TODO Change the xmlrpc_* options to http_*
+ interface = config['xmlrpc_interface'] or '0.0.0.0'
+ port = config['xmlrpc_port']
+ _logger.info('HTTP service (werkzeug) running on %s:%s', interface, port)
+ threading.Thread(target=serve, args=(interface, port, True)).start()
-def stop_server():
+def stop_service():
""" Initiate the shutdown of the WSGI server.
The server is supposed to have been started by start_server() above.
"""
if httpd:
- httpd.shutdown()
+ if not openerp.evented:
+ httpd.shutdown()
+ close_socket(httpd.socket)
+ else:
+ import gevent
+ httpd.stop()
+ gevent.shutdown()
+
+def close_socket(sock):
+ """ Closes a socket instance cleanly
+
+ :param sock: the network socket to close
+ :type sock: socket.socket
+ """
+ try:
+ sock.shutdown(socket.SHUT_RDWR)
+ except socket.error, e:
+ # On OSX, socket shutdowns both sides if any side closes it
+ # causing an error 57 'Socket is not connected' on shutdown
+ # of the other side (or something), see
+ # http://bugs.python.org/issue4397
+ # note: stdlib fixed test, not behavior
+ if e.errno != errno.ENOTCONN or platform.system() not in ['Darwin', 'Windows']:
+ raise
+ sock.close()
+
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: