#27545: Django conditional If-Match: * returns precondition failed response
-------------------------------------+-------------------------------------
               Reporter:  David      |          Owner:  nobody
  Harrigan                           |
                   Type:  Bug        |         Status:  new
              Component:  HTTP       |        Version:  1.10
  handling                           |       Keywords:  precondition,
               Severity:  Normal     |  etags, etag,  if-match
           Triage Stage:             |      Has patch:  0
  Unreviewed                         |
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  0
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 I believe there is a small bug in how `If-Match: *` behavior is supposed
 to work in Django version <= 1.10.  I know that 1.11 is migrating to
 RFC-7232 specification conditional header, and that version <= 1.10
 implements according to RFC-2616.

 Expected behavior of `If-Match: *` according to RFC-2616:
 > If any of the entity tags match the entity tag of the entity that
 > would have been returned in the response to a similar GET request
 > (without the If-Match header) on that resource, or if "*" is given
 > and any current entity exists for that resource, then the server MAY
 > perform the requested method as if the If-Match header field did not
 > exist.

 So if `*` is given as the field-value, Django should allow the process to
 continue as long as the entity exits.

 Current behavior:
 https://github.com/django/django/blob/1.10.3/django/utils/cache.py#L184

 Where `etag` variable is the etag for the entity in question.

 {{{
 # returns precondition failed if this evaluates to true
 (not etag and '*' in etags) or (etag and etag not in etags)
 }}}

 **Problem**: * in etags not considered here if `etag` is present.
 According to the RFC,  as long as the entity is present on the server,
 If-Match: * should yield in as If-Match header was not given by the
 client.   This scenario here in Django implementation results in
 precondition failed.

 I believe the above code should be re-written as something like:
 {{{
 not etag or                                          # not etag == no
 entity, so always return a 412
 not ('*' in etags or etag in etags)    # allow * in etags or client
 specified etag in etags
 }}}

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

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/056.12ade50a654c1a226c5c9af0e7553fc5%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to