blob: 0073e57837bc3753bc1829bef8fa0c5024ed963f [file] [log] [blame]
Copybara854996b2021-09-07 19:36:02 +00001# Copyright 2016 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style
3# license that can be found in the LICENSE file or at
4# https://developers.google.com/open-source/licenses/bsd
5
6"""This file sets up all the urls for monorail pages."""
7from __future__ import print_function
8from __future__ import division
9from __future__ import absolute_import
10
11
Adrià Vilanova Martínezde942802022-07-15 14:06:55 +020012from six.moves import http_client
Copybara854996b2021-09-07 19:36:02 +000013import logging
14
15import webapp2
16
17
18def MakeRedirect(redirect_to_this_uri, permanent=True):
19 """Return a new request handler class that redirects to the given URL."""
20
21 class Redirect(webapp2.RequestHandler):
22 """Redirect is a response handler that issues a redirect to another URI."""
23
24 def get(self, **_kw):
25 """Send the 301/302 response code and write the Location: redirect."""
26 self.response.location = redirect_to_this_uri
27 self.response.headers.add('Strict-Transport-Security',
28 'max-age=31536000; includeSubDomains')
29 self.response.status = (
Adrià Vilanova Martínezde942802022-07-15 14:06:55 +020030 http_client.MOVED_PERMANENTLY if permanent else http_client.FOUND)
Copybara854996b2021-09-07 19:36:02 +000031
32 return Redirect
33
34
35def MakeRedirectInScope(uri_in_scope, scope, permanent=True, keep_qs=False):
36 """Redirect to a URI within a given scope, e.g., per project or user.
37
38 Args:
39 uri_in_scope: a uri within a project or user starting with a slash.
40 scope: a string indicating the uri-space scope:
41 p for project pages
42 u for user pages
43 g for group pages
44 permanent: True for a HTTP 301 permanently moved response code,
45 otherwise a HTTP 302 temporarily moved response will be used.
46 keep_qs: set to True to make the redirect retain the query string.
47 When true, permanent is ignored.
48
49 Example:
50 self._SetupProjectPage(
51 redirect.MakeRedirectInScope('/newpage', 'p'), '/oldpage')
52
53 Returns:
54 A class that can be used with webapp2.
55 """
56 assert uri_in_scope.startswith('/')
57
58 class RedirectInScope(webapp2.RequestHandler):
59 """A handler that redirects to another URI in the same scope."""
60
61 def get(self, **_kw):
62 """Send the 301/302 response code and write the Location: redirect."""
63 split_path = self.request.path.lstrip('/').split('/')
64 if len(split_path) > 1:
65 project_or_user = split_path[1]
66 url = '//%s/%s/%s%s' % (
67 self.request.host, scope, project_or_user, uri_in_scope)
68 else:
69 url = '/'
70 if keep_qs and self.request.query_string:
71 url += '?' + self.request.query_string
72 self.response.location = url
73
74 self.response.headers.add('Strict-Transport-Security',
75 'max-age=31536000; includeSubDomains')
76 if permanent and not keep_qs:
Adrià Vilanova Martínezde942802022-07-15 14:06:55 +020077 self.response.status = http_client.MOVED_PERMANENTLY
Copybara854996b2021-09-07 19:36:02 +000078 else:
Adrià Vilanova Martínezde942802022-07-15 14:06:55 +020079 self.response.status = http_client.FOUND
Copybara854996b2021-09-07 19:36:02 +000080
81 return RedirectInScope