changeset 862:e3e2effc9a4c

server: LiberviaRootResource now manages root url redirection, and former redirection has been replaced by it: as a nice side effect, the root URL doesn't show "libervia.html" anymore (LiberviaRootResource actually do URL rewritting).
author Goffi <goffi@goffi.org>
date Mon, 25 Jan 2016 17:02:13 +0100
parents 5cefc6ab302f
children 20fbca3c949a
files src/server/server.py
diffstat 1 files changed, 51 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/src/server/server.py	Mon Jan 25 16:41:38 2016 +0100
+++ b/src/server/server.py	Mon Jan 25 17:02:13 2016 +0100
@@ -125,9 +125,13 @@
             raise ValueError(u"url_redirections_profile need to be filled if you want to use url_redirections_dict")
 
         for old, new in options['url_redirections_dict'].iteritems():
-            if not old or not old.startswith('/'):
+            if not old.strip():
+                # root URL special case
+                old = ''
+            elif not old.startswith('/'):
                 raise ValueError(u"redirected url must start with '/', got {}".format(old))
-            old = self._normalizeURL(old)
+            else:
+                old = self._normalizeURL(old)
             new_url = urlparse.urlsplit(new.encode('utf-8'))
             if new_url.scheme == 'xmpp':
                 # XMPP URI
@@ -153,9 +157,14 @@
             else:
                 raise NotImplementedError(u"{scheme}: scheme is not managed for url_redirections_dict".format(scheme=new_url.scheme))
             self.redirections[old] = request_data
+            if not old:
+                log.info(u"Root URL redirected to {uri}".format(uri=request_data[1].decode('utf-8')))
         del options['url_redirections_dict']
         del options['url_redirections_profile']
 
+        if not '' in self.redirections:
+            self.redirections[''] = self._getRequestData(C.LIBERVIA_MAIN_PAGE)
+
     def _normalizeURL(self, url, lower=True):
         """Return URL normalized for self.redirections dict
 
@@ -193,6 +202,45 @@
         #      (e.g. for blog items)
         return self._normalizeURL(path, lower=False).split('/'), uri, path, args
 
+    def _redirect(self, request, request_data):
+        """Redirect an URL by rewritting request
+
+        this is *NOT* a HTTP redirection, but equivalent to URL rewritting
+        @param request(web.http.request): original request
+        @param request_data(tuple): data returned by self._getRequestData
+        @return (web_resource.Resource): resource to use
+        """
+        path_list, uri, path, args = request_data
+        try:
+            request._redirected
+        except AttributeError:
+            pass
+        else:
+            log.warning(D_(u"recursive redirection, please fix this URL:\n{old} ==> {new}").format(
+                old=request.uri,
+                new=uri,
+                ))
+            return web_resource.NoResource()
+        log.debug(u"Redirecting URL {old} to {new}".format(
+            old=request.uri,
+            new=uri,
+            ))
+        # we change the request to reflect the new url
+        request._redirected = True # here to avoid recursive redirections
+        request.postpath = path_list[1:]
+        request.uri = uri
+        request.path = path
+        request.args = args
+        # and we start again to look for a child with the new url
+        return self.getChildWithDefault(path_list[0], request)
+
+    def getChildWithDefault(self, name, request):
+        # XXX: this method is overriden only for root url
+        #      which is the only ones who need to be handled before other children
+        if name == '' and not request.postpath:
+            return self._redirect(request, self.redirections[''])
+        return super(LiberviaRootResource, self).getChildWithDefault(name, request)
+
     def getChild(self, name, request):
         resource = super(LiberviaRootResource, self).getChild(name, request)
 
@@ -206,29 +254,7 @@
                 # no redirection for this url
                 pass
             else:
-                path_list, uri, path, args = request_data
-                try:
-                    request._redirected
-                except AttributeError:
-                    pass
-                else:
-                    log.warning(D_(u"recursive redirection, please fix this URL:\n{old} ==> {new}").format(
-                        old=request.uri,
-                        new=uri,
-                        ))
-                    return web_resource.NoResource()
-                log.debug(u"Redirecting URL {old} to {new}".format(
-                    old=request.uri,
-                    new=uri,
-                    ))
-                # we change the request to reflect the new url
-                request._redirected = True # here to avoid recursive redirections
-                request.postpath = path_list[1:]
-                request.uri = uri
-                request.path = path
-                request.args = args
-                # and we start again to look for a child with the new url
-                return self.getChildWithDefault(path_list[0], request)
+                return self._redirect(request, request_data)
 
         return resource
 
@@ -1422,9 +1448,6 @@
                 # FIXME: check that no information is leaked (c.f. https://twistedmatrix.com/documents/current/web/howto/using-twistedweb.html#request-encoders)
                 root.putChild(path, web_resource.EncodingResourceWrapper(resource, [server.GzipEncoderFactory()]))
 
-            # we redirect root url to libevia's dynamic part
-            putChild('', web_util.Redirect(C.LIBERVIA_MAIN_PAGE))
-
             # JSON APIs
             putChild('json_signal_api', self.signal_handler)
             putChild('json_api', MethodHandler(self))