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