]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/HttpHeader.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / HttpHeader.cc
index 3d2539d0ee2d2ea3233420f265a10a9ed7ba3a08..6561001e01c00fd8c9c95314022d8b105d1d1c38 100644 (file)
@@ -1,7 +1,4 @@
-
 /*
- * $Id$
- *
  * DEBUG: section 55    HTTP Header
  * AUTHOR: Alex Rousskov
  *
  *  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.
- *
  */
 
 #include "squid.h"
 #include "base64.h"
+#include "globals.h"
 #include "HttpHdrCc.h"
 #include "HttpHdrContRange.h"
 #include "HttpHdrSc.h"
 #include "HttpHeader.h"
+#include "HttpHeaderFieldInfo.h"
 #include "HttpHeaderStat.h"
 #include "HttpHeaderTools.h"
 #include "MemBuf.h"
 #include "mgr/Registration.h"
 #include "profiler/Profiler.h"
-#include "protos.h"
 #include "rfc1123.h"
+#include "SquidConfig.h"
+#include "SquidString.h"
 #include "StatHist.h"
 #include "Store.h"
+#include "StrList.h"
 #include "TimeOrTag.h"
 
 /*
@@ -107,11 +107,13 @@ static const HttpHeaderFieldAttrs HeadersAttrs[] = {
     {"Expires", HDR_EXPIRES, ftDate_1123},
     {"From", HDR_FROM, ftStr},
     {"Host", HDR_HOST, ftStr},
+    {"HTTP2-Settings", HDR_HTTP2_SETTINGS, ftStr}, /* for now */
     {"If-Match", HDR_IF_MATCH, ftStr}, /* for now */
     {"If-Modified-Since", HDR_IF_MODIFIED_SINCE, ftDate_1123},
     {"If-None-Match", HDR_IF_NONE_MATCH, ftStr},       /* for now */
     {"If-Range", HDR_IF_RANGE, ftDate_1123_or_ETag},
     {"Keep-Alive", HDR_KEEP_ALIVE, ftStr},
+    {"Key", HDR_KEY, ftStr},
     {"Last-Modified", HDR_LAST_MODIFIED, ftDate_1123},
     {"Link", HDR_LINK, ftStr},
     {"Location", HDR_LOCATION, ftStr},
