# Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: kinkie@squid-cache.org-20110927061457-e3ymf0lynnjrbfoe # target_branch: ../trunk/ # testament_sha1: af534634e953b3458b088a72cb1df44f4feb9762 # timestamp: 2011-09-27 08:22:53 +0200 # base_revision_id: squid3@treenet.co.nz-20110918025418-\ # uoxqj1fxx199qsgb # # Begin patch === modified file 'src/HttpHdrCc.cc' --- src/HttpHdrCc.cc 2010-12-27 20:25:30 +0000 +++ src/HttpHdrCc.cc 2011-09-27 05:16:58 +0000 @@ -1,9 +1,6 @@ - /* - * $Id$ * * DEBUG: section 65 HTTP Cache Control Header - * AUTHOR: Alex Rousskov * * SQUID Web Proxy Cache http://www.squid-cache.org/ * ---------------------------------------------------------- @@ -34,30 +31,45 @@ */ #include "squid.h" +#include "base/StringArea.h" #include "Store.h" #include "HttpHeader.h" - -/* this table is used for parsing cache control header */ -static const HttpHeaderFieldAttrs CcAttrs[CC_ENUM_END] = { - {"public", (http_hdr_type)CC_PUBLIC}, - - {"private", (http_hdr_type)CC_PRIVATE}, - {"no-cache", (http_hdr_type)CC_NO_CACHE}, - {"no-store", (http_hdr_type)CC_NO_STORE}, - {"no-transform", (http_hdr_type)CC_NO_TRANSFORM}, - {"must-revalidate", (http_hdr_type)CC_MUST_REVALIDATE}, - {"proxy-revalidate", (http_hdr_type)CC_PROXY_REVALIDATE}, - {"only-if-cached", (http_hdr_type)CC_ONLY_IF_CACHED}, - {"max-age", (http_hdr_type)CC_MAX_AGE}, - {"s-maxage", (http_hdr_type)CC_S_MAXAGE}, - {"max-stale", (http_hdr_type)CC_MAX_STALE}, - {"stale-if-error", (http_hdr_type)CC_STALE_IF_ERROR}, - {"min-fresh", (http_hdr_type)CC_MIN_FRESH}, - {"Other,", (http_hdr_type)CC_OTHER} /* ',' will protect from matches */ +#include "HttpHdrCc.h" + +#if HAVE_MAP +#include +#endif + +/* a row in the table used for parsing cache control header and statistics */ +typedef struct { + const char *name; + http_hdr_cc_type id; + HttpHeaderFieldStat stat; +} HttpHeaderCcFields; + +/* order must match that of enum http_hdr_cc_type. The constraint is verified at initialization time */ +static HttpHeaderCcFields CcAttrs[CC_ENUM_END] = { + {"public", CC_PUBLIC}, + {"private", CC_PRIVATE}, + {"no-cache", CC_NO_CACHE}, + {"no-store", CC_NO_STORE}, + {"no-transform", CC_NO_TRANSFORM}, + {"must-revalidate", CC_MUST_REVALIDATE}, + {"proxy-revalidate", CC_PROXY_REVALIDATE}, + {"max-age", CC_MAX_AGE}, + {"s-maxage", CC_S_MAXAGE}, + {"max-stale", CC_MAX_STALE}, + {"min-fresh", CC_MIN_FRESH}, + {"only-if-cached", CC_ONLY_IF_CACHED}, + {"stale-if-error", CC_STALE_IF_ERROR}, + {"Other,", CC_OTHER} /* ',' will protect from matches */ }; -HttpHeaderFieldInfo *CcFieldsInfo = NULL; +/// Map an header name to its type, to expedite parsing +typedef std::map CcNameToIdMap_t; +static CcNameToIdMap_t CcNameToIdMap; +/// iterate over a table of http_header_cc_type structs http_hdr_cc_type &operator++ (http_hdr_cc_type &aHeader) { int tmp = (int)aHeader; @@ -66,52 +78,34 @@ } -/* local prototypes */ -static int httpHdrCcParseInit(HttpHdrCc * cc, const String * str); - - -/* module initialization */ - +/// Module initialization hook void httpHdrCcInitModule(void) { - CcFieldsInfo = httpHeaderBuildFieldsInfo(CcAttrs, CC_ENUM_END); + /* build lookup and accounting structures */ + for (int32_t i = 0;i < CC_ENUM_END; ++i) { + const HttpHeaderCcFields &f=CcAttrs[i]; + assert(i == f.id); /* verify assumption: the id is the key into the array */ + const StringArea k(f.name,strlen(f.name)); + CcNameToIdMap[k]=f.id; + } } +/// Module cleanup hook. void httpHdrCcCleanModule(void) { - httpHeaderDestroyFieldsInfo(CcFieldsInfo, CC_ENUM_END); - CcFieldsInfo = NULL; -} - -/* implementation */ - -HttpHdrCc * -httpHdrCcCreate(void) -{ - HttpHdrCc *cc = (HttpHdrCc *)memAllocate(MEM_HTTP_HDR_CC); - cc->max_age = cc->s_maxage = cc->max_stale = cc->min_fresh = -1; - return cc; -} - -/* creates an cc object from a 0-terminating string */ -HttpHdrCc * -httpHdrCcParseCreate(const String * str) -{ - HttpHdrCc *cc = httpHdrCcCreate(); - - if (!httpHdrCcParseInit(cc, str)) { - httpHdrCcDestroy(cc); - cc = NULL; - } - - return cc; -} - -/* parses a 0-terminating string and inits cc */ -static int -httpHdrCcParseInit(HttpHdrCc * cc, const String * str) + // HdrCcNameToIdMap is self-cleaning +} + +void +HttpHdrCc::clear() +{ + *this=HttpHdrCc(); +} + +bool +HttpHdrCc::parse(const String & str) { const char *item; const char *p; /* '=' parameter */ @@ -119,11 +113,11 @@ http_hdr_cc_type type; int ilen; int nlen; - assert(cc && str); + HttpHdrCc *cc=this; //TODO: remove after review /* iterate through comma separated list */ - while (strListGetItem(str, ',', &item, &ilen, &pos)) { + while (strListGetItem(&str, ',', &item, &ilen, &pos)) { /* isolate directive name */ if ((p = (const char *)memchr(item, '=', ilen)) && (p - item < ilen)) @@ -132,19 +126,18 @@ nlen = ilen; /* find type */ - type = (http_hdr_cc_type ) httpHeaderIdByName(item, nlen, - CcFieldsInfo, CC_ENUM_END); - - if (type < 0) { - debugs(65, 2, "hdr cc: unknown cache-directive: near '" << item << "' in '" << str << "'"); - type = CC_OTHER; - } + const StringArea tmpstr(item,nlen); + const CcNameToIdMap_t::const_iterator i=CcNameToIdMap.find(tmpstr); + if (i==CcNameToIdMap.end()) + type=CC_OTHER; + else + type=i->second; // ignore known duplicate directives if (EBIT_TEST(cc->mask, type)) { if (type != CC_OTHER) { debugs(65, 2, "hdr cc: ignoring duplicate cache-directive: near '" << item << "' in '" << str << "'"); - CcFieldsInfo[type].stat.repCount++; + ++CcAttrs[type].stat.repCount; continue; } } else { @@ -155,11 +148,12 @@ switch (type) { case CC_MAX_AGE: - - if (!p || !httpHeaderParseInt(p, &cc->max_age)) { + int32_t ma; + if (!p || !httpHeaderParseInt(p, &ma)) { debugs(65, 2, "cc: invalid max-age specs near '" << item << "'"); - cc->max_age = -1; - EBIT_CLR(cc->mask, type); + cc->setMaxAge(MAX_AGE_UNSET); + } else { + cc->setMaxAge(ma); } break; @@ -168,8 +162,7 @@ if (!p || !httpHeaderParseInt(p, &cc->s_maxage)) { debugs(65, 2, "cc: invalid s-maxage specs near '" << item << "'"); - cc->s_maxage = -1; - EBIT_CLR(cc->mask, type); + cc->setSMaxAge(S_MAXAGE_UNSET); } break; @@ -178,7 +171,7 @@ if (!p || !httpHeaderParseInt(p, &cc->max_stale)) { debugs(65, 2, "cc: max-stale directive is valid without value"); - cc->max_stale = -1; + cc->setMaxStale(MAX_STALE_ALWAYS); } break; @@ -187,8 +180,7 @@ if (!p || !httpHeaderParseInt(p, &cc->min_fresh)) { debugs(65, 2, "cc: invalid min-fresh specs near '" << item << "'"); - cc->min_fresh = -1; - EBIT_CLR(cc->mask, type); + cc->setMinFresh(MIN_FRESH_UNSET); } break; @@ -196,8 +188,7 @@ case CC_STALE_IF_ERROR: if (!p || !httpHeaderParseInt(p, &cc->stale_if_error)) { debugs(65, 2, "cc: invalid stale-if-error specs near '" << item << "'"); - cc->stale_if_error = -1; - EBIT_CLR(cc->mask, type); + cc->setStaleIfError(STALE_IF_ERROR_UNSET); } break; @@ -216,32 +207,7 @@ } } - return cc->mask != 0; -} - -void -httpHdrCcDestroy(HttpHdrCc * cc) -{ - assert(cc); - - if (cc->other.defined()) - cc->other.clean(); - - memFree(cc, MEM_HTTP_HDR_CC); -} - -HttpHdrCc * -httpHdrCcDup(const HttpHdrCc * cc) -{ - HttpHdrCc *dup; - assert(cc); - dup = httpHdrCcCreate(); - dup->mask = cc->mask; - dup->max_age = cc->max_age; - dup->s_maxage = cc->s_maxage; - dup->max_stale = cc->max_stale; - dup->min_fresh = cc->min_fresh; - return dup; + return (cc->mask != 0); } void @@ -255,24 +221,23 @@ if (EBIT_TEST(cc->mask, flag) && flag != CC_OTHER) { /* print option name */ - packerPrintf(p, (pcount ? ", " SQUIDSTRINGPH : SQUIDSTRINGPH), - SQUIDSTRINGPRINT(CcFieldsInfo[flag].name)); + packerPrintf(p, (pcount ? ", %s": "%s") , CcAttrs[flag].name); /* handle options with values */ if (flag == CC_MAX_AGE) - packerPrintf(p, "=%d", (int) cc->max_age); + packerPrintf(p, "=%d", (int) cc->getMaxAge()); if (flag == CC_S_MAXAGE) - packerPrintf(p, "=%d", (int) cc->s_maxage); + packerPrintf(p, "=%d", (int) cc->getSMaxAge()); - if (flag == CC_MAX_STALE && cc->max_stale >= 0) - packerPrintf(p, "=%d", (int) cc->max_stale); + if (flag == CC_MAX_STALE && cc->getMaxStale() >= 0) + packerPrintf(p, "=%d", (int) cc->getMaxStale()); if (flag == CC_MIN_FRESH) - packerPrintf(p, "=%d", (int) cc->min_fresh); + packerPrintf(p, "=%d", (int) cc->getMinFresh()); - pcount++; + ++pcount; } } @@ -281,32 +246,6 @@ SQUIDSTRINGPRINT(cc->other)); } -/* negative max_age will clean old max_Age setting */ -void -httpHdrCcSetMaxAge(HttpHdrCc * cc, int max_age) -{ - assert(cc); - cc->max_age = max_age; - - if (max_age >= 0) - EBIT_SET(cc->mask, CC_MAX_AGE); - else - EBIT_CLR(cc->mask, CC_MAX_AGE); -} - -/* negative s_maxage will clean old s-maxage setting */ -void -httpHdrCcSetSMaxAge(HttpHdrCc * cc, int s_maxage) -{ - assert(cc); - cc->s_maxage = s_maxage; - - if (s_maxage >= 0) - EBIT_SET(cc->mask, CC_S_MAXAGE); - else - EBIT_CLR(cc->mask, CC_S_MAXAGE); -} - void httpHdrCcUpdateStats(const HttpHdrCc * cc, StatHist * hist) { @@ -324,9 +263,13 @@ extern const HttpHeaderStat *dump_stat; /* argh! */ const int id = (int) val; const int valid_id = id >= 0 && id < CC_ENUM_END; - const char *name = valid_id ? CcFieldsInfo[id].name.termedBuf() : "INVALID"; + const char *name = valid_id ? CcAttrs[id].name : "INVALID"; if (count || valid_id) storeAppendPrintf(sentry, "%2d\t %-20s\t %5d\t %6.2f\n", id, name, count, xdiv(count, dump_stat->ccParsedCount)); } + +#if !_USE_INLINE_ +#include "HttpHdrCc.cci" +#endif === added file 'src/HttpHdrCc.cci' --- src/HttpHdrCc.cci 1970-01-01 00:00:00 +0000 +++ src/HttpHdrCc.cci 2011-09-27 05:31:10 +0000 @@ -0,0 +1,122 @@ +/* + * + * DEBUG: section 65 HTTP Cache Control Header + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * incorporates software developed and/or copyrighted by other + * sources; see the CREDITS file for full details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ + + +void +HttpHdrCc::setMaxAge(int max_age_) +{ + + if (max_age_ >= 0) { + EBIT_SET(mask, CC_MAX_AGE); + max_age = max_age_; + } else { + EBIT_CLR(mask, CC_MAX_AGE); + max_age=MAX_AGE_UNSET; + } +} + +int32_t +HttpHdrCc::getMaxAge() const +{ + return max_age; +} + +void +HttpHdrCc::setSMaxAge(int32_t s_maxage) +{ + if (s_maxage >= 0) { + EBIT_SET(mask, CC_S_MAXAGE); + this->s_maxage=s_maxage; + } else { + EBIT_CLR(mask, CC_S_MAXAGE); + this->s_maxage=S_MAXAGE_UNSET; + } +} + +int32_t +HttpHdrCc::getSMaxAge() const +{ + return s_maxage; +} + +void +HttpHdrCc::setMaxStale(int32_t max_stale) +{ + if (max_stale>=0 || max_stale==MAX_STALE_ALWAYS) { + EBIT_SET(mask,CC_MAX_STALE); + this->max_stale=max_stale; + } else { + EBIT_CLR(mask, CC_MAX_STALE); + this->max_stale=MAX_STALE_UNSET; + } +} +int32_t +HttpHdrCc::getMaxStale() const +{ + return max_stale; +} + +void +HttpHdrCc::setStaleIfError(int32_t stale_if_error) +{ + if (stale_if_error >= 0) { + EBIT_SET(mask, CC_STALE_IF_ERROR); + this->stale_if_error=stale_if_error; + } else { + EBIT_CLR(mask, CC_STALE_IF_ERROR); + this->stale_if_error=STALE_IF_ERROR_UNSET; + } +} + +int32_t +HttpHdrCc::getStaleIfError() const +{ + return stale_if_error; +} + +void +HttpHdrCc::setMinFresh(int32_t min_fresh) +{ + if (min_fresh >= 0) { + EBIT_SET(mask, CC_MIN_FRESH); + this->min_fresh=min_fresh; + } else { + EBIT_CLR(mask, CC_MIN_FRESH); + this->min_fresh=MIN_FRESH_UNSET; + } +} + +int32_t +HttpHdrCc::getMinFresh() const +{ + return min_fresh; +} === added file 'src/HttpHdrCc.h' --- src/HttpHdrCc.h 1970-01-01 00:00:00 +0000 +++ src/HttpHdrCc.h 2011-09-27 06:14:57 +0000 @@ -0,0 +1,112 @@ +/* + * HttpHdrCc.h + * + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * incorporates software developed and/or copyrighted by other + * sources; see the CREDITS file for full details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + */ + +#ifndef SQUID_HTTPHDRCC_H +#define SQUID_HTTPHDRCC_H + +#include "config.h" +#include "MemPool.h" +#include "SquidString.h" + +/** Http Cache-Control header representation + * + * Store and parse the Cache-Control HTTP header. + */ +class HttpHdrCc +{ + +public: + static const int32_t MAX_AGE_UNSET=-1; //max-age is unset + static const int32_t S_MAXAGE_UNSET=-1; //s-maxage is unset + static const int32_t MAX_STALE_UNSET=-1; //max-stale is unset + static const int32_t MAX_STALE_ALWAYS=-2; //max-stale is set to no value + static const int32_t STALE_IF_ERROR_UNSET=-1; //stale_if_error is unset + static const int32_t MIN_FRESH_UNSET=-1; //min_fresh is unset + + HttpHdrCc() : + mask(0), max_age(MAX_AGE_UNSET), s_maxage(S_MAXAGE_UNSET), + max_stale(MAX_STALE_UNSET), stale_if_error(STALE_IF_ERROR_UNSET), + min_fresh(MIN_FRESH_UNSET) {} + + /// reset data-members to default state + void clear(); + + /// parse a header-string and fill in appropriate values. + bool parse(const String & s); + + /// max-age setter. Clear by setting to MAX_AGE_UNSET + _SQUID_INLINE_ void setMaxAge(int32_t max_age); + _SQUID_INLINE_ int32_t getMaxAge() const; + + /// s-maxage setter. Clear by setting to S_MAXAGE_UNSET + _SQUID_INLINE_ void setSMaxAge(int32_t s_maxage); + _SQUID_INLINE_ int32_t getSMaxAge() const; + + /// max-stale setter. Clear by setting to MAX_STALE_UNSET + _SQUID_INLINE_ void setMaxStale(int32_t max_stale); + _SQUID_INLINE_ int32_t getMaxStale() const; + + /// stale-if-error setter. Clear by setting to STALE_IF_ERROR_UNSET + _SQUID_INLINE_ void setStaleIfError(int32_t stale_if_error); + _SQUID_INLINE_ int32_t getStaleIfError() const; + + /// min-fresh setter. Clear by setting to MIN_FRESH_UNSET + _SQUID_INLINE_ void setMinFresh(int32_t min_fresh); + _SQUID_INLINE_ int32_t getMinFresh() const; + + MEMPROXY_CLASS(HttpHdrCc); + + /** bit-mask representing what header values are set among those + * recognized by squid. + * + * managed via EBIT_SET/TEST/CLR + */ + int32_t mask; +private: + int32_t max_age; + int32_t s_maxage; + int32_t max_stale; + int32_t stale_if_error; + int32_t min_fresh; +public: + /**comma-separated representation of the header values which were + * received but are not recognized. + */ + String other; +}; + +MEMPROXY_CLASS_INLINE(HttpHdrCc); + +#if _USE_INLINE_ +#include "HttpHdrCc.cci" +#endif + +#endif /* SQUID_HTTPHDRCC_H */ === modified file 'src/HttpHeader.cc' --- src/HttpHeader.cc 2011-08-29 03:47:54 +0000 +++ src/HttpHeader.cc 2011-09-27 06:14:57 +0000 @@ -36,6 +36,7 @@ #include "squid.h" #include "base64.h" #include "HttpHdrContRange.h" +#include "HttpHdrCc.h" #include "HttpHdrSc.h" #include "HttpHeader.h" #include "MemBuf.h" @@ -1310,16 +1311,19 @@ HttpHdrCc * HttpHeader::getCc() const { - HttpHdrCc *cc; - String s; - if (!CBIT_TEST(mask, HDR_CACHE_CONTROL)) return NULL; PROF_start(HttpHeader_getCc); + String s; getList(HDR_CACHE_CONTROL, &s); - cc = httpHdrCcParseCreate(&s); + HttpHdrCc *cc=new HttpHdrCc(); + + if (!cc->parse(s)) { + delete cc; + cc = NULL; + } HttpHeaderStats[owner].ccParsedCount++; === modified file 'src/HttpReply.cc' --- src/HttpReply.cc 2011-07-16 15:21:48 +0000 +++ src/HttpReply.cc 2011-09-26 19:50:51 +0000 @@ -38,6 +38,7 @@ #include "Store.h" #include "HttpReply.h" #include "HttpHdrContRange.h" +#include "HttpHdrCc.h" #include "HttpHdrSc.h" #include "acl/FilledChecklist.h" #include "HttpRequest.h" @@ -330,21 +331,21 @@ if (cache_control) { if (date >= 0) { - if (cache_control->s_maxage >= 0) - return date + cache_control->s_maxage; + if (cache_control->getSMaxAge() != HttpHdrCc::S_MAXAGE_UNSET) + return date + cache_control->getSMaxAge(); - if (cache_control->max_age >= 0) - return date + cache_control->max_age; + if (cache_control->getMaxAge() != HttpHdrCc::MAX_AGE_UNSET) + return date + cache_control->getMaxAge(); } else { /* * Conservatively handle the case when we have a max-age * header, but no Date for reference? */ - if (cache_control->s_maxage >= 0) + if (cache_control->getSMaxAge() != HttpHdrCc::S_MAXAGE_UNSET) return squid_curtime; - if (cache_control->max_age >= 0) + if (cache_control->getMaxAge() != HttpHdrCc::MAX_AGE_UNSET) return squid_curtime; } } @@ -402,7 +403,7 @@ content_type.clean(); if (cache_control) { - httpHdrCcDestroy(cache_control); + delete cache_control; cache_control = NULL; } === modified file 'src/HttpRequest.cc' --- src/HttpRequest.cc 2011-08-04 03:21:06 +0000 +++ src/HttpRequest.cc 2011-09-14 18:21:46 +0000 @@ -37,6 +37,7 @@ #include "squid.h" #include "DnsLookupDetails.h" #include "HttpRequest.h" +#include "HttpHdrCc.h" #if USE_AUTH #include "auth/UserRequest.h" #endif @@ -145,7 +146,7 @@ header.clean(); if (cache_control) { - httpHdrCcDestroy(cache_control); + delete cache_control; cache_control = NULL; } === modified file 'src/Makefile.am' --- src/Makefile.am 2011-09-11 23:40:46 +0000 +++ src/Makefile.am 2011-09-27 06:14:57 +0000 @@ -342,7 +342,9 @@ HttpStatusCode.h \ HttpStatusLine.cc \ HttpStatusLine.h \ + HttpHdrCc.h \ HttpHdrCc.cc \ + HttpHdrCc.cci \ HttpHdrRange.cc \ HttpHdrSc.cc \ HttpHdrSc.h \ @@ -1034,7 +1036,9 @@ cbdata.h \ ETag.cc \ HttpBody.cc \ + HttpHdrCc.h \ HttpHdrCc.cc \ + HttpHdrCc.cci \ HttpHdrContRange.cc \ HttpHdrContRange.h \ HttpHdrRange.cc \ @@ -1129,7 +1133,9 @@ HttpHeaderTools.cc \ HttpHdrContRange.cc \ HttpHdrRange.cc \ + HttpHdrCc.h \ HttpHdrCc.cc \ + HttpHdrCc.cci \ HttpHdrSc.cc \ HttpHdrScTarget.cc \ HttpMsg.cc \ @@ -1294,7 +1300,9 @@ HttpBody.cc \ HttpHeader.cc \ HttpHeaderTools.cc \ + HttpHdrCc.h \ HttpHdrCc.cc \ + HttpHdrCc.cci \ HttpHdrContRange.cc \ HttpHdrRange.cc \ HttpHdrSc.cc \ @@ -1430,7 +1438,9 @@ fd.cc \ filemap.cc \ HttpBody.cc \ + HttpHdrCc.h \ HttpHdrCc.cc \ + HttpHdrCc.cci \ HttpHdrContRange.cc \ HttpHdrSc.cc \ HttpHdrScTarget.cc \ @@ -1605,7 +1615,9 @@ HttpBody.cc \ HttpHeader.cc \ HttpHeaderTools.cc \ + HttpHdrCc.h \ HttpHdrCc.cc \ + HttpHdrCc.cci \ HttpHdrContRange.cc \ HttpHdrRange.cc \ HttpHdrSc.cc \ @@ -1790,7 +1802,9 @@ HttpBody.cc \ HttpHeader.cc \ HttpHeaderTools.cc \ + HttpHdrCc.h \ HttpHdrCc.cc \ + HttpHdrCc.cci \ HttpHdrContRange.cc \ HttpHdrRange.cc \ HttpHdrSc.cc \ @@ -1971,7 +1985,9 @@ $(HTCPSOURCE) \ http.cc \ HttpBody.cc \ + HttpHdrCc.h \ HttpHdrCc.cc \ + HttpHdrCc.cci \ HttpHdrContRange.cc \ HttpHdrRange.cc \ HttpHdrSc.cc \ @@ -2196,7 +2212,9 @@ HttpBody.cc \ HttpHeader.cc \ HttpHeaderTools.cc \ + HttpHdrCc.h \ HttpHdrCc.cc \ + HttpHdrCc.cci \ HttpHdrContRange.cc \ HttpHdrRange.cc \ HttpHdrSc.cc \ @@ -2328,7 +2346,9 @@ event.cc \ EventLoop.cc \ filemap.cc \ + HttpHdrCc.h \ HttpHdrCc.cc \ + HttpHdrCc.cci \ HttpHdrContRange.cc \ HttpHdrRange.cc \ HttpHdrSc.cc \ @@ -2566,7 +2586,9 @@ MemBuf.cc \ HttpHdrContRange.cc \ Packer.cc \ + HttpHdrCc.h \ HttpHdrCc.cc \ + HttpHdrCc.cci \ HttpHdrSc.cc \ HttpHdrScTarget.cc \ url.cc \ @@ -2696,7 +2718,9 @@ MemBuf.cc \ HttpHdrContRange.cc \ Packer.cc \ + HttpHdrCc.h \ HttpHdrCc.cc \ + HttpHdrCc.cci \ HttpHdrSc.cc \ HttpHdrScTarget.cc \ url.cc \ @@ -2825,7 +2849,9 @@ MemBuf.cc \ HttpHdrContRange.cc \ Packer.cc \ + HttpHdrCc.h \ HttpHdrCc.cc \ + HttpHdrCc.cci \ HttpHdrSc.cc \ HttpHdrScTarget.cc \ url.cc \ @@ -2927,7 +2953,9 @@ $(HTCPSOURCE) \ http.cc \ HttpBody.cc \ + HttpHdrCc.h \ HttpHdrCc.cc \ + HttpHdrCc.cci \ HttpHdrContRange.cc \ HttpHdrRange.cc \ HttpHdrSc.cc \ === modified file 'src/base/Makefile.am' --- src/base/Makefile.am 2011-09-12 00:31:13 +0000 +++ src/base/Makefile.am 2011-09-27 05:16:58 +0000 @@ -19,4 +19,5 @@ RunnersRegistry.h \ Subscription.h \ TextException.cc \ - TextException.h + TextException.h \ + StringArea.h === added file 'src/base/StringArea.h' --- src/base/StringArea.h 1970-01-01 00:00:00 +0000 +++ src/base/StringArea.h 2011-09-27 05:16:58 +0000 @@ -0,0 +1,60 @@ +/* + * StringArea.h + * + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * incorporates software developed and/or copyrighted by other + * sources; see the CREDITS file for full details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + */ + +#ifndef SQUID_STRINGAREA_H +#define SQUID_STRINGAREA_H + +#if HAVE_CSTRING +#include +#endif + +/** A char* plus length combination. Useful for temporary storing + * and quickly looking up strings. + * + * The pointed-to string may not be null-terminated. + * The pointed-to string is not copied. + * + * Not meant for stand-alone storage. Validity of the + * pointed-to string is responsibility of the caller. + */ +class StringArea { + public: + StringArea(const char * ptr, size_t len): theStart(ptr), theLen(len) {} + bool operator==(const StringArea &s) const { return theLen==s.theLen && strncmp(theStart,s.theStart,theLen)==0; } + bool operator!=(const StringArea &s) const { return !operator==(s); } + bool operator< ( const StringArea &s) const { return theLen < s.theLen || strncmp(theStart,s.theStart,theLen) < 0; } + + private: + const char *theStart; + size_t theLen; +}; + +#endif /* SQUID_STRINGAREA_H */ === modified file 'src/client_side_request.cc' --- src/client_side_request.cc 2011-09-04 18:28:39 +0000 +++ src/client_side_request.cc 2011-09-16 18:33:19 +0000 @@ -67,6 +67,7 @@ #include "compat/inet_pton.h" #include "fde.h" #include "format/Tokens.h" +#include "HttpHdrCc.h" #include "HttpReply.h" #include "HttpRequest.h" #include "ip/QosConfig.h" === modified file 'src/enums.h' --- src/enums.h 2011-07-16 04:00:55 +0000 +++ src/enums.h 2011-09-14 18:21:46 +0000 @@ -218,7 +218,6 @@ MEM_DLINK_NODE, MEM_DREAD_CTRL, MEM_DWRITE_Q, - MEM_HTTP_HDR_CC, MEM_HTTP_HDR_CONTENT_RANGE, MEM_MD5_DIGEST, MEM_NETDBENTRY, === modified file 'src/http.cc' --- src/http.cc 2011-08-30 15:04:30 +0000 +++ src/http.cc 2011-09-21 07:52:42 +0000 @@ -58,6 +58,7 @@ #include "http.h" #include "HttpControlMsg.h" #include "HttpHdrContRange.h" +#include "HttpHdrCc.h" #include "HttpHdrSc.h" #include "HttpHdrScTarget.h" #include "HttpReply.h" @@ -927,7 +928,8 @@ if (!ignoreCacheControl && rep->cache_control) { if (EBIT_TEST(rep->cache_control->mask, CC_PROXY_REVALIDATE) || EBIT_TEST(rep->cache_control->mask, CC_MUST_REVALIDATE) || - EBIT_TEST(rep->cache_control->mask, CC_S_MAXAGE)) + rep->cache_control->getSMaxAge() != HttpHdrCc::S_MAXAGE_UNSET + ) EBIT_SET(entry->flags, ENTRY_REVALIDATE); } @@ -1760,7 +1762,7 @@ HttpHdrCc *cc = hdr_in->getCc(); if (!cc) - cc = httpHdrCcCreate(); + cc = new HttpHdrCc(); #if 0 /* see bug 2330 */ /* Set no-cache if determined needed but not found */ @@ -1769,10 +1771,10 @@ #endif /* Add max-age only without no-cache */ - if (!EBIT_TEST(cc->mask, CC_MAX_AGE) && !EBIT_TEST(cc->mask, CC_NO_CACHE)) { + if (cc->getMaxAge()==HttpHdrCc::MAX_AGE_UNSET && !EBIT_TEST(cc->mask, CC_NO_CACHE)) { const char *url = entry ? entry->url() : urlCanonical(request); - httpHdrCcSetMaxAge(cc, getMaxAge(url)); + cc->setMaxAge(getMaxAge(url)); } @@ -1782,7 +1784,7 @@ hdr_out->putCc(cc); - httpHdrCcDestroy(cc); + delete cc; } /* maybe append Connection: keep-alive */ === modified file 'src/mem.cc' --- src/mem.cc 2011-08-10 15:54:51 +0000 +++ src/mem.cc 2011-09-16 18:33:19 +0000 @@ -453,7 +453,6 @@ memDataInit(MEM_DLINK_NODE, "dlink_node", sizeof(dlink_node), 10); memDataInit(MEM_DREAD_CTRL, "dread_ctrl", sizeof(dread_ctrl), 0); memDataInit(MEM_DWRITE_Q, "dwrite_q", sizeof(dwrite_q), 0); - memDataInit(MEM_HTTP_HDR_CC, "HttpHdrCc", sizeof(HttpHdrCc), 0); memDataInit(MEM_HTTP_HDR_CONTENT_RANGE, "HttpHdrContRange", sizeof(HttpHdrContRange), 0); memDataInit(MEM_NETDBENTRY, "netdbEntry", sizeof(netdbEntry), 0); memDataInit(MEM_NET_DB_NAME, "net_db_name", sizeof(net_db_name), 0); === modified file 'src/mime.cc' --- src/mime.cc 2011-01-28 07:58:53 +0000 +++ src/mime.cc 2011-09-14 18:21:46 +0000 @@ -34,6 +34,7 @@ */ #include "squid.h" +#include "HttpHdrCc.h" #include "Store.h" #include "StoreClient.h" #include "HttpReply.h" @@ -462,9 +463,9 @@ reply->setHeaders(HTTP_OK, NULL, mimeGetContentType(icon), sb.st_size, sb.st_mtime, -1); - reply->cache_control = httpHdrCcCreate(); + reply->cache_control = new HttpHdrCc(); - httpHdrCcSetMaxAge(reply->cache_control, 86400); + reply->cache_control->setMaxAge(86400); reply->header.putCc(reply->cache_control); === modified file 'src/protos.h' --- src/protos.h 2011-08-30 15:04:30 +0000 +++ src/protos.h 2011-09-16 18:33:19 +0000 @@ -237,13 +237,7 @@ /* Http Cache Control Header Field */ SQUIDCEXTERN void httpHdrCcInitModule(void); SQUIDCEXTERN void httpHdrCcCleanModule(void); -SQUIDCEXTERN HttpHdrCc *httpHdrCcCreate(void); -SQUIDCEXTERN HttpHdrCc *httpHdrCcParseCreate(const String * str); -SQUIDCEXTERN void httpHdrCcDestroy(HttpHdrCc * cc); -SQUIDCEXTERN HttpHdrCc *httpHdrCcDup(const HttpHdrCc * cc); SQUIDCEXTERN void httpHdrCcPackInto(const HttpHdrCc * cc, Packer * p); -SQUIDCEXTERN void httpHdrCcSetMaxAge(HttpHdrCc * cc, int max_age); -SQUIDCEXTERN void httpHdrCcSetSMaxAge(HttpHdrCc * cc, int s_maxage); SQUIDCEXTERN void httpHdrCcUpdateStats(const HttpHdrCc * cc, StatHist * hist); void httpHdrCcStatDumper(StoreEntry * sentry, int idx, double val, double size, int count); === modified file 'src/refresh.cc' --- src/refresh.cc 2011-09-12 00:31:13 +0000 +++ src/refresh.cc 2011-09-27 06:14:57 +0000 @@ -38,6 +38,7 @@ #endif #include "squid.h" +#include "HttpHdrCc.h" #include "mgr/Registration.h" #include "Store.h" #include "MemObject.h" @@ -267,14 +268,15 @@ if (request && !request->flags.ignore_cc) { const HttpHdrCc *const cc = request->cache_control; - if (cc && cc->min_fresh > 0) { + if (cc && cc->getMinFresh()!=HttpHdrCc::MIN_FRESH_UNSET) { + const int32_t minFresh=cc->getMinFresh(); debugs(22, 3, "\tage + min-fresh:\t" << age << " + " << - cc->min_fresh << " = " << age + cc->min_fresh); + minFresh << " = " << age + minFresh); debugs(22, 3, "\tcheck_time + min-fresh:\t" << check_time << " + " - << cc->min_fresh << " = " << - mkrfc1123(check_time + cc->min_fresh)); - age += cc->min_fresh; - check_time += cc->min_fresh; + << minFresh << " = " << + mkrfc1123(check_time + minFresh)); + age += minFresh; + check_time += minFresh; } } @@ -286,8 +288,8 @@ // stale-if-error requires any failure be passed thru when its period is over. if (request && entry->mem_obj && entry->mem_obj->getReply() && entry->mem_obj->getReply()->cache_control && - EBIT_TEST(entry->mem_obj->getReply()->cache_control->mask, CC_STALE_IF_ERROR) && - entry->mem_obj->getReply()->cache_control->stale_if_error < staleness) { + entry->mem_obj->getReply()->cache_control->getStaleIfError() != HttpHdrCc::STALE_IF_ERROR_UNSET && + entry->mem_obj->getReply()->cache_control->getStaleIfError() < staleness) { debugs(22, 3, "refreshCheck: stale-if-error period expired."); request->flags.fail_on_validation_err = 1; @@ -334,31 +336,31 @@ #endif if (NULL != cc) { - if (cc->max_age > -1) { + if (cc->getMaxAge() != HttpHdrCc::MAX_AGE_UNSET) { #if USE_HTTP_VIOLATIONS - if (R->flags.ignore_reload && cc->max_age == 0) { + if (R->flags.ignore_reload && cc->getMaxAge() == 0) { debugs(22, 3, "refreshCheck: MAYBE: client-max-age = 0 and ignore-reload"); } else #endif { - if (cc->max_age == 0) { + if (cc->getMaxAge() == 0) { debugs(22, 3, "refreshCheck: YES: client-max-age = 0"); return STALE_EXCEEDS_REQUEST_MAX_AGE_VALUE; } - if (age > cc->max_age) { + if (age > cc->getMaxAge()) { debugs(22, 3, "refreshCheck: YES: age > client-max-age"); return STALE_EXCEEDS_REQUEST_MAX_AGE_VALUE; } } } - if (EBIT_TEST(cc->mask, CC_MAX_STALE) && staleness > -1) { - if (cc->max_stale < 0) { + if (cc->getMaxStale()>=0 && staleness > -1) { + if (cc->getMaxStale()==HttpHdrCc::MAX_STALE_ALWAYS) { /* max-stale directive without a value */ debugs(22, 3, "refreshCheck: NO: max-stale wildcard"); return FRESH_REQUEST_MAX_STALE_ALL; - } else if (staleness < cc->max_stale) { + } else if (staleness < cc->getMaxStale()) { debugs(22, 3, "refreshCheck: NO: staleness < max-stale"); return FRESH_REQUEST_MAX_STALE_VALUE; } === modified file 'src/structs.h' --- src/structs.h 2011-09-11 22:21:35 +0000 +++ src/structs.h 2011-09-16 18:33:19 +0000 @@ -723,21 +723,6 @@ String value; /* field-value from HTTP/1.1 */ }; -/* http cache control header field */ - -class HttpHdrCc -{ - -public: - int mask; - int max_age; - int s_maxage; - int max_stale; - int stale_if_error; - int min_fresh; - String other; -}; - /* per field statistics */ class HttpHeaderFieldStat # Begin bundle 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