summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJairo Llopis <Yajo@users.noreply.github.com>2018-05-09 08:46:15 +0100
committerxmo-odoo <xmo@odoo.com>2018-05-09 09:46:15 +0200
commit285ead28e31ca54e9629d5153d0d03d7b4951535 (patch)
tree3de03167228179eff72a3d12f2b42cd11c0d7803
parente9e8fd24cf77397d57b73fb6ceb9befd326de19b (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__.py1
-rw-r--r--odoo/addons/base/controllers/__init__.py1
-rw-r--r--odoo/addons/base/controllers/rpc.py44
-rw-r--r--odoo/http.py5
-rw-r--r--odoo/service/wsgi_server.py44
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.