[request] gather all base_url logic in a single place (closes #2200756)
authorPierre-Yves David <pierre-yves.david@logilab.fr>
Mon, 27 Feb 2012 15:24:14 +0100
changeset 8309 48ef505aa9f9
parent 8308 805a257709f6
child 8310 87f2f18a77ef
[request] gather all base_url logic in a single place (closes #2200756) * Handle ``https base-url`` in the core code: ``./req.py`` and ``web/request.py`` * Remove custom ``base_url`` handling if web request
etwist/request.py
etwist/server.py
req.py
test/unittest_req.py
web/request.py
web/test/unittest_request.py
wsgi/handler.py
wsgi/request.py
--- a/etwist/request.py	Thu Mar 15 17:30:28 2012 +0100
+++ b/etwist/request.py	Mon Feb 27 15:24:14 2012 +0100
@@ -31,9 +31,8 @@
 
 
 class CubicWebTwistedRequestAdapter(CubicWebRequestBase):
-    def __init__(self, req, vreg, https, base_url):
+    def __init__(self, req, vreg, https):
         self._twreq = req
-        self._base_url = base_url
         super(CubicWebTwistedRequestAdapter, self).__init__(vreg, https, req.args)
         for key, (name, stream) in req.files.iteritems():
             if name is None:
@@ -45,10 +44,6 @@
         for k, v in req.received_headers.iteritems():
             self._headers_in.addRawHeader(k, v)
 
-    def base_url(self):
-        """return the root url of the instance"""
-        return self._base_url
-
     def http_method(self):
         """returns 'POST', 'GET', 'HEAD', etc."""
         return self._twreq.method
--- a/etwist/server.py	Thu Mar 15 17:30:28 2012 +0100
+++ b/etwist/server.py	Mon Feb 27 15:24:14 2012 +0100
@@ -157,15 +157,12 @@
         host = request.host
         # dual http/https access handling: expect a rewrite rule to prepend
         # 'https' to the path to detect https access
+        https = False
         if origpath.split('/', 2)[1] == 'https':
             origpath = origpath[6:]
             request.uri = request.uri[6:]
             https = True
-            baseurl = self.https_url or self.base_url
-        else:
-            https = False
-            baseurl = self.base_url
-        req = CubicWebTwistedRequestAdapter(request, self.appli.vreg, https, baseurl)
+        req = CubicWebTwistedRequestAdapter(request, self.appli.vreg, https)
         if req.authmode == 'http':
             # activate realm-based auth
             realm = self.config['realm']
--- a/req.py	Thu Mar 15 17:30:28 2012 +0100
+++ b/req.py	Mon Feb 27 15:24:14 2012 +0100
@@ -204,6 +204,9 @@
         parameters. Values are automatically URL quoted, and the
         publishing method to use may be specified or will be guessed.
 
+        if ``__secure__`` argument is True, the request will try to build a
+        https url.
+
         raises :exc:`ValueError` if None is found in arguments
         """
         # use *args since we don't want first argument to be "anonymous" to
@@ -222,7 +225,8 @@
                 method = 'view'
         base_url = kwargs.pop('base_url', None)
         if base_url is None:
-            base_url = self.base_url()
+            secure = kwargs.pop('__secure__', None)
+            base_url = self.base_url(secure=secure)
         if '_restpath' in kwargs:
             assert method == 'view', method
             path = kwargs.pop('_restpath')
@@ -415,8 +419,11 @@
             raise ValueError(self._('can\'t parse %(value)r (expected %(format)s)')
                              % {'value': value, 'format': format})
 
-    def base_url(self):
-        """return the root url of the instance"""
+    def base_url(self, secure=None):
+        """return the root url of the instance
+        """
+        if secure:
+            raise NotImplementedError()
         return self.vreg.config['base-url']
 
     # abstract methods to override according to the web front-end #############
--- a/test/unittest_req.py	Thu Mar 15 17:30:28 2012 +0100
+++ b/test/unittest_req.py	Mon Feb 27 15:24:14 2012 +0100
@@ -36,7 +36,7 @@
         req = RequestSessionBase(None)
         req.from_controller = lambda : 'view'
         req.relative_path = lambda includeparams=True: None
-        req.base_url = lambda : 'http://testing.fr/cubicweb/'
+        req.base_url = lambda secure=None: 'http://testing.fr/cubicweb/'
         self.assertEqual(req.build_url(), u'http://testing.fr/cubicweb/view')
         self.assertEqual(req.build_url(None), u'http://testing.fr/cubicweb/view')
         self.assertEqual(req.build_url('one'), u'http://testing.fr/cubicweb/one')
--- a/web/request.py	Thu Mar 15 17:30:28 2012 +0100
+++ b/web/request.py	Mon Feb 27 15:24:14 2012 +0100
@@ -86,7 +86,7 @@
     """
     ajax_request = False # to be set to True by ajax controllers
 
-    def __init__(self, vreg, https, form=None):
+    def __init__(self, vreg, https=False, form=None):
         """
         :vreg: Vregistry,
         :https: boolean, s this a https request
@@ -144,6 +144,22 @@
         self.ajax_request = value
     json_request = property(_get_json_request, _set_json_request)
 
+    def base_url(self, secure=None):
+        """return the root url of the instance
+
+        secure = False -> base-url
+        secure = None  -> https-url if req.https
+        secure = True  -> https if it exist
+        """
+        if secure is None:
+            secure = self.https
+        base_url = None
+        if secure:
+            base_url = self.vreg.config.get('https-url')
+        if base_url is None:
+            base_url = super(CubicWebRequestBase, self).base_url()
+        return base_url
+
     @property
     def authmode(self):
         """Authentification mode of the instance
--- a/web/test/unittest_request.py	Thu Mar 15 17:30:28 2012 +0100
+++ b/web/test/unittest_request.py	Mon Feb 27 15:24:14 2012 +0100
@@ -5,7 +5,9 @@
 
 from functools import partial
 
-from cubicweb.web.request import (_parse_accept_header,
+from cubicweb.devtools.fake import FakeConfig
+
+from cubicweb.web.request import (CubicWebRequestBase, _parse_accept_header,
                                   _mimetype_sort_key, _mimetype_parser, _charset_sort_key)
 
 
@@ -65,5 +67,23 @@
                           ('utf-8', 'utf-8', 0.7),
                           ('*', '*', 0.7)])
 
+    def test_base_url(self):
+        dummy_vreg = type('DummyVreg', (object,), {})()
+        dummy_vreg.config = FakeConfig()
+        dummy_vreg.config['base-url'] = 'http://babar.com/'
+        dummy_vreg.config['https-url'] = 'https://toto.com/'
+
+        req = CubicWebRequestBase(dummy_vreg, https=False)
+        self.assertEqual('http://babar.com/', req.base_url())
+        self.assertEqual('http://babar.com/', req.base_url(False))
+        self.assertEqual('https://toto.com/', req.base_url(True))
+
+        req = CubicWebRequestBase(dummy_vreg, https=True)
+        self.assertEqual('https://toto.com/', req.base_url())
+        self.assertEqual('http://babar.com/', req.base_url(False))
+        self.assertEqual('https://toto.com/', req.base_url(True))
+
+
+
 if __name__ == '__main__':
     unittest_main()
--- a/wsgi/handler.py	Thu Mar 15 17:30:28 2012 +0100
+++ b/wsgi/handler.py	Mon Feb 27 15:24:14 2012 +0100
@@ -161,7 +161,7 @@
 
     def __call__(self, environ, start_response):
         """WSGI protocol entry point"""
-        req = CubicWebWsgiRequest(environ, self.appli.vreg, self.base_url)
+        req = CubicWebWsgiRequest(environ, self.appli.vreg)
         response = self._render(req)
         start_response(response.status, response.headers)
         return response.body
--- a/wsgi/request.py	Thu Mar 15 17:30:28 2012 +0100
+++ b/wsgi/request.py	Mon Feb 27 15:24:14 2012 +0100
@@ -40,14 +40,13 @@
     """most of this code COMES FROM DJANO
     """
 
-    def __init__(self, environ, vreg, base_url=None):
+    def __init__(self, environ, vreg):
         self.environ = environ
         self.path = environ['PATH_INFO']
         self.method = environ['REQUEST_METHOD'].upper()
         self._headers = dict([(normalize_header(k[5:]), v) for k, v in self.environ.items()
                               if k.startswith('HTTP_')])
         https = environ.get("HTTPS") in ('yes', 'on', '1')
-        self._base_url = base_url or self.instance_uri()
         post, files = self.get_posted_data()
         super(CubicWebWsgiRequest, self).__init__(vreg, https, post)
         if files is not None:
@@ -67,9 +66,6 @@
 
     ## cubicweb request interface ################################################
 
-    def base_url(self):
-        return self._base_url
-
     def http_method(self):
         """returns 'POST', 'GET', 'HEAD', etc."""
         return self.method