Bug #2578
closedIf-None-Match handling does not comply with RFC2616
Description
In the case where a client knows there might be more than one ETag for a resource, it can supply all of the ETags it has and the server should return a 304 if one of them matches. A client could suppose that an ETag is weak and submit it as such, regardless of whether the server originally send a weak ETag.
Attached is a patch that adds full support for If-None-Match as defined in RFC2616.
This patch does not attempt to cause lighttpd to actually send weak ETags.
Files
Updated by stbuehler over 10 years ago
- % Done changed from 90 to 50
Hi. Thx for your work so far!
- I wasn't completely happy with the parser and rewrote it a little bit
- We usually use tabs to indent
- "ISO C90 forbids mixed declarations and code" (http-header-glue.c)
- As far as I understand the RFC weak ETag validation must not be used for ranged requests; I therefor had to disable the weak check. Also added a test case for it, and made the two weak cases "TODO" items.
- I think the RFC accepts empty "tokens" - skipping
","
inSTART
should fix it, i.e.If-None-Match: ,"1", ,, "2"
- Tokens must always be separated by at least one
","
-TAIL
must only go toSTART
with a","
- I'm not completely sure whether the quoted pairs have to match - is
"a"
equal to"\a"
or not? For now I assume they are not equal: "both validators MUST be identical in every way"
See http://git.lighttpd.net/lighttpd/lighttpd-1.x.git/commit/?h=lighttpd-1.4.x-stbuehler-if-non-match-2578 for my current patch.
I can add your account name + email (or something else) as author if you want.
Any good ideas how to solve the weak ETag validation vs. ranged request thing? Is it really needed? Perhaps etag_is_equal
could be extended to return whether it was a strong or a weak match, although I'd like a different function name for that.
- I think
char
is a bad substitute forbool
- char is a "special" integral type. It certainly saves no memory on the stack, in registers or in function parameters. I usedint
instead. - Mixed returning of enum values and "boolean" values (
!...
) - this is wrong. The function names indicates the return value is a boolean, and therefore the returned values should only be0
or1
(orFALSE
/TRUE
). - Just directly return on success instead of using a special state (and
!state
is not very readably - enum values should be compared explicitly, so searching for them is easier) enum { FOUND_TOKEN = 0, START, TOKEN, MAYBE_WEAK, QUOTING, TAIL } states;
- unused variablestates
. Perhaps this was inteded as a typedef (typedef enum {...} states;
)?- I like to do comparisions with constant values the other way round, so I don't accidentally assign stuff (
if ('"' == *current)
instead ofif (*current == '"')
); yourconst char*
pointers would have prevented assignments too ofc. - We have
case
labels on the same indentation level as the surrounding switch - that way{
and}
add and remove always exactly one level.
Updated by stbuehler over 9 years ago
- Status changed from New to Fixed
- % Done changed from 50 to 100
Applied in changeset r2994.
Also available in: Atom