Re: [squid-dev] [PATCH] Revalidate without Last-Modified
On 08/23/2016 09:17 AM, Amos Jeffries wrote: > On 24/08/2016 12:07 a.m., Eduard Bagdasaryan wrote: >> 2016-08-21 15:58 GMT+03:00 Amos Jeffries: >>> To change anything between those markers we have to do a full cache >>> versioning and up/down-grade compatibility dance. >> Could you please clarify what versioning problems you are talking >> about? > I was referring to that block of members being read and written > directly to cache files. Either swap.state or the object metadata section. > I dont think they are referenced individully, but as a raw-pointer to > the first members address cast to some other identically laid out > StoreMeta* type (yucky). Yes, this happens in at least two places: > bzr grep timestamp src | fgrep \& ... > src/store_rebuild.cc:memcpy(>timestamp, x.value, > STORE_HDR_METASIZE); > src/store_swapmeta.cc:t = > StoreMeta::Factory(STORE_META_STD_LFS,STORE_HDR_METASIZE,>timestamp) > The point of those comments AFAIK is to make it obvious that kind of > this is/was being done with them and prevent us doing what you did. Agreed. Since improving this code is way outside this simple fix scope, I recommend returning the renamed lastmod data member into that "keep them together" section, with a comment: time_t lastmod_; ///< received Last-Modified value or -1; treat as private Please note that "received Last-Modified value or -1" is just my guess what lastmod_ is -- use the right description if my guess is wrong. Renaming lastmod (and temporary making it private) already forced you to check and, if needed, adjust most of the old code using that data member. Keeping lastmod_ public is not ideal, but it does not make things worse and allows you to stay focused. Fixing related problems is only a good idea when those fixes are simple and do not stray you off course too much. HTH, Alex. ___ squid-dev mailing list squid-dev@lists.squid-cache.org http://lists.squid-cache.org/listinfo/squid-dev
Re: [squid-dev] Coding standards
On 08/23/2016 05:48 AM, Adam Majer wrote: > What are the coding standards for Squid? Just to add to Kinkie's correct response: We do not have a comprehensive standard, unfortunately, but you can find a few requirements at http://wiki.squid-cache.org/SquidCodingGuidelines (which should be updated to answer the C++11 question). HTH, Alex. ___ squid-dev mailing list squid-dev@lists.squid-cache.org http://lists.squid-cache.org/listinfo/squid-dev
Re: [squid-dev] [PATCH] Incorrect processing of long URIs
On 08/23/2016 08:08 AM, Amos Jeffries wrote: > A followup patch can be done to give skipDelimiter a 'const char* which' > parameter that takes a description/name for the delimiter to improve > that debug output. > > so: > skipDelimiter(blah, "method") > > produces: > invalid request-line: missing method delimiter Good idea! I would s/which/where/ s/missing delimiter/missing delimiter / because the URI field has two associated delimiters (left and right), and a "where" parameter would be able to detail the missing delimiter better: invalid request-line: missing delimiter after method invalid request-line: missing delimiter before "HTTP/1" Same for the "too many delimiters" error, of course. Thank you, Alex. ___ squid-dev mailing list squid-dev@lists.squid-cache.org http://lists.squid-cache.org/listinfo/squid-dev
Re: [squid-dev] [PATCH] Incorrect processing of long URIs
On 08/23/2016 03:26 AM, Eduard Bagdasaryan wrote: > 2016-08-23 3:08 GMT+03:00 Alex Rousskov: >> I do not understand why you decided to use maxMethodLength in >> parseRequestFirstLine(). AFAICT, parseMethodField() already does >> everything we need: It logs an error message and sets parseStatusCode >> accordingly. > Yes, it does partly what we need but it does not parse the delimiter( > and inform about possible failure). ... which is unrelated to the maxMethodLength move I questioned above. > skipDelimiter() does this with message: > >> invalid request-line: missing delimiter > > which does not hint that our case is a 'bad' method If the method parses OK but the delimiter is missing, then our case can be considered to be a case of a "missing delimiter" rather than of a "bad method". It is all relative, of course: If a request line starts with a few token characters, then it is impossible to say whether the method suffix is invalid or the following delimiter -- it takes two to tango. > and less informative than: > >> invalid request-line: method exceeds 32-byte limit How is a "missing delimiter" error is less informative than "method exceeds 32-byte limit", especially when the method does not actually exceed that limit? [Rhetorical] > I followed your sketch and refreshed the patch. > +debugs(74, ErrorLevel(), "invalid request-line exceeds " << > +Config.maxRequestHeaderSize << "-byte limit"); bzr grep "invalid request-line" src s/request-line/request-line: URI/ for consistency and clarity sake. > +const CharacterSet = DelimiterCharacters(); I wonder whether we should make this variable static to avoid repeated function calls on a performance-sensitive code path. Same for the old "delimiters" variable left inside parseRequestFirstLine(), of course. These polishing touches can be done during commit. +1 Alex. ___ squid-dev mailing list squid-dev@lists.squid-cache.org http://lists.squid-cache.org/listinfo/squid-dev
Re: [squid-dev] [PATCH] Incorrect processing of long URIs
On 23/08/2016 9:26 p.m., Eduard Bagdasaryan wrote: > 2016-08-23 3:08 GMT+03:00 Alex Rousskov: > >> I do not understand why you decided to use maxMethodLength in >> parseRequestFirstLine(). AFAICT, parseMethodField() already does >> everything we need: It logs an error message and sets parseStatusCode >> accordingly. > > Yes, it does partly what we need but it does not parse the delimiter( > and inform about possible failure). skipDelimiter() does this with > message: > >> invalid request-line: missing delimiter > > which does not hint that our case is a 'bad' method and > less informative than: > >> invalid request-line: method exceeds 32-byte limit > > Probably this does not make much sense, so I followed your > sketch and refreshed the patch. A followup patch can be done to give skipDelimiter a 'const char* which' parameter that takes a description/name for the delimiter to improve that debug output. so: skipDelimiter(blah, "method") produces: invalid request-line: missing method delimiter Amos ___ squid-dev mailing list squid-dev@lists.squid-cache.org http://lists.squid-cache.org/listinfo/squid-dev
Re: [squid-dev] [PATCH] Revalidate without Last-Modified
2016-08-21 15:58 GMT+03:00 Amos Jeffries: > To change anything between those markers we have to do a full cache > versioning and up/down-grade compatibility dance. Could you please clarify what versioning problems you are talking about? It seems that StoreEntry's STORE_META_STD fields are not used directly while storing/restoring metainformation. I found only places where field-by-field assignment is performed (e.g., InitStoreEntry::operator()), so making StoreEntry::lastmod 'private' should not do any harm there. So probably we could mark with "START OF ON-DISK STORE_META_STD TLV field" (or similar) the StoreEntry::lastmod, which is now private. > lastModifiedDelta() returning -1 when the actual delta is any -N value > is wrong conceptually. A delta should be the actual difference value -N < 0 < +N. Since we need and use only the positive outcome of this method inside refreshStaleness(), probably rename it to ageWhenCached() (or similar)? Returning '-1' would mean that it is impossible to calculate the age ('lastmod' is absent or greater than timestamp). Eduard. ___ squid-dev mailing list squid-dev@lists.squid-cache.org http://lists.squid-cache.org/listinfo/squid-dev
Re: [squid-dev] Coding standards
Hi Adam! You're absolutely right; Squid 4.0 is c++11; squid 3.5 is not getting new features right now. On Tue, Aug 23, 2016 at 12:48 PM, Adam Majerwrote: > Hello, > > What are the coding standards for Squid? More specifically, I would like > to know if C++11 (or later?) is allowed in Squid 4.0. I'm assuming that > Squid 3.5 is still on the old C++03. > > Thanks, > Adam > > ___ > squid-dev mailing list > squid-dev@lists.squid-cache.org > http://lists.squid-cache.org/listinfo/squid-dev > -- Francesco ___ squid-dev mailing list squid-dev@lists.squid-cache.org http://lists.squid-cache.org/listinfo/squid-dev
[squid-dev] Coding standards
Hello, What are the coding standards for Squid? More specifically, I would like to know if C++11 (or later?) is allowed in Squid 4.0. I'm assuming that Squid 3.5 is still on the old C++03. Thanks, Adam ___ squid-dev mailing list squid-dev@lists.squid-cache.org http://lists.squid-cache.org/listinfo/squid-dev
Re: [squid-dev] [PATCH] Incorrect processing of long URIs
2016-08-23 3:08 GMT+03:00 Alex Rousskov: > I do not understand why you decided to use maxMethodLength in > parseRequestFirstLine(). AFAICT, parseMethodField() already does > everything we need: It logs an error message and sets parseStatusCode > accordingly. Yes, it does partly what we need but it does not parse the delimiter( and inform about possible failure). skipDelimiter() does this with message: > invalid request-line: missing delimiter which does not hint that our case is a 'bad' method and less informative than: > invalid request-line: method exceeds 32-byte limit Probably this does not make much sense, so I followed your sketch and refreshed the patch. Eduard. MUST respond with 414 (URI Too Long) when request target exceeds limits. Before the fix, Squid simply closed client connection after receiving a huge URI (or a huge request-line), violating the RFC 7230 MUST. This happened because a high-level Must(have buffer space) check in ConnStateData::clientParseRequests() would throw an exception. Now these problems are detected inside the low-level RequestParser code, where we can distinguish huge URIs from huge methods. === modified file 'src/http/one/RequestParser.cc' --- src/http/one/RequestParser.cc 2016-05-20 08:28:33 + +++ src/http/one/RequestParser.cc 2016-08-23 09:01:24 + @@ -58,60 +58,65 @@ while (!buf_.isEmpty() && (buf_[0] == '\n' || (buf_[0] == '\r' && buf_[1] == '\n'))) { buf_.consume(1); } } } /** * Attempt to parse the method field out of an HTTP message request-line. * * Governed by: * RFC 1945 section 5.1 * RFC 7230 section 2.6, 3.1 and 3.5 */ bool Http::One::RequestParser::parseMethodField(Http1::Tokenizer ) { // method field is a sequence of TCHAR. // Limit to 32 characters to prevent overly long sequences of non-HTTP // being sucked in before mismatch is detected. 32 is itself annoyingly // big but there are methods registered by IANA that reach 17 bytes: // http://www.iana.org/assignments/http-methods static const size_t maxMethodLength = 32; // TODO: make this configurable? SBuf methodFound; if (!tok.prefix(methodFound, CharacterSet::TCHAR, maxMethodLength)) { debugs(33, ErrorLevel(), "invalid request-line: missing or malformed method"); parseStatusCode = Http::scBadRequest; return false; } method_ = HttpRequestMethod(methodFound); + +const CharacterSet = DelimiterCharacters(); +if (!skipDelimiter(tok.skipAll(delimiters))) +return false; + return true; } /// the characters which truly are valid within URI static const CharacterSet & UriValidCharacters() { /* RFC 3986 section 2: * " * A URI is composed from a limited set of characters consisting of * digits, letters, and a few graphic symbols. * " */ static const CharacterSet UriChars = CharacterSet("URI-Chars","") + // RFC 3986 section 2.2 - reserved characters CharacterSet("gen-delims", ":/?#[]@") + CharacterSet("sub-delims", "!$&'()*+,;=") + // RFC 3986 section 2.3 - unreserved characters CharacterSet::ALPHA + CharacterSet::DIGIT + CharacterSet("unreserved", "-._~") + // RFC 3986 section 2.1 - percent encoding "%" HEXDIG CharacterSet("pct-encoded", "%") + CharacterSet::HEXDIG; return UriChars; } /// characters which Squid will accept in the HTTP request-target (URI) @@ -243,73 +248,83 @@ return false; } } return true; } /** * Attempt to parse the first line of a new request message. * * Governed by: * RFC 1945 section 5.1 * RFC 7230 section 2.6, 3.1 and 3.5 * * \retval -1 an error occurred. parseStatusCode indicates HTTP status result. * \retval 1 successful parse. member fields contain the request-line items * \retval 0 more data is needed to complete the parse */ int Http::One::RequestParser::parseRequestFirstLine() { debugs(74, 5, "parsing possible request: buf.length=" << buf_.length()); debugs(74, DBG_DATA, buf_); SBuf line; // Earlier, skipGarbageLines() took care of any leading LFs (if allowed). // Now, the request line has to end at the first LF. static const CharacterSet lineChars = CharacterSet::LF.complement("notLF"); ::Parser::Tokenizer lineTok(buf_); if (!lineTok.prefix(line, lineChars) || !lineTok.skip('\n')) { +if (buf_.length() >= Config.maxRequestHeaderSize) { +/* who should we blame for our failure to parse this line? */ + +Http1::Tokenizer methodTok(buf_); +if (!parseMethodField(methodTok)) +return -1; // blame a bad method (or its delimiter) + +// assume it is the URI +debugs(74, ErrorLevel(), "invalid request-line exceeds " << +