2 * Copyright (C) 1996-2020 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_CLIENTSIDEREQUEST_H
10 #define SQUID_CLIENTSIDEREQUEST_H
12 #include "AccessLogEntry.h"
13 #include "acl/forward.h"
14 #include "client_side.h"
15 #include "clientStream.h"
16 #include "http/forward.h"
17 #include "HttpHeaderRange.h"
22 #include "adaptation/forward.h"
23 #include "adaptation/Initiator.h"
26 class ClientRequestContext
;
30 /* client_side_request.c - client side request related routines (pure logic) */
31 int clientBeginRequest(const HttpRequestMethod
&, char const *, CSCB
*, CSD
*, ClientStreamData
, HttpHeader
const *, char *, size_t, const MasterXactionPointer
&);
33 class ClientHttpRequest
35 : public Adaptation::Initiator
, // to start adaptation transactions
36 public BodyConsumer
// to receive reply bodies in request satisf. mode
39 CBDATA_CLASS(ClientHttpRequest
);
42 ClientHttpRequest(ConnStateData
*csd
);
44 /* Not implemented - present to prevent synthetic operations */
45 ClientHttpRequest(ClientHttpRequest
const &);
46 ClientHttpRequest
& operator=(ClientHttpRequest
const &);
48 String
rangeBoundaryStr() const;
50 void updateCounters();
52 MemObject
* memObject() const {
53 return (storeEntry() ? storeEntry()->mem_obj
: nullptr);
55 bool multipartRangeRequest() const;
56 void processRequest();
58 bool onlyIfCached()const;
59 bool gotEnough() const;
60 StoreEntry
*storeEntry() const { return entry_
; }
61 void storeEntry(StoreEntry
*);
62 StoreEntry
*loggingEntry() const { return loggingEntry_
; }
63 void loggingEntry(StoreEntry
*);
65 ConnStateData
* getConn() const {
66 return (cbdataReferenceValid(conn_
) ? conn_
: nullptr);
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
*);
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
*);
79 /** Details of the client socket which produced us.
80 * Treat as read-only for the lifetime of this HTTP request.
82 Comm::ConnectionPointer clientConnection
;
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
;
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().
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.
101 String store_id
; /* StoreID for transactions where the request member is nil */
104 Out() : offset(0), size(0), headers_sz(0) {}
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.
112 /// Response header and body bytes written to the client connection.
114 /// Response header bytes written to the client connection.
115 /// Not to be confused with clientReplyContext::headers_sz.
119 HttpHdrRangeIter range_iter
; /* data for iterating thru range specs */
120 size_t req_sz
; /* raw request size on input, not current request size */
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.
126 AccessLogEntry::Pointer al
; ///< access.log entry
129 Flags() : accel(false), internal(false), done_copying(false) {}
137 Redirect() : status(Http::scNone
), location(NULL
) {}
139 Http::StatusCode status
;
144 dlink_list client_stream
;
145 int64_t mRangeCLen() const;
147 ClientRequestContext
*calloutContext
;
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.
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
);
162 /// Prepares to satisfy a Range request with a generated HTTP 206 response.
163 /// Initializes range_iter state to allow raw range_iter access.
164 /// \returns Content-Length value for the future response; never negative
165 int64_t prepPartialResponseGeneration();
167 /// Build an error reply. For use with the callouts.
168 void calloutsError(const err_type error
, const ErrorDetail::Pointer
&errDetail
);
170 /// if necessary, stores new error information (if any)
171 void updateError(const Error
&error
);
174 // AsyncJob virtual methods
175 virtual bool doneAll() const {
176 return Initiator::doneAll() &&
177 BodyConsumer::doneAll() && false;
179 virtual void callException(const std::exception
&ex
);
183 /// assigns log_uri with aUri without copying the entire C-string
184 void absorbLogUri(char *aUri
);
185 /// resets the current request and log_uri to nil
187 /// initializes the current unassigned request to the virgin request
188 /// sets the current request, asserting that it was unset
189 void assignRequest(HttpRequest
*aRequest
);
191 int64_t maxReplyBodySize_
;
193 StoreEntry
*loggingEntry_
;
194 ConnStateData
* conn_
;
197 /// whether (and how) the request needs to be bumped
198 Ssl::BumpMode sslBumpNeed_
;
201 /// returns raw sslBump mode value
202 Ssl::BumpMode
sslBumpNeed() const { return sslBumpNeed_
; }
203 /// returns true if and only if the request needs to be bumped
204 bool sslBumpNeeded() const { return sslBumpNeed_
== Ssl::bumpServerFirst
|| sslBumpNeed_
== Ssl::bumpClientFirst
|| sslBumpNeed_
== Ssl::bumpBump
|| sslBumpNeed_
== Ssl::bumpPeek
|| sslBumpNeed_
== Ssl::bumpStare
; }
205 /// set the sslBumpNeeded state
206 void sslBumpNeed(Ssl::BumpMode mode
);
208 void sslBumpEstablish(Comm::Flag errflag
);
214 void startAdaptation(const Adaptation::ServiceGroupPointer
&g
);
215 bool requestSatisfactionMode() const { return request_satisfaction_mode
; }
218 /// Handles an adaptation client request failure.
219 /// Bypasses the error if possible, or build an error reply.
220 void handleAdaptationFailure(const ErrorDetail::Pointer
&errDetail
, bool bypassable
= false);
222 // Adaptation::Initiator API
223 virtual void noteAdaptationAnswer(const Adaptation::Answer
&answer
);
224 void handleAdaptedHeader(Http::Message
*msg
);
225 void handleAdaptationBlock(const Adaptation::Answer
&answer
);
226 virtual void noteAdaptationAclCheckDone(Adaptation::ServiceGroupPointer group
);
228 // BodyConsumer API, called by BodyPipe
229 virtual void noteMoreBodyDataAvailable(BodyPipe::Pointer
);
230 virtual void noteBodyProductionEnded(BodyPipe::Pointer
);
231 virtual void noteBodyProducerAborted(BodyPipe::Pointer
);
233 void endRequestSatisfaction();
234 /// called by StoreEntry when it has more buffer space available
235 void resumeBodyStorage();
238 CbcPointer
<Adaptation::Initiate
> virginHeadSource
;
239 BodyPipe::Pointer adaptedBodySource
;
241 bool request_satisfaction_mode
;
242 int64_t request_satisfaction_offset
;
246 /* client http based routines */
247 char *clientConstructTraceEcho(ClientHttpRequest
*);
249 ACLFilledChecklist
*clientAclChecklistCreate(const acl_access
* acl
,ClientHttpRequest
* http
);
250 void clientAclChecklistFill(ACLFilledChecklist
&, ClientHttpRequest
*);
251 int clientHttpRequestStatus(int fd
, ClientHttpRequest
const *http
);
252 void clientAccessCheck(ClientHttpRequest
*);
254 /* ones that should be elsewhere */
255 void tunnelStart(ClientHttpRequest
*);
257 #endif /* SQUID_CLIENTSIDEREQUEST_H */