/*
- * 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.
#include "Store.h"
#include "StrList.h"
-/* local constants */
-
-/* If we receive a 304 from the origin during a cache revalidation, we must
- * update the headers of the existing entry. Specifically, we need to update all
- * end-to-end headers and not any hop-by-hop headers (rfc2616 13.5.3).
- *
- * This is not the whole story though: since it is possible for a faulty/malicious
- * origin server to set headers it should not in a 304, we must explicitly ignore
- * these too. Specifically all entity-headers except those permitted in a 304
- * (rfc2616 10.3.5) must be ignored.
- *
- * The list of headers we don't update is made up of:
- * all hop-by-hop headers
- * all entity-headers except Expires and Content-Location
- *
- * These headers are now stored in RegisteredHeadersHash.gperf and accessible
- * as Http::HeaderLookupTable.lookup(id).denied304
- */
-static HttpHeaderMask Denied304HeadersMask;
-
-/* module initialization */
-void
-httpReplyInitModule(void)
-{
- assert(Http::scNone == 0); // HttpReply::parse() interface assumes that
- httpHeaderMaskInit(&Denied304HeadersMask, 0);
-
- for (auto id : WholeEnum<Http::HdrType>()) {
- if (Http::HeaderLookupTable.lookup(id).denied304)
- CBIT_SET(Denied304HeadersMask, id);
- }
-}
-
-HttpReply::HttpReply() : HttpMsg(hoReply), date (0), last_modified (0),
- expires (0), surrogate_control (NULL), content_range (NULL), keep_alive (0),
- protoPrefix("HTTP/"), bodySizeMax(-2)
+HttpReply::HttpReply():
+ Http::Message(hoReply),
+ date(0),
+ last_modified(0),
+ expires(0),
+ surrogate_control(nullptr),
+ keep_alive(0),
+ protoPrefix("HTTP/"),
+ bodySizeMax(-2),
+ content_range(nullptr)
{
init();
}
{
hdrCacheInit();
sline.init();
- pstate = psReadyToParseStartLine;
+ pstate = Http::Message::psReadyToParseStartLine;
do_clean = true;
}
return 1;
}
-void
+bool
HttpReply::updateOnNotModified(HttpReply const * freshRep)
{
assert(freshRep);
+ /* update raw headers */
+ if (!header.update(&freshRep->header))
+ return false;
+
/* clean cache */
hdrCacheClean();
- /* update raw headers */
- header.update(&freshRep->header,
- (const HttpHeaderMask *) &Denied304HeadersMask);
header.compact();
/* init cache */
hdrCacheInit();
+
+ return true;
}
/* internal routines */
/* The s-maxage and max-age directive takes priority over Expires */
if (cache_control) {
- if (date >= 0) {
- if (cache_control->hasSMaxAge())
- return date + cache_control->sMaxAge();
-
- if (cache_control->hasMaxAge())
- return date + cache_control->maxAge();
- } else {
- /*
- * Conservatively handle the case when we have a max-age
- * header, but no Date for reference?
- */
-
- if (cache_control->hasSMaxAge())
- return squid_curtime;
-
- if (cache_control->hasMaxAge())
- return squid_curtime;
- }
+ int maxAge = -1;
+ /*
+ * Conservatively handle the case when we have a max-age
+ * header, but no Date for reference?
+ */
+ if (cache_control->hasSMaxAge(&maxAge) || cache_control->hasMaxAge(&maxAge))
+ return (date >= 0) ? date + maxAge : squid_curtime;
}
if (Config.onoff.vary_ignore_expire &&
void
HttpReply::hdrCacheInit()
{
- HttpMsg::hdrCacheInit();
+ Http::Message::hdrCacheInit();
http_ver = sline.version;
content_length = header.getInt64(Http::HdrType::CONTENT_LENGTH);
date = header.getTime(Http::HdrType::DATE);
last_modified = header.getTime(Http::HdrType::LAST_MODIFIED);
surrogate_control = header.getSc();
- content_range = header.getContRange();
+ content_range = (sline.status() == Http::scPartialContent) ?
+ header.getContRange() : nullptr;
keep_alive = persistent() ? 1 : 0;
const char *str = header.getStr(Http::HdrType::CONTENT_TYPE);
expires = hdrExpirationTime();
}
+const HttpHdrContRange *
+HttpReply::contentRange() const
+{
+ assert(!content_range || sline.status() == Http::scPartialContent);
+ return content_range;
+}
+
/* sync this routine when you update HttpReply struct */
void
HttpReply::hdrCacheClean()
int
HttpReply::httpMsgParseError()
{
- int result(HttpMsg::httpMsgParseError());
+ int result(Http::Message::httpMsgParseError());
/* indicate an error in the status line */
sline.set(Http::ProtocolVersion(), Http::scInvalidHeader);
return result;
HTTPMSGLOCK(ch.reply);
for (AclSizeLimit *l = Config.ReplyBodySize; l; l = l -> next) {
/* if there is no ACL list or if the ACLs listed match use this size value */
- if (!l->aclList || ch.fastCheck(l->aclList) == ACCESS_ALLOWED) {
+ if (!l->aclList || ch.fastCheck(l->aclList).allowed()) {
debugs(58, 4, HERE << "bodySizeMax=" << bodySizeMax);
bodySizeMax = l->size; // may be -1
break;
return rep;
}
-bool HttpReply::inheritProperties(const HttpMsg *aMsg)
+bool
+HttpReply::inheritProperties(const Http::Message *aMsg)
{
const HttpReply *aRep = dynamic_cast<const HttpReply*>(aMsg);
if (!aRep)
header.delById(Http::HdrType::WARNING);
if (newWarning.size()) { // some warnings left
HttpHeaderEntry *const e =
- new HttpHeaderEntry(Http::HdrType::WARNING, NULL, newWarning.termedBuf());
+ new HttpHeaderEntry(Http::HdrType::WARNING, SBuf(), newWarning.termedBuf());
header.addEntry(e);
}
}
return newValue;
}
+bool
+HttpReply::olderThan(const HttpReply *them) const
+{
+ if (!them || !them->date || !date)
+ return false;
+ return date < them->date;
+}
+