]> git.ipfire.org Git - thirdparty/squid.git/blame - src/client_side_request.h
Use RegisteredRunners for WCCP (de)activation (#2104)
[thirdparty/squid.git] / src / client_side_request.h
CommitLineData
c8be6d7b 1/*
1f7b830e 2 * Copyright (C) 1996-2025 The Squid Software Foundation and contributors
c8be6d7b 3 *
bbc27441
AJ
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.
c8be6d7b 7 */
8
ff9d9458
FC
9#ifndef SQUID_SRC_CLIENT_SIDE_REQUEST_H
10#define SQUID_SRC_CLIENT_SIDE_REQUEST_H
c8be6d7b 11
12f5a662 12#include "AccessLogEntry.h"
c56edb4a 13#include "acl/FilledChecklist.h"
a2ac85d9 14#include "client_side.h"
63df1d28 15#include "http/forward.h"
43ca19e0 16#include "HttpHeaderRange.h"
63ed9e8e 17#include "log/forward.h"
02c8dde5 18#include "LogTags.h"
1a6cca01 19#include "Store.h"
528b2c61 20
a83c6ed6
AR
21#if USE_ADAPTATION
22#include "adaptation/forward.h"
23#include "adaptation/Initiator.h"
de31d06f 24#endif
25
c6983ec7
FC
26class ClientRequestContext;
27class ConnStateData;
90f396d5 28class MemObject;
62e76326 29
62e76326 30class ClientHttpRequest
a83c6ed6 31#if USE_ADAPTATION
f53969cc
SM
32 : public Adaptation::Initiator, // to start adaptation transactions
33 public BodyConsumer // to receive reply bodies in request satisf. mode
5f8252d2 34#endif
62e76326 35{
337b9aa4
AR
36#if USE_ADAPTATION
37 CBDATA_CHILD(ClientHttpRequest);
38#else
5c2f68b7 39 CBDATA_CLASS(ClientHttpRequest);
337b9aa4 40#endif
62e76326 41
528b2c61 42public:
1d1457f2
AJ
43 ClientHttpRequest(ConnStateData *);
44 ClientHttpRequest(ClientHttpRequest &&) = delete;
337b9aa4
AR
45#if USE_ADAPTATION
46 ~ClientHttpRequest() override;
47#else
528b2c61 48 ~ClientHttpRequest();
337b9aa4 49#endif
62e76326 50
30abd221 51 String rangeBoundaryStr() const;
528b2c61 52 void freeResources();
53 void updateCounters();
54 void logRequest();
1a6cca01
AJ
55 MemObject * memObject() const {
56 return (storeEntry() ? storeEntry()->mem_obj : nullptr);
57 }
528b2c61 58 bool multipartRangeRequest() const;
8e2745f4 59 void processRequest();
60 void httpStart();
0655fa4d 61 bool onlyIfCached()const;
62 bool gotEnough() const;
1a6cca01 63 StoreEntry *storeEntry() const { return entry_; }
86a2f789 64 void storeEntry(StoreEntry *);
1a6cca01 65 StoreEntry *loggingEntry() const { return loggingEntry_; }
0976f8db 66 void loggingEntry(StoreEntry *);
0655fa4d 67
1d1457f2 68 ConnStateData *getConn() const {
1a6cca01
AJ
69 return (cbdataReferenceValid(conn_) ? conn_ : nullptr);
70 }
be364179 71
bec110e4
EB
72 /// Initializes the current request with the virgin request.
73 /// Call this method when the virgin request becomes known.
74 /// To update the current request later, use resetRequest().
75 void initRequest(HttpRequest *);
76
77 /// Resets the current request to the latest adapted or redirected
78 /// request. Call this every time adaptation or redirection changes
79 /// the request. To set the virgin request, use initRequest().
80 void resetRequest(HttpRequest *);
81
333c433b
EB
82 // XXX: unify the uriChanged condition calculation with resetRequest() callers, removing this method
83 /// resetRequest() variation for callers with custom URI change detection logic
84 /// \param uriChanged whether the new request URI differs from the current request URI
85 void resetRequestXXX(HttpRequest *, bool uriChanged);
86
87 /// Checks whether the current request is internal and adjusts it accordingly.
88 void checkForInternalAccess();
89
12f5a662
EB
90 /// update the code in the transaction processing tags
91 void updateLoggingTags(const LogTags_ot code) { al->cache.code.update(code); }
92
93 /// the processing tags associated with this request transaction.
94 const LogTags &loggingTags() const { return al->cache.code; }
95
1d1457f2
AJ
96 int64_t mRangeCLen() const;
97
98 void doCallouts();
99
100 // The three methods below prepare log_uri and friends for future logging.
101 // Call the best-fit method whenever the current request or its URI changes.
102
103 /// sets log_uri when we know the current request
104 void setLogUriToRequestUri();
105
106 /// sets log_uri to a parsed request URI when Squid fails to parse or
107 /// validate other request components, yielding no current request
108 void setLogUriToRawUri(const char *, const HttpRequestMethod &);
109
110 /// sets log_uri and uri to an internally-generated "error:..." URI when
111 /// neither the current request nor the parsed request URI are known
112 void setErrorUri(const char *);
113
114 /// Prepares to satisfy a Range request with a generated HTTP 206 response.
115 /// Initializes range_iter state to allow raw range_iter access.
116 /// \returns Content-Length value for the future response; never negative
117 int64_t prepPartialResponseGeneration();
118
119 /// Build an error reply. For use with the callouts.
120 void calloutsError(const err_type, const ErrorDetail::Pointer &);
be364179 121
1d1457f2
AJ
122 /// if necessary, stores new error information (if any)
123 void updateError(const Error &);
124
125public:
bec110e4
EB
126 /// Request currently being handled by ClientHttpRequest.
127 /// Usually remains nil until the virgin request header is parsed or faked.
128 /// Starts as a virgin request; see initRequest().
129 /// Adaptation and redirections replace it; see resetRequest().
1d1457f2 130 HttpRequest * const request = nullptr;
bec110e4
EB
131
132 /// Usually starts as a URI received from the client, with scheme and host
133 /// added if needed. Is used to create the virgin request for initRequest().
134 /// URIs of adapted/redirected requests replace it via resetRequest().
1d1457f2 135 char *uri = nullptr;
bec110e4
EB
136
137 // TODO: remove this field and store the URI directly in al->url
138 /// Cleaned up URI of the current (virgin or adapted/redirected) request,
139 /// computed URI of an internally-generated requests, or
140 /// one of the hard-coded "error:..." URIs.
1d1457f2 141 char * const log_uri = nullptr;
bec110e4 142
a8a0b1c2 143 String store_id; /* StoreID for transactions where the request member is nil */
62e76326 144
cc8c4af2 145 struct Out {
66d51f4f
AR
146 /// Roughly speaking, this offset points to the next body byte we want
147 /// to receive from Store. Without Ranges (and I/O errors), we should
148 /// have received (and written to the client) all the previous bytes.
149 /// XXX: The offset is updated by various receive-write steps, making
150 /// its exact meaning illusive. Its Out class placement is confusing.
1d1457f2 151 int64_t offset = 0;
66d51f4f 152 /// Response header and body bytes written to the client connection.
1d1457f2 153 uint64_t size = 0;
66d51f4f 154 /// Response header bytes written to the client connection.
1d1457f2 155 size_t headers_sz = 0;
3d0ac046 156 } out;
62e76326 157
f53969cc 158 HttpHdrRangeIter range_iter; /* data for iterating thru range specs */
1d1457f2 159 size_t req_sz = 0; ///< raw request size on input, not current request size
62e76326 160
12f5a662 161 const AccessLogEntry::Pointer al; ///< access.log entry
62e76326 162
cc8c4af2 163 struct Flags {
1d1457f2 164 bool accel = false;
1d1457f2 165 bool done_copying = false;
3d0ac046 166 } flags;
62e76326 167
cc8c4af2 168 struct Redirect {
1d1457f2
AJ
169 Http::StatusCode status = Http::scNone;
170 char *location = nullptr;
3d0ac046 171 } redirect;
62e76326 172
528b2c61 173 dlink_node active;
174 dlink_list client_stream;
de31d06f 175
1d1457f2 176 ClientRequestContext *calloutContext = nullptr;
1cf238db 177
528b2c61 178private:
bec110e4 179 /// assigns log_uri with aUri without copying the entire C-string
1d1457f2 180 void absorbLogUri(char *);
bec110e4
EB
181 /// resets the current request and log_uri to nil
182 void clearRequest();
183 /// initializes the current unassigned request to the virgin request
184 /// sets the current request, asserting that it was unset
1d1457f2 185 void assignRequest(HttpRequest *);
bec110e4 186
1d1457f2
AJ
187 int64_t maxReplyBodySize_ = 0;
188 StoreEntry *entry_ = nullptr;
189 StoreEntry *loggingEntry_ = nullptr;
190 ConnStateData * conn_ = nullptr;
de31d06f 191
cb4f4424 192#if USE_OPENSSL
807ecef2 193public:
08097970
AR
194 /// returns raw sslBump mode value
195 Ssl::BumpMode sslBumpNeed() const { return sslBumpNeed_; }
196 /// returns true if and only if the request needs to be bumped
5d65362c 197 bool sslBumpNeeded() const { return sslBumpNeed_ == Ssl::bumpServerFirst || sslBumpNeed_ == Ssl::bumpClientFirst || sslBumpNeed_ == Ssl::bumpBump || sslBumpNeed_ == Ssl::bumpPeek || sslBumpNeed_ == Ssl::bumpStare; }
e0c0d54c 198 /// set the sslBumpNeeded state
1d1457f2 199 void sslBumpNeed(Ssl::BumpMode);
807ecef2 200 void sslBumpStart();
1d1457f2
AJ
201 void sslBumpEstablish(Comm::Flag);
202
203private:
204 /// whether (and how) the request needs to be bumped
205 Ssl::BumpMode sslBumpNeed_ = Ssl::bumpEnd;
807ecef2 206#endif
207
a83c6ed6 208#if USE_ADAPTATION
de31d06f 209public:
1d1457f2 210 void startAdaptation(const Adaptation::ServiceGroupPointer &);
940307b9 211 bool requestSatisfactionMode() const { return request_satisfaction_mode; }
9d4d7c5e 212
1d1457f2 213 /* AsyncJob API */
337b9aa4 214 bool doneAll() const override {
1d1457f2
AJ
215 return Initiator::doneAll() &&
216 BodyConsumer::doneAll() &&
217 false; // TODO: Refactor into a proper AsyncJob
218 }
337b9aa4 219 void callException(const std::exception &) override;
1d1457f2 220
32fd6d8a 221private:
f53969cc 222 /// Handles an adaptation client request failure.
32fd6d8a 223 /// Bypasses the error if possible, or build an error reply.
1d1457f2 224 void handleAdaptationFailure(const ErrorDetail::Pointer &, bool bypassable = false);
5f8252d2 225
1d1457f2
AJ
226 void handleAdaptedHeader(Http::Message *);
227 void handleAdaptationBlock(const Adaptation::Answer &);
5f8252d2 228
1d1457f2 229 /* Adaptation::Initiator API */
337b9aa4
AR
230 void noteAdaptationAclCheckDone(Adaptation::ServiceGroupPointer) override;
231 void noteAdaptationAnswer(const Adaptation::Answer &) override;
1d1457f2
AJ
232
233 /* BodyConsumer API */
337b9aa4
AR
234 void noteMoreBodyDataAvailable(BodyPipe::Pointer) override;
235 void noteBodyProductionEnded(BodyPipe::Pointer) override;
236 void noteBodyProducerAborted(BodyPipe::Pointer) override;
5f8252d2 237
238 void endRequestSatisfaction();
0ad2b63b
CT
239 /// called by StoreEntry when it has more buffer space available
240 void resumeBodyStorage();
5f8252d2 241
242private:
4299f876 243 CbcPointer<Adaptation::Initiate> virginHeadSource;
a83c6ed6 244 BodyPipe::Pointer adaptedBodySource;
5f8252d2 245
ba3fe8d9 246 /// noteBodyProductionEnded() was called
1d1457f2 247 bool receivedWholeAdaptedReply = false;
ba3fe8d9 248
1d1457f2
AJ
249 bool request_satisfaction_mode = false;
250 int64_t request_satisfaction_offset = 0;
de31d06f 251#endif
528b2c61 252};
253
254/* client http based routines */
8a648e8d 255char *clientConstructTraceEcho(ClientHttpRequest *);
c0941a6a 256
c56edb4a 257ACLFilledChecklist::MakingPointer clientAclChecklistCreate(const acl_access *, ClientHttpRequest *);
819be284 258void clientAclChecklistFill(ACLFilledChecklist &, ClientHttpRequest *);
8a648e8d 259void clientAccessCheck(ClientHttpRequest *);
528b2c61 260
261/* ones that should be elsewhere */
ac9f46af 262void tunnelStart(ClientHttpRequest *);
528b2c61 263
ff9d9458 264#endif /* SQUID_SRC_CLIENT_SIDE_REQUEST_H */