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