[Django] #27083: Problems with ETag parsing and comparison

9 views
Skip to first unread message

Django

unread,
Aug 18, 2016, 6:11:51 AM8/18/16
to django-...@googlegroups.com
#27083: Problems with ETag parsing and comparison
-------------------------------+--------------------
Reporter: marfire | Owner: nobody
Type: Bug | Status: new
Component: HTTP handling | Version: master
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------
There are a number of problems with the way Django currently parses and
compares ETags. The main issue is that we don't properly distinguish
between weak and strong ETags. Specifically:

- Since we don't distinguish between weak and strong ETags, all of our
comparisons are implicitly weak (see
[https://tools.ietf.org/html/rfc7232#section-2.3.2 section 2.3.2 of RFC
7232]). The specification, however, says that we "MUST use the strong
comparison function when comparing entity-tags for `If-Match`" (section
3.1).
- There's no way to supply a weak ETag via the `condition()` decorator.
- If the developer specifies a weak ETag directly (by assigning to the
`ETag` header in the response), we don't parse it properly and it will
never match.
- We interpret the ETag format and implement the matching algorithm based
on the old specification (RFC 2616), not the new one (RFC 7232). They are
somewhat different.

Correcting this is mostly straightforward. The only tricky issue is what
to do about the ETags returned from `etag_func()` in the `condition()`
decorator. We currently treat these as unquoted (and implicitly strong)
ETags. We can't suddenly require these to be quoted ETags since that would
break backwards compatibility.

Instead we can allow either quoted or unquoted ETags to be returned. Since
quotes are not an allowed character in the unquoted part of the ETag under
the new specification, there won't be any ambiguity. Existing code will
work as before, but it will now be possible for someone to provide an
`etag_func()` that returns a weak ETag.

There is still the possibility of a backwards incompatibility, though,
since as noted above the current ETag specification is slightly
incompatible with the old one (having to do with changing from an escaped
string to an opaque string). That is, there exist ETags that would have
been valid and would have matched under the old specification that will
not match after this change. I would expect actual use of such ETags to be
rare or nonexistent, and since the problem would be caused by user code
that is incompatible with the HTTP specification this doesn't seem like a
fatal problem.

--
Ticket URL: <https://code.djangoproject.com/ticket/27083>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Aug 18, 2016, 7:07:21 AM8/18/16
to django-...@googlegroups.com
#27083: Problems with ETag parsing and comparison
-------------------------------+--------------------------------------
Reporter: marfire | Owner: marfire
Type: Bug | Status: assigned

Component: HTTP handling | Version: master
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 1 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 1

Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Changes (by marfire):

* status: new => assigned
* cc: k@… (added)
* needs_better_patch: => 1
* needs_tests: => 1
* owner: nobody => marfire
* needs_docs: => 1
* has_patch: 0 => 1


Comment:

[https://github.com/django/django/pull/7112 PR]

--
Ticket URL: <https://code.djangoproject.com/ticket/27083#comment:1>

Django

unread,
Aug 18, 2016, 9:00:16 AM8/18/16
to django-...@googlegroups.com
#27083: Problems with ETag parsing and comparison
-------------------------------+------------------------------------

Reporter: marfire | Owner: marfire
Type: Bug | Status: assigned
Component: HTTP handling | Version: master
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted

Has patch: 1 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------+------------------------------------
Changes (by timgraham):

* stage: Unreviewed => Accepted


--
Ticket URL: <https://code.djangoproject.com/ticket/27083#comment:2>

Django

unread,
Sep 2, 2016, 12:59:49 PM9/2/16
to django-...@googlegroups.com
#27083: Problems with ETag parsing and comparison
-------------------------------+------------------------------------
Reporter: marfire | Owner: marfire
Type: Bug | Status: assigned
Component: HTTP handling | Version: master
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------+------------------------------------
Changes (by marfire):

* needs_better_patch: 1 => 0
* needs_tests: 1 => 0
* needs_docs: 1 => 0


--
Ticket URL: <https://code.djangoproject.com/ticket/27083#comment:3>

Django

unread,
Sep 8, 2016, 3:45:43 PM9/8/16
to django-...@googlegroups.com
#27083: Add support for weak ETags

-------------------------------+------------------------------------
Reporter: marfire | Owner: marfire
Type: Bug | Status: assigned
Component: HTTP handling | Version: master
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1

Easy pickings: 0 | UI/UX: 0
-------------------------------+------------------------------------
Changes (by timgraham):

* needs_better_patch: 0 => 1


Comment:

I left some comments for improvement.

--
Ticket URL: <https://code.djangoproject.com/ticket/27083#comment:4>

Django

unread,
Sep 8, 2016, 11:42:37 PM9/8/16
to django-...@googlegroups.com
#27083: Add support for weak ETags
-------------------------------+------------------------------------
Reporter: marfire | Owner: marfire
Type: Bug | Status: assigned
Component: HTTP handling | Version: master
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------+------------------------------------
Changes (by marfire):

* needs_better_patch: 1 => 0


--
Ticket URL: <https://code.djangoproject.com/ticket/27083#comment:5>

Django

unread,
Sep 10, 2016, 8:28:10 AM9/10/16
to django-...@googlegroups.com
#27083: Add support for weak ETags
-------------------------------+------------------------------------
Reporter: marfire | Owner: marfire
Type: Bug | Status: closed

Component: HTTP handling | Version: master
Severity: Normal | Resolution: fixed

Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------+------------------------------------
Changes (by Tim Graham <timograham@…>):

* status: assigned => closed
* resolution: => fixed


Comment:

In [changeset:"4ef0e019b7dd3d2bf93b5c705b3b7df9cdb77561" 4ef0e019]:
{{{
#!CommitTicketReference repository=""
revision="4ef0e019b7dd3d2bf93b5c705b3b7df9cdb77561"
Fixed #27083 -- Added support for weak ETags.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/27083#comment:6>

Django

unread,
Sep 16, 2016, 6:15:19 AM9/16/16
to django-...@googlegroups.com
#27083: Parse conditional HTTP headers according to RFC 7232

-------------------------------+------------------------------------
Reporter: marfire | Owner: marfire
Type: Bug | Status: closed
Component: HTTP handling | Version: master
Severity: Normal | Resolution: fixed
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------+------------------------------------

--
Ticket URL: <https://code.djangoproject.com/ticket/27083#comment:7>

Django

unread,
Sep 16, 2016, 3:46:35 PM9/16/16
to django-...@googlegroups.com
#27083: Parse conditional HTTP headers according to RFC 7232
-------------------------------+------------------------------------
Reporter: marfire | Owner: marfire
Type: Bug | Status: closed
Component: HTTP handling | Version: master
Severity: Normal | Resolution: fixed
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------+------------------------------------

Comment (by Tim Graham <timograham@…>):

In [changeset:"22e303887b7f807b39239880e33b9018566e0137" 22e3038]:
{{{
#!CommitTicketReference repository=""
revision="22e303887b7f807b39239880e33b9018566e0137"
Refs #27083 -- Updated conditional header comparison to match RFC 7232.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/27083#comment:8>

Reply all
Reply to author
Forward
0 new messages