summaryrefslogtreecommitdiff
path: root/django/utils/http.py
AgeCommit message (Collapse)Author
2026-04-22Fixed #36991 -- Raised BadRequest for invalid encodings in Content-Type headers.Dinesh
2026-04-08Refs #35440 -- Optimized parse_header_parameters() for the simplest case.Pravin Kamble
Added a fast-path to parse_header_parameters Benchmark results (50,000 iterations): - Simple headers: ~73% improvement Thanks Nick Pope (@ngnpope) for the review.
2025-11-26Fixed #36743 -- Increased URL max length enforced in HttpResponseRedirectBase.varunkasyap
Refs CVE-2025-64458. The previous limit of 2048 characters reused the URLValidator constant and proved too restrictive for legitimate redirects to some third-party services. This change introduces a separate `MAX_URL_REDIRECT_LENGTH` constant (defaulting to 16384) and uses it in HttpResponseRedirectBase. Thanks Jacob Walls for report and review.
2025-11-07Fixed #36705 -- Avoided string concatenation in utils.Kasyap Pentamaraju
Repeated string concatenation performs poorly on PyPy. Thanks Seokchan Yoon for the report.
2025-09-15Fixed #36520 -- Reverted "Fixed #35440 -- Simplified parse_header_parameters ↵Natalia
by leveraging stdlid's Message." This partially reverts commit 9aabe7eae3eeb3e64c5a0f3687118cd806158550. The simplification of parse_header_parameters using stdlib's Message is reverted due to a performance regression. The check for the header maximum length remains in place, per Security Team guidance. Thanks to David Smith for reporting the regression, and Jacob Walls for the review.
2025-07-23Refs #36500 -- Rewrapped long docstrings and block comments via a script.django-bot
Rewrapped long docstrings and block comments to 79 characters + newline using script from https://github.com/medmunds/autofix-w505.
2025-04-02Fixed CVE-2025-27556 -- Mitigated potential DoS in ↵Sarah Boyce
url_has_allowed_host_and_scheme() on Windows. Thank you sw0rd1ight for the report.
2025-03-27Fixed #35440 -- Simplified parse_header_parameters by leveraging stdlid's ↵Khudyakov Artem
Message. The `parse_header_parameters` function historically used Python's `cgi` module (now deprecated). In 34e2148fc725e7200050f74130d7523e3cd8507a, the logic was inlined to work around this deprecation ( #33173). Later, in d4d5427571b4bf3a21c902276c2a00215c2a37cc, the header parsing logic was further cleaned up to align with `multipartparser.py` (#33697). This change takes it a step further by replacing the copied `cgi` logic with Python's `email.message.Message` API for a more robust and maintainable header parsing implementation. Thanks to Raphael Gaschignard for testing, and to Adam Johnson and Shai Berger for reviews. Co-authored-by: Ben Cail <bcail@crossway.org> Co-authored-by: Natalia <124304+nessita@users.noreply.github.com>
2025-02-18Refs #36005 -- Used datetime.UTC alias instead of datetime.timezone.utc.Mariusz Felisiak
datetime.UTC was added in Python 3.11.
2025-01-07Fixed #36023 -- Handled controls chars in content_disposition_header.Alex Vandiver
To use the simple `filename="..."` form, the value must conform to the official grammar from RFC6266[^1]: filename-parm = "filename" "=" value value = <value, defined in [RFC2616], Section 3.6> ; token | quoted-string The `quoted-string` definition comes from RFC 9110[^2]: ``` quoted-string = DQUOTE *( qdtext / quoted-pair ) DQUOTE qdtext = HTAB / SP / %x21 / %x23-5B / %x5D-7E / obs-text The backslash octet ("\") can be used as a single-octet quoting mechanism within quoted-string and comment constructs. Recipients that process the value of a quoted-string MUST handle a quoted-pair as if it were replaced by the octet following the backslash. quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text ) A sender SHOULD NOT generate a quoted-pair in a quoted-string except where necessary to quote DQUOTE and backslash octets occurring within that string. ``` That is, quoted strings are able to express horizontal tabs, space characters, and everything in the range from 0x21 to 0x7e, expect for 0x22 (`"`) and 0x5C (`\`), which can still be expressed but must be escaped with their own `\`. We ignore the case of `obs-text`, which is defined as the range 0x80-0xFF, since its presence is there for permissive parsing of accidental high-bit characters, and it should not be generated by conforming implementations. Transform this character range into a regex and apply it in addition to the "is ASCII" check. This ensures that all simple filenames are expressed in the simple format, and that all filenames with newlines and other control characters are properly expressed with the percent-encoded `filename*=...`form. [^1]: https://datatracker.ietf.org/doc/html/rfc6266#section-4.1 [^2]: https://datatracker.ietf.org/doc/html/rfc9110#name-quoted-strings
2024-05-29Fixed 35467 -- Replaced urlparse with urlsplit where appropriate.Jake Howard
This work should not generate any change of functionality, and `urlsplit` is approximately 6x faster. Most use cases of `urlparse` didn't touch the path, so they can be converted to `urlsplit` without any issue. Most of those which do use `.path`, simply parse the URL, mutate the querystring, then put them back together, which is also fine (so long as urlunsplit is used).
2023-11-28Refs #34986 -- Fixed mocking in ↵Nick Pope
utils_tests.test_http.HttpDateProcessingTests.test_parsing_rfc850. Mocking in the `datetime` module can be tricky. In CPython the datetime C module is used, but PyPy uses a pure Python implementation. This caused issues with the prior approach to mocking `datetime.datetime`. See https://docs.python.org/3/library/unittest.mock-examples.html#partial-mocking
2023-01-18Refs #34233 -- Used str.removeprefix()/removesuffix().Mariusz Felisiak
2023-01-18Fixed #34233 -- Dropped support for Python 3.8 and 3.9.Mariusz Felisiak
2022-12-05Fixed #34194 -- Added django.utils.http.content_disposition_header().Alex Vandiver
2022-11-10Updated documentation and comments for RFC updates.Nick Pope
- Updated references to RFC 1123 to RFC 5322 - Only partial as RFC 5322 sort of sub-references RFC 1123. - Updated references to RFC 2388 to RFC 7578 - Except RFC 2388 Section 5.3 which has no equivalent. - Updated references to RFC 2396 to RFC 3986 - Updated references to RFC 2616 to RFC 9110 - Updated references to RFC 3066 to RFC 5646 - Updated references to RFC 7230 to RFC 9112 - Updated references to RFC 7231 to RFC 9110 - Updated references to RFC 7232 to RFC 9110 - Updated references to RFC 7234 to RFC 9111 - Tidied up style of text when referring to RFC documents
2022-07-01Updated vendored _urlsplit() to strip newline and tabs.Michael Manfre
Refs Python CVE-2022-0391. Django is not affected, but others who incorrectly use internal function url_has_allowed_host_and_scheme() with unsanitized input could be at risk.
2022-06-28Refs #33697 -- Used django.utils.http.parse_header_parameters() for parsing ↵Mehrdad
boundary streams. This also removes unused parse_header() and _parse_header_params() helpers in django.http.multipartparser.
2022-05-11Refs #33173 -- Removed use of deprecated cgi module.Carlton Gibson
https://peps.python.org/pep-0594/#cgi
2022-02-07Refs #33476 -- Reformatted code with Black.django-bot
2022-01-07Fixed #28628 -- Changed \d to [0-9] in regexes where appropriate.Ad Timmering
2021-05-12Fixed #32366 -- Updated datetime module usage to recommended approach.Nick Pope
- Replaced datetime.utcnow() with datetime.now(). - Replaced datetime.utcfromtimestamp() with datetime.fromtimestamp(). - Replaced datetime.utctimetuple() with datetime.timetuple(). - Replaced calendar.timegm() and datetime.utctimetuple() with datetime.timestamp().
2021-02-10Fixed #32355 -- Dropped support for Python 3.6 and 3.7Mariusz Felisiak
2021-01-14Refs #30747 -- Removed django.utils.http.is_safe_url() per deprecation timeline.Mariusz Felisiak
2021-01-14Refs #27753 -- Removed django.utils.http urllib aliases per deprecation ↵Mariusz Felisiak
timeline.
2020-09-03Refs #21231 -- Backport urllib.parse.parse_qsl() from Python 3.8.Nick Pope
2020-05-11Refs #30116 -- Simplified regex match group access with Match.__getitem__().Jon Dufresne
The method has been available since Python 3.6. The shorter syntax is also marginally faster.
2019-10-29Fixed #30899 -- Lazily compiled import time regular expressions.Hasan Ramezani
2019-09-30Fixed #28690 -- Fixed handling of two-digit years in parse_http_date().Ad Timmering
Due to RFC7231 ayear that appears to be more than 50 years in the future are interpreted as representing the past.
2019-09-02Fixed #30747 -- Renamed is_safe_url() to url_has_allowed_host_and_scheme().Carlton Gibson
2019-08-11Fixed #30677 -- Improved error message for urlencode() and Client when None ↵swatantra
is passed as data.
2019-05-27Refs #30485 -- Avoided unnecessary instance checks in urlencode.Simon Charette
Given doseq defaults to False it should avoid an unnecessary instance check in most cases.
2019-05-24Fixed #30485 -- Adjusted django.utils.http.urlencode for doseq=False case.Johan Lübcke
2019-02-04Refs #27753 -- Deprecated django.utils.http urllib aliases.Tim Graham
2019-01-17Refs #28965 -- Removed utils.http.cookie_date() per deprecation timeline.Tim Graham
2018-12-27Fixed #30024 -- Made urlencode() and Client raise TypeError when None is ↵Jon Dufresne
passed as data.
2018-10-10Refs #27795 -- Removed force_bytes() usage from django/utils/http.py.Jon Dufresne
django.utils.http.urlsafe_base64_encode() now returns a string, not a bytestring. Since URLs are represented as strings, urlsafe_base64_encode() should return a string. All uses immediately decoded the bytestring to a string anyway. As the inverse operation, urlsafe_base64_decode() accepts a string.
2018-08-01Fixed CVE-2018-14574 -- Fixed open redirect possibility in CommonMiddleware.Andreas Hug
2018-06-29Fixed #29525 -- Allowed is_safe_url()'s allowed_hosts arg to be a string.Przemysław Suliga
2018-01-11Fixed #28638 -- Made allowed_hosts a required argument of is_safe_url().Jon Dufresne
2018-01-02Refs #28965 -- Deprecated unused django.utils.http.cookie_date().Tim Graham
2017-12-07Fixed #28906 -- Removed unnecessary bool() calls.Tim Graham
2017-12-04Fixed #28860 -- Removed unnecessary len() calls.Дилян Палаузов
2017-10-13Updated email.Util (Python 2) references to email.utils (Python 3).Tim Graham
2017-10-12Fixed #28679 -- Fixed urlencode()'s handling of bytes.François Freitag
Regression in fee42fd99ee470528858c2ccb3621135c30ec262. Thanks Claude Paroz, Jon Dufresne, and Tim Graham for the guidance.
2017-09-22Refs #26956 -- Removed the host parameter of django.utils.http.is_safe_url().Tim Graham
Per deprecation timeline.
2017-09-07Reverted "Fixed #27818 -- Replaced try/except/pass with contextlib.suppress()."Tim Graham
This reverts commit 550cb3a365dee4edfdd1563224d5304de2a57fda because try/except performs better.
2017-06-28Fixed #27818 -- Replaced try/except/pass with contextlib.suppress().Mads Jensen
2017-05-10Fixed #28142 -- Fixed is_safe_url() crash on invalid IPv6 URLs.UmanShahzad
2017-04-04Fixed #27912, CVE-2017-7233 -- Fixed is_safe_url() with numeric URLs.Tim Graham
This is a security fix.