|
15 | 15 | )
|
16 | 16 | from django.conf import settings
|
17 | 17 | from django.core.exceptions import SuspiciousOperation
|
| 18 | +from django.http.response import BadHeaderError, ResponseHeaders |
18 | 19 | from django.shortcuts import redirect
|
19 | 20 | from django.urls import reverse
|
20 | 21 | from django.utils.deprecation import MiddlewareMixin
|
@@ -369,14 +370,25 @@ def _get_https_redirect(self, request):
|
369 | 370 | return None
|
370 | 371 |
|
371 | 372 | def add_resolver_headers(self, request, response):
|
372 |
| - # TODO: find a better way to re-use the unresolved URL so we don't |
373 |
| - # query the db multiple times on the same request. |
374 |
| - # https://github.com/readthedocs/readthedocs.org/issues/10456 |
375 | 373 | if hasattr(request, "unresolved_url") and request.unresolved_url is not None:
|
376 | 374 | # TODO: add more ``X-RTD-Resolver-*`` headers
|
377 |
| - response["X-RTD-Resolver-Filename"] = escape( |
378 |
| - request.unresolved_url.filename |
379 |
| - ) |
| 375 | + header_value = escape(request.unresolved_url.filename) |
| 376 | + try: |
| 377 | + # Use Django internals to validate the header's value before injecting it. |
| 378 | + ResponseHeaders({})._convert_to_charset( |
| 379 | + header_value, |
| 380 | + "latin-1", |
| 381 | + mime_encode=True, |
| 382 | + ) |
| 383 | + |
| 384 | + response["X-RTD-Resolver-Filename"] = header_value |
| 385 | + except BadHeaderError: |
| 386 | + # Skip adding the header because it fails validation |
| 387 | + log.info( |
| 388 | + "Skip adding X-RTD-Resolver-Filename header due to invalid value.", |
| 389 | + filename=request.unresolved_url.filename, |
| 390 | + value=header_value, |
| 391 | + ) |
380 | 392 |
|
381 | 393 | def process_response(self, request, response): # noqa
|
382 | 394 | self.add_proxito_headers(request, response)
|
|
0 commit comments