/*
- * Copyright (C) 1996-2016 The Squid Software Foundation and contributors
+ * Copyright (C) 1996-2018 The Squid Software Foundation and contributors
*
* Squid software is distributed under GPLv2+ license and includes
* contributions from numerous individuals and organizations.
}
/**
- * return true if a given directive is found in at least one of
- * the "connection" header-fields note: if Http::HdrType::PROXY_CONNECTION is
- * present we ignore Http::HdrType::CONNECTION.
+ * \return true if a given directive is found in the Connection header field-value.
+ *
+ * \note if no Connection header exists we may check the Proxy-Connection header
*/
-int
-httpHeaderHasConnDir(const HttpHeader * hdr, const char *directive)
+bool
+httpHeaderHasConnDir(const HttpHeader * hdr, const SBuf &directive)
{
String list;
- int res;
+
/* what type of header do we have? */
+ if (hdr->getList(Http::HdrType::CONNECTION, &list))
+ return strListIsMember(&list, directive, ',') != 0;
#if USE_HTTP_VIOLATIONS
- if (hdr->has(Http::HdrType::PROXY_CONNECTION))
- list = hdr->getList(Http::HdrType::PROXY_CONNECTION);
- else
+ if (hdr->getList(Http::HdrType::PROXY_CONNECTION, &list))
+ return strListIsMember(&list, directive, ',') != 0;
#endif
- if (hdr->has(Http::HdrType::CONNECTION))
- list = hdr->getList(Http::HdrType::CONNECTION);
- else
- return 0;
-
- res = strListIsMember(&list, directive, ',');
-
- list.clean();
- return res;
+ // else, no connection header for it to exist in
+ return false;
}
/** handy to printf prefixes of potentially very long buffers */
return 1;
}
-int
-httpHeaderParseOffset(const char *start, int64_t * value)
+bool
+httpHeaderParseOffset(const char *start, int64_t *value, char **endPtr)
{
+ char *end = nullptr;
errno = 0;
- int64_t res = strtoll(start, NULL, 10);
- if (!res && EINVAL == errno) { /* maybe not portable? */
- debugs(66, 7, "failed to parse offset in " << start);
- return 0;
+ const int64_t res = strtoll(start, &end, 10);
+ if (errno && !res) {
+ debugs(66, 7, "failed to parse malformed offset in " << start);
+ return false;
+ }
+ if (errno == ERANGE && (res == LLONG_MIN || res == LLONG_MAX)) { // no overflow
+ debugs(66, 7, "failed to parse huge offset in " << start);
+ return false;
+ }
+ if (start == end) {
+ debugs(66, 7, "failed to parse empty offset");
+ return false;
}
*value = res;
+ if (endPtr)
+ *endPtr = end;
debugs(66, 7, "offset " << start << " parsed as " << res);
- return 1;
+ return true;
}
/**
ACLFilledChecklist checklist(hm->access_list, request, NULL);
- if (checklist.fastCheck() == ACCESS_ALLOWED) {
+ if (checklist.fastCheck().allowed()) {
/* aclCheckFast returns true for allow. */
debugs(66, 7, "checklist for mangler is positive. Mangle");
retval = 1;
if (e.id == Http::HdrType::OTHER) {
// does it have an ACL list configured?
// Optimize: use a name type that we do not need to convert to here
- const ManglersByName::const_iterator i = custom.find(e.name.termedBuf());
+ SBuf tmp(e.name); // XXX: performance regression. c_str() reallocates
+ const ManglersByName::const_iterator i = custom.find(tmp.c_str());
if (i != custom.end())
return &i->second;
}
ACLFilledChecklist checklist(NULL, request, NULL);
for (HeaderWithAclList::const_iterator hwa = headersAdd.begin(); hwa != headersAdd.end(); ++hwa) {
- if (!hwa->aclList || checklist.fastCheck(hwa->aclList) == ACCESS_ALLOWED) {
+ if (!hwa->aclList || checklist.fastCheck(hwa->aclList).allowed()) {
const char *fieldValue = NULL;
MemBuf mb;
if (hwa->quoted) {
if (!fieldValue || fieldValue[0] == '\0')
fieldValue = "-";
- HttpHeaderEntry *e = new HttpHeaderEntry(hwa->fieldId, hwa->fieldName.c_str(),
- fieldValue);
+ HttpHeaderEntry *e = new HttpHeaderEntry(hwa->fieldId, SBuf(hwa->fieldName), fieldValue);
heads->addEntry(e);
}
}