]> git.ipfire.org Git - thirdparty/squid.git/blame - src/HttpRequest.cc
Summary: Final MSVC fixups.
[thirdparty/squid.git] / src / HttpRequest.cc
CommitLineData
99edd1c3 1
2/*
190154cf 3 * $Id: HttpRequest.cc,v 1.43 2003/08/10 11:00:40 robertc Exp $
99edd1c3 4 *
5 * DEBUG: section 73 HTTP Request
6 * AUTHOR: Duane Wessels
7 *
2b6662ba 8 * SQUID Web Proxy Cache http://www.squid-cache.org/
e25c139f 9 * ----------------------------------------------------------
99edd1c3 10 *
2b6662ba 11 * Squid is the result of efforts by numerous individuals from
12 * the Internet community; see the CONTRIBUTORS file for full
13 * details. Many organizations have provided support for Squid's
14 * development; see the SPONSORS file for full details. Squid is
15 * Copyrighted (C) 2001 by the Regents of the University of
16 * California; see the COPYRIGHT file for full details. Squid
17 * incorporates software developed and/or copyrighted by other
18 * sources; see the CREDITS file for full details.
99edd1c3 19 *
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
cbdec147 32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
e25c139f 33 *
51ee7c82 34 * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
99edd1c3 35 */
36
528b2c61 37#include "HttpRequest.h"
99edd1c3 38#include "squid.h"
e6ccf245 39#include "authenticate.h"
528b2c61 40#include "HttpHeaderRange.h"
41
190154cf 42static void httpRequestHdrCacheInit(HttpRequest * req);
51ee7c82 43MemPool (*HttpRequest::Pool)(NULL);
99edd1c3 44
75faaa7a 45void *
51ee7c82 46HttpRequest::operator new (size_t byteCount)
75faaa7a 47{
51ee7c82 48 /* derived classes with different sizes must implement their own new */
49 assert (byteCount == sizeof (HttpRequest));
50
51 if (!Pool)
52 Pool = memPoolCreate("HttpRequest", sizeof (HttpRequest));
53
54 return memPoolAlloc(Pool);
75faaa7a 55}
56
57void
51ee7c82 58HttpRequest::operator delete (void *address)
75faaa7a 59{
51ee7c82 60 memPoolFree (Pool, address);
75faaa7a 61}
62
75faaa7a 63HttpRequest::HttpRequest() : header(hoRequest)
64{
65 /* We should initialise these ... */
66#if 0
67 method_t method;
68 protocol_t protocol;
69 char login[MAX_LOGIN_SZ];
70 char host[SQUIDHOSTNAMELEN + 1];
71 auth_user_request_t *auth_user_request;
72 u_short port;
73 String urlpath;
74 char *canonical;
75 int link_count; /* free when zero */
76 request_flags flags;
77 HttpHdrCc *cache_control;
78 HttpHdrRange *range;
79 http_version_t http_ver;
80 time_t ims;
81 int imslen;
82 int max_forwards;
83 /* these in_addr's could probably be sockaddr_in's */
84
85 struct in_addr client_addr;
86
87 struct in_addr my_addr;
88 unsigned short my_port;
89 unsigned short client_port;
90 HttpHeader header;
91 ConnStateData::Pointer body_connection; /* used by clientReadBody() */
92 int content_length;
93 HierarchyLogEntry hier;
94 err_type errType;
95 char *peer_login; /* Configured peer login:password */
96 time_t lastmod; /* Used on refreshes */
97 const char *vary_headers; /* Used when varying entities are detected. Changes how the store key is calculated */
98 char *peer_domain; /* Configured peer forceddomain */
99#endif
100}
101
190154cf 102HttpRequest *
528b2c61 103requestCreate(method_t method, protocol_t protocol, const char *aUrlpath)
99edd1c3 104{
190154cf 105 HttpRequest *req = new HttpRequest;
99edd1c3 106 req->method = method;
107 req->protocol = protocol;
62e76326 108
528b2c61 109 if (aUrlpath)
62e76326 110 req->urlpath = aUrlpath;
111
99edd1c3 112 req->max_forwards = -1;
62e76326 113
9bc73deb 114 req->lastmod = -1;
62e76326 115
7e3ce7b9 116 req->client_addr = no_addr;
62e76326 117
7e3ce7b9 118 req->my_addr = no_addr;
62e76326 119
528b2c61 120 httpRequestHdrCacheInit(req);
62e76326 121
99edd1c3 122 return req;
123}
124
125void
190154cf 126requestDestroy(HttpRequest * req)
99edd1c3 127{
128 assert(req);
62e76326 129
a2ac85d9 130 if (req->body_connection.getRaw() != NULL)
62e76326 131 clientAbortBody(req);
132
94439e4e 133 if (req->auth_user_request)
62e76326 134 authenticateAuthUserRequestUnlock(req->auth_user_request);
135
b0431342 136 safe_free(req->canonical);
62e76326 137
f66a9ef4 138 safe_free(req->vary_headers);
62e76326 139
528b2c61 140 req->urlpath.clean();
62e76326 141
99edd1c3 142 httpHeaderClean(&req->header);
62e76326 143
8e092300 144 if (req->cache_control)
62e76326 145 httpHdrCcDestroy(req->cache_control);
146
d192d11f 147 if (req->range)
00d77d6b 148 delete req->range;
62e76326 149
abb929f0 150 req->tag.clean();
151
152 req->extacl_user.clean();
153
154 req->extacl_passwd.clean();
155
4a972fa2 156 req->extacl_log.clean();
157
00d77d6b 158 delete req;
99edd1c3 159}
160
190154cf 161HttpRequest *
162requestLink(HttpRequest * request)
99edd1c3 163{
164 assert(request);
165 request->link_count++;
166 return request;
167}
168
169void
190154cf 170requestUnlink(HttpRequest * request)
99edd1c3 171{
172 if (!request)
62e76326 173 return;
174
1cc5cec5 175 assert(request->link_count > 0);
62e76326 176
a7eb786a 177 if (--request->link_count > 0)
62e76326 178 return;
179
a7eb786a 180 requestDestroy(request);
99edd1c3 181}
182
183int
190154cf 184httpRequestParseHeader(HttpRequest * req, const char *parse_start)
99edd1c3 185{
186 const char *blk_start, *blk_end;
62e76326 187
99edd1c3 188 if (!httpMsgIsolateHeaders(&parse_start, &blk_start, &blk_end))
62e76326 189 return 0;
190
528b2c61 191 int result = httpHeaderParse(&req->header, blk_start, blk_end);
62e76326 192
528b2c61 193 if (result)
62e76326 194 httpRequestHdrCacheInit(req);
195
528b2c61 196 return result;
99edd1c3 197}
198
a00a7c85 199/* swaps out request using httpRequestPack */
99edd1c3 200void
190154cf 201httpRequestSwapOut(const HttpRequest * req, StoreEntry * e)
99edd1c3 202{
a00a7c85 203 Packer p;
2246b732 204 assert(req && e);
a00a7c85 205 packerToStoreInit(&p, e);
206 httpRequestPack(req, &p);
207 packerClean(&p);
208}
209
210/* packs request-line and headers, appends <crlf> terminator */
211void
190154cf 212httpRequestPack(const HttpRequest * req, Packer * p)
a00a7c85 213{
214 assert(req && p);
215 /* pack request-line */
216 packerPrintf(p, "%s %s HTTP/1.0\r\n",
62e76326 217 RequestMethodStr[req->method], req->urlpath.buf());
a00a7c85 218 /* headers */
219 httpHeaderPackInto(&req->header, p);
2246b732 220 /* trailer */
a00a7c85 221 packerAppend(p, "\r\n", 2);
2246b732 222}
223
224#if UNUSED_CODE
225void
190154cf 226httpRequestSetHeaders(HttpRequest * req, method_t method, const char *uri, const char *header_str)
2246b732 227{
2246b732 228 assert(req && uri && header_str);
229 assert(!req->header.len);
5999b776 230 httpHeaderParse(&req->header, header_str, header_str + strlen(header_str));
99edd1c3 231}
eeb423fb 232
2246b732 233#endif
234
235/* returns the length of request line + headers + crlf */
236int
190154cf 237httpRequestPrefixLen(const HttpRequest * req)
2246b732 238{
239 assert(req);
240 return strlen(RequestMethodStr[req->method]) + 1 +
62e76326 241 req->urlpath.size() + 1 +
242 4 + 1 + 3 + 2 +
243 req->header.len + 2;
2246b732 244}
99edd1c3 245
6bccf575 246/*
247 * Returns true if HTTP allows us to pass this header on. Does not
248 * check anonymizer (aka header_access) configuration.
249 */
99edd1c3 250int
5999b776 251httpRequestHdrAllowed(const HttpHeaderEntry * e, String * strConn)
99edd1c3 252{
253 assert(e);
97474590 254 /* check connection header */
62e76326 255
528b2c61 256 if (strConn && strListIsMember(strConn, e->name.buf(), ','))
62e76326 257 return 0;
258
99edd1c3 259 return 1;
260}
e429f975 261
190154cf 262/* sync this routine when you update HttpRequest struct */
528b2c61 263static void
190154cf 264httpRequestHdrCacheInit(HttpRequest * req)
528b2c61 265{
266 const HttpHeader *hdr = &req->header;
62e76326 267 /* const char *str; */
528b2c61 268 req->content_length = httpHeaderGetInt(hdr, HDR_CONTENT_LENGTH);
269 /* TODO: canonicalise these into an HttpEntity */
270#if 0
62e76326 271
528b2c61 272 req->date = httpHeaderGetTime(hdr, HDR_DATE);
273 req->last_modified = httpHeaderGetTime(hdr, HDR_LAST_MODIFIED);
274 str = httpHeaderGetStr(hdr, HDR_CONTENT_TYPE);
62e76326 275
528b2c61 276 if (str)
62e76326 277 stringLimitInit(&req->content_type, str, strcspn(str, ";\t "));
528b2c61 278 else
650c4b88 279 req->content_type = String();
62e76326 280
528b2c61 281#endif
62e76326 282
528b2c61 283 req->cache_control = httpHeaderGetCc(hdr);
62e76326 284
528b2c61 285 req->range = httpHeaderGetRange(hdr);
62e76326 286
528b2c61 287#if 0
62e76326 288
528b2c61 289 req->keep_alive = httpMsgIsPersistent(req->http_ver, &req->header);
290
291 /* be sure to set expires after date and cache-control */
292 req->expires = httpReplyHdrExpirationTime(req);
62e76326 293
528b2c61 294#endif
295}
296
e429f975 297/* request_flags */
298bool
299request_flags::resetTCP() const
300{
301 return reset_tcp != 0;
302}
303
304void
305request_flags::setResetTCP()
306{
307 debug (73, 9) ("request_flags::setResetTCP\n");
308 reset_tcp = 1;
309}
310
311void
312request_flags::clearResetTCP()
313{
314 debug(73, 9) ("request_flags::clearResetTCP\n");
315 reset_tcp = 0;
316}
528b2c61 317
318bool
190154cf 319HttpRequest::multipartRangeRequest() const
528b2c61 320{
321 return (range && range->specs.count > 1);
322}
8000a965 323
324void
325request_flags::destinationIPLookupCompleted()
326{
327 destinationIPLookedUp_ = true;
328}
329
330bool
331request_flags::destinationIPLookedUp() const
332{
333 return destinationIPLookedUp_;
334}