Bug #753

Repeated headers produce 400 Bad Request

Added by Anonymous over 8 years ago. Updated over 5 years ago.

Status:FixedStart date:
Priority:NormalDue date:
Assignee:jan% Done:

100%

Category:core
Target version:1.4.23
Missing in 1.5.x:

Description

I've filed a bug in the squid-cache bugzilla (http://www.squid-cache.org/bugs/show_bug.cgi?id=1677) that squid produces a duplicate "If-None-Match:" header in it's request, which seems to make lighttpd return a "400 Bad Request":


# telnet localhost 80
GET / HTTP/1.0
If-Modified-Since: Thu, 06 Jul 2006 09:57:57 GMT
If-None-Match: "714413461" 
If-None-Match: "714413461" 

HTTP/1.0 400 Bad Request
Connection: close
Content-Type: text/html
Content-Length: 349
Date: Wed, 12 Jul 2006 08:14:49 GMT
Server: lighttpd/1.4.11

But - according to RFC 2616, the repeated "If-None-Match:" header is both legal and equivalent to

If-None-Match: "714413461", "714413461"

which, if used instead, works just fine.

(Excerpt from RFC 2616:


| 4.2 Message Headers
[...]
|    Multiple message-header fields with the same field-name MAY be
|    present in a message if and only if the entire field-value for that
|    header field is defined as a comma-separated list [i.e., #(values)].
|    It MUST be possible to combine the multiple header fields into one
|    "field-name: field-value" pair, without changing the semantics of the
|    message, by appending each subsequent field-value to the first, each
|    separated by a comma. The order in which header fields with the same
|    field-name are received is therefore significant to the
|    interpretation of the combined field value, and thus a proxy MUST NOT
|    change the order of these field values when a message is forwarded.

| 14.26 If-None-Match
[...]
|        If-None-Match = "If-None-Match" ":" ( "*" | 1#entity-tag )

)

So while squid shouldn't duplicate the header in the first place, lighttpd should not produce a 400 Bad Request in response...

(Yeah, it should also probably say "HTTP/1.1" in the request from squid (which they said they won't do before they're fully 1.1 compliant), but changing the request into a valid HTTP/1.1 request still produces a 400 response code...)

-- Bugzilla-Briareos

Associated revisions

Revision 2528
Added by stbuehler over 5 years ago

Ignore multiple "If-None-Match" headers (only use first one, fixes #753)

Revision 2529
Added by stbuehler over 5 years ago

Ignore multiple "If-None-Match" headers (only use first one, fixes #753)

History

#1 Updated by Anonymous over 8 years ago

More bugs in If-None-Match processing. Looks like lighttpd reads If-None-Match as a string header and not a list header.

If-None-Match: "currentetag"

produces a 304

If-None-Match: "currentetag", "anotheretag"

produces a 200, where a 304 was expected..

-- hno

#2 Updated by stbuehler about 6 years ago

  • Status changed from New to Fixed
  • Resolution set to invalid

If-None-Match = "If-None-Match" ":" ( "*" | 1#entity-tag )

Only one etag is allowed, so '"currentetag", "anotheretag"' is read as one etag, which of course doesn't match.

The a,b intepretation doesn't match the etag syntax anyway; so 400 is the right answer. 1.5 worksaround this by killing a duplicate if it has the same etag.

#3 Updated by Anonymous about 6 years ago

  • Status changed from Fixed to Need Feedback
  • Resolution deleted (invalid)

No, the initial reporter is right here.

Please read the definition of #rule in the BNF description again:

#rule
A construct "#" is defined, similar to "*", for defining lists of
elements. The full form is "<n>#<m>element" indicating at least
<n> and at most <m> elements, each separated by one or more commas
(",") and OPTIONAL linear white space (LWS). This makes the usual
form of lists very easy; a rule such as
( *LWS element *( *LWS "," *LWS element ))
can be shown as
1#element

Which means that 1#etag is a list of etags, with at least one member.

-- hno

#4 Updated by stbuehler about 6 years ago

Sry, you are right. (stupid "bnf" syntax...).

#5 Updated by icy over 5 years ago

  • Target version changed from 1.4.21 to 1.4.22
  • Patch available set to No

#6 Updated by stbuehler over 5 years ago

  • Target version changed from 1.4.22 to 1.4.23

#7 Updated by stbuehler over 5 years ago

  • Status changed from Need Feedback to Fixed
  • % Done changed from 0 to 100

Applied in changeset r2528.

Also available in: Atom