Skip to content

Commit

Permalink
✏️✨ added new middleware feature tags
Browse files Browse the repository at this point in the history
├── ✨ the tags:
│     pigeon.middleware.MiddlewareTags
│     attribute will be set by the middleware for every
│     request
└── ✏️🐛 fixed typo
  • Loading branch information
lstuma committed Nov 1, 2023
1 parent e7d0b92 commit 0463f6d
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/pigeon/middleware/components/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def postprocess(cls, response: HTTPResponse, request: HTTPRequest) -> HTTPRespo
@classmethod
def preprocess(cls, request: HTTPRequest) -> HTTPRequest | int:
# set keep-alive property for HTTPRequest object
request.keep_alive = cls.is_keep_alive(request=request)
request.tags.keep_alive = cls.is_keep_alive(request=request)
return request

@classmethod
Expand Down
11 changes: 5 additions & 6 deletions src/pigeon/middleware/components/cors.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def allowed(cls, request: HTTPRequest) -> bool:
"""
Checks if Origin header and Host header are valid.
"""
return not request.is_cors or all((
return not request.tags.is_cors or all((
cls.cors_origin_allowed(request),
cls.cors_method_allowed(request),
cls.cors_headers_allowed(request),
Expand All @@ -56,7 +56,7 @@ def allowed(cls, request: HTTPRequest) -> bool:

@classmethod
def preprocess(cls, request: HTTPRequest) -> HTTPRequest:
request.is_cors = cls.is_cors(request)
request.tags.cors = cls.is_cors(request)

if not cls.allowed(request):
return error(400)
Expand All @@ -71,8 +71,8 @@ def get_headers(cls, request: HTTPRequest) -> dict:
headers = {
'Access-Control-Allow-Credentials': str(settings.cors_allow_creds),
'Access-Control-Allow-Origin': request.headers('origin'),
'Access-Control-Allow-Headers': ', '.join(settings.cors_allow_headers),
'Access-Control-Allow-Methods': ', '.join(settings.cors_allow_methods),
'Access-Control-Allow-Headers': ', '.join(settings.cors_allowed_headers),
'Access-Control-Allow-Methods': ', '.join(settings.cors_allowed_methods),
'Access-Control-Max-Age': str(settings.cors_max_age)
}

Expand All @@ -81,11 +81,10 @@ def get_headers(cls, request: HTTPRequest) -> dict:
@classmethod
def postprocess(cls, response: HTTPResponse, request: HTTPRequest) -> HTTPResponse:

if not request.is_cors:
if not request.tags.cors:
return response

# get default CORS headers
cors_headers = cls.get_headers(request)
# add CORS headers to response
response.set_headers(headers=cors_headers)

9 changes: 7 additions & 2 deletions src/pigeon/middleware/pipe.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from pigeon.http import HTTPRequest, HTTPResponse, error
import pigeon.conf.middleware as middleware
import pigeon.http.parsing.parser as parser
from pigeon.middleware.tags import MiddlewareTags
import traceback

log = create_log('MIDDLEWARE', 'green')

Expand All @@ -26,9 +28,11 @@ def preprocess(raw: bytes) -> HTTPResponse | HTTPRequest:

# try processing the request
try:
request.tags = MiddlewareTags()
return middleware.PROCESSORS[request.protocol].preprocess(request=request)
except Exception:
except Exception as e:
log(1, f'MIDDLEWARE FAILED WHEN PREPROCESSING REQUEST - SKIPPING')
log(4, f'TRACEBACK:\n{"".join(traceback.format_tb(e.__traceback__))}')
return error(500)


Expand Down Expand Up @@ -66,6 +70,7 @@ def postprocess(message: HTTPMessage, response: HTTPResponse) -> HTTPResponse:
# request failed postprocessing - return error to client

return response
except Exception:
except Exception as e:
log(1, f'MIDDLEWARE FAILED WHEN POSTPROCESSING REQUEST - SKIPPING')
log(4, f'TRACEBACK:\n{"".join(traceback.format_tb(e.__traceback__))}')
return error(code=500, request=request)
3 changes: 3 additions & 0 deletions src/pigeon/middleware/processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,15 @@ def process(cls, request: HTTPRequest) -> HTTPResponse:
# gather response for request
if settings.static_url_base and request.path.startswith(settings.static_url_base):
# request for static file
request.tags.is_static_request = True
response = handle_static_request(request)
elif settings.media_url_base and request.path.startswith(settings.media_url_base):
# request for media file
request.tags.is_media_request = True
response = handle_media_request(request)
elif request.path in settings.views:
# views
request.tags.is_view_request = True
response = settings.views[request.path](request)
else:
# page does not exist
Expand Down
21 changes: 21 additions & 0 deletions src/pigeon/middleware/tags.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
class MiddlewareTags:
"""
Used to tag requests by middleware. Tags will be further used when processing
requeqst (especially in postprocessing) to further analyze the nature of the request
and set appropriate headers.
A tag can be accessed using MiddlewareTags().<tagname> and will either return its respective
value or False if it has not been set. This allows for processing of tags even if they have not
been set.
To set a tag
"""
def __init__(self):
self._tags = dict()

def __getattr__(self, key):
return self._tags.get(key) or False

def set(self, key, value):
self._tags[key] = value

1 comment on commit 0463f6d

@lstuma
Copy link
Member Author

@lstuma lstuma commented on 0463f6d Nov 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fix #19
(added cache-control)

Please sign in to comment.