5 * SQUID Web Proxy Cache http://www.squid-cache.org/
6 * ----------------------------------------------------------
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.
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.
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.
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.
33 #ifndef SQUID_CLIENTSIDE_H
34 #define SQUID_CLIENTSIDE_H
37 #include "StoreIOBuffer.h"
40 #include "base/AsyncJob.h"
41 #include "CommCalls.h"
45 class ClientHttpRequest
;
47 class clientStreamNode
;
49 class AuthUserRequest
;
51 class ChunkedCodingParser
;
57 class ClientSocketContext
: public RefCountable
61 typedef RefCount
<ClientSocketContext
> Pointer
;
62 void *operator new(size_t);
63 void operator delete(void *);
64 ClientSocketContext();
65 ~ClientSocketContext();
66 bool startOfOutput() const;
67 void writeComplete(int fd
, char *bufnotused
, size_t size
, comm_err_t errflag
);
68 void keepaliveNextRequest();
69 ClientHttpRequest
*http
; /* we own this */
71 char reqbuf
[HTTP_REQBUF_SZ
];
76 unsigned deferred
:1; /* This is a pipelined request waiting for the current object to complete */
78 unsigned parsed_ok
:1; /* Was this parsed correctly? */
80 bool mayUseConnection() const {return mayUseConnection_
;}
82 void mayUseConnection(bool aBool
) {
83 mayUseConnection_
= aBool
;
84 debug (33,3)("ClientSocketContext::mayUseConnection: This %p marked %d\n",
92 clientStreamNode
*node
;
94 StoreIOBuffer queuedBuffer
;
97 DeferredParams deferredparams
;
98 int64_t writtenToSocket
;
100 int64_t getNextRangeOffset() const;
101 bool canPackMoreRanges() const;
102 clientStream_status_t
socketState();
103 void sendBody(HttpReply
* rep
, StoreIOBuffer bodyData
);
104 void sendStartOfMessage(HttpReply
* rep
, StoreIOBuffer bodyData
);
105 size_t lengthToSend(Range
<int64_t> const &available
);
106 void noteSentBodyBytes(size_t);
107 void buildRangeHeader(HttpReply
* rep
);
109 clientStreamNode
* getTail() const;
110 clientStreamNode
* getClientReplyContext() const;
111 void connIsFinished();
112 void removeFromConnectionList(ConnStateData
* conn
);
113 void deferRecipientForLater(clientStreamNode
* node
, HttpReply
* rep
, StoreIOBuffer receivedData
);
114 bool multipartRangeRequest() const;
115 void registerWithConn();
118 CBDATA_CLASS(ClientSocketContext
);
119 void prepareReply(HttpReply
* rep
);
120 void packRange(StoreIOBuffer
const &, MemBuf
* mb
);
121 void deRegisterWithConn();
123 void initiateClose(const char *reason
);
124 bool mayUseConnection_
; /* This request may use the connection. Don't read anymore requests for now */
125 bool connRegistered_
;
128 /** A connection to a socket */
129 class ConnStateData
: public BodyProducer
/*, public RefCountable*/
138 int getAvailableBufferLength() const;
139 bool areAllContextsForThisConnection() const;
140 void freeAllContexts();
141 void readNextRequest();
142 void makeSpaceAvailable();
143 ClientSocketContext::Pointer
getCurrentContext() const;
144 void addContextToQueue(ClientSocketContext
* context
);
145 int getConcurrentRequestCount() const;
150 /// chunk buffering and parsing algorithm state
151 typedef enum { chunkUnknown
, chunkNone
, chunkParsing
, chunkReady
, chunkError
} DechunkingState
;
156 char *addressToReadInto() const;
158 ChunkedCodingParser
*bodyParser
; ///< parses chunked request body
159 MemBuf chunked
; ///< contains unparsed raw (chunked) body data
160 MemBuf dechunked
; ///< accumulates parsed (dechunked) content
163 size_t allocatedSize
;
164 size_t chunkedSeen
; ///< size of processed or ignored raw read data
165 DechunkingState dechunkingState
; ///< request dechunking state
168 int64_t bodySizeLeft();
171 * Is this connection based authentication? if so what type it
174 auth_type_t auth_type
;
177 * note this is ONLY connection based because NTLM is against HTTP spec.
178 * the user details for connection based authentication
180 AuthUserRequest
*auth_user_request
;
183 * used by the owner of the connection, opaque otherwise
184 * TODO: generalise the connection owner concept.
186 ClientSocketContext::Pointer currentobject
;
193 char rfc931
[USER_IDENT_SZ
];
197 bool readMoreRequests
;
198 bool swanSang
; // XXX: temporary flag to check proper cleanup
201 int fd
; /* pinned server side connection */
202 char *host
; /* host name of pinned connection */
203 int port
; /* port of pinned connection */
204 bool pinned
; /* this connection was pinned */
205 bool auth
; /* pinned for www authentication */
206 struct peer
*peer
; /* peer the connection goes via */
207 AsyncCall::Pointer closeHandler
; /*The close handler for pinned server side connection*/
210 http_port_list
*port
;
212 bool transparent() const;
213 void transparent(bool const);
214 bool reading() const;
215 void reading(bool const);
217 bool closing() const;
218 void startClosing(const char *reason
);
220 BodyPipe::Pointer
expectRequestBody(int64_t size
);
221 virtual void noteMoreBodySpaceAvailable(BodyPipe::Pointer
);
222 virtual void noteBodyConsumerAborted(BodyPipe::Pointer
);
224 void handleReadData(char *buf
, size_t size
);
225 void handleRequestBodyData();
228 * Correlate the current ConnStateData object with the pinning_fd socket descriptor.
230 void pinConnection(int fd
, HttpRequest
*request
, struct peer
*peer
, bool auth
);
232 * Decorrelate the ConnStateData object from its pinned peer
234 void unpinConnection();
236 * Checks if there is pinning info if it is valid. It can close the server side connection
237 * if pinned info is not valid.
238 \param request if it is not NULL also checks if the pinning info refers to the request client side HttpRequest
239 \param peer if it is not NULL also check if the peer is the pinning peer
240 \return The fd of the server side connection or -1 if fails.
242 int validatePinnedConnection(HttpRequest
*request
, const struct peer
*peer
=NULL
);
244 * returts the pinned peer if exists, NULL otherwise
246 struct peer
*pinnedPeer() const {return pinning
.peer
;}
247 bool pinnedAuth() const {return pinning
.auth
;}
249 // pining related comm callbacks
250 void clientPinnedConnectionClosed(const CommCloseCbParams
&io
);
253 void clientReadRequest(const CommIoCbParams
&io
);
254 void connStateClosed(const CommCloseCbParams
&io
);
255 void requestTimeout(const CommTimeoutCbParams
¶ms
);
258 virtual bool doneAll() const { return BodyProducer::doneAll() && false;}
259 virtual void swanSong();
262 bool switchToHttps();
263 bool switchedToHttps() const { return switchedToHttps_
; }
265 bool switchedToHttps() const { return false; }
268 void startDechunkingRequest(HttpParser
*hp
);
269 bool parseRequestChunks(HttpParser
*hp
);
270 void finishDechunkingRequest(HttpParser
*hp
);
273 int connReadWasError(comm_err_t flag
, int size
, int xerrno
);
274 int connFinishedWithConn(int size
);
275 void clientMaybeReadData(int do_next_read
);
276 void clientAfterReadingRequests(int do_next_read
);
279 CBDATA_CLASS2(ConnStateData
);
284 bool switchedToHttps_
;
285 BodyPipe::Pointer bodyPipe
; // set when we are reading request body
288 /* convenience class while splitting up body handling */
289 /* temporary existence only - on stack use expected */
291 void setLogUri(ClientHttpRequest
* http
, char const *uri
);
293 const char *findTrailingHTTPVersion(const char *uriAndHTTPVersion
, const char *end
= NULL
);
295 #endif /* SQUID_CLIENTSIDE_H */