2 * Copyright (C) 1996-2022 The Squid Software Foundation and contributors
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
9 #ifndef SQUID_CLIENTSIDEREPLY_H
10 #define SQUID_CLIENTSIDEREPLY_H
12 #include "acl/forward.h"
13 #include "client_side_request.h"
14 #include "ip/forward.h"
15 #include "RequestFlags.h"
16 #include "StoreClient.h"
20 /* XXX make static method */
22 class clientReplyContext
: public RefCountable
, public StoreClient
24 CBDATA_CLASS(clientReplyContext
);
28 static STCB HandleIMSReply
;
29 static STCB SendMoreData
;
31 clientReplyContext(ClientHttpRequest
*);
32 ~clientReplyContext();
37 void sendClientUpstreamResponse();
39 void identifyStoreObject();
40 void identifyFoundObject(StoreEntry
*entry
, const char *detail
);
41 int storeOKTransferDone() const;
42 int storeNotOKTransferDone() const;
43 /// replaces current response store entry with the given one
44 void setReplyToStoreEntry(StoreEntry
*e
, const char *reason
);
45 /// builds error using clientBuildError() and calls setReplyToError() below
46 void setReplyToError(err_type
, Http::StatusCode
, const HttpRequestMethod
&, char const *, const ConnStateData
*, HttpRequest
*, const char *,
48 Auth::UserRequest::Pointer
);
52 /// creates a store entry for the reply and appends err to it
53 void setReplyToError(const HttpRequestMethod
& method
, ErrorState
*err
);
54 /// creates a store entry for the reply and appends error reply to it
55 void setReplyToReply(HttpReply
*reply
);
56 void createStoreEntry(const HttpRequestMethod
& m
, RequestFlags flags
);
57 void removeStoreReference(store_client
** scp
, StoreEntry
** ep
);
58 void removeClientStoreReference(store_client
**scp
, ClientHttpRequest
*http
);
59 void startError(ErrorState
* err
);
60 void processExpired();
61 clientStream_status_t
replyStatus();
63 void traceReply(clientStreamNode
* node
);
64 const char *storeId() const { return (http
->store_id
.size() > 0 ? http
->store_id
.termedBuf() : http
->uri
); }
66 Http::StatusCode purgeStatus
;
69 virtual LogTags
*loggingTags() const;
71 ClientHttpRequest
*http
;
72 /// Base reply header bytes received from Store.
73 /// Compatible with ClientHttpRequest::Out::offset.
74 /// Not to be confused with ClientHttpRequest::Out::headers_sz.
76 store_client
*sc
; /* The store_client we're using */
77 StoreIOBuffer tempBuffer
; /* For use in validating requests via IMS */
78 int old_reqsize
; /* ... again, for the buffer */
81 char tempbuf
[HTTP_REQBUF_SZ
]; ///< a temporary buffer if we need working storage
84 Flags() : storelogiccomplete(0), complete(0), headersSent(false) {}
86 unsigned storelogiccomplete
:1;
87 unsigned complete
:1; ///< we have read all we can from upstream
90 clientStreamNode
*ourNode
; /* This will go away if/when this file gets refactored some more */
94 virtual void fillChecklist(ACLFilledChecklist
&) const;
96 clientStreamNode
*getNextNode() const;
98 bool errorInStream(StoreIOBuffer
const &result
, size_t const &sizeToProcess
)const ;
99 void sendStreamError(StoreIOBuffer
const &result
);
100 void pushStreamData(StoreIOBuffer
const &result
, char *source
);
101 clientStreamNode
* next() const;
102 StoreIOBuffer holdingBuffer
;
104 void processReplyAccess();
105 static ACLCB ProcessReplyAccessResult
;
106 void processReplyAccessResult(const Acl::Answer
&accessAllowed
);
108 void buildReplyHeader ();
109 bool alwaysAllowResponse(Http::StatusCode sline
) const;
110 int checkTransferDone();
111 void processOnlyIfCachedMiss();
112 bool processConditional();
113 void cacheHit(StoreIOBuffer result
);
114 void handleIMSReply(StoreIOBuffer result
);
115 void sendMoreData(StoreIOBuffer result
);
116 void triggerInitialStoreRead();
117 void sendClientOldEntry();
118 void purgeAllCached();
119 /// attempts to release the cached entry
120 /// \returns whether the entry was released
121 bool purgeEntry(StoreEntry
&, const Http::MethodType
, const char *descriptionPrefix
= "");
122 /// releases both cached GET and HEAD entries
125 bool blockedHit() const;
126 const char *storeLookupString(bool found
) const { return found
? "match" : "mismatch"; }
127 void detailStoreLookup(const char *detail
);
129 void sendBodyTooLargeError();
130 void sendPreconditionFailedError();
131 void sendNotModified();
132 void sendNotModifiedOrPreconditionFailedError();
134 /// Classification of the initial Store lookup.
135 /// This very first lookup happens without the Vary-driven key augmentation.
136 /// TODO: Exclude internal Store match bans from the "mismatch" category.
137 const char *firstStoreLookup_
= nullptr;
139 StoreEntry
*old_entry
;
140 /* ... for entry to be validated */
141 store_client
*old_sc
;
148 crNone
= 0, ///< collapsed revalidation is not allowed for this context
149 crInitiator
, ///< we initiated collapsed revalidation request
150 crSlave
///< we collapsed on the existing revalidation request
151 } CollapsedRevalidation
;
153 CollapsedRevalidation collapsedRevalidation
;
156 // TODO: move to SideAgent parent, when we have one
157 void purgeEntriesByUrl(HttpRequest
*, const char *);
159 #endif /* SQUID_CLIENTSIDEREPLY_H */