]>
Commit | Line | Data |
---|---|---|
6039b729 | 1 | /* |
4893a72b FC |
2 | * DEBUG: section 33 Client-side Routines |
3 | * AUTHOR: Duane Wessels | |
6039b729 | 4 | * |
5 | * SQUID Web Proxy Cache http://www.squid-cache.org/ | |
6 | * ---------------------------------------------------------- | |
7 | * | |
8 | * Squid is the result of efforts by numerous individuals from | |
9 | * the Internet community; see the CONTRIBUTORS file for full | |
10 | * details. Many organizations have provided support for Squid's | |
11 | * development; see the SPONSORS file for full details. Squid is | |
12 | * Copyrighted (C) 2001 by the Regents of the University of | |
13 | * California; see the COPYRIGHT file for full details. Squid | |
14 | * incorporates software developed and/or copyrighted by other | |
15 | * sources; see the CREDITS file for full details. | |
16 | * | |
17 | * This program is free software; you can redistribute it and/or modify | |
18 | * it under the terms of the GNU General Public License as published by | |
19 | * the Free Software Foundation; either version 2 of the License, or | |
20 | * (at your option) any later version. | |
9e008dda | 21 | * |
6039b729 | 22 | * This program is distributed in the hope that it will be useful, |
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
25 | * GNU General Public License for more details. | |
9e008dda | 26 | * |
6039b729 | 27 | * You should have received a copy of the GNU General Public License |
28 | * along with this program; if not, write to the Free Software | |
29 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. | |
30 | * | |
31 | */ | |
32 | ||
33 | #ifndef SQUID_CLIENTSIDE_H | |
34 | #define SQUID_CLIENTSIDE_H | |
35 | ||
a98c2da5 | 36 | #include "comm.h" |
655daa06 | 37 | #include "HttpControlMsg.h" |
4c14658e | 38 | #include "HttpParser.h" |
c34e0177 | 39 | #include "SBuf.h" |
582c2af2 FC |
40 | #if USE_AUTH |
41 | #include "auth/UserRequest.h" | |
42 | #endif | |
cb4f4424 | 43 | #if USE_OPENSSL |
061bbdec CT |
44 | #include "ssl/support.h" |
45 | #endif | |
0655fa4d | 46 | |
47 | class ConnStateData; | |
0655fa4d | 48 | class ClientHttpRequest; |
0655fa4d | 49 | class clientStreamNode; |
3ff65596 | 50 | class ChunkedCodingParser; |
e166785a | 51 | class HelperReply; |
e4a14600 A |
52 | namespace AnyP |
53 | { | |
54 | class PortCfg; | |
42e3ce76 | 55 | } // namespace Anyp |
3ff65596 | 56 | |
27774cee AJ |
57 | /** |
58 | * Badly named. | |
59 | * This is in fact the processing context for a single HTTP request. | |
60 | * | |
61 | * Managing what has been done, and what happens next to the data buffer | |
62 | * holding what we hope is an HTTP request. | |
63 | * | |
64 | * Parsing is still a mess of global functions done in conjunction with the | |
65 | * real socket controller which generated ClientHttpRequest. | |
66 | * It also generates one of us and passes us control from there based on | |
67 | * the results of the parse. | |
68 | * | |
69 | * After that all the request interpretation and adaptation is in our scope. | |
70 | * Then finally the reply fetcher is created by this and we get the result | |
71 | * back. Which we then have to manage writing of it to the ConnStateData. | |
72 | * | |
73 | * The socket level management is done by a ConnStateData which owns us. | |
74 | * The scope of this objects control over a socket consists of the data | |
75 | * buffer received from ConnStateData with an initially unknown length. | |
76 | * When that length is known it sets the end bounary of our acces to the | |
77 | * buffer. | |
78 | * | |
79 | * The individual processing actions are done by other Jobs which we | |
80 | * kick off as needed. | |
e3b6f153 AR |
81 | * |
82 | * XXX: If an async call ends the ClientHttpRequest job, ClientSocketContext | |
83 | * (and ConnStateData) may not know about it, leading to segfaults and | |
84 | * assertions like areAllContextsForThisConnection(). This is difficult to fix | |
85 | * because ClientHttpRequest lacks a good way to communicate its ongoing | |
86 | * destruction back to the ClientSocketContext which pretends to "own" *http. | |
27774cee | 87 | */ |
0655fa4d | 88 | class ClientSocketContext : public RefCountable |
89 | { | |
90 | ||
91 | public: | |
92 | typedef RefCount<ClientSocketContext> Pointer; | |
bead5d2c | 93 | ClientSocketContext(const Comm::ConnectionPointer &aConn, ClientHttpRequest *aReq); |
0655fa4d | 94 | ~ClientSocketContext(); |
95 | bool startOfOutput() const; | |
c8407295 | 96 | void writeComplete(const Comm::ConnectionPointer &conn, char *bufnotused, size_t size, Comm::Flag errflag); |
0655fa4d | 97 | void keepaliveNextRequest(); |
be364179 AJ |
98 | |
99 | Comm::ConnectionPointer clientConnection; /// details about the client connection socket. | |
e3b6f153 | 100 | ClientHttpRequest *http; /* we pretend to own that job */ |
fedd1531 | 101 | HttpReply *reply; |
0655fa4d | 102 | char reqbuf[HTTP_REQBUF_SZ]; |
103 | Pointer next; | |
104 | ||
9e008dda | 105 | struct { |
0655fa4d | 106 | |
9e008dda | 107 | unsigned deferred:1; /* This is a pipelined request waiting for the current object to complete */ |
0655fa4d | 108 | |
9e008dda | 109 | unsigned parsed_ok:1; /* Was this parsed correctly? */ |
2fadd50d | 110 | } flags; |
0655fa4d | 111 | bool mayUseConnection() const {return mayUseConnection_;} |
112 | ||
9e008dda | 113 | void mayUseConnection(bool aBool) { |
0655fa4d | 114 | mayUseConnection_ = aBool; |
96e03dd8 | 115 | debugs(33,3, HERE << "This " << this << " marked " << aBool); |
0655fa4d | 116 | } |
117 | ||
7d9b0628 | 118 | class DeferredParams |
0655fa4d | 119 | { |
7d9b0628 | 120 | |
121 | public: | |
0655fa4d | 122 | clientStreamNode *node; |
123 | HttpReply *rep; | |
124 | StoreIOBuffer queuedBuffer; | |
7d9b0628 | 125 | }; |
0655fa4d | 126 | |
7d9b0628 | 127 | DeferredParams deferredparams; |
57d55dfa | 128 | int64_t writtenToSocket; |
0655fa4d | 129 | void pullData(); |
47f6e231 | 130 | int64_t getNextRangeOffset() const; |
0655fa4d | 131 | bool canPackMoreRanges() const; |
132 | clientStream_status_t socketState(); | |
133 | void sendBody(HttpReply * rep, StoreIOBuffer bodyData); | |
134 | void sendStartOfMessage(HttpReply * rep, StoreIOBuffer bodyData); | |
47f6e231 | 135 | size_t lengthToSend(Range<int64_t> const &available); |
0655fa4d | 136 | void noteSentBodyBytes(size_t); |
137 | void buildRangeHeader(HttpReply * rep); | |
0655fa4d | 138 | clientStreamNode * getTail() const; |
139 | clientStreamNode * getClientReplyContext() const; | |
140 | void connIsFinished(); | |
1cf238db | 141 | void removeFromConnectionList(ConnStateData * conn); |
2324cda2 | 142 | void deferRecipientForLater(clientStreamNode * node, HttpReply * rep, StoreIOBuffer receivedData); |
0655fa4d | 143 | bool multipartRangeRequest() const; |
0655fa4d | 144 | void registerWithConn(); |
f692498b | 145 | void noteIoError(const int xerrno); ///< update state to reflect I/O error |
0655fa4d | 146 | |
655daa06 AR |
147 | /// starts writing 1xx control message to the client |
148 | void writeControlMsg(HttpControlMsg &msg); | |
149 | ||
150 | protected: | |
1b76e6c1 | 151 | static IOCB WroteControlMsg; |
c8407295 | 152 | void wroteControlMsg(const Comm::ConnectionPointer &conn, char *bufnotused, size_t size, Comm::Flag errflag, int xerrno); |
655daa06 | 153 | |
0655fa4d | 154 | private: |
0655fa4d | 155 | void prepareReply(HttpReply * rep); |
4ad60609 | 156 | void packChunk(const StoreIOBuffer &bodyData, MemBuf &mb); |
2512d159 | 157 | void packRange(StoreIOBuffer const &, MemBuf * mb); |
0655fa4d | 158 | void deRegisterWithConn(); |
55e44db9 | 159 | void doClose(); |
5f8252d2 | 160 | void initiateClose(const char *reason); |
655daa06 AR |
161 | |
162 | AsyncCall::Pointer cbControlMsgSent; ///< notifies HttpControlMsg Source | |
163 | ||
0655fa4d | 164 | bool mayUseConnection_; /* This request may use the connection. Don't read anymore requests for now */ |
165 | bool connRegistered_; | |
c7bf588b | 166 | |
f49c09b2 | 167 | CBDATA_CLASS2(ClientSocketContext); |
0655fa4d | 168 | }; |
169 | ||
a98c2da5 | 170 | class ConnectionDetail; |
cb4f4424 | 171 | #if USE_OPENSSL |
87f237a9 A |
172 | namespace Ssl |
173 | { | |
174 | class ServerBump; | |
061bbdec CT |
175 | } |
176 | #endif | |
27774cee AJ |
177 | /** |
178 | * Manages a connection to a client. | |
179 | * | |
079a8480 | 180 | * Multiple requests (up to pipeline_prefetch) can be pipelined. This object is responsible for managing |
27774cee AJ |
181 | * which one is currently being fulfilled and what happens to the queue if the current one |
182 | * causes the client connection to be closed early. | |
183 | * | |
184 | * Act as a manager for the connection and passes data in buffer to the current parser. | |
185 | * the parser has ambiguous scope at present due to being made from global functions | |
186 | * I believe this object uses the parser to identify boundaries and kick off the | |
187 | * actual HTTP request handling objects (ClientSocketContext, ClientHttpRequest, HttpRequest) | |
188 | * | |
189 | * If the above can be confirmed accurate we can call this object PipelineManager or similar | |
190 | */ | |
655daa06 | 191 | class ConnStateData : public BodyProducer, public HttpControlMsgSink |
6039b729 | 192 | { |
193 | ||
194 | public: | |
94bfd31f | 195 | explicit ConnStateData(const MasterXaction::Pointer &xact); |
6039b729 | 196 | ~ConnStateData(); |
197 | ||
198 | void readSomeData(); | |
6039b729 | 199 | bool areAllContextsForThisConnection() const; |
200 | void freeAllContexts(); | |
f692498b | 201 | void notifyAllContexts(const int xerrno); ///< tell everybody about the err |
4959e21e | 202 | /// Traffic parsing |
f35961af | 203 | bool clientParseRequests(); |
6039b729 | 204 | void readNextRequest(); |
0655fa4d | 205 | ClientSocketContext::Pointer getCurrentContext() const; |
206 | void addContextToQueue(ClientSocketContext * context); | |
207 | int getConcurrentRequestCount() const; | |
a2ac85d9 | 208 | bool isOpen() const; |
39cb8c41 | 209 | void checkHeaderLimits(); |
6039b729 | 210 | |
655daa06 AR |
211 | // HttpControlMsgSink API |
212 | virtual void sendControlMsg(HttpControlMsg msg); | |
6039b729 | 213 | |
5c336a3b | 214 | // Client TCP connection details from comm layer. |
73c36fd9 | 215 | Comm::ConnectionPointer clientConnection; |
6039b729 | 216 | |
9e008dda | 217 | struct In { |
6039b729 | 218 | In(); |
219 | ~In(); | |
8a64f7f1 | 220 | bool maybeMakeSpaceAvailable(); |
3ff65596 | 221 | |
e1381638 | 222 | ChunkedCodingParser *bodyParser; ///< parses chunked request body |
e7287625 | 223 | SBuf buf; |
0b86805b | 224 | } in; |
6039b729 | 225 | |
39cb8c41 AR |
226 | /** number of body bytes we need to comm_read for the "current" request |
227 | * | |
228 | * \retval 0 We do not need to read any [more] body bytes | |
229 | * \retval negative May need more but do not know how many; could be zero! | |
230 | * \retval positive Need to read exactly that many more body bytes | |
231 | */ | |
232 | int64_t mayNeedToReadMoreBody() const; | |
3b299123 | 233 | |
2f1431ea | 234 | #if USE_AUTH |
63be0a78 | 235 | /** |
cc1e110a AJ |
236 | * Fetch the user details for connection based authentication |
237 | * NOTE: this is ONLY connection based because NTLM and Negotiate is against HTTP spec. | |
3b299123 | 238 | */ |
cc1e110a AJ |
239 | const Auth::UserRequest::Pointer &getAuth() const { return auth_; } |
240 | ||
241 | /** | |
242 | * Set the user details for connection-based authentication to use from now until connection closure. | |
243 | * | |
244 | * Any change to existing credentials shows that something invalid has happened. Such as: | |
245 | * - NTLM/Negotiate auth was violated by the per-request headers missing a revalidation token | |
246 | * - NTLM/Negotiate auth was violated by the per-request headers being for another user | |
247 | * - SSL-Bump CONNECT tunnel with persistent credentials has ended | |
248 | */ | |
249 | void setAuth(const Auth::UserRequest::Pointer &aur, const char *cause); | |
2f1431ea | 250 | #endif |
63be0a78 | 251 | |
252 | /** | |
3b299123 | 253 | * used by the owner of the connection, opaque otherwise |
254 | * TODO: generalise the connection owner concept. | |
255 | */ | |
256 | ClientSocketContext::Pointer currentobject; | |
6039b729 | 257 | |
b7ac5457 | 258 | Ip::Address log_addr; |
6039b729 | 259 | int nrequests; |
260 | ||
9e008dda | 261 | struct { |
f35961af | 262 | bool readMore; ///< needs comm_read (for this request or new requests) |
6e1d409c | 263 | bool swanSang; // XXX: temporary flag to check proper cleanup |
2fadd50d | 264 | } flags; |
d67acb4e | 265 | struct { |
73c36fd9 | 266 | Comm::ConnectionPointer serverConnection; /* pinned server side connection */ |
d67acb4e AJ |
267 | char *host; /* host name of pinned connection */ |
268 | int port; /* port of pinned connection */ | |
269 | bool pinned; /* this connection was pinned */ | |
270 | bool auth; /* pinned for www authentication */ | |
693cb033 | 271 | bool zeroReply; ///< server closed w/o response (ERR_ZERO_SIZE_OBJECT) |
a3c6762c | 272 | CachePeer *peer; /* CachePeer the connection goes via */ |
7ac40923 | 273 | AsyncCall::Pointer readHandler; ///< detects serverConnection closure |
9e008dda AJ |
274 | AsyncCall::Pointer closeHandler; /*The close handler for pinned server side connection*/ |
275 | } pinning; | |
d67acb4e | 276 | |
94bfd31f | 277 | /// Squid listening port details where this connection arrived. |
fa720bfb | 278 | AnyP::PortCfgPointer port; |
6039b729 | 279 | |
280 | bool transparent() const; | |
6039b729 | 281 | bool reading() const; |
f84dd7eb | 282 | void stopReading(); ///< cancels comm_read if it is scheduled |
5f8252d2 | 283 | |
cf6eb29e CT |
284 | /// true if we stopped receiving the request |
285 | const char *stoppedReceiving() const { return stoppedReceiving_; } | |
286 | /// true if we stopped sending the response | |
287 | const char *stoppedSending() const { return stoppedSending_; } | |
288 | /// note request receiving error and close as soon as we write the response | |
289 | void stopReceiving(const char *error); | |
290 | /// note response sending error and close as soon as we read the request | |
291 | void stopSending(const char *error); | |
292 | ||
eb44b2d7 | 293 | void expectNoForwarding(); ///< cleans up virgin request [body] forwarding state |
6039b729 | 294 | |
3e62bd58 | 295 | BodyPipe::Pointer expectRequestBody(int64_t size); |
1cf238db | 296 | virtual void noteMoreBodySpaceAvailable(BodyPipe::Pointer); |
297 | virtual void noteBodyConsumerAborted(BodyPipe::Pointer); | |
5f8252d2 | 298 | |
7e66d5e2 | 299 | bool handleReadData(); |
39cb8c41 | 300 | bool handleRequestBodyData(); |
0b86805b | 301 | |
d67acb4e AJ |
302 | /** |
303 | * Correlate the current ConnStateData object with the pinning_fd socket descriptor. | |
304 | */ | |
a3c6762c | 305 | void pinConnection(const Comm::ConnectionPointer &pinServerConn, HttpRequest *request, CachePeer *peer, bool auth); |
d67acb4e | 306 | /** |
a3c6762c | 307 | * Decorrelate the ConnStateData object from its pinned CachePeer |
d67acb4e | 308 | */ |
9e008dda | 309 | void unpinConnection(); |
d67acb4e AJ |
310 | /** |
311 | * Checks if there is pinning info if it is valid. It can close the server side connection | |
312 | * if pinned info is not valid. | |
313 | \param request if it is not NULL also checks if the pinning info refers to the request client side HttpRequest | |
a3c6762c | 314 | \param CachePeer if it is not NULL also check if the CachePeer is the pinning CachePeer |
e3a4aecc | 315 | \return The details of the server side connection (may be closed if failures were present). |
d67acb4e | 316 | */ |
a3c6762c | 317 | const Comm::ConnectionPointer validatePinnedConnection(HttpRequest *request, const CachePeer *peer); |
d67acb4e | 318 | /** |
a3c6762c | 319 | * returts the pinned CachePeer if exists, NULL otherwise |
d67acb4e | 320 | */ |
a3c6762c | 321 | CachePeer *pinnedPeer() const {return pinning.peer;} |
d67acb4e AJ |
322 | bool pinnedAuth() const {return pinning.auth;} |
323 | ||
324 | // pining related comm callbacks | |
325 | void clientPinnedConnectionClosed(const CommCloseCbParams &io); | |
326 | ||
1cf238db | 327 | // comm callbacks |
328 | void clientReadRequest(const CommIoCbParams &io); | |
329 | void connStateClosed(const CommCloseCbParams &io); | |
330 | void requestTimeout(const CommTimeoutCbParams ¶ms); | |
331 | ||
332 | // AsyncJob API | |
6658cc16 | 333 | virtual void start(); |
1cf238db | 334 | virtual bool doneAll() const { return BodyProducer::doneAll() && false;} |
6e1d409c | 335 | virtual void swanSong(); |
1cf238db | 336 | |
84c77748 AR |
337 | /// Changes state so that we close the connection and quit after serving |
338 | /// the client-side-detected error response instead of getting stuck. | |
339 | void quitAfterError(HttpRequest *request); // meant to be private | |
340 | ||
7ac40923 AR |
341 | /// The caller assumes responsibility for connection closure detection. |
342 | void stopPinnedConnectionMonitoring(); | |
343 | ||
cb4f4424 | 344 | #if USE_OPENSSL |
fd4624d7 | 345 | /// called by FwdState when it is done bumping the server |
d7ce0bcd AR |
346 | void httpsPeeked(Comm::ConnectionPointer serverConnection); |
347 | ||
95d2589c | 348 | /// Start to create dynamic SSL_CTX for host or uses static port SSL context. |
1ce2822d | 349 | void getSslContextStart(); |
95d2589c CT |
350 | /** |
351 | * Done create dynamic ssl certificate. | |
352 | * | |
353 | * \param[in] isNew if generated certificate is new, so we need to add this certificate to storage. | |
354 | */ | |
1ce2822d | 355 | void getSslContextDone(SSL_CTX * sslContext, bool isNew = false); |
95d2589c | 356 | /// Callback function. It is called when squid receive message from ssl_crtd. |
e166785a | 357 | static void sslCrtdHandleReplyWrapper(void *data, const HelperReply &reply); |
95d2589c | 358 | /// Proccess response from ssl_crtd. |
e166785a | 359 | void sslCrtdHandleReply(const HelperReply &reply); |
95d2589c | 360 | |
caf3666d | 361 | void switchToHttps(HttpRequest *request, Ssl::BumpMode bumpServerMode); |
ae7ff0b8 | 362 | bool switchedToHttps() const { return switchedToHttps_; } |
fd4624d7 | 363 | Ssl::ServerBump *serverBump() {return sslServerBump;} |
38450a50 CT |
364 | inline void setServerBump(Ssl::ServerBump *srvBump) { |
365 | if (!sslServerBump) | |
366 | sslServerBump = srvBump; | |
367 | else | |
368 | assert(sslServerBump == srvBump); | |
369 | } | |
fb2178bb CT |
370 | /// Fill the certAdaptParams with the required data for certificate adaptation |
371 | /// and create the key for storing/retrieve the certificate to/from the cache | |
06997a38 | 372 | void buildSslCertGenerationParams(Ssl::CertificateProperties &certProperties); |
7a957a93 AR |
373 | /// Called when the client sends the first request on a bumped connection. |
374 | /// Returns false if no [delayed] error should be written to the client. | |
375 | /// Otherwise, writes the error to the client and returns true. Also checks | |
376 | /// for SQUID_X509_V_ERR_DOMAIN_MISMATCH on bumped requests. | |
8eb0a7ee | 377 | bool serveDelayedError(ClientSocketContext *context); |
08097970 AR |
378 | |
379 | Ssl::BumpMode sslBumpMode; ///< ssl_bump decision (Ssl::bumpEnd if n/a). | |
380 | ||
ae7ff0b8 | 381 | #else |
382 | bool switchedToHttps() const { return false; } | |
383 | #endif | |
384 | ||
457857fe CT |
385 | /* clt_conn_tag=tag annotation access */ |
386 | const SBuf &connectionTag() const { return connectionTag_; } | |
387 | void connectionTag(const char *aTag) { connectionTag_ = aTag; } | |
388 | ||
39cb8c41 AR |
389 | protected: |
390 | void startDechunkingRequest(); | |
391 | void finishDechunkingRequest(bool withSuccess); | |
392 | void abortChunkedRequestBody(const err_type error); | |
393 | err_type handleChunkedRequestBody(size_t &putSize); | |
3ff65596 | 394 | |
7ac40923 AR |
395 | void startPinnedConnectionMonitoring(); |
396 | void clientPinnedConnectionRead(const CommIoCbParams &io); | |
397 | ||
1cf238db | 398 | private: |
1cf238db | 399 | int connFinishedWithConn(int size); |
f35961af | 400 | void clientAfterReadingRequests(); |
079a8480 | 401 | bool concurrentRequestQueueFilled() const; |
1cf238db | 402 | |
00d0ce87 | 403 | /* PROXY protocol functionality */ |
6658cc16 | 404 | bool proxyProtocolValidateClient(); |
3d74cb1f | 405 | bool parseProxyProtocolHeader(); |
70a16fea AJ |
406 | bool parseProxy1p0(); |
407 | bool parseProxy2p0(); | |
3bd97e7e | 408 | bool proxyProtocolError(const char *reason = NULL); |
00d0ce87 | 409 | |
3bd97e7e | 410 | /// whether PROXY protocol header is still expected |
00d0ce87 AJ |
411 | bool needProxyProtocolHeader_; |
412 | ||
cc1e110a AJ |
413 | #if USE_AUTH |
414 | /// some user details that can be used to perform authentication on this connection | |
415 | Auth::UserRequest::Pointer auth_; | |
416 | #endif | |
417 | ||
4959e21e | 418 | HttpParser parser_; |
89aec9b6 | 419 | |
4959e21e | 420 | // XXX: CBDATA plays with public/private and leaves the following 'private' fields all public... :( |
1cf238db | 421 | |
cb4f4424 | 422 | #if USE_OPENSSL |
ae7ff0b8 | 423 | bool switchedToHttps_; |
fb2178bb CT |
424 | /// The SSL server host name appears in CONNECT request or the server ip address for the intercepted requests |
425 | String sslConnectHostOrIp; ///< The SSL server host name as passed in the CONNECT request | |
426 | String sslCommonName; ///< CN name for SSL certificate generation | |
427 | String sslBumpCertKey; ///< Key to use to store/retrieve generated certificate | |
d7ce0bcd | 428 | |
fd4624d7 CT |
429 | /// HTTPS server cert. fetching state for bump-ssl-server-first |
430 | Ssl::ServerBump *sslServerBump; | |
aebe6888 | 431 | Ssl::CertSignAlgorithm signAlgorithm; ///< The signing algorithm to use |
d7ce0bcd AR |
432 | #endif |
433 | ||
cf6eb29e CT |
434 | /// the reason why we no longer write the response or nil |
435 | const char *stoppedSending_; | |
436 | /// the reason why we no longer read the request or nil | |
437 | const char *stoppedReceiving_; | |
438 | ||
f84dd7eb | 439 | AsyncCall::Pointer reader; ///< set when we are reading |
5f8252d2 | 440 | BodyPipe::Pointer bodyPipe; // set when we are reading request body |
c7bf588b | 441 | |
457857fe CT |
442 | SBuf connectionTag_; ///< clt_conn_tag=Tag annotation for client connection |
443 | ||
c7bf588b | 444 | CBDATA_CLASS2(ConnStateData); |
6039b729 | 445 | }; |
446 | ||
727552f4 | 447 | void setLogUri(ClientHttpRequest * http, char const *uri, bool cleanUrl = false); |
de31d06f | 448 | |
8596962e | 449 | const char *findTrailingHTTPVersion(const char *uriAndHTTPVersion, const char *end = NULL); |
450 | ||
8a648e8d | 451 | int varyEvaluateMatch(StoreEntry * entry, HttpRequest * req); |
4efc6056 | 452 | |
8a648e8d FC |
453 | void clientOpenListenSockets(void); |
454 | void clientHttpConnectionsClose(void); | |
455 | void httpRequestFree(void *); | |
93da1f99 | 456 | |
6039b729 | 457 | #endif /* SQUID_CLIENTSIDE_H */ |