]> git.ipfire.org Git - thirdparty/squid.git/blob - src/client_side.h
a40f7f528dc427a4cd9c76679e5af597f5eda79b
[thirdparty/squid.git] / src / client_side.h
1 /*
2 * $Id$
3 *
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.
21 *
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.
26 *
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
36 #include "comm.h"
37 #include "StoreIOBuffer.h"
38 #include "BodyPipe.h"
39 #include "RefCount.h"
40 #include "base/AsyncJob.h"
41 #include "CommCalls.h"
42
43 class ConnStateData;
44
45 class ClientHttpRequest;
46
47 class clientStreamNode;
48
49 class AuthUserRequest;
50
51 class ChunkedCodingParser;
52 class HttpParser;
53
54 template <class T>
55 class Range;
56
57 class ClientSocketContext : public RefCountable
58 {
59
60 public:
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 */
70 HttpReply *reply;
71 char reqbuf[HTTP_REQBUF_SZ];
72 Pointer next;
73
74 struct {
75
76 unsigned deferred:1; /* This is a pipelined request waiting for the current object to complete */
77
78 unsigned parsed_ok:1; /* Was this parsed correctly? */
79 } flags;
80 bool mayUseConnection() const {return mayUseConnection_;}
81
82 void mayUseConnection(bool aBool) {
83 mayUseConnection_ = aBool;
84 debug (33,3)("ClientSocketContext::mayUseConnection: This %p marked %d\n",
85 this, aBool);
86 }
87
88 class DeferredParams
89 {
90
91 public:
92 clientStreamNode *node;
93 HttpReply *rep;
94 StoreIOBuffer queuedBuffer;
95 };
96
97 DeferredParams deferredparams;
98 int64_t writtenToSocket;
99 void pullData();
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);
108 int fd() const;
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();
116
117 private:
118 CBDATA_CLASS(ClientSocketContext);
119 void prepareReply(HttpReply * rep);
120 void packRange(StoreIOBuffer const &, MemBuf * mb);
121 void deRegisterWithConn();
122 void doClose();
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_;
126 };
127
128 /** A connection to a socket */
129 class ConnStateData : public BodyProducer/*, public RefCountable*/
130 {
131
132 public:
133
134 ConnStateData();
135 ~ConnStateData();
136
137 void readSomeData();
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;
146 bool isOpen() const;
147
148 int fd;
149
150 /// chunk buffering and parsing algorithm state
151 typedef enum { chunkUnknown, chunkNone, chunkParsing, chunkReady, chunkError } DechunkingState;
152
153 struct In {
154 In();
155 ~In();
156 char *addressToReadInto() const;
157
158 ChunkedCodingParser *bodyParser; ///< parses chunked request body
159 MemBuf chunked; ///< contains unparsed raw (chunked) body data
160 MemBuf dechunked; ///< accumulates parsed (dechunked) content
161 char *buf;
162 size_t notYetUsed;
163 size_t allocatedSize;
164 size_t chunkedSeen; ///< size of processed or ignored raw read data
165 DechunkingState dechunkingState; ///< request dechunking state
166 } in;
167
168 int64_t bodySizeLeft();
169
170 /**
171 * Is this connection based authentication? if so what type it
172 * is.
173 */
174 auth_type_t auth_type;
175
176 /**
177 * note this is ONLY connection based because NTLM is against HTTP spec.
178 * the user details for connection based authentication
179 */
180 AuthUserRequest *auth_user_request;
181
182 /**
183 * used by the owner of the connection, opaque otherwise
184 * TODO: generalise the connection owner concept.
185 */
186 ClientSocketContext::Pointer currentobject;
187
188 IpAddress peer;
189
190 IpAddress me;
191
192 IpAddress log_addr;
193 char rfc931[USER_IDENT_SZ];
194 int nrequests;
195
196 struct {
197 bool readMoreRequests;
198 bool swanSang; // XXX: temporary flag to check proper cleanup
199 } flags;
200 struct {
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*/
208 } pinning;
209
210 http_port_list *port;
211
212 bool transparent() const;
213 void transparent(bool const);
214 bool reading() const;
215 void reading(bool const);
216
217 bool closing() const;
218 void startClosing(const char *reason);
219
220 BodyPipe::Pointer expectRequestBody(int64_t size);
221 virtual void noteMoreBodySpaceAvailable(BodyPipe::Pointer);
222 virtual void noteBodyConsumerAborted(BodyPipe::Pointer);
223
224 void handleReadData(char *buf, size_t size);
225 void handleRequestBodyData();
226
227 /**
228 * Correlate the current ConnStateData object with the pinning_fd socket descriptor.
229 */
230 void pinConnection(int fd, HttpRequest *request, struct peer *peer, bool auth);
231 /**
232 * Decorrelate the ConnStateData object from its pinned peer
233 */
234 void unpinConnection();
235 /**
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.
241 */
242 int validatePinnedConnection(HttpRequest *request, const struct peer *peer=NULL);
243 /**
244 * returts the pinned peer if exists, NULL otherwise
245 */
246 struct peer *pinnedPeer() const {return pinning.peer;}
247 bool pinnedAuth() const {return pinning.auth;}
248
249 // pining related comm callbacks
250 void clientPinnedConnectionClosed(const CommCloseCbParams &io);
251
252 // comm callbacks
253 void clientReadRequest(const CommIoCbParams &io);
254 void connStateClosed(const CommCloseCbParams &io);
255 void requestTimeout(const CommTimeoutCbParams &params);
256
257 // AsyncJob API
258 virtual bool doneAll() const { return BodyProducer::doneAll() && false;}
259 virtual void swanSong();
260
261 #if USE_SSL
262 bool switchToHttps();
263 bool switchedToHttps() const { return switchedToHttps_; }
264 #else
265 bool switchedToHttps() const { return false; }
266 #endif
267
268 void startDechunkingRequest(HttpParser *hp);
269 bool parseRequestChunks(HttpParser *hp);
270 void finishDechunkingRequest(HttpParser *hp);
271
272 private:
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);
277
278 private:
279 CBDATA_CLASS2(ConnStateData);
280 bool transparent_;
281 bool reading_;
282 bool closing_;
283
284 bool switchedToHttps_;
285 BodyPipe::Pointer bodyPipe; // set when we are reading request body
286 };
287
288 /* convenience class while splitting up body handling */
289 /* temporary existence only - on stack use expected */
290
291 void setLogUri(ClientHttpRequest * http, char const *uri);
292
293 const char *findTrailingHTTPVersion(const char *uriAndHTTPVersion, const char *end = NULL);
294
295 #endif /* SQUID_CLIENTSIDE_H */