Pando's `request.headers.cookie` silently ignores parsing errors. This commit removes that attribute entirely by monkey-patching Pando.
133 lines
4.9 KiB
Cheetah
133 lines
4.9 KiB
Cheetah
import os.path
|
|
import sys
|
|
|
|
from pando.http import status_strings
|
|
from pando.utils import utcnow
|
|
|
|
from liberapay.exceptions import LazyResponse
|
|
from liberapay.i18n.base import HTTP_ERRORS
|
|
|
|
python_dir = f"python{sys.version_info.major}.{sys.version_info.minor}"
|
|
project_root = website.project_root.rstrip(os.path.sep) + os.path.sep
|
|
|
|
def get_short_traceback(exception):
|
|
tb = getattr(exception, '__traceback__', None)
|
|
if tb:
|
|
r = []
|
|
for i in range(25):
|
|
frame = tb.tb_frame
|
|
filepath = frame.f_code.co_filename.split(os.path.sep)
|
|
try:
|
|
i = filepath.index(python_dir)
|
|
except Exception:
|
|
filepath = os.path.sep.join(filepath)
|
|
if filepath.startswith(project_root):
|
|
filepath = filepath.removeprefix(project_root)
|
|
else:
|
|
if filepath[i+1] == 'site-packages':
|
|
i += 1
|
|
filepath = os.path.sep.join(filepath[i+1:])
|
|
r.append(f'{filepath}:{tb.tb_lineno} ({frame.f_code.co_name})')
|
|
tb = tb.tb_next
|
|
if tb is None:
|
|
break
|
|
return '\n ' + '\n '.join(r)
|
|
else:
|
|
return ' none'
|
|
|
|
def render_cookies(request):
|
|
return '; '.join(
|
|
f"{name}=[{len(value)} bytes]" for name, value in request.cookies.items()
|
|
) or 'none'
|
|
|
|
[----------------------------------------]
|
|
|
|
sentry_ident = state.get('sentry_ident')
|
|
code = response.code
|
|
msg = _(HTTP_ERRORS[code]) if code in HTTP_ERRORS else status_strings.get(code, '')
|
|
if not msg:
|
|
website.tell_sentry(Warning(f"missing error message for HTTP code {code}"))
|
|
|
|
if isinstance(response, LazyResponse):
|
|
response.render_body(state)
|
|
err = response.text
|
|
if code == 500 and not err:
|
|
err = _("Looks like you've found a bug! Sorry for the inconvenience, we'll get it fixed ASAP!")
|
|
|
|
referer = request.headers.get(b'Referer')
|
|
user_agent = request.headers.get(b'User-Agent')
|
|
|
|
[----------------------------------------] text/html
|
|
% extends "templates/layouts/base.html"
|
|
|
|
% set title = '' if response.html_template is defined else msg
|
|
|
|
% block content
|
|
% if response.html_template is defined
|
|
% include response.html_template
|
|
% else
|
|
% if code >= 400 and code <= 499
|
|
% if code == 404
|
|
<p>{{ _(
|
|
"The requested page could not be found. Please "
|
|
"{link_open}contact us{link_close} if you need assistance.",
|
|
link_open='<a href="https://liberapay.com/about/contact">'|safe,
|
|
link_close='</a>'|safe,
|
|
) }}</p>
|
|
% else
|
|
<p>{{ _(
|
|
"Your request has been rejected by our software. Please "
|
|
"{link_open}contact us{link_close} if you need assistance.",
|
|
link_open='<a href="https://liberapay.com/about/contact">'|safe,
|
|
link_close='</a>'|safe,
|
|
) }}</p>
|
|
% endif
|
|
% endif
|
|
|
|
% if err
|
|
% if '\n' in err
|
|
<pre>{{ err }}</pre>
|
|
% else
|
|
<p>{{ _("Error message:") }}</p>
|
|
<div class="alert alert-danger">{{ err }}</div>
|
|
% endif
|
|
% endif
|
|
|
|
% if sentry_ident
|
|
<p>{{ _(
|
|
"The details of this error have been recorded. If you decide to contact us, "
|
|
"please include the following error identification code in your message: {0}.",
|
|
'<code>%s</code>'|safe % sentry_ident
|
|
) }}</p>
|
|
% else
|
|
<br>
|
|
<p>{{ _("If you decide to contact us please include the following debugging information in your message:") }}</p>
|
|
<pre>URL: {{ website.canonical_scheme }}://{{ request.hostname }}{{ request.line.uri.decoded }}{{ '\n'
|
|
}}Method: {{ request.method }}{{ '\n'
|
|
}}Referer: {{ repr(referer) }}{{ '\n'
|
|
}}User-Agent: {{ repr(user_agent) }}{{ '\n'
|
|
}}Cookies: {{ render_cookies(request) }}{{ '\n'
|
|
}}IP address: {{ request.source }} ({{ request.source_country }}){{ '\n'
|
|
}}Time: {{ utcnow() }}{{ '\n'
|
|
}}Response code: {{ code }}{{ '\n'
|
|
}}Response message: {{ repr(err) }}{{ '\n'
|
|
}}User: {{ user }}{{ '\n'
|
|
}}Locale: {{ locale }}{{ '\n'
|
|
}}Website version: {{ website.version }}{{ '\n'
|
|
}}Traceback:{{
|
|
get_short_traceback(response.__cause__ or response)
|
|
}}</pre>
|
|
% endif
|
|
% endif
|
|
% endblock
|
|
[----------------------------------------] application/json via json_dump
|
|
{
|
|
"error_code": code,
|
|
"error_id": sentry_ident,
|
|
"error_message_long": err,
|
|
"error_message_short": msg,
|
|
"html_template": getattr(response, 'html_template', None),
|
|
}
|
|
[----------------------------------------] text/plain
|
|
{{err or msg}}
|