diff options
| author | Jairo Llopis <Yajo@users.noreply.github.com> | 2018-05-09 08:46:15 +0100 |
|---|---|---|
| committer | xmo-odoo <xmo@odoo.com> | 2018-05-09 09:46:15 +0200 |
| commit | 285ead28e31ca54e9629d5153d0d03d7b4951535 (patch) | |
| tree | 3de03167228179eff72a3d12f2b42cd11c0d7803 | |
| parent | e9e8fd24cf77397d57b73fb6ceb9befd326de19b (diff) | |
[IMP] Handle XMLRPC calls from standard controllers
This way, XMLRPC calls can get request details form the standard
`odoo.http.request` system.
Move jsonrpc to the same controller while at it, for coherence.
Fix #24183
| -rw-r--r-- | odoo/addons/base/__init__.py | 1 | ||||
| -rw-r--r-- | odoo/addons/base/controllers/__init__.py | 1 | ||||
| -rw-r--r-- | odoo/addons/base/controllers/rpc.py | 44 | ||||
| -rw-r--r-- | odoo/http.py | 5 | ||||
| -rw-r--r-- | odoo/service/wsgi_server.py | 44 |
5 files changed, 49 insertions, 46 deletions
diff --git a/odoo/addons/base/__init__.py b/odoo/addons/base/__init__.py index 062fe68d3a5..39fa2f90b03 100644 --- a/odoo/addons/base/__init__.py +++ b/odoo/addons/base/__init__.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +from . import controllers from . import models from . import report from . import wizard diff --git a/odoo/addons/base/controllers/__init__.py b/odoo/addons/base/controllers/__init__.py new file mode 100644 index 00000000000..c4aab8e5cf3 --- /dev/null +++ b/odoo/addons/base/controllers/__init__.py @@ -0,0 +1 @@ +from . import rpc diff --git a/odoo/addons/base/controllers/rpc.py b/odoo/addons/base/controllers/rpc.py new file mode 100644 index 00000000000..f58bcda1605 --- /dev/null +++ b/odoo/addons/base/controllers/rpc.py @@ -0,0 +1,44 @@ +from xmlrpc.client import dumps, loads + +from werkzeug.wrappers import Response + +from odoo.http import Controller, dispatch_rpc, request, route +from odoo.service import wsgi_server + + +class RPC(Controller): + """Handle RPC connections.""" + + def _xmlrpc(self, service): + """Common method to handle an XML-RPC request.""" + data = request.httprequest.get_data() + params, method = loads(data) + result = dispatch_rpc(service, method, params) + return dumps((result,), methodresponse=1, allow_none=False) + + @route("/xmlrpc/<service>", auth="none", method="POST", csrf=False) + def xmlrpc_1(self, service): + """XML-RPC service that returns faultCode as strings. + + This entrypoint is historical and non-compliant, but kept for + backwards-compatibility. + """ + try: + response = self._xmlrpc(service) + except Exception as error: + response = wsgi_server.xmlrpc_handle_exception_string(error) + return Response(response=response, mimetype='text/xml') + + @route("/xmlrpc/2/<service>", auth="none", method="POST", csrf=False) + def xmlrpc_2(self, service): + """XML-RPC service that returns faultCode as int.""" + try: + response = self._xmlrpc(service) + except Exception as error: + response = wsgi_server.xmlrpc_handle_exception_int(error) + return Response(response=response, mimetype='text/xml') + + @route('/jsonrpc', type='json', auth="none") + def jsonrpc(self, service, method, args): + """ Method used by client APIs to contact OpenERP. """ + return dispatch_rpc(service, method, args) diff --git a/odoo/http.py b/odoo/http.py index e06f345964d..1dafdbf9656 100644 --- a/odoo/http.py +++ b/odoo/http.py @@ -1634,11 +1634,6 @@ def content_disposition(filename): #---------------------------------------------------------- class CommonController(Controller): - @route('/jsonrpc', type='json', auth="none") - def jsonrpc(self, service, method, args): - """ Method used by client APIs to contact OpenERP. """ - return dispatch_rpc(service, method, args) - @route('/gen_session_id', type='json', auth="none") def gen_session_id(self): nsession = root.session_store.new() diff --git a/odoo/service/wsgi_server.py b/odoo/service/wsgi_server.py index 45f9de07b52..23acfefad03 100644 --- a/odoo/service/wsgi_server.py +++ b/odoo/service/wsgi_server.py @@ -99,48 +99,13 @@ def _patch_xmlrpc_marshaller(): xmlrpclib.Marshaller.dispatch[bytes] = dump_bytes -def wsgi_xmlrpc(environ, start_response): - """ Two routes are available for XML-RPC - - /xmlrpc/<service> route returns faultCode as strings. This is a historic - violation of the protocol kept for compatibility. - - /xmlrpc/2/<service> is a new route that returns faultCode as int and is - therefore fully compliant. - """ - if environ['REQUEST_METHOD'] == 'POST' and environ['PATH_INFO'].startswith('/xmlrpc/'): - length = int(environ['CONTENT_LENGTH']) - data = environ['wsgi.input'].read(length) - - # Distinguish betweed the 2 faultCode modes - string_faultcode = True - service = environ['PATH_INFO'][len('/xmlrpc/'):] - if environ['PATH_INFO'].startswith('/xmlrpc/2/'): - service = service[len('2/'):] - string_faultcode = False - - params, method = xmlrpclib.loads(data) - try: - result = odoo.http.dispatch_rpc(service, method, params) - response = xmlrpclib.dumps((result,), methodresponse=1, allow_none=False) - except Exception as e: - if string_faultcode: - response = xmlrpc_handle_exception_string(e) - else: - response = xmlrpc_handle_exception_int(e) - - return werkzeug.wrappers.Response( - response=response, - mimetype='text/xml', - )(environ, start_response) - def application_unproxied(environ, start_response): """ WSGI entry point.""" # cleanup db/uid trackers - they're set at HTTP dispatch in # web.session.OpenERPSession.send() and at RPC dispatch in # odoo.service.web_services.objects_proxy.dispatch(). # /!\ The cleanup cannot be done at the end of this `application` - # method because werkzeug still produces relevant logging afterwards + # method because werkzeug still produces relevant logging afterwards if hasattr(threading.current_thread(), 'uid'): del threading.current_thread().uid if hasattr(threading.current_thread(), 'dbname'): @@ -149,11 +114,8 @@ def application_unproxied(environ, start_response): del threading.current_thread().url with odoo.api.Environment.manage(): - # Try all handlers until one returns some result (i.e. not None). - for handler in [wsgi_xmlrpc, odoo.http.root]: - result = handler(environ, start_response) - if result is None: - continue + result = odoo.http.root(environ, start_response) + if result is not None: return result # We never returned from the loop. |
