]> git.ipfire.org Git - thirdparty/squid.git/blob - src/client_side.h
Moved src/ICAP/AsyncJob.* to src/base/ to prepare for the src/ICAP move to
[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 template <class T>
52 class Range;
53
54 class ClientSocketContext : public RefCountable
55 {
56
57 public:
58 typedef RefCount<ClientSocketContext> Pointer;
59 void *operator new(size_t);
60 void operator delete(void *);
61 ClientSocketContext();
62 ~ClientSocketContext();
63 bool startOfOutput() const;
64 void writeComplete(int fd, char *bufnotused, size_t size, comm_err_t errflag);
65 void keepaliveNextRequest();
66 ClientHttpRequest *http; /* we own this */
67 HttpReply *reply;
68 char reqbuf[HTTP_REQBUF_SZ];
69 Pointer next;
70
71 struct {
72
73 unsigned deferred:1; /* This is a pipelined request waiting for the current object to complete */
74
75 unsigned parsed_ok:1; /* Was this parsed correctly? */
76 } flags;
77 bool mayUseConnection() const {return mayUseConnection_;}
78
79 void mayUseConnection(bool aBool) {
80 mayUseConnection_ = aBool;
81 debug (33,3)("ClientSocketContext::mayUseConnection: This %p marked %d\n",
82 this, aBool);
83 }
84
85 class DeferredParams
86 {
87
88 public:
89 clientStreamNode *node;
90 HttpReply *rep;
91 StoreIOBuffer queuedBuffer;
92 };
93
94 DeferredParams deferredparams;
95 int64_t writtenToSocket;
96 void pullData();
97 int64_t getNextRangeOffset() const;
98 bool canPackMoreRanges() const;
99 clientStream_status_t socketState();
100 void sendBody(HttpReply * rep, StoreIOBuffer bodyData);
101 void sendStartOfMessage(HttpReply * rep, StoreIOBuffer bodyData);
102 size_t lengthToSend(Range<int64_t> const &available);
103 void noteSentBodyBytes(size_t);
104 void buildRangeHeader(HttpReply * rep);
105 int fd() const;
106 clientStreamNode * getTail() const;
107 clientStreamNode * getClientReplyContext() const;
108 void connIsFinished();
109 void removeFromConnectionList(ConnStateData * conn);
110 void deferRecipientForLater(clientStreamNode * node, HttpReply * rep, StoreIOBuffer receivedData);
111 bool multipartRangeRequest() const;
112 void registerWithConn();
113
114 private:
115 CBDATA_CLASS(ClientSocketContext);
116 void prepareReply(HttpReply * rep);
117 void packRange(StoreIOBuffer const &, MemBuf * mb);
118 void deRegisterWithConn();
119 void doClose();
120 void initiateClose(const char *reason);
121 bool mayUseConnection_; /* This request may use the connection. Don't read anymore requests for now */
122 bool connRegistered_;
123 };
124
125 /** A connection to a socket */
126 class ConnStateData : public BodyProducer/*, public RefCountable*/
127 {
128
129 public:
130
131 ConnStateData();
132 ~ConnStateData();
133
134 void readSomeData();
135 int getAvailableBufferLength() const;
136 bool areAllContextsForThisConnection() const;
137 void freeAllContexts();
138 void readNextRequest();
139 void makeSpaceAvailable();
140 ClientSocketContext::Pointer getCurrentContext() const;
141 void addContextToQueue(ClientSocketContext * context);
142 int getConcurrentRequestCount() const;
143 bool isOpen() const;
144
145 int fd;
146
147 struct In {
148 In();
149 ~In();
150 char *addressToReadInto() const;
151 char *buf;
152 size_t notYetUsed;
153 size_t allocatedSize;
154 } in;
155
156 int64_t bodySizeLeft();
157
158 /**
159 * Is this connection based authentication? if so what type it
160 * is.
161 */
162 auth_type_t auth_type;
163
164 /**
165 * note this is ONLY connection based because NTLM is against HTTP spec.
166 * the user details for connection based authentication
167 */
168 AuthUserRequest *auth_user_request;
169
170 /**
171 * used by the owner of the connection, opaque otherwise
172 * TODO: generalise the connection owner concept.
173 */
174 ClientSocketContext::Pointer currentobject;
175
176 IpAddress peer;
177
178 IpAddress me;
179
180 IpAddress log_addr;
181 char rfc931[USER_IDENT_SZ];
182 int nrequests;
183
184 struct {
185 bool readMoreRequests;
186 bool swanSang; // XXX: temporary flag to check proper cleanup
187 } flags;
188 struct {
189 int fd; /* pinned server side connection */
190 char *host; /* host name of pinned connection */
191 int port; /* port of pinned connection */
192 bool pinned; /* this connection was pinned */
193 bool auth; /* pinned for www authentication */
194 struct peer *peer; /* peer the connection goes via */
195 AsyncCall::Pointer closeHandler; /*The close handler for pinned server side connection*/
196 } pinning;
197
198 http_port_list *port;
199
200 bool transparent() const;
201 void transparent(bool const);
202 bool reading() const;
203 void reading(bool const);
204
205 bool closing() const;
206 void startClosing(const char *reason);
207
208 BodyPipe::Pointer expectRequestBody(int64_t size);
209 virtual void noteMoreBodySpaceAvailable(BodyPipe::Pointer);
210 virtual void noteBodyConsumerAborted(BodyPipe::Pointer);
211
212 void handleReadData(char *buf, size_t size);
213 void handleRequestBodyData();
214
215 /**
216 * Correlate the current ConnStateData object with the pinning_fd socket descriptor.
217 */
218 void pinConnection(int fd, HttpRequest *request, struct peer *peer, bool auth);
219 /**
220 * Decorrelate the ConnStateData object from its pinned peer
221 */
222 void unpinConnection();
223 /**
224 * Checks if there is pinning info if it is valid. It can close the server side connection
225 * if pinned info is not valid.
226 \param request if it is not NULL also checks if the pinning info refers to the request client side HttpRequest
227 \param peer if it is not NULL also check if the peer is the pinning peer
228 \return The fd of the server side connection or -1 if fails.
229 */
230 int validatePinnedConnection(HttpRequest *request, const struct peer *peer=NULL);
231 /**
232 * returts the pinned peer if exists, NULL otherwise
233 */
234 struct peer *pinnedPeer() const {return pinning.peer;}
235 bool pinnedAuth() const {return pinning.auth;}
236
237 // pining related comm callbacks
238 void clientPinnedConnectionClosed(const CommCloseCbParams &io);
239
240 // comm callbacks
241 void clientReadRequest(const CommIoCbParams &io);
242 void connStateClosed(const CommCloseCbParams &io);
243 void requestTimeout(const CommTimeoutCbParams &params);
244
245 // AsyncJob API
246 virtual bool doneAll() const { return BodyProducer::doneAll() && false;}
247 virtual void swanSong();
248
249 #if USE_SSL
250 bool switchToHttps();
251 bool switchedToHttps() const { return switchedToHttps_; }
252 #else
253 bool switchedToHttps() const { return false; }
254 #endif
255
256 private:
257 int connReadWasError(comm_err_t flag, int size, int xerrno);
258 int connFinishedWithConn(int size);
259 void clientMaybeReadData(int do_next_read);
260 void clientAfterReadingRequests(int do_next_read);
261
262 private:
263 CBDATA_CLASS2(ConnStateData);
264 bool transparent_;
265 bool reading_;
266 bool closing_;
267
268 bool switchedToHttps_;
269 BodyPipe::Pointer bodyPipe; // set when we are reading request body
270 };
271
272 /* convenience class while splitting up body handling */
273 /* temporary existence only - on stack use expected */
274
275 void setLogUri(ClientHttpRequest * http, char const *uri);
276
277 const char *findTrailingHTTPVersion(const char *uriAndHTTPVersion, const char *end = NULL);
278
279 #endif /* SQUID_CLIENTSIDE_H */