HttpHdrCc.c
上传用户:liugui
上传日期:2007-01-04
资源大小:822k
文件大小:6k
源码类别:

代理服务器

开发平台:

Unix_Linux

  1. /*
  2.  * $Id: HttpHdrCc.c,v 1.16 1998/12/05 00:54:09 wessels Exp $
  3.  *
  4.  * DEBUG: section 65    HTTP Cache Control Header
  5.  * AUTHOR: Alex Rousskov
  6.  *
  7.  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
  8.  * ----------------------------------------------------------
  9.  *
  10.  *  Squid is the result of efforts by numerous individuals from the
  11.  *  Internet community.  Development is led by Duane Wessels of the
  12.  *  National Laboratory for Applied Network Research and funded by the
  13.  *  National Science Foundation.  Squid is Copyrighted (C) 1998 by
  14.  *  Duane Wessels and the University of California San Diego.  Please
  15.  *  see the COPYRIGHT file for full details.  Squid incorporates
  16.  *  software developed and/or copyrighted by other sources.  Please see
  17.  *  the CREDITS file for full details.
  18.  *
  19.  *  This program is free software; you can redistribute it and/or modify
  20.  *  it under the terms of the GNU General Public License as published by
  21.  *  the Free Software Foundation; either version 2 of the License, or
  22.  *  (at your option) any later version.
  23.  *  
  24.  *  This program is distributed in the hope that it will be useful,
  25.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  26.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  27.  *  GNU General Public License for more details.
  28.  *  
  29.  *  You should have received a copy of the GNU General Public License
  30.  *  along with this program; if not, write to the Free Software
  31.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
  32.  *
  33.  */
  34. #include "squid.h"
  35. /* this table is used for parsing cache control header */
  36. static const HttpHeaderFieldAttrs CcAttrs[CC_ENUM_END] =
  37. {
  38.     {"public", CC_PUBLIC},
  39.     {"private", CC_PRIVATE},
  40.     {"no-cache", CC_NO_CACHE},
  41.     {"no-store", CC_NO_STORE},
  42.     {"no-transform", CC_NO_TRANSFORM},
  43.     {"must-revalidate", CC_MUST_REVALIDATE},
  44.     {"proxy-revalidate", CC_PROXY_REVALIDATE},
  45.     {"only-if-cached", CC_ONLY_IF_CACHED},
  46.     {"max-age", CC_MAX_AGE},
  47.     {"Other,", CC_OTHER} /* ',' will protect from matches */
  48. };
  49. HttpHeaderFieldInfo *CcFieldsInfo = NULL;
  50. /* local prototypes */
  51. static int httpHdrCcParseInit(HttpHdrCc * cc, const String * str);
  52. /* module initialization */
  53. void
  54. httpHdrCcInitModule()
  55. {
  56.     CcFieldsInfo = httpHeaderBuildFieldsInfo(CcAttrs, CC_ENUM_END);
  57. }
  58. void
  59. httpHdrCcCleanModule()
  60. {
  61.     httpHeaderDestroyFieldsInfo(CcFieldsInfo, CC_ENUM_END);
  62.     CcFieldsInfo = NULL;
  63. }
  64. /* implementation */
  65. HttpHdrCc *
  66. httpHdrCcCreate()
  67. {
  68.     HttpHdrCc *cc = memAllocate(MEM_HTTP_HDR_CC);
  69.     cc->max_age = -1;
  70.     return cc;
  71. }
  72. /* creates an cc object from a 0-terminating string */
  73. HttpHdrCc *
  74. httpHdrCcParseCreate(const String * str)
  75. {
  76.     HttpHdrCc *cc = httpHdrCcCreate();
  77.     if (!httpHdrCcParseInit(cc, str)) {
  78. httpHdrCcDestroy(cc);
  79. cc = NULL;
  80.     }
  81.     return cc;
  82. }
  83. /* parses a 0-terminating string and inits cc */
  84. static int
  85. httpHdrCcParseInit(HttpHdrCc * cc, const String * str)
  86. {
  87.     const char *item;
  88.     const char *p; /* '=' parameter */
  89.     const char *pos = NULL;
  90.     int type;
  91.     int ilen;
  92.     assert(cc && str);
  93.     /* iterate through comma separated list */
  94.     while (strListGetItem(str, ',', &item, &ilen, &pos)) {
  95. /* strip '=' statements @?@ */
  96. if ((p = strchr(item, '=')) && (p - item < ilen))
  97.     ilen = p++ - item;
  98. /* find type */
  99. type = httpHeaderIdByName(item, ilen,
  100.     CcFieldsInfo, CC_ENUM_END);
  101. if (type < 0) {
  102.     debug(65, 2) ("hdr cc: unknown cache-directive: near '%s' in '%s'n", item, strBuf(*str));
  103.     type = CC_OTHER;
  104. }
  105. if (EBIT_TEST(cc->mask, type)) {
  106.     if (type != CC_OTHER)
  107. debug(65, 2) ("hdr cc: ignoring duplicate cache-directive: near '%s' in '%s'n", item, strBuf(*str));
  108.     CcFieldsInfo[type].stat.repCount++;
  109.     continue;
  110. }
  111. /* update mask */
  112. EBIT_SET(cc->mask, type);
  113. /* post-processing special cases */
  114. switch (type) {
  115. case CC_MAX_AGE:
  116.     if (!p || !httpHeaderParseInt(p, &cc->max_age)) {
  117. debug(65, 2) ("cc: invalid max-age specs near '%s'n", item);
  118. cc->max_age = -1;
  119. EBIT_CLR(cc->mask, type);
  120.     }
  121.     break;
  122. default:
  123.     /* note that we ignore most of '=' specs */
  124.     break;
  125. }
  126.     }
  127.     return cc->mask != 0;
  128. }
  129. void
  130. httpHdrCcDestroy(HttpHdrCc * cc)
  131. {
  132.     assert(cc);
  133.     memFree(cc, MEM_HTTP_HDR_CC);
  134. }
  135. HttpHdrCc *
  136. httpHdrCcDup(const HttpHdrCc * cc)
  137. {
  138.     HttpHdrCc *dup;
  139.     assert(cc);
  140.     dup = httpHdrCcCreate();
  141.     dup->mask = cc->mask;
  142.     dup->max_age = cc->max_age;
  143.     return dup;
  144. }
  145. void
  146. httpHdrCcPackInto(const HttpHdrCc * cc, Packer * p)
  147. {
  148.     http_hdr_cc_type flag;
  149.     int pcount = 0;
  150.     assert(cc && p);
  151.     for (flag = 0; flag < CC_ENUM_END; flag++) {
  152. if (flag == CC_MAX_AGE && cc->max_age >= 0) {
  153.     packerPrintf(p, "max-age=%d", (int) cc->max_age);
  154.     pcount++;
  155. } else if (EBIT_TEST(cc->mask, flag) && flag != CC_OTHER) {
  156.     packerPrintf(p, (pcount ? ", %s" : "%s"), strBuf(CcFieldsInfo[flag].name));
  157.     pcount++;
  158. }
  159.     }
  160. }
  161. void
  162. httpHdrCcJoinWith(HttpHdrCc * cc, const HttpHdrCc * new_cc)
  163. {
  164.     assert(cc && new_cc);
  165.     if (cc->max_age < 0)
  166. cc->max_age = new_cc->max_age;
  167.     cc->mask |= new_cc->mask;
  168. }
  169. /* negative max_age will clean old max_Age setting */
  170. void
  171. httpHdrCcSetMaxAge(HttpHdrCc * cc, int max_age)
  172. {
  173.     assert(cc);
  174.     cc->max_age = max_age;
  175.     if (max_age >= 0)
  176. EBIT_SET(cc->mask, CC_MAX_AGE);
  177.     else
  178. EBIT_CLR(cc->mask, CC_MAX_AGE);
  179. }
  180. void
  181. httpHdrCcUpdateStats(const HttpHdrCc * cc, StatHist * hist)
  182. {
  183.     http_hdr_cc_type c;
  184.     assert(cc);
  185.     for (c = 0; c < CC_ENUM_END; c++)
  186. if (EBIT_TEST(cc->mask, c))
  187.     statHistCount(hist, c);
  188. }
  189. void
  190. httpHdrCcStatDumper(StoreEntry * sentry, int idx, double val, double size, int count)
  191. {
  192.     extern const HttpHeaderStat *dump_stat; /* argh! */
  193.     const int id = (int) val;
  194.     const int valid_id = id >= 0 && id < CC_ENUM_END;
  195.     const char *name = valid_id ? strBuf(CcFieldsInfo[id].name) : "INVALID";
  196.     if (count || valid_id)
  197. storeAppendPrintf(sentry, "%2dt %-20st %5dt %6.2fn",
  198.     id, name, count, xdiv(count, dump_stat->ccParsedCount));
  199. }