]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/HttpHdrSc.cc
Maintenance: Remove FIXME and \todo labels (#647)
[thirdparty/squid.git] / src / HttpHdrSc.cc
index 83906481cc1c42db734e6c6af72fc4c508998121..a30498230dbbad048c23114af69534d69772f181 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ * Copyright (C) 1996-2020 The Squid Software Foundation and contributors
  *
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
@@ -9,9 +9,10 @@
 /* DEBUG: section 90    HTTP Cache Control Header */
 
 #include "squid.h"
-#include "HttpHdrSc.h"
+#include "base/LookupTable.h"
+//#include "HttpHdrSc.h" // pulled in by HttpHdrScTarget.h
+#include "HttpHdrScTarget.h"
 #include "HttpHeader.h"
-#include "HttpHeaderFieldInfo.h"
 #include "HttpHeaderFieldStat.h"
 #include "HttpHeaderStat.h"
 #include "HttpHeaderTools.h"
 #include "util.h"
 
 #include <map>
-
-/* a row in the table used for parsing surrogate-control header and statistics */
-typedef struct {
-    const char *name;
-    http_hdr_sc_type id;
-    HttpHeaderFieldStat stat;
-} HttpHeaderScFields;
+#include <vector>
 
 /* this table is used for parsing surrogate control header */
 /* order must match that of enum http_hdr_sc_type. The constraint is verified at initialization time */
-//todo: implement constraint
-static const HttpHeaderFieldAttrs ScAttrs[SC_ENUM_END] = {
-    HttpHeaderFieldAttrs("no-store", (http_hdr_type)SC_NO_STORE),
-    HttpHeaderFieldAttrs("no-store-remote", (http_hdr_type)SC_NO_STORE_REMOTE),
-    HttpHeaderFieldAttrs("max-age", (http_hdr_type)SC_MAX_AGE),
-    HttpHeaderFieldAttrs("content", (http_hdr_type)SC_CONTENT),
-    HttpHeaderFieldAttrs("Other,", (http_hdr_type)SC_OTHER) /* ',' will protect from matches */
+// TODO: implement constraint
+static const LookupTable<http_hdr_sc_type>::Record ScAttrs[] {
+    {"no-store", SC_NO_STORE},
+    {"no-store-remote", SC_NO_STORE_REMOTE},
+    {"max-age", SC_MAX_AGE},
+    {"content", SC_CONTENT},
+    {"Other,", SC_OTHER}, /* ',' will protect from matches */
+    {nullptr, SC_ENUM_END} /* SC_ENUM_END taken as invalid value */
 };
+LookupTable<http_hdr_sc_type> scLookupTable(SC_ENUM_END, ScAttrs);
+std::vector<HttpHeaderFieldStat> scHeaderStats(SC_ENUM_END);
 
-HttpHeaderFieldInfo *ScFieldsInfo = NULL;
-
+// used when iterating over flags
 http_hdr_sc_type &operator++ (http_hdr_sc_type &aHeader)
 {
-    int tmp = (int)aHeader;
-    aHeader = (http_hdr_sc_type)(++tmp);
+    int tmp = static_cast<int>(aHeader);
+    aHeader = static_cast<http_hdr_sc_type>(++tmp);
     return aHeader;
 }
 
-int operator - (http_hdr_sc_type const &anSc, http_hdr_sc_type const &anSc2)
-{
-    return (int)anSc - (int)anSc2;
-}
-
-/* module initialization */
-
 void
 httpHdrScInitModule(void)
 {
-    ScFieldsInfo = httpHeaderBuildFieldsInfo(ScAttrs, SC_ENUM_END);
-}
-
-void
-httpHdrScCleanModule(void)
-{
-    httpHeaderDestroyFieldsInfo(ScFieldsInfo, SC_ENUM_END);
-    ScFieldsInfo = NULL;
+    // check invariant on ScAttrs
+    for (int i = 0; ScAttrs[i].name != nullptr; ++i)
+        assert(i == ScAttrs[i].id);
 }
 
 /* implementation */
@@ -94,7 +79,7 @@ HttpHdrSc::parse(const String * str)
     const char *pos = NULL;
     const char *target = NULL; /* ;foo */
     const char *temp = NULL; /* temp buffer */
-    int type;
+    http_hdr_sc_type type;
     int ilen, vlen;
     int initiallen;
     HttpHdrScTarget *sct;
@@ -113,24 +98,22 @@ HttpHdrSc::parse(const String * str)
             ++p;
         }
 
-        /* decrease ilen to still match the token for ';' qualified non '=' statments */
+        /* decrease ilen to still match the token for ';' qualified non '=' statements */
         else if ((p = strchr(item, ';')) && (p - item < ilen)) {
             ilen = p - item;
             ++p;
         }
 
         /* find type */
-        /* TODO: use a type-safe map-based lookup */
-        type = httpHeaderIdByName(item, ilen,
-                                  ScFieldsInfo, SC_ENUM_END);
+        type = scLookupTable.lookup(SBuf(item,ilen));
 
-        if (type < 0) {
+        if (type == SC_ENUM_END) {
             debugs(90, 2, "hdr sc: unknown control-directive: near '" << item << "' in '" << str << "'");
             type = SC_OTHER;
         }
 
         /* Is this a targeted directive? */
-        /* TODO: remove the temporary useage and use memrchr and the information we have instead */
+        /* TODO: remove the temporary usage and use memrchr and the information we have instead */
         temp = xstrndup (item, initiallen + 1);
 
         if (!((target = strrchr (temp, ';')) && !strchr (target, '"') && *(target + 1) != '\0'))
@@ -147,11 +130,11 @@ HttpHdrSc::parse(const String * str)
 
         safe_free (temp);
 
-        if (sct->isSet(static_cast<http_hdr_sc_type>(type))) {
+        if (sct->isSet(type)) {
             if (type != SC_OTHER)
                 debugs(90, 2, "hdr sc: ignoring duplicate control-directive: near '" << item << "' in '" << str << "'");
 
-            ++ ScFieldsInfo[type].stat.repCount;
+            ++ scHeaderStats[type].repCount;
 
             continue;
         }
@@ -235,7 +218,7 @@ HttpHdrSc::HttpHdrSc(const HttpHdrSc &sc)
 }
 
 void
-HttpHdrScTarget::packInto(Packer * p) const
+HttpHdrScTarget::packInto(Packable * p) const
 {
     http_hdr_sc_type flag;
     int pcount = 0;
@@ -245,27 +228,26 @@ HttpHdrScTarget::packInto(Packer * p) const
         if (isSet(flag) && flag != SC_OTHER) {
 
             /* print option name */
-            packerPrintf(p, (pcount ? ", " SQUIDSTRINGPH : SQUIDSTRINGPH),
-                         SQUIDSTRINGPRINT(ScFieldsInfo[flag].name));
+            p->appendf((pcount ? ", %s" : "%s"), ScAttrs[flag].name);
 
             /* handle options with values */
 
             if (flag == SC_MAX_AGE)
-                packerPrintf(p, "=%d", (int) max_age);
+                p->appendf("=%d", (int) max_age);
 
             if (flag == SC_CONTENT)
-                packerPrintf(p, "=\"" SQUIDSTRINGPH "\"", SQUIDSTRINGPRINT(content_));
+                p->appendf("=\"" SQUIDSTRINGPH "\"", SQUIDSTRINGPRINT(content_));
 
             ++pcount;
         }
     }
 
     if (hasTarget())
-        packerPrintf (p, ";" SQUIDSTRINGPH, SQUIDSTRINGPRINT(target));
+        p->appendf(";" SQUIDSTRINGPH, SQUIDSTRINGPRINT(target));
 }
 
 void
-HttpHdrSc::packInto(Packer * p) const
+HttpHdrSc::packInto(Packable * p) const
 {
     dlink_node *node;
     assert(p);
@@ -307,8 +289,8 @@ httpHdrScTargetStatDumper(StoreEntry * sentry, int, double val, double, int coun
 {
     extern const HttpHeaderStat *dump_stat;     /* argh! */
     const int id = (int) val;
-    const int valid_id = id >= 0 && id < SC_ENUM_END;
-    const char *name = valid_id ? ScFieldsInfo[id].name.termedBuf() : "INVALID";
+    const bool valid_id = id >= 0 && id < SC_ENUM_END;
+    const char *name = valid_id ? ScAttrs[id].name : "INVALID";
 
     if (count || valid_id)
         storeAppendPrintf(sentry, "%2d\t %-20s\t %5d\t %6.2f\n",
@@ -320,8 +302,8 @@ httpHdrScStatDumper(StoreEntry * sentry, int, double val, double, int count)
 {
     extern const HttpHeaderStat *dump_stat; /* argh! */
     const int id = (int) val;
-    const int valid_id = id >= 0 && id < SC_ENUM_END;
-    const char *name = valid_id ? ScFieldsInfo[id].name.termedBuf() : "INVALID";
+    const bool valid_id = id >= 0 && id < SC_ENUM_END;
+    const char *name = valid_id ? ScAttrs[id].name : "INVALID";
 
     if (count || valid_id)
         storeAppendPrintf(sentry, "%2d\t %-20s\t %5d\t %6.2f\n",
@@ -369,3 +351,13 @@ HttpHdrSc::getMergedTarget(const char *ourtarget)
     return NULL;
 }
 
+void
+HttpHdrSc::addTarget(HttpHdrScTarget *t) {
+    dlinkAdd(t, &t->node, &targets);
+}
+
+void
+HttpHdrSc::addTargetAtTail(HttpHdrScTarget *t) {
+    dlinkAddTail (t, &t->node, &targets);
+}
+