74 purgeStatus(
Http::scNone),
83 collapsedRevalidation(crNone)
107 errstate->auth_user_request = auth_user_request;
151 entry->
lock(
"clientReplyContext::setReplyToStoreEntry");
169 if ((e = *ep) !=
nullptr) {
173 e->
unlock(
"clientReplyContext::removeStoreReference");
189 debugs(88, 3,
"clientReplyContext::saveState: saving store context");
203 debugs(88, 3,
"clientReplyContext::restoreState: Restoring store context");
260 debugs(88, 3,
"clientReplyContext::processExpired: '" <<
http->
uri <<
"'");
276#if STORE_CLIENT_LIST_DEBUG
291 if (collapsingAllowed) {
295 entry->
lock(
"clientReplyContext::processExpired#alreadyRevalidating");
297 e->abandon(__func__);
299 collapsingAllowed =
false;
306 debugs(88, 5,
"collapsed on existing revalidation entry: " << *entry);
315 debugs(88, 5,
"allow other revalidation requests to collapse on " << *entry);
331 ETag etag = {
nullptr, -1};
352 debugs(88,
DBG_CRITICAL,
"clientReplyContext::processExpired: Found ENTRY_ABORTED object");
462 debugs(88, 3,
"origin replied 304, revalidated existing entry and forwarding 304 to client");
468 debugs(88, 3,
"origin replied 304, revalidated existing entry and sending " << oldStatus <<
" to client");
481 debugs(88, 3,
"origin replied " << status <<
" but with an older date header, sending old entry (" << oldStatus <<
") to client");
487 debugs(88, 3,
"origin replied " << status <<
", forwarding to client");
495 debugs(88, 3,
"origin replied with error " << status <<
", forwarding to client due to fail_on_validation_err");
502 debugs(88, 3,
"origin replied with error " << status <<
", sending old entry (" << oldStatus <<
") to client");
525 debugs(88, 3,
"HIT object being deleted. Ignore the HIT.");
536 debugs(88, 3,
"clientCacheHit: request aborted");
540 debugs(88, 3,
"clientCacheHit: swapin failure for " <<
http->
uri);
551 debugs(88, 3,
"unshareable " << *e <<
". MISS");
558 debugs(88, 3,
"refusing aborted " << *e);
586 debugs(88, 2,
"clientProcessHit: Vary MATCH!");
598 debugs(88, 2,
"clientProcessHit: Vary detected!");
611 debugs(88, 5,
"PURGE gets a HIT");
619 debugs(88, 5,
"negative-HIT");
624 debugs(88, 5,
"send_hit forces a MISS");
629 debugs(88, 5,
"clientCacheHit: in refreshCheck() block");
643 debugs(88, 3,
"validate HIT object? NO. Can't calculate entry modification time. Do MISS.");
652 debugs(88, 3,
"validate HIT object? NO. Client sent CC:no-cache. Do CLIENT_REFRESH_MISS");
660 debugs(88, 3,
"validate HIT object? YES.");
667 debugs(88, 3,
"validate HIT object? NO. Client protocol non-HTTP. Do MISS.");
677 debugs(88, 5,
"conditional HIT");
685 debugs(88, 5,
"plain old HIT");
717 debugs(88,
DBG_CRITICAL,
"clientProcessMiss: miss on a special object (" << url <<
").");
798 debugs(88, 4,
"miss because " << replyStatusCode <<
" != 200");
872 if (m.respMaybeCacheable()) {
905 debugs(88, 3,
"Config2.onoff.enable_purge = " <<
926 auto firstFound =
false;
934 entry->abandon(__func__);
1015#define SENDING_BODY 0
1016#define SENDING_HDRSONLY 1
1022 if (entry ==
nullptr)
1057 const auto debugLevel = done ? 3 : 5;
1058 debugs(88, debugLevel, done <<
1061 " headers_sz=" << headers_sz);
1062 return done ? 1 : 0;
1093 if (expectedBodySize < 0)
1097 const auto debugLevel = done ? 3 : 5;
1098 debugs(88, debugLevel, done <<
1100 " expectedBodySize=" << expectedBodySize);
1101 return done ? 1 : 0;
1129 debugs(88, 5,
"clientReplyStatus: no storeEntry");
1138 debugs(88, 5,
"clientReplyStatus: aborted storeEntry");
1147 debugs(88, 5,
"clientReplyStatus: truncated response body");
1152 debugs(88, 5,
"clientReplyStatus: closing, !done, but read 0 bytes");
1157 const int64_t expectedBodySize =
1160 debugs(88, 5,
"clientReplyStatus: client didn't get all it expected");
1164 debugs(88, 5,
"clientReplyStatus: stream complete; keepalive=" <<
1171 debugs(88, 5,
"clientReplyStatus: client reply body is too large");
1284 hdr->
putExt(
"X-Cache-Age", age);
1317 int connection_auth_blocked = 0;
1318 while ((e = hdr->
getEntry(&pos))) {
1322 if ((strncasecmp(value,
"NTLM", 4) == 0 &&
1323 (value[4] ==
'\0' || value[4] ==
' '))
1325 (strncasecmp(value,
"Negotiate", 9) == 0 &&
1326 (value[9] ==
'\0' || value[9] ==
' '))
1328 (strncasecmp(value,
"Kerberos", 8) == 0 &&
1329 (value[8] ==
'\0' || value[8] ==
' '))) {
1331 hdr->
delAt(pos, connection_auth_blocked);
1350 if (connection_auth_blocked)
1373 cacheStatus.
append(hitOrFwd);
1375 cacheStatus.
append(
";detail=");
1387 debugs(33, 3,
"clientBuildReplyHeader: Error, don't keep-alive");
1390 debugs(33, 2,
"clientBuildReplyHeader: Connection Keep-Alive not requested by admin or client");
1393 debugs(88, 3,
"clientBuildReplyHeader: Shutting down, don't keep-alive.");
1396 debugs(33, 2,
"clientBuildReplyHeader: Connection oriented auth but server side non-persistent");
1399 debugs(88, 3,
"clientBuildReplyHeader: can't keep-alive, unknown body size" );
1402 debugs(88, 3,
"clientBuildReplyHeader: Not many unused FDs, can't keep-alive");
1406 debugs(88, 3,
"clientBuildReplyHeader: bumped reply forces close");
1410 debugs(88, 3,
"pinned reply forces close");
1416 debugs(88, 3,
"listening port closed");
1423 debugs(88, 3,
"clientBuildReplyHeader: chunked reply");
1475 e->
lock(
"clientReplyContext::forgetHit");
1477 e->
unlock(
"clientReplyContext::forgetHit");
1521 debugs(85, 3,
"StoreEntry is NULL - MISS");
1529 debugs(85, 3,
"offline HIT " << *e);
1537 debugs(85, 3,
"REDIRECT status forced StoreEntry to NULL (no body on 3XX responses) " << *e);
1544 if (!e->validToSend()) {
1545 debugs(85, 3,
"!storeEntryValidToSend MISS " << *e);
1554 debugs(85, 3,
"ENTRY_SPECIAL HIT " << *e);
1561 debugs(85, 3,
"no-cache REFRESH MISS " << *e);
1569 debugs(85, 3,
"prohibited CF MISS " << *e);
1576 debugs(85, 3,
"default HIT " << *e);
1606 assert(aNode !=
nullptr);
1726 debugs(88, 5,
"A stream error has occurred, marking as complete and sending no data.");
1738 if (result.
length == 0) {
1739 debugs(88, 5,
"clientReplyContext::pushStreamData: marking request as complete due to 0 length store result");
1849 auto replyChecklist =
1851 replyChecklist->updateReply(
reply);
1866 <<
' ' <<
http->
uri <<
" is " << accessAllowed <<
", because it matched "
1869 if (!accessAllowed.
allowed()) {
1897 debugs(88, 3,
"clientReplyContext::sendMoreData: Appending " <<
1898 (
int) body_size <<
" bytes after " <<
reply->
hdr_sz <<
1899 " bytes of headers");
1930 if (
next()->readBuffer.offset > 0) {
1931 if (
Less(body_size,
next()->readBuffer.offset)) {
1933 localTempBuffer.
length = 0;
1934 localTempBuffer.
data =
nullptr;
1940 localTempBuffer.
length = body_size;
1941 localTempBuffer.
data = body_buf;
1961 if (!conn->isOpen()) {
1962 debugs(33,3,
"not sending more data to closing connection " << conn->clientConnection);
1965 if (conn->pinning.zeroReply) {
1966 debugs(33,3,
"not sending more data after a pinned zero reply " << conn->clientConnection);
1981 debugs(88, 5, conn->clientConnection <<
1982 " '" << entry->
url() <<
"'" <<
2007 assert(result.
length <= ourClientStreamsBuffer.length);
2008 memcpy(ourClientStreamsBuffer.data, result.
data, result.
length);
2009 result.
data = ourClientStreamsBuffer.data;
2042 debugs(88, 7,
"no: " << their <<
" vs. " <<
next()->readBuffer);
2121 const auto err =
new ErrorState(page_id, status, request, al);
#define Assure(condition)
class SquidConfig2 Config2
constexpr bool Less(const A a, const B b)
whether integer a is less than integer b, with correct overflow handling
void(void *, StoreIOBuffer) STCB
int storeClientIsThisAClient(store_client *sc, void *someClient)
err_type FindDenyInfoPage(const Acl::Answer &answer, const bool redirect_allowed)
int cbdataReferenceValid(const void *p)
#define cbdataReferenceDone(var)
#define cbdataReference(var)
#define CBDATA_CLASS_INIT(type)
Acl::Answer const & fastCheck()
static void NonBlockingCheck(MakingPointer &&p, ACLCB *cb, void *data)
void updateReply(const HttpReply::Pointer &)
class AccessLogEntry::CacheDetails cache
class AccessLogEntry::HttpDetails http
const SBuf & lastCheckDescription() const
describes the ACL that was evaluated last while obtaining this answer (for debugging)
ProtocolType protocol
which protocol this version is for
AnyP::UriScheme const & getScheme() const
void host(const char *src)
static void AddReplyAuthHeader(HttpReply *rep, UserRequest::Pointer auth_user_request, HttpRequest *request, int accelerated, int internal)
Add the appropriate [Proxy-]Authenticate header to the given reply.
struct ClientHttpRequest::Out out
HttpRequest *const request
ConnStateData * getConn() const
void updateLoggingTags(const LogTags_ot code)
update the code in the transaction processing tags
struct ClientHttpRequest::Flags flags
bool onlyIfCached() const
bool requestSatisfactionMode() const
StoreEntry * storeEntry() const
const LogTags & loggingTags() const
the processing tags associated with this request transaction.
const AccessLogEntry::Pointer al
access.log entry
StoreEntry * loggingEntry() const
struct ClientHttpRequest::Redirect redirect
AnyP::Port port
destination port of the request that caused serverConnection
static DelayId DelayClient(ClientHttpRequest *, HttpReply *reply=nullptr)
int weak
true if it is a weak validator
const char * str
quoted-string
Http::StatusCode httpStatus
static void Start(const Comm::ConnectionPointer &client, StoreEntry *, HttpRequest *, const AccessLogEntryPointer &alp)
Initiates request forwarding to a peer or origin server.
void set(const SBuf &newContent)
HttpReplyPointer make304() const
void setHeaders(Http::StatusCode status, const char *reason, const char *ctype, int64_t clen, time_t lmt, time_t expires)
int64_t bodySize(const HttpRequestMethod &) const
void removeIrrelevantContentLength()
Some response status codes prohibit sending Content-Length (RFC 7230 section 3.3.2).
bool receivedBodyTooLarge(HttpRequest &, int64_t receivedBodySize)
void redirect(Http::StatusCode, const char *)
bool expectedBodyTooLarge(HttpRequest &request)
HttpReply * clone() const override
bool conditional() const
has at least one recognized If-* header
CbcPointer< ConnStateData > clientConnectionManager
bool multipartRangeRequest() const
void pack(Packable *p, bool maskSensitiveInfo=false) const
SBuf vary_headers
The variant second-stage cache key. Generated from Vary header pattern for this request.
String etag
A strong etag of the cached entry. Used for refreshing that entry.
ConnStateData * pinnedConnection()
void ignoreRange(const char *reason)
forgets about the cached Range header (for a reason)
Auth::UserRequest::Pointer auth_user_request
AnyP::Uri url
the request URI
const SBuf & effectiveRequestUri() const
RFC 7230 section 5.5 - Effective Request URI.
AnyP::ProtocolVersion http_ver
AnyP::ProtocolVersion version
breakdown of protocol version label: (HTTP/ICY) and (0.9/1.0/1.1)
Http::StatusCode status() const
retrieve the status code for this status line
static const Address & NoAddr()
static Pointer MakePortful(const AnyP::PortCfgPointer &aPort)
void init(mb_size_t szInit, mb_size_t szMax)
mb_size_t contentSize() const
available data size
const HttpReply & freshestReply() const
const char * storeId() const
const HttpReply & baseReply() const
bool failOnValidationError
bool connectionAuthDisabled
SupportOrVeto cachable
whether the response may be stored in the cache
static const size_type npos
int cmp(const SBuf &S, const size_type n) const
shorthand version for compare()
size_type find(char c, size_type startPos=0) const
SBuf & append(const SBuf &S)
Comm::ConnectionPointer clientConnection
struct SquidConfig2::@102 onoff
struct SquidConfig::@90 onoff
struct SquidConfig::@91 accessList
bool didCollapse
whether startCollapsingOn() was called and returned true
bool mayInitiateCollapsing() const
whether Squid configuration allows us to become a CF initiator
bool startCollapsingOn(const StoreEntry &, const bool doingRevalidation) const
void completeSuccessfully(const char *whyWeAreSureWeStoredTheWholeReply)
bool hasIfMatchEtag(const HttpRequest &request) const
has ETag matching at least one of the If-Match etags
void ensureMemObject(const char *storeId, const char *logUri, const HttpRequestMethod &aMethod)
initialize mem_obj (if needed) and set URIs/method (if missing)
bool hasIfNoneMatchEtag(const HttpRequest &request) const
has ETag matching at least one of the If-None-Match etags
void dump(int debug_lvl) const
int unlock(const char *context)
bool hasEtag(ETag &etag) const
whether this entry has an ETag; if yes, puts ETag value into parameter
void lastModified(const time_t when)
void release(const bool shareable=false)
bool hasParsedReplyHeader() const
whether this entry has access to [deserialized] [HTTP] response headers
void lock(const char *context)
void clearPublicKeyScope()
void storeErrorResponse(HttpReply *reply)
Store a prepared error response. MemObject locks the reply object.
bool mayStartHitting() const
int checkNegativeHit() const
void replaceHttpReply(const HttpReplyPointer &, const bool andStartWriting=true)
bool modifiedSince(const time_t ims, const int imslen=-1) const
int64_t objectLen() const
store_status_t store_status
void releaseRequest(const bool shareable=false)
struct StoreIOBuffer::@123 flags
bool allowCollapsing(StoreEntry *, const RequestFlags &, const HttpRequestMethod &)
tries to make the entry available for collapsing future requests
static bool SmpAware()
whether there are any SMP-aware storages
void evictIfFound(const cache_key *) override
char const * rawBuf() const
char const * termedBuf() const
void handleIMSReply(StoreIOBuffer result)
clientStreamNode * ourNode
void sendNotModifiedOrPreconditionFailedError()
void setReplyToReply(HttpReply *reply)
creates a store entry for the reply and appends error reply to it
static ACLCB ProcessReplyAccessResult
bool alwaysAllowResponse(Http::StatusCode sline) const
static STCB HandleIMSReply
void sendPreconditionFailedError()
send 412 (Precondition Failed) to client
void triggerInitialStoreRead(STCB=SendMoreData)
void cacheHit(StoreIOBuffer result)
bool matchesStreamBodyBuffer(const StoreIOBuffer &) const
void sendStreamError(StoreIOBuffer const &result)
@ crInitiator
we initiated collapsed revalidation request
@ crNone
collapsed revalidation is not allowed for this context
@ crSlave
we collapsed on the existing revalidation request
void pushStreamData(const StoreIOBuffer &)
void sendClientUpstreamResponse(const StoreIOBuffer &upstreamResponse)
Http::StatusCode purgeStatus
void startError(ErrorState *err)
void identifyFoundObject(StoreEntry *entry, const char *detail)
void sendNotModified()
send 304 (Not Modified) to client
void createStoreEntry(const HttpRequestMethod &m, RequestFlags flags)
void setReplyToStoreEntry(StoreEntry *e, const char *reason)
replaces current response store entry with the given one
bool errorInStream(const StoreIOBuffer &result) const
void processOnlyIfCachedMiss()
bool blockedHit() const
whether squid.conf send_hit prevents us from serving this hit
static decltype(::storeClientCopy) storeClientCopy
int storeNotOKTransferDone() const
void removeClientStoreReference(store_client **scp, ClientHttpRequest *http)
friend CSR clientGetMoreData
~clientReplyContext() override
struct clientReplyContext::Flags flags
void processReplyAccessResult(const Acl::Answer &accessAllowed)
const char * firstStoreLookup_
void sendBodyTooLargeError()
CollapsedRevalidation collapsedRevalidation
void sendClientOldEntry()
char tempbuf[HTTP_REQBUF_SZ]
const char * storeLookupString(bool found) const
bool purgeEntry(StoreEntry &, const Http::MethodType, const char *descriptionPrefix="")
void requestMoreBodyFromStore()
clientStreamNode * next() const
void noteStreamBufferredBytes(const StoreIOBuffer &)
void sendMoreData(StoreIOBuffer result)
StoreIOBuffer lastStreamBufferedBytes
HTTP response body bytes stored in our Client Stream buffer (if any)
clientStream_status_t replyStatus()
void removeStoreReference(store_client **scp, StoreEntry **ep)
LogTags * loggingTags() const override
const char * storeId() const
bool processConditional()
process conditional request from client
int storeOKTransferDone() const
void processReplyAccess()
clientStreamNode * getNextNode() const
void fillChecklist(ACLFilledChecklist &) const override
configure the given checklist (to reflect the current transaction state)
void identifyStoreObject()
void setReplyToError(err_type, Http::StatusCode, char const *, const ConnStateData *, HttpRequest *, const char *, Auth::UserRequest::Pointer)
builds error using clientBuildError() and calls setReplyToError() below
void purgeDoPurge()
releases both cached GET and HEAD entries
clientReplyContext(ClientHttpRequest *)
void detailStoreLookup(const char *detail)
remembers the very first Store lookup classification, ignoring the rest
void setDelayId(DelayId delay_id)
void CSD(clientStreamNode *, ClientHttpRequest *)
client stream detach
void CSR(clientStreamNode *, ClientHttpRequest *)
client stream read
clientStream_status_t CSS(clientStreamNode *, ClientHttpRequest *)
ACLFilledChecklist::MakingPointer clientAclChecklistCreate(const acl_access *acl, ClientHttpRequest *http)
int varyEvaluateMatch(StoreEntry *entry, HttpRequest *request)
void clientAclChecklistFill(ACLFilledChecklist &checklist, ClientHttpRequest *http)
ErrorState * clientBuildError(err_type, Http::StatusCode, char const *, const ConnStateData *, HttpRequest *, const AccessLogEntry::Pointer &)
void purgeEntriesByUrl(HttpRequest *req, const char *url)
void purgeEntriesByUrl(HttpRequest *, const char *)
#define debugs(SECTION, LEVEL, CONTENT)
#define EBIT_TEST(flag, bit)
void dlinkDelete(dlink_node *m, dlink_list *list)
void dlinkAdd(void *data, dlink_node *m, dlink_list *list)
dlink_list ClientActiveRequests
@ STREAM_UNPLANNED_COMPLETE
@ ERR_PRECONDITION_FAILED
@ ERR_ONLY_IF_CACHED_MISS
void clientStreamCallback(clientStreamNode *thisObject, ClientHttpRequest *http, HttpReply *rep, StoreIOBuffer replyBuffer)
void clientStreamDetach(clientStreamNode *thisObject, ClientHttpRequest *http)
void errorAppendEntry(StoreEntry *entry, ErrorState *err)
void ipcacheInvalidateNegative(const char *name)
void ipcacheInvalidate(const char *name)
void HTTPMSGUNLOCK(M *&a)
void HTTPMSGLOCK(Http::Message *a)
bool IsConnOpen(const Comm::ConnectionPointer &conn)
enum Http::_method_t MethodType
@ scProxyAuthenticationRequired
const SBuf & MethodStr(const MethodType m)
AnyP::ProtocolVersion ProtocolVersion()
int doNfmarkLocalHit(const Comm::ConnectionPointer &conn)
Config TheConfig
Globally available instance of Qos::Config.
int doTosLocalMiss(const Comm::ConnectionPointer &conn, const hier_code hierCode)
int doNfmarkLocalMiss(const Comm::ConnectionPointer &conn, const hier_code hierCode)
int doTosLocalHit(const Comm::ConnectionPointer &conn)
Controller & Root()
safely access controller singleton
void neighborsHtcpClear(StoreEntry *e, HttpRequest *req, const HttpRequestMethod &method, htcp_clr_reason reason)
int refreshCheckHTTP(const StoreEntry *entry, HttpRequest *request)
unsigned char cache_key
Store key.
StoreEntry * storeGetPublicByRequestMethod(HttpRequest *req, const HttpRequestMethod &method, const KeyScope keyScope)
StoreEntry * storeGetPublicByRequest(HttpRequest *req, const KeyScope keyScope)
StoreEntry * storeCreateEntry(const char *url, const char *logUrl, const RequestFlags &flags, const HttpRequestMethod &method)
StoreEntry * storeGetPublic(const char *uri, const HttpRequestMethod &method)
int storeUnregister(store_client *sc, StoreEntry *e, void *data)
store_client * storeClientListAdd(StoreEntry *e, void *data)
const cache_key * storeKeyPublic(const char *url, const HttpRequestMethod &method, const KeyScope keyScope)
const char * storeKeyText(const cache_key *key)
uint64_t size
Response header and body bytes written to the client connection.
unsigned complete
we have read all we can from upstream
unsigned storelogiccomplete