# Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: kinkie@squid-cache.org-20110914182510-dc93071il4btr77r # target_branch: ../squid-trunk-co # testament_sha1: 3704ad4a8933070fbe4ec3f26c8ac97d8278d061 # timestamp: 2011-09-14 20:25:15 +0200 # base_revision_id: kinkie@squid-cache.org-20110912232115-\ # l1ygojvxm4gwciq1 # # Begin patch === modified file 'src/HttpHdrCc.cc' --- src/HttpHdrCc.cc 2010-12-27 20:25:30 +0000 +++ src/HttpHdrCc.cc 2011-09-14 18:25:10 +0000 @@ -1,9 +1,7 @@ /* - * $Id$ * * DEBUG: section 65 HTTP Cache Control Header - * AUTHOR: Alex Rousskov * * SQUID Web Proxy Cache http://www.squid-cache.org/ * ---------------------------------------------------------- @@ -36,28 +34,58 @@ #include "squid.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 */ -}; - -HttpHeaderFieldInfo *CcFieldsInfo = NULL; - +#include "HttpHdrCc.h" + +#if HAVE_MAP +#include +#endif + +/** dumb char* /length combo for quick lookups. + * + * Data is not copied. + * Validity of the pointed-to storage is responsibility of the caller. + * */ +class strblob { + public: + strblob(const char * ptr, size_t len): thePtr(ptr), theLen(len) {} + bool operator==(strblob &s) const { return theLen==s.theLen && 0==strncmp(thePtr,s.thePtr,theLen); } + bool operator< ( const strblob &s2) const { return strncmp(thePtr,s2.thePtr,theLen) < 0; } + + private: + const char *thePtr; + size_t theLen; +}; + +/* this table is 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 */ +}; + +/// 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 +94,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 strblob 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 +129,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 +142,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 strblob tmpstr(item,nlen); + const CcNameToIdMap_t::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 { @@ -216,32 +225,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,8 +239,7 @@ 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 */ @@ -272,7 +255,7 @@ if (flag == CC_MIN_FRESH) packerPrintf(p, "=%d", (int) cc->min_fresh); - pcount++; + ++pcount; } } @@ -281,30 +264,15 @@ 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 +HttpHdrCc::setMaxAge(int max_age_) +{ + max_age = max_age_; + + if (max_age_ >= 0) + EBIT_SET(mask, CC_MAX_AGE); + else + EBIT_CLR(mask, CC_MAX_AGE); } void @@ -324,7 +292,7 @@ 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", === added file 'src/HttpHdrCc.h' --- src/HttpHdrCc.h 1970-01-01 00:00:00 +0000 +++ src/HttpHdrCc.h 2011-09-14 18:21:46 +0000 @@ -0,0 +1,83 @@ +/* + * 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_HTTPHEADERCACHECONTROL_H_ +#define SQUID_HTTPHEADERCACHECONTROL_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: + explicit HttpHdrCc() : + mask(0), max_age(-1), s_maxage(-1), + max_stale(-1), stale_if_error(0), + min_fresh(-1) {} + + /// reset to the after-default-construction state. + void clear(); + + /**parse the supplied string filling in HttpHdrCc's fields. + * + * \note: internal structures are not cleaned-up beforehand. + * caller must explicitly clear() beforehand if he wants that + */ + bool parse(const String &s); + + /** set the max_age value + * + * \param max_age the new max age. Values <0 clear it. + */ + void setMaxAge(int32_t max_age); + + MEMPROXY_CLASS(HttpHdrCc); + + /// bit-mask for the various Cc directives, keyed on http_hdr_cc_type + int32_t mask; + int32_t max_age; + int32_t s_maxage; + int32_t max_stale; + int32_t stale_if_error; + int32_t min_fresh; + /// comma-separated string accumulating unknown Cache-control directives. + String other; +}; + +MEMPROXY_CLASS_INLINE(HttpHdrCc); + +#endif /* SQUID_HTTPHEADERCACHECONTROL_H_ */ === modified file 'src/HttpHeader.cc' --- src/HttpHeader.cc 2011-08-29 03:47:54 +0000 +++ src/HttpHeader.cc 2011-09-14 18:21:46 +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" @@ -1312,14 +1313,22 @@ { HttpHdrCc *cc; String s; + bool gotList; if (!CBIT_TEST(mask, HDR_CACHE_CONTROL)) return NULL; PROF_start(HttpHeader_getCc); - getList(HDR_CACHE_CONTROL, &s); - - cc = httpHdrCcParseCreate(&s); + gotList=getList(HDR_CACHE_CONTROL, &s); + + cc=new HttpHdrCc(); + if (!gotList) + return cc; + + 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-14 18:21:46 +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" @@ -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-08-23 13:27:51 +0000 +++ src/Makefile.am 2011-09-12 22:54:38 +0000 @@ -341,6 +341,7 @@ HttpStatusCode.h \ HttpStatusLine.cc \ HttpStatusLine.h \ + HttpHdrCc.h \ HttpHdrCc.cc \ HttpHdrRange.cc \ HttpHdrSc.cc \ @@ -1015,6 +1016,7 @@ cbdata.h \ ETag.cc \ HttpBody.cc \ + HttpHdrCc.h \ HttpHdrCc.cc \ HttpHdrContRange.cc \ HttpHdrContRange.h \ @@ -1072,7 +1074,7 @@ tests_testHttpReply_DEPENDENCIES= $(SQUID_CPPUNIT_LA) ## Tests for the ACLMaxUserIP class -## acl needs wordlist. wordlist needs MemBug +## acl needs wordlist. wordlist needs MemBuf ## MemBuf needs mem, MemBuf needs event, ## event needs cbdata. ## ACLMaxUserUP needs $(AUTH_LIBS) @@ -1108,6 +1110,7 @@ HttpHeaderTools.cc \ HttpHdrContRange.cc \ HttpHdrRange.cc \ + HttpHdrCc.h \ HttpHdrCc.cc \ HttpHdrSc.cc \ HttpHdrScTarget.cc \ @@ -1268,6 +1271,7 @@ HttpBody.cc \ HttpHeader.cc \ HttpHeaderTools.cc \ + HttpHdrCc.h \ HttpHdrCc.cc \ HttpHdrContRange.cc \ HttpHdrRange.cc \ @@ -1399,6 +1403,7 @@ fd.cc \ filemap.cc \ HttpBody.cc \ + HttpHdrCc.h \ HttpHdrCc.cc \ HttpHdrContRange.cc \ HttpHdrSc.cc \ @@ -1571,6 +1576,7 @@ HttpBody.cc \ HttpHeader.cc \ HttpHeaderTools.cc \ + HttpHdrCc.h \ HttpHdrCc.cc \ HttpHdrContRange.cc \ HttpHdrRange.cc \ @@ -1749,6 +1755,7 @@ HttpBody.cc \ HttpHeader.cc \ HttpHeaderTools.cc \ + HttpHdrCc.h \ HttpHdrCc.cc \ HttpHdrContRange.cc \ HttpHdrRange.cc \ @@ -1923,6 +1930,7 @@ $(HTCPSOURCE) \ http.cc \ HttpBody.cc \ + HttpHdrCc.h \ HttpHdrCc.cc \ HttpHdrContRange.cc \ HttpHdrRange.cc \ @@ -2140,6 +2148,7 @@ HttpBody.cc \ HttpHeader.cc \ HttpHeaderTools.cc \ + HttpHdrCc.h \ HttpHdrCc.cc \ HttpHdrContRange.cc \ HttpHdrRange.cc \ @@ -2270,6 +2279,7 @@ event.cc \ EventLoop.cc \ filemap.cc \ + HttpHdrCc.h \ HttpHdrCc.cc \ HttpHdrContRange.cc \ HttpHdrRange.cc \ @@ -2504,6 +2514,7 @@ MemBuf.cc \ HttpHdrContRange.cc \ Packer.cc \ + HttpHdrCc.h \ HttpHdrCc.cc \ HttpHdrSc.cc \ HttpHdrScTarget.cc \ @@ -2634,6 +2645,7 @@ MemBuf.cc \ HttpHdrContRange.cc \ Packer.cc \ + HttpHdrCc.h \ HttpHdrCc.cc \ HttpHdrSc.cc \ HttpHdrScTarget.cc \ @@ -2758,6 +2770,7 @@ MemBuf.cc \ HttpHdrContRange.cc \ Packer.cc \ + HttpHdrCc.h \ HttpHdrCc.cc \ HttpHdrSc.cc \ HttpHdrScTarget.cc \ @@ -2860,6 +2873,7 @@ $(HTCPSOURCE) \ http.cc \ HttpBody.cc \ + HttpHdrCc.h \ HttpHdrCc.cc \ HttpHdrContRange.cc \ HttpHdrRange.cc \ === modified file 'src/client_side_request.cc' --- src/client_side_request.cc 2011-09-02 12:35:57 +0000 +++ src/client_side_request.cc 2011-09-12 23:25:55 +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-29 03:47:54 +0000 +++ src/http.cc 2011-09-14 18:21:46 +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" @@ -1758,7 +1759,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 */ @@ -1770,7 +1771,7 @@ if (!EBIT_TEST(cc->mask, CC_MAX_AGE) && !EBIT_TEST(cc->mask, CC_NO_CACHE)) { const char *url = entry ? entry->url() : urlCanonical(request); - httpHdrCcSetMaxAge(cc, getMaxAge(url)); + cc->setMaxAge(getMaxAge(url)); } @@ -1780,7 +1781,7 @@ hdr_out->putCc(cc); - httpHdrCcDestroy(cc); + delete cc; } /* maybe append Connection: keep-alive */ === modified file 'src/mem.cc' --- src/mem.cc 2011-07-16 04:00:55 +0000 +++ src/mem.cc 2011-09-14 18:21:46 +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-26 16:50:49 +0000 +++ src/protos.h 2011-09-12 19:20:37 +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-09 16:33:54 +0000 +++ src/refresh.cc 2011-09-14 18:21:46 +0000 @@ -38,6 +38,7 @@ #endif #include "squid.h" +#include "HttpHdrCc.h" #include "mgr/Registration.h" #include "Store.h" #include "MemObject.h" === modified file 'src/structs.h' --- src/structs.h 2011-08-26 16:50:49 +0000 +++ src/structs.h 2011-09-02 10:54:19 +0000 @@ -696,21 +696,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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