feat: allow setting a custom http status code for redirects

Signed-off-by: Akhil Narang <me@akhilnarang.dev>
This commit is contained in:
Akhil Narang 2023-12-13 12:23:47 +05:30
parent 91dce0b007
commit 44667901bf
No known key found for this signature in database
GPG key ID: 9DCC61E211BF645F
5 changed files with 27 additions and 10 deletions

View file

@ -64,7 +64,8 @@ class RequestToken(Exception):
class Redirect(Exception):
http_status_code = 301
def __init__(self, http_status_code: int = 301):
self.http_status_code = http_status_code
class CSRFTokenError(Exception):

View file

@ -1,10 +1,12 @@
{
"actions": [],
"creation": "2019-05-07 11:08:35.889625",
"doctype": "DocType",
"engine": "InnoDB",
"field_order": [
"source",
"target"
"target",
"redirect_http_status"
],
"fields": [
{
@ -20,10 +22,19 @@
"in_list_view": 1,
"label": "Target",
"reqd": 1
},
{
"default": "301",
"fieldname": "redirect_http_status",
"fieldtype": "Int",
"label": "Redirect HTTP Status",
"options": "301\n302\n307\n308",
"reqd": 1
}
],
"istable": 1,
"modified": "2019-05-07 11:11:46.867684",
"links": [],
"modified": "2023-12-13 12:09:50.726082",
"modified_by": "Administrator",
"module": "Website",
"name": "Website Route Redirect",
@ -31,5 +42,6 @@
"permissions": [],
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "ASC"
"sort_order": "ASC",
"states": []
}

View file

@ -17,7 +17,9 @@ class WebsiteRouteRedirect(Document):
parent: DF.Data
parentfield: DF.Data
parenttype: DF.Data
redirect_http_status: DF.Int
source: DF.SmallText
target: DF.SmallText
# end: auto-generated types
pass

View file

@ -14,7 +14,7 @@ class RedirectPage:
return build_response(
self.path,
"",
301,
self.http_status_code,
{
"Location": frappe.flags.redirect_location or (frappe.local.response or {}).get("location"),
"Cache-Control": "no-store, no-cache, must-revalidate",

View file

@ -35,8 +35,8 @@ class PathResolver:
try:
resolve_redirect(self.path, request.query_string)
except frappe.Redirect:
return frappe.flags.redirect_location, RedirectPage(self.path)
except frappe.Redirect as e:
return frappe.flags.redirect_location, RedirectPage(self.path, e.http_status_code)
endpoint = resolve_path(self.path)
@ -105,7 +105,9 @@ def resolve_redirect(path, query_string=None):
]
"""
redirects = frappe.get_hooks("website_redirects")
redirects += frappe.get_all("Website Route Redirect", ["source", "target"], order_by=None)
redirects += frappe.get_all(
"Website Route Redirect", ["source", "target", "redirect_http_status"], order_by=None
)
if not redirects:
return
@ -124,14 +126,14 @@ def resolve_redirect(path, query_string=None):
try:
match = re.match(pattern, path_to_match)
except re.error as e:
except re.error:
frappe.log_error("Broken Redirect: " + pattern)
if match:
redirect_to = re.sub(pattern, rule["target"], path_to_match)
frappe.flags.redirect_location = redirect_to
frappe.cache.hset("website_redirects", path_to_match, redirect_to)
raise frappe.Redirect
raise frappe.Redirect(rule.get("redirect_http_status", 301))
def resolve_path(path):