From: Stephen D. <sd...@gm...> - 2012-10-27 13:04:21
|
On Sat, Oct 27, 2012 at 1:13 PM, Gustaf Neumann <ne...@wu...> wrote: > On 26.10.12 15:47, Stephen Deasey wrote: >> I think the spec says that for HTTP/1.1, if the client doesn't >> explicitly say to NOT send the body gzipped, say by using a q value of >> 0 (which we don't actually check for, woops...), then the server can >> choose the encoding, although it should prefer the identity, unless >> that's unavailable. So we're being very pushy... > > now we do check for the qvalues used in connection with > gzip. So, a client can now specify explicitly, that gzip is > NOT wanted via "gzip; q=0". What the code still does not do > is comparing the identity-qvalue with the gzip-qvalue or > combination with wildcards "....*;q=..." Jeff had a go at this as well: https://bitbucket.org/jeffr/naviserver-queues/changesets Here's the feedback I tacked on to the end of a mercurial question via email: It bothers me a bit that a fresh Ns_Set has to be allocated, and also the parsing code is pretty gnarly and hard to verify. It looks about right, but I'd have to resort to pencil and paper to be more sure, and the fact I haven't done that reminds me that people tend to not look too closely at these things and that's where bugs can fester. I wonder if there's another way of doing this... You'll have to double check the details, but IIRC q values go from 0-999. If 'gzip' is present without a q value then it's as if it had q=1 -- that's the default. If it's not present, it's as if it were but with q=0. So, how about a function like Ns_HeaderQ(header, attr) which returns the integer q value for the specified atttribute. It simply uses strstr to find gzip. If it doesn't, return 0. If it does, then check for a q=. If it's the character '0', return 0. If there's no q, return 1. If it's something else, parse the int and return that. Then you can use it something like: if (!(connPtr->flags & NS_CONN_SENTHDRS) && !(connPtr->flags & NS_CONN_SKIPBODY)) { contentEncoding = Ns_SetIGet(Ns_ConnHeaders(conn), "Accept-Encoding"); if (Ns_HeaderQ(contentEncoding, "gzip") > 0 || Ns_HeaderQ(contentEncoding, "*") > 0) { gzip = 1; I'm not sure how eager the server should be sending gzipped content. An alternative to the above would be to keep the existing eager use of gzip, but respect the client's negative assertion: if (!(connPtr->flags & NS_CONN_SENTHDRS) && !(connPtr->flags & NS_CONN_SKIPBODY)) { contentEncoding = Ns_SetIGet(Ns_ConnHeaders(conn), "Accept-Encoding"); if (connPtr->request->version >= 1.1) { if ((!Ns_HeaderQ(contentEncoding, "gzip", &q) || q > 0) && (!Ns_HeaderQ(contentEncoding, "*", &q) || q > 0)) { gzip = 1; } } else if ((Ns_HeaderQ(contentEncoding, "gzip", &q) && q > 0) || (Ns_HeaderQ(contentEncoding, "*", &q) && q > 0)) { gzip = 1; } Here Ns_HeaderQ is modified to return NS_TRUE or NS_FALSE depending on whether the attribute is present, and the q value is returned into the given variable. HTTP 1.0 clients have to explicitly ask for gzip, 1.1 clients get it unless the say they don't want it. |