}
/*
- * 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;
}
/*
bool getList(http_hdr_type id, String *s) const;
String getStrOrList(http_hdr_type id) const;
String getByName(const char *name) const;
+ /// sets value and returns true iff a [possibly empty] named field is there
+ bool getByNameIfPresent(const char *name, String &value) const;
String getByNameListMember(const char *name, const char *member, const char separator) const;
String getListMember(http_hdr_type id, const char *member, const char separator) const;
int has(http_hdr_type id) const;
debugs(28, 3, "aclHeaderData::match: checking '" << hdrName << "'");
- String value = hdrId != HDR_BAD_HDR ? hdr->getStrOrList(hdrId) : hdr->getByName(hdrName.termedBuf());
+ String value;
+ if (hdrId != HDR_BAD_HDR) {
+ if (!hdr->has(hdrId))
+ return false;
+ value = hdr->getStrOrList(hdrId);
+ } else {
+ if (!hdr->getByNameIfPresent(hdrName.termedBuf(), value))
+ return false;
+ }
- return regex_rule->match(value.termedBuf());
+ // By now, we know the header is present, but:
+ // HttpHeader::get*() return an undefined String for empty header values;
+ // String::termedBuf() returns NULL for undefined Strings; and
+ // ACLRegexData::match() always fails on NULL strings.
+ // This makes it possible to detect an empty header value using regex:
+ const char *cvalue = value.defined() ? value.termedBuf() : "";
+ return regex_rule->match(cvalue);
}
wordlist *