#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 "SquidString.h"
#include "TimeOrTag.h"
/*
{"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},
HDR_CONNECTION,
HDR_EXPECT,
HDR_IF_MATCH, HDR_IF_NONE_MATCH,
+ HDR_KEY,
HDR_LINK, HDR_PRAGMA,
HDR_PROXY_CONNECTION,
HDR_PROXY_SUPPORT,
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,
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,
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
};
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;
}
/*
- * 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;
/* 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;
}
/*
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;
}
for (i = 1; i < HttpHeaderStatCount; ++i) {
httpHeaderStatDump(HttpHeaderStats + i, e);
- storeAppendPrintf(e, "%s\n", "<br>");
}
/* field stats for all messages */