[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
--- 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