bugfix to negotiate(), port to Flask

This commit is contained in:
Yusur 2025-08-10 10:48:32 +02:00
parent 55c9f5fee2
commit ac66f3632c
3 changed files with 20 additions and 8 deletions

View file

@ -16,6 +16,8 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
from typing import Any from typing import Any
from flask import Flask, abort, current_app, g, request from flask import Flask, abort, current_app, g, request
from suou.http import WantsContentType
from .i18n import I18n from .i18n import I18n
from .configparse import ConfigOptions from .configparse import ConfigOptions
from .dorks import SENSITIVE_ENDPOINTS from .dorks import SENSITIVE_ENDPOINTS
@ -82,8 +84,19 @@ def harden(app: Flask):
return app return app
def negotiate() -> WantsContentType:
"""
Return an appropriate MIME type for the sake of content negotiation.
"""
if any(request.path.startswith(f'/{p.strip('/')}/') for p in current_app.config.get('REST_PATHS', [])):
return WantsContentType.JSON
elif request.user_agent.string.startswith('Mozilla/'):
return WantsContentType.HTML
else:
return request.accept_mimetypes.best_match([WantsContentType.PLAIN, WantsContentType.JSON, WantsContentType.HTML])
# Optional dependency: do not import into __init__.py # Optional dependency: do not import into __init__.py
__all__ = ('add_context_from_config', 'add_i18n', 'get_flask_conf', 'harden') __all__ = ('add_context_from_config', 'add_i18n', 'get_flask_conf', 'harden', 'negotiate')

View file

@ -16,8 +16,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
from __future__ import annotations from __future__ import annotations
from flask import current_app from quart import current_app, Quart, request, g
from quart import Quart, request, g
from quart_schema import QuartSchema from quart_schema import QuartSchema
from suou.http import WantsContentType from suou.http import WantsContentType
@ -58,14 +57,14 @@ def add_i18n(app: Quart, i18n: I18n, var_name: str = 'T', *,
def negotiate() -> WantsContentType: def negotiate() -> WantsContentType:
""" """
Return an appropriate MIME type for content negotiation. Return an appropriate MIME type for the sake of content negotiation.
""" """
if 'application/json' in request.accept_mimetypes or any(request.path.startswith(f'/{p.strip('/')}/') for p in current_app.config.get('REST_PATHS')): if any(request.path.startswith(f'/{p.strip('/')}/') for p in current_app.config.get('REST_PATHS', [])):
return WantsContentType.JSON return WantsContentType.JSON
elif request.user_agent.string.startswith('Mozilla/'): elif request.user_agent.string.startswith('Mozilla/'):
return WantsContentType.HTML return WantsContentType.HTML
else: else:
return WantsContentType.PLAIN return request.accept_mimetypes.best_match([WantsContentType.PLAIN, WantsContentType.JSON, WantsContentType.HTML])
def add_rest(app: Quart, *bases: str, **kwargs) -> QuartSchema: def add_rest(app: Quart, *bases: str, **kwargs) -> QuartSchema:

View file

@ -87,7 +87,7 @@ class SassAsyncMiddleware(_MiddlewareFactory):
'type': 'http.response.start', 'type': 'http.response.start',
'status': self.error_status, 'status': self.error_status,
'headers': [ 'headers': [
'Content-Type: text/css; charset=utf-8' ('Content-Type', 'text/css; charset=utf-8'),
] ]
}) })
await send({ await send({
@ -124,7 +124,7 @@ class SassAsyncMiddleware(_MiddlewareFactory):
'type': 'http.response.start', 'type': 'http.response.start',
'status': 200, 'status': 200,
'headers': [ 'headers': [
'Content-Type: text/css; charset=utf-8' ('Content-Type', 'text/css; charset=utf-8'),
] ]
}) })
async for chunk in _read_file(os.path.join(package_dir, result)): async for chunk in _read_file(os.path.join(package_dir, result)):