Skip to content

Commit

Permalink
fix: force fallback route to be evaluated at the end
Browse files Browse the repository at this point in the history
  • Loading branch information
eaguad1337 committed Jan 8, 2024
1 parent 08afe2a commit d4a1469
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 3 deletions.
2 changes: 2 additions & 0 deletions src/masonite/routes/HTTPRoute.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def __init__(
compilers=None,
controllers_locations=["app.http.controllers"],
controller_bindings=[],
is_fallback=False,
**options,
):
if not url.startswith("/"):
Expand All @@ -40,6 +41,7 @@ def __init__(
self.controller_class = None
self.controller_instance = None
self.controller_method = None
self.is_fallback = is_fallback
self._domain = None
self._name = name
self._casts_map = {}
Expand Down
1 change: 1 addition & 0 deletions src/masonite/routes/Route.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ def fallback(self, controller, module_location=None, **options):
request_method=["get", "head"],
compilers=self.compilers,
controllers_locations=module_location or self.controllers_locations,
is_fallback=True,
**options,
)

Expand Down
26 changes: 26 additions & 0 deletions src/masonite/routes/Router.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ def find(self, path, request_method, subdomain=None):
from .HTTPRoute import HTTPRoute

for route in self.routes:
if route.is_fallback:
continue

if route.match(path, request_method, subdomain=subdomain):
return route

Expand All @@ -33,6 +36,11 @@ def find(self, path, request_method, subdomain=None):
if not matched_methods:
return None

# check if there is a fallback route
fallback_route = self.get_fallback_route()
if fallback_route:
return fallback_route

# if alternative methods have been found, check if current request method is OPTIONS
# to build a proper response else build a method not allowed response
if request_method == "OPTIONS":
Expand All @@ -49,6 +57,24 @@ def preflight_response(app):
else:
raise MethodNotAllowedException(matched_methods, request_method)

def get_fallback_route(self):
"""
This method is used to get the fallback route from the list of routes.
The fallback route is the one where the `is_fallback` attribute is True.
If there are multiple fallback routes, it returns the first one.
If there are no fallback routes, it returns an empty list.
Returns:
fallback_route (Route): The fallback route if it exists, otherwise an empty list.
"""
fallback_route = list(filter(lambda r: r.is_fallback, self.routes))

if len(fallback_route) > 0:
fallback_route = fallback_route[0]

return fallback_route

def matches(self, path):
for route in self.routes:
if route.matches(path):
Expand Down
5 changes: 2 additions & 3 deletions tests/integrations/web.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,8 @@
Route.view("/test_view", "test_view", {"show": "111"}),
Route.get("/api/uploads/", "WelcomeController@test").middleware("throttle:api"),
Route.any("/any", "WelcomeController@any"),
Route.fallback("WelcomeController@fallback")
]

Broadcast.routes()
Auth.routes()

Route.fallback("WelcomeController@fallback")
Auth.routes()

0 comments on commit d4a1469

Please sign in to comment.