@@ -187,6 +189,7 @@ static http_hdr_type ListHeadersArr[] = {
     HDR_CONNECTION,
     HDR_EXPECT,
     HDR_IF_MATCH, HDR_IF_NONE_MATCH,
+    HDR_KEY,
     HDR_LINK, HDR_PRAGMA,
     HDR_PROXY_CONNECTION,
     HDR_PROXY_SUPPORT,
@@ -231,6 +234,7 @@ static HttpHeaderMask ReplyHeadersMask;             /* set run-time using ReplyHeaders */
 static http_hdr_type ReplyHeadersArr[] = {
     HDR_ACCEPT, HDR_ACCEPT_CHARSET, HDR_ACCEPT_ENCODING, HDR_ACCEPT_LANGUAGE,
     HDR_ACCEPT_RANGES, HDR_AGE,
+    HDR_KEY,
     HDR_LOCATION, HDR_MAX_FORWARDS,
     HDR_MIME_VERSION, HDR_PUBLIC, HDR_RETRY_AFTER, HDR_SERVER, HDR_SET_COOKIE, HDR_SET_COOKIE2,
     HDR_ORIGIN,
@@ -251,6 +255,7 @@ static http_hdr_type ReplyHeadersArr[] = {
 static HttpHeaderMask RequestHeadersMask;      /* set run-time using RequestHeaders */
 static http_hdr_type RequestHeadersArr[] = {
     HDR_AUTHORIZATION, HDR_FROM, HDR_HOST,
+    HDR_HTTP2_SETTINGS,
     HDR_IF_MATCH, HDR_IF_MODIFIED_SINCE, HDR_IF_NONE_MATCH,
     HDR_IF_RANGE, HDR_MAX_FORWARDS,
     HDR_ORIGIN,
@@ -261,7 +266,7 @@ static http_hdr_type RequestHeadersArr[] = {
 
 static HttpHeaderMask HopByHopHeadersMask;
 static http_hdr_type HopByHopHeadersArr[] = {
-    HDR_CONNECTION, HDR_KEEP_ALIVE, /*HDR_PROXY_AUTHENTICATE,*/ HDR_PROXY_AUTHORIZATION,
+    HDR_CONNECTION, HDR_HTTP2_SETTINGS, HDR_KEEP_ALIVE, /*HDR_PROXY_AUTHENTICATE,*/ HDR_PROXY_AUTHORIZATION,
     HDR_TE, HDR_TRAILER, HDR_TRANSFER_ENCODING, HDR_UPGRADE, HDR_PROXY_CONNECTION
 };
 
@@ -279,9 +284,10 @@ static int HttpHeaderStatCount = countof(HttpHeaderStats);
 static int HeaderEntryParsedCount = 0;
 
 /*
- * local routines
+ * forward declarations and local routines
  */
 
+class StoreEntry;
 #define assert_eid(id) assert((id) >= 0 && (id) < HDR_ENUM_END)
 
 static void httpHeaderNoteParsedEntry(http_hdr_type id, String const &value, int error);
@@ -289,6 +295,9 @@ static void httpHeaderNoteParsedEntry(http_hdr_type id, String const &value, int
 static void httpHeaderStatInit(HttpHeaderStat * hs, const char *label);
 static void httpHeaderStatDump(const HttpHeaderStat * hs, StoreEntry * e);
 
+/** store report about current header usage and other stats */
+static void httpHeaderStoreReport(StoreEntry * e);
+
 /*
  * Module initialization routines
  */
@@ -434,37 +443,37 @@ HttpHeader::clean()
 
     PROF_start(HttpHeaderClean);
 
-    /*
-     * An unfortunate bug.  The entries array is initialized
-     * such that count is set to zero.  httpHeaderClean() seems to
-     * be called both when 'hdr' is created, and destroyed.  Thus,
-     * we accumulate a large number of zero counts for 'hdr' before
-     * it is ever used.  Can't think of a good way to fix it, except
-     * adding a state variable that indicates whether or not 'hdr'
-     * has been used.  As a hack, just never count zero-sized header
-     * arrays.
-     */
-
     if (owner <= hoReply) {
+        /*
+         * An unfortunate bug.  The entries array is initialized
+         * such that count is set to zero.  httpHeaderClean() seems to
+         * be called both when 'hdr' is created, and destroyed.  Thus,
+         * we accumulate a large number of zero counts for 'hdr' before
+         * it is ever used.  Can't think of a good way to fix it, except
+         * adding a state variable that indicates whether or not 'hdr'
+         * has been used.  As a hack, just never count zero-sized header
+         * arrays.
+         */
         if (0 != entries.count)
             HttpHeaderStats[owner].hdrUCountDistr.count(entries.count);
 
         ++ HttpHeaderStats[owner].destroyedCount;
 
         HttpHeaderStats[owner].busyDestroyedCount += entries.count > 0;
+    } // if (owner <= hoReply)
 
-        while ((e = getEntry(&pos))) {
-            /* tmp hack to try to avoid coredumps */
+    while ((e = getEntry(&pos))) {
+        /* tmp hack to try to avoid coredumps */
 
-            if (e->id < 0 || e->id >= HDR_ENUM_END) {
-                debugs(55, DBG_CRITICAL, "HttpHeader::clean BUG: entry[" << pos << "] is invalid (" << e->id << "). Ignored.");
-            } else {
+        if (e->id < 0 || e->id >= HDR_ENUM_END) {
+            debugs(55, DBG_CRITICAL, "HttpHeader::clean BUG: entry[" << pos << "] is invalid (" << e->id << "). Ignored.");
+        } else {
+            if (owner <= hoReply)
                 HttpHeaderStats[owner].fieldTypeDistr.count(e->id);
-                /* yes, this deletion leaves us in an inconsistent state */
-                delete e;
-            }
+            /* yes, this deletion leaves us in an inconsistent state */
+            delete e;
         }
-    } // if (owner <= hoReply)
+    }
     entries.clean();
     httpHeaderMaskInit(&mask, 0);
     len = 0;
@@ -1016,10 +1025,19 @@ HttpHeader::getStrOrList(http_hdr_type id) const
 }
 
 /*
- * Returns the value of the specified header.
+ * Returns the value of the specified header and/or an undefined String.
  */
 String
 HttpHeader::getByName(const char *name) const
+{
+    String result;
+    // ignore presence: return undefined string if an empty header is present
+    (void)getByNameIfPresent(name, result);
+    return result;
+}
+
+bool
+HttpHeader::getByNameIfPresent(const char *name, String &result) const
 {
     http_hdr_type id;
     HttpHeaderPos pos = HttpHeaderInitPos;
@@ -1030,19 +1048,23 @@ HttpHeader::getByName(const char *name) const
     /* First try the quick path */
     id = httpHeaderIdByNameDef(name, strlen(name));
 
-    if (id != -1)
-        return getStrOrList(id);
-
-    String result;
+    if (id != -1) {
+        if (!has(id))
+            return false;
+        result = getStrOrList(id);
+        return true;
+    }
 
     /* Sorry, an unknown header name. Do linear search */
+    bool found = false;
     while ((e = getEntry(&pos))) {
         if (e->id == HDR_OTHER && e->name.caseCmp(name) == 0) {
+            found = true;
             strListAdd(&result, e->value.termedBuf(), ',');
         }
     }
 
-    return result;
+    return found;
 }
 
 /*
@@ -1721,6 +1743,7 @@ httpHeaderStatDump(const HttpHeaderStat * hs, StoreEntry * e)
     storeAppendPrintf(e, "%2s\t %-5s\t %5s\t %6s\n",
                       "id", "#flds", "count", "%total");
     hs->hdrUCountDistr.dump(e, httpHeaderFldsPerHdrDumper);
+    storeAppendPrintf(e, "\n");
     dump_stat = NULL;
 }
 
@@ -1742,7 +1765,6 @@ httpHeaderStoreReport(StoreEntry * e)
 
     for (i = 1; i < HttpHeaderStatCount; ++i) {
         httpHeaderStatDump(HttpHeaderStats + i, e);
-        storeAppendPrintf(e, "%s\n", "<br>");
     }
 
     /* field stats for all messages */