Mercurial > libervia-web
comparison src/server/server.py @ 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 | 0e9341e537d6 |
children | f024fc5744d0 |
comparison
equal
deleted
inserted
replaced
861:5cefc6ab302f | 862:e3e2effc9a4c |
---|---|
123 self.redirections = {} | 123 self.redirections = {} |
124 if options['url_redirections_dict'] and not options['url_redirections_profile']: | 124 if options['url_redirections_dict'] and not options['url_redirections_profile']: |
125 raise ValueError(u"url_redirections_profile need to be filled if you want to use url_redirections_dict") | 125 raise ValueError(u"url_redirections_profile need to be filled if you want to use url_redirections_dict") |
126 | 126 |
127 for old, new in options['url_redirections_dict'].iteritems(): | 127 for old, new in options['url_redirections_dict'].iteritems(): |
128 if not old or not old.startswith('/'): | 128 if not old.strip(): |
129 # root URL special case | |
130 old = '' | |
131 elif not old.startswith('/'): | |
129 raise ValueError(u"redirected url must start with '/', got {}".format(old)) | 132 raise ValueError(u"redirected url must start with '/', got {}".format(old)) |
130 old = self._normalizeURL(old) | 133 else: |
134 old = self._normalizeURL(old) | |
131 new_url = urlparse.urlsplit(new.encode('utf-8')) | 135 new_url = urlparse.urlsplit(new.encode('utf-8')) |
132 if new_url.scheme == 'xmpp': | 136 if new_url.scheme == 'xmpp': |
133 # XMPP URI | 137 # XMPP URI |
134 parsed_qs = urlparse.parse_qs(new_url.geturl()) | 138 parsed_qs = urlparse.parse_qs(new_url.geturl()) |
135 try: | 139 try: |
151 location = urlparse.urlunsplit(('', '', new_url.path, new_url.query, new_url.fragment)) | 155 location = urlparse.urlunsplit(('', '', new_url.path, new_url.query, new_url.fragment)) |
152 request_data = self._getRequestData(location) | 156 request_data = self._getRequestData(location) |
153 else: | 157 else: |
154 raise NotImplementedError(u"{scheme}: scheme is not managed for url_redirections_dict".format(scheme=new_url.scheme)) | 158 raise NotImplementedError(u"{scheme}: scheme is not managed for url_redirections_dict".format(scheme=new_url.scheme)) |
155 self.redirections[old] = request_data | 159 self.redirections[old] = request_data |
160 if not old: | |
161 log.info(u"Root URL redirected to {uri}".format(uri=request_data[1].decode('utf-8'))) | |
156 del options['url_redirections_dict'] | 162 del options['url_redirections_dict'] |
157 del options['url_redirections_profile'] | 163 del options['url_redirections_profile'] |
164 | |
165 if not '' in self.redirections: | |
166 self.redirections[''] = self._getRequestData(C.LIBERVIA_MAIN_PAGE) | |
158 | 167 |
159 def _normalizeURL(self, url, lower=True): | 168 def _normalizeURL(self, url, lower=True): |
160 """Return URL normalized for self.redirections dict | 169 """Return URL normalized for self.redirections dict |
161 | 170 |
162 @param url(unicode): URL to normalize | 171 @param url(unicode): URL to normalize |
190 args = http.parse_qs(argstring, 1) | 199 args = http.parse_qs(argstring, 1) |
191 | 200 |
192 # XXX: splitted path case must not be changed, as it may be significant | 201 # XXX: splitted path case must not be changed, as it may be significant |
193 # (e.g. for blog items) | 202 # (e.g. for blog items) |
194 return self._normalizeURL(path, lower=False).split('/'), uri, path, args | 203 return self._normalizeURL(path, lower=False).split('/'), uri, path, args |
204 | |
205 def _redirect(self, request, request_data): | |
206 """Redirect an URL by rewritting request | |
207 | |
208 this is *NOT* a HTTP redirection, but equivalent to URL rewritting | |
209 @param request(web.http.request): original request | |
210 @param request_data(tuple): data returned by self._getRequestData | |
211 @return (web_resource.Resource): resource to use | |
212 """ | |
213 path_list, uri, path, args = request_data | |
214 try: | |
215 request._redirected | |
216 except AttributeError: | |
217 pass | |
218 else: | |
219 log.warning(D_(u"recursive redirection, please fix this URL:\n{old} ==> {new}").format( | |
220 old=request.uri, | |
221 new=uri, | |
222 )) | |
223 return web_resource.NoResource() | |
224 log.debug(u"Redirecting URL {old} to {new}".format( | |
225 old=request.uri, | |
226 new=uri, | |
227 )) | |
228 # we change the request to reflect the new url | |
229 request._redirected = True # here to avoid recursive redirections | |
230 request.postpath = path_list[1:] | |
231 request.uri = uri | |
232 request.path = path | |
233 request.args = args | |
234 # and we start again to look for a child with the new url | |
235 return self.getChildWithDefault(path_list[0], request) | |
236 | |
237 def getChildWithDefault(self, name, request): | |
238 # XXX: this method is overriden only for root url | |
239 # which is the only ones who need to be handled before other children | |
240 if name == '' and not request.postpath: | |
241 return self._redirect(request, self.redirections['']) | |
242 return super(LiberviaRootResource, self).getChildWithDefault(name, request) | |
195 | 243 |
196 def getChild(self, name, request): | 244 def getChild(self, name, request): |
197 resource = super(LiberviaRootResource, self).getChild(name, request) | 245 resource = super(LiberviaRootResource, self).getChild(name, request) |
198 | 246 |
199 if isinstance(resource, web_resource.NoResource): | 247 if isinstance(resource, web_resource.NoResource): |
204 request_data = self.redirections[current_url] | 252 request_data = self.redirections[current_url] |
205 except KeyError: | 253 except KeyError: |
206 # no redirection for this url | 254 # no redirection for this url |
207 pass | 255 pass |
208 else: | 256 else: |
209 path_list, uri, path, args = request_data | 257 return self._redirect(request, request_data) |
210 try: | |
211 request._redirected | |
212 except AttributeError: | |
213 pass | |
214 else: | |
215 log.warning(D_(u"recursive redirection, please fix this URL:\n{old} ==> {new}").format( | |
216 old=request.uri, | |
217 new=uri, | |
218 )) | |
219 return web_resource.NoResource() | |
220 log.debug(u"Redirecting URL {old} to {new}".format( | |
221 old=request.uri, | |
222 new=uri, | |
223 )) | |
224 # we change the request to reflect the new url | |
225 request._redirected = True # here to avoid recursive redirections | |
226 request.postpath = path_list[1:] | |
227 request.uri = uri | |
228 request.path = path | |
229 request.args = args | |
230 # and we start again to look for a child with the new url | |
231 return self.getChildWithDefault(path_list[0], request) | |
232 | 258 |
233 return resource | 259 return resource |
234 | 260 |
235 def createSimilarFile(self, path): | 261 def createSimilarFile(self, path): |
236 # XXX: this method need to be overriden to avoid recreating a LiberviaRootResource | 262 # XXX: this method need to be overriden to avoid recreating a LiberviaRootResource |
1419 ## URLs ## | 1445 ## URLs ## |
1420 def putChild(path, resource): | 1446 def putChild(path, resource): |
1421 """Add a child to the root resource""" | 1447 """Add a child to the root resource""" |
1422 # FIXME: check that no information is leaked (c.f. https://twistedmatrix.com/documents/current/web/howto/using-twistedweb.html#request-encoders) | 1448 # FIXME: check that no information is leaked (c.f. https://twistedmatrix.com/documents/current/web/howto/using-twistedweb.html#request-encoders) |
1423 root.putChild(path, web_resource.EncodingResourceWrapper(resource, [server.GzipEncoderFactory()])) | 1449 root.putChild(path, web_resource.EncodingResourceWrapper(resource, [server.GzipEncoderFactory()])) |
1424 | |
1425 # we redirect root url to libevia's dynamic part | |
1426 putChild('', web_util.Redirect(C.LIBERVIA_MAIN_PAGE)) | |
1427 | 1450 |
1428 # JSON APIs | 1451 # JSON APIs |
1429 putChild('json_signal_api', self.signal_handler) | 1452 putChild('json_signal_api', self.signal_handler) |
1430 putChild('json_api', MethodHandler(self)) | 1453 putChild('json_api', MethodHandler(self)) |
1431 putChild('register_api', _register) | 1454 putChild('register_api', _register) |