]> git.ipfire.org Git - thirdparty/squid.git/blame - src/client_side_request.h
Detail client closures of CONNECT tunnels during TLS handshake (#691)
[thirdparty/squid.git] / src / client_side_request.h
CommitLineData
c8be6d7b 1/*
77b1029d 2 * Copyright (C) 1996-2020 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
9#ifndef SQUID_CLIENTSIDEREQUEST_H
10#define SQUID_CLIENTSIDEREQUEST_H
11
450e0c10 12#include "AccessLogEntry.h"
602d9612 13#include "acl/forward.h"
a2ac85d9 14#include "client_side.h"
602d9612 15#include "clientStream.h"
63df1d28 16#include "http/forward.h"
43ca19e0 17#include "HttpHeaderRange.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{
5c2f68b7 39 CBDATA_CLASS(ClientHttpRequest);
62e76326 40
528b2c61 41public:
be364179 42 ClientHttpRequest(ConnStateData *csd);
528b2c61 43 ~ClientHttpRequest();
44 /* Not implemented - present to prevent synthetic operations */
45 ClientHttpRequest(ClientHttpRequest const &);
46 ClientHttpRequest& operator=(ClientHttpRequest const &);
62e76326 47
30abd221 48 String rangeBoundaryStr() const;
528b2c61 49 void freeResources();
50 void updateCounters();
51 void logRequest();
1a6cca01
AJ
52 MemObject * memObject() const {
53 return (storeEntry() ? storeEntry()->mem_obj : nullptr);
54 }
528b2c61 55 bool multipartRangeRequest() const;
8e2745f4 56 void processRequest();
57 void httpStart();
0655fa4d 58 bool onlyIfCached()const;
59 bool gotEnough() const;
1a6cca01 60 StoreEntry *storeEntry() const { return entry_; }
86a2f789 61 void storeEntry(StoreEntry *);
1a6cca01 62 StoreEntry *loggingEntry() const { return loggingEntry_; }
0976f8db 63 void loggingEntry(StoreEntry *);
0655fa4d 64
1a6cca01
AJ
65 ConnStateData * getConn() const {
66 return (cbdataReferenceValid(conn_) ? conn_ : nullptr);
67 }
be364179 68
bec110e4
EB
69 /// Initializes the current request with the virgin request.
70 /// Call this method when the virgin request becomes known.
71 /// To update the current request later, use resetRequest().
72 void initRequest(HttpRequest *);
73
74 /// Resets the current request to the latest adapted or redirected
75 /// request. Call this every time adaptation or redirection changes
76 /// the request. To set the virgin request, use initRequest().
77 void resetRequest(HttpRequest *);
78
be364179
AJ
79 /** Details of the client socket which produced us.
80 * Treat as read-only for the lifetime of this HTTP request.
81 */
82 Comm::ConnectionPointer clientConnection;
83
bec110e4
EB
84 /// Request currently being handled by ClientHttpRequest.
85 /// Usually remains nil until the virgin request header is parsed or faked.
86 /// Starts as a virgin request; see initRequest().
87 /// Adaptation and redirections replace it; see resetRequest().
88 HttpRequest * const request;
89
90 /// Usually starts as a URI received from the client, with scheme and host
91 /// added if needed. Is used to create the virgin request for initRequest().
92 /// URIs of adapted/redirected requests replace it via resetRequest().
528b2c61 93 char *uri;
bec110e4
EB
94
95 // TODO: remove this field and store the URI directly in al->url
96 /// Cleaned up URI of the current (virgin or adapted/redirected) request,
97 /// computed URI of an internally-generated requests, or
98 /// one of the hard-coded "error:..." URIs.
99 char * const log_uri;
100
a8a0b1c2 101 String store_id; /* StoreID for transactions where the request member is nil */
62e76326 102
cc8c4af2
AJ
103 struct Out {
104 Out() : offset(0), size(0), headers_sz(0) {}
105
66d51f4f
AR
106 /// Roughly speaking, this offset points to the next body byte we want
107 /// to receive from Store. Without Ranges (and I/O errors), we should
108 /// have received (and written to the client) all the previous bytes.
109 /// XXX: The offset is updated by various receive-write steps, making
110 /// its exact meaning illusive. Its Out class placement is confusing.
47f6e231 111 int64_t offset;
66d51f4f 112 /// Response header and body bytes written to the client connection.
ac9f46af 113 uint64_t size;
66d51f4f
AR
114 /// Response header bytes written to the client connection.
115 /// Not to be confused with clientReplyContext::headers_sz.
62e76326 116 size_t headers_sz;
3d0ac046 117 } out;
62e76326 118
f53969cc
SM
119 HttpHdrRangeIter range_iter; /* data for iterating thru range specs */
120 size_t req_sz; /* raw request size on input, not current request size */
62e76326 121
02c8dde5
AJ
122 /// the processing tags associated with this request transaction.
123 // NP: still an enum so each stage altering it must take care when replacing it.
124 LogTags logType;
62e76326 125
41ebd397 126 AccessLogEntry::Pointer al; ///< access.log entry
62e76326 127
cc8c4af2 128 struct Flags {
7976fed3 129 Flags() : accel(false), internal(false), done_copying(false) {}
cc8c4af2 130
be4d35dc 131 bool accel;
be4d35dc
FC
132 bool internal;
133 bool done_copying;
3d0ac046 134 } flags;
62e76326 135
cc8c4af2
AJ
136 struct Redirect {
137 Redirect() : status(Http::scNone), location(NULL) {}
138
955394ce 139 Http::StatusCode status;
62e76326 140 char *location;
3d0ac046 141 } redirect;
62e76326 142
528b2c61 143 dlink_node active;
144 dlink_list client_stream;
145 int mRangeCLen();
62e76326 146
de31d06f 147 ClientRequestContext *calloutContext;
148 void doCallouts();
149
bec110e4
EB
150 // The three methods below prepare log_uri and friends for future logging.
151 // Call the best-fit method whenever the current request or its URI changes.
152
153 /// sets log_uri when we know the current request
154 void setLogUriToRequestUri();
155 /// sets log_uri to a parsed request URI when Squid fails to parse or
156 /// validate other request components, yielding no current request
157 void setLogUriToRawUri(const char *rawUri, const HttpRequestMethod &);
158 /// sets log_uri and uri to an internally-generated "error:..." URI when
159 /// neither the current request nor the parsed request URI are known
160 void setErrorUri(const char *errorUri);
161
32fd6d8a 162 /// Build an error reply. For use with the callouts.
83b053a0
CT
163 void calloutsError(const err_type error, const ErrorDetail::Pointer &errDetail);
164
165 /// if necessary, stores new error information (if any)
166 void updateError(const Error &error);
32fd6d8a 167
a83c6ed6
AR
168#if USE_ADAPTATION
169 // AsyncJob virtual methods
26ac0430
AJ
170 virtual bool doneAll() const {
171 return Initiator::doneAll() &&
172 BodyConsumer::doneAll() && false;
173 }
9d52ba11 174 virtual void callException(const std::exception &ex);
1cf238db 175#endif
176
528b2c61 177private:
bec110e4
EB
178 /// assigns log_uri with aUri without copying the entire C-string
179 void absorbLogUri(char *aUri);
180 /// resets the current request and log_uri to nil
181 void clearRequest();
182 /// initializes the current unassigned request to the virgin request
183 /// sets the current request, asserting that it was unset
184 void assignRequest(HttpRequest *aRequest);
185
47f6e231 186 int64_t maxReplyBodySize_;
86a2f789 187 StoreEntry *entry_;
0976f8db 188 StoreEntry *loggingEntry_;
1cf238db 189 ConnStateData * conn_;
de31d06f 190
cb4f4424 191#if USE_OPENSSL
caf3666d 192 /// whether (and how) the request needs to be bumped
08097970 193 Ssl::BumpMode sslBumpNeed_;
e0c0d54c 194
807ecef2 195public:
08097970
AR
196 /// returns raw sslBump mode value
197 Ssl::BumpMode sslBumpNeed() const { return sslBumpNeed_; }
198 /// returns true if and only if the request needs to be bumped
5d65362c 199 bool sslBumpNeeded() const { return sslBumpNeed_ == Ssl::bumpServerFirst || sslBumpNeed_ == Ssl::bumpClientFirst || sslBumpNeed_ == Ssl::bumpBump || sslBumpNeed_ == Ssl::bumpPeek || sslBumpNeed_ == Ssl::bumpStare; }
e0c0d54c 200 /// set the sslBumpNeeded state
08097970 201 void sslBumpNeed(Ssl::BumpMode mode);
807ecef2 202 void sslBumpStart();
c8407295 203 void sslBumpEstablish(Comm::Flag errflag);
807ecef2 204#endif
205
a83c6ed6 206#if USE_ADAPTATION
de31d06f 207
208public:
a22e6cd3 209 void startAdaptation(const Adaptation::ServiceGroupPointer &g);
940307b9 210 bool requestSatisfactionMode() const { return request_satisfaction_mode; }
9d4d7c5e 211
32fd6d8a 212private:
f53969cc 213 /// Handles an adaptation client request failure.
32fd6d8a 214 /// Bypasses the error if possible, or build an error reply.
83b053a0 215 void handleAdaptationFailure(const ErrorDetail::Pointer &errDetail, bool bypassable = false);
5f8252d2 216
16b8a262 217 // Adaptation::Initiator API
3af10ac0 218 virtual void noteAdaptationAnswer(const Adaptation::Answer &answer);
63df1d28 219 void handleAdaptedHeader(Http::Message *msg);
3af10ac0 220 void handleAdaptationBlock(const Adaptation::Answer &answer);
79628299 221 virtual void noteAdaptationAclCheckDone(Adaptation::ServiceGroupPointer group);
5f8252d2 222
223 // BodyConsumer API, called by BodyPipe
1cf238db 224 virtual void noteMoreBodyDataAvailable(BodyPipe::Pointer);
225 virtual void noteBodyProductionEnded(BodyPipe::Pointer);
226 virtual void noteBodyProducerAborted(BodyPipe::Pointer);
5f8252d2 227
228 void endRequestSatisfaction();
0ad2b63b
CT
229 /// called by StoreEntry when it has more buffer space available
230 void resumeBodyStorage();
5f8252d2 231
232private:
4299f876 233 CbcPointer<Adaptation::Initiate> virginHeadSource;
a83c6ed6 234 BodyPipe::Pointer adaptedBodySource;
5f8252d2 235
b044675d 236 bool request_satisfaction_mode;
57d55dfa 237 int64_t request_satisfaction_offset;
de31d06f 238#endif
528b2c61 239};
240
241/* client http based routines */
8a648e8d 242char *clientConstructTraceEcho(ClientHttpRequest *);
c0941a6a 243
8a648e8d 244ACLFilledChecklist *clientAclChecklistCreate(const acl_access * acl,ClientHttpRequest * http);
819be284 245void clientAclChecklistFill(ACLFilledChecklist &, ClientHttpRequest *);
8a648e8d
FC
246int clientHttpRequestStatus(int fd, ClientHttpRequest const *http);
247void clientAccessCheck(ClientHttpRequest *);
528b2c61 248
249/* ones that should be elsewhere */
ac9f46af 250void tunnelStart(ClientHttpRequest *);
528b2c61 251
c8be6d7b 252#endif /* SQUID_CLIENTSIDEREQUEST_H */
f53969cc 253