]> git.ipfire.org Git - thirdparty/squid.git/blame - src/HttpReply.cc
Summary: Merge String loss fix.
[thirdparty/squid.git] / src / HttpReply.cc
CommitLineData
2ac76861 1
cb69b4c7 2/*
0353e724 3 * $Id: HttpReply.cc,v 1.56 2003/03/06 11:51:55 robertc Exp $
cb69b4c7 4 *
123abbe1 5 * DEBUG: section 58 HTTP Reply (Response)
cb69b4c7 6 * AUTHOR: Alex Rousskov
7 *
2b6662ba 8 * SQUID Web Proxy Cache http://www.squid-cache.org/
e25c139f 9 * ----------------------------------------------------------
cb69b4c7 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.
cb69b4c7 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 *
cb69b4c7 34 */
35
528b2c61 36#include "HttpReply.h"
cb69b4c7 37#include "squid.h"
528b2c61 38#include "Store.h"
39#include "HttpHeader.h"
40#include "HttpHdrContRange.h"
4fb35c3c 41#include "ACLChecklist.h"
cb69b4c7 42
43/* local constants */
44
2246b732 45/* these entity-headers must be ignored if a bogus server sends them in 304 */
46static HttpHeaderMask Denied304HeadersMask;
47static http_hdr_type Denied304HeadersArr[] =
62e76326 48 {
49 HDR_ALLOW, HDR_CONTENT_ENCODING, HDR_CONTENT_LANGUAGE, HDR_CONTENT_LENGTH,
50 HDR_CONTENT_LOCATION, HDR_CONTENT_RANGE, HDR_LAST_MODIFIED, HDR_LINK,
51 HDR_OTHER
52 };
2246b732 53
e6ccf245 54HttpMsgParseState &operator++ (HttpMsgParseState &aState)
55{
56 aState = (HttpMsgParseState)(++(int)aState);
57 return aState;
58}
59
60
cb69b4c7 61/* local routines */
2246b732 62static void httpReplyInit(HttpReply * rep);
63static void httpReplyClean(HttpReply * rep);
2ac76861 64static void httpReplyDoDestroy(HttpReply * rep);
d8b249ef 65static void httpReplyHdrCacheInit(HttpReply * rep);
66static void httpReplyHdrCacheClean(HttpReply * rep);
2ac76861 67static int httpReplyParseStep(HttpReply * rep, const char *parse_start, int atEnd);
68static int httpReplyParseError(HttpReply * rep);
cb69b4c7 69static int httpReplyIsolateStart(const char **parse_start, const char **blk_start, const char **blk_end);
d20b1cd0 70static time_t httpReplyHdrExpirationTime(const HttpReply * rep);
cb69b4c7 71
72
2246b732 73/* module initialization */
74void
9bc73deb 75httpReplyInitModule(void)
2246b732 76{
97474590 77 httpHeaderMaskInit(&Denied304HeadersMask, 0);
2246b732 78 httpHeaderCalcMask(&Denied304HeadersMask, (const int *) Denied304HeadersArr, countof(Denied304HeadersArr));
79}
80
81
cb69b4c7 82HttpReply *
9bc73deb 83httpReplyCreate(void)
cb69b4c7 84{
0353e724 85 HttpReply *rep = new HttpReply;
399e85ea 86 debug(58, 7) ("creating rep: %p\n", rep);
cb69b4c7 87 httpReplyInit(rep);
88 return rep;
89}
90
5446b331 91static void
2ac76861 92httpReplyInit(HttpReply * rep)
cb69b4c7 93{
94 assert(rep);
95 rep->hdr_sz = 0;
a560ee93 96 rep->maxBodySize = 0;
cb69b4c7 97 rep->pstate = psReadyToParseStartLine;
98 httpBodyInit(&rep->body);
2246b732 99 httpHeaderInit(&rep->header, hoReply);
d8b249ef 100 httpReplyHdrCacheInit(rep);
cb69b4c7 101 httpStatusLineInit(&rep->sline);
102}
103
5446b331 104static void
2ac76861 105httpReplyClean(HttpReply * rep)
cb69b4c7 106{
107 assert(rep);
108 httpBodyClean(&rep->body);
d8b249ef 109 httpReplyHdrCacheClean(rep);
110 httpHeaderClean(&rep->header);
cb69b4c7 111 httpStatusLineClean(&rep->sline);
112}
113
114void
2ac76861 115httpReplyDestroy(HttpReply * rep)
cb69b4c7 116{
117 assert(rep);
399e85ea 118 debug(58, 7) ("destroying rep: %p\n", rep);
cb69b4c7 119 httpReplyClean(rep);
63259c34 120 httpReplyDoDestroy(rep);
cb69b4c7 121}
122
123void
2ac76861 124httpReplyReset(HttpReply * rep)
cb69b4c7 125{
126 httpReplyClean(rep);
127 httpReplyInit(rep);
128}
129
63259c34 130/* absorb: copy the contents of a new reply to the old one, destroy new one */
131void
2ac76861 132httpReplyAbsorb(HttpReply * rep, HttpReply * new_rep)
63259c34 133{
134 assert(rep && new_rep);
135 httpReplyClean(rep);
136 *rep = *new_rep;
528b2c61 137 new_rep->header.entries.clean();
63259c34 138 /* cannot use Clean() on new reply now! */
139 httpReplyDoDestroy(new_rep);
140}
141
9bc73deb 142/*
143 * httpReplyParse takes character buffer of HTTP headers (buf),
144 * which may not be NULL-terminated, and fills in an HttpReply
145 * structure (rep). The parameter 'end' specifies the offset to
146 * the end of the reply headers. The caller may know where the
147 * end is, but is unable to NULL-terminate the buffer. This function
148 * returns true on success.
149 */
cb69b4c7 150int
9bc73deb 151httpReplyParse(HttpReply * rep, const char *buf, ssize_t end)
cb69b4c7 152{
153 /*
9bc73deb 154 * this extra buffer/copy will be eliminated when headers become
155 * meta-data in store. Currently we have to xstrncpy the buffer
156 * becuase somebody may feed a non NULL-terminated buffer to
157 * us.
cb69b4c7 158 */
e6ccf245 159 char *headers = (char *)memAllocate(MEM_4K_BUF);
cb69b4c7 160 int success;
25b0856c 161 size_t s = XMIN(end + 1, 4096);
cb69b4c7 162 /* reset current state, because we are not used in incremental fashion */
163 httpReplyReset(rep);
25b0856c 164 /* put a string terminator. s is how many bytes to touch in
165 * 'buf' including the terminating NULL. */
166 xstrncpy(headers, buf, s);
cb69b4c7 167 success = httpReplyParseStep(rep, headers, 0);
db1cd23c 168 memFree(headers, MEM_4K_BUF);
cb69b4c7 169 return success == 1;
170}
171
172void
528b2c61 173httpReplyPackHeadersInto(const HttpReply * rep, Packer * p)
cb69b4c7 174{
175 assert(rep);
176 httpStatusLinePackInto(&rep->sline, p);
d8b249ef 177 httpHeaderPackInto(&rep->header, p);
cb69b4c7 178 packerAppend(p, "\r\n", 2);
528b2c61 179}
180
181void
182httpReplyPackInto(const HttpReply * rep, Packer * p)
183{
184 httpReplyPackHeadersInto(rep, p);
cb69b4c7 185 httpBodyPackInto(&rep->body, p);
186}
187
188/* create memBuf, create mem-based packer, pack, destroy packer, return MemBuf */
189MemBuf
2ac76861 190httpReplyPack(const HttpReply * rep)
cb69b4c7 191{
192 MemBuf mb;
193 Packer p;
194 assert(rep);
195
196 memBufDefInit(&mb);
197 packerToMemInit(&p, &mb);
198 httpReplyPackInto(rep, &p);
199 packerClean(&p);
200 return mb;
201}
202
528b2c61 203/* swap: create swap-based packer, pack, destroy packer
204 * This eats the reply.
205 */
cb69b4c7 206void
528b2c61 207httpReplySwapOut(HttpReply * rep, StoreEntry * e)
cb69b4c7 208{
cb69b4c7 209 assert(rep && e);
210
528b2c61 211 storeEntryReplaceObject(e, rep);
cb69b4c7 212}
213
214MemBuf
ccf44862 215httpPackedReply(http_version_t ver, http_status status, const char *ctype,
62e76326 216 int clen, time_t lmt, time_t expires)
cb69b4c7 217{
218 HttpReply *rep = httpReplyCreate();
219 MemBuf mb;
220 httpReplySetHeaders(rep, ver, status, ctype, NULL, clen, lmt, expires);
221 mb = httpReplyPack(rep);
222 httpReplyDestroy(rep);
223 return mb;
224}
225
528b2c61 226HttpReply *
227httpReplyMake304 (const HttpReply * rep)
cb69b4c7 228{
62e76326 229 static const http_hdr_type ImsEntries[] = {HDR_DATE, HDR_CONTENT_TYPE, HDR_EXPIRES, HDR_LAST_MODIFIED, /* eof */ HDR_OTHER};
230
528b2c61 231 HttpReply *rv;
728da2ee 232 int t;
de336bbe 233 HttpHeaderEntry *e;
528b2c61 234 http_version_t ver;
cb69b4c7 235 assert(rep);
236
528b2c61 237 rv = httpReplyCreate ();
238 /* rv->content_length; */
239 rv->date = rep->date;
240 rv->last_modified = rep->last_modified;
241 rv->expires = rep->expires;
242 rv->content_type = rep->content_type;
243 /* rv->cache_control */
244 /* rv->content_range */
245 /* rv->keep_alive */
246 httpBuildVersion(&ver, 1, 0);
247 httpStatusLineSet(&rv->sline, ver,
62e76326 248 HTTP_NOT_MODIFIED, "");
249
de336bbe 250 for (t = 0; ImsEntries[t] != HDR_OTHER; ++t)
62e76326 251 if ((e = httpHeaderFindEntry(&rep->header, ImsEntries[t])))
252 httpHeaderAddEntry(&rv->header, httpHeaderEntryClone(e));
253
528b2c61 254 /* rv->body */
255 return rv;
256}
257
258MemBuf
259httpPacked304Reply(const HttpReply * rep)
260{
261 /* Not as efficient as skipping the header duplication,
262 * but easier to maintain
263 */
264 HttpReply *temp;
265 MemBuf rv;
266 assert (rep);
267 temp = httpReplyMake304 (rep);
268 rv = httpReplyPack(temp);
269 httpReplyDestroy (temp);
270 return rv;
cb69b4c7 271}
272
273void
ccf44862 274httpReplySetHeaders(HttpReply * reply, http_version_t ver, http_status status, const char *reason,
62e76326 275 const char *ctype, int clen, time_t lmt, time_t expires)
cb69b4c7 276{
277 HttpHeader *hdr;
278 assert(reply);
279 httpStatusLineSet(&reply->sline, ver, status, reason);
d8b249ef 280 hdr = &reply->header;
281 httpHeaderPutStr(hdr, HDR_SERVER, full_appname_string);
282 httpHeaderPutStr(hdr, HDR_MIME_VERSION, "1.0");
283 httpHeaderPutTime(hdr, HDR_DATE, squid_curtime);
62e76326 284
d8b249ef 285 if (ctype) {
62e76326 286 httpHeaderPutStr(hdr, HDR_CONTENT_TYPE, ctype);
287 reply->content_type = ctype;
d8b249ef 288 } else
650c4b88 289 reply->content_type = String();
62e76326 290
de336bbe 291 if (clen >= 0)
62e76326 292 httpHeaderPutInt(hdr, HDR_CONTENT_LENGTH, clen);
293
cb69b4c7 294 if (expires >= 0)
62e76326 295 httpHeaderPutTime(hdr, HDR_EXPIRES, expires);
296
2ac76861 297 if (lmt > 0) /* this used to be lmt != 0 @?@ */
62e76326 298 httpHeaderPutTime(hdr, HDR_LAST_MODIFIED, lmt);
299
d8b249ef 300 reply->date = squid_curtime;
62e76326 301
d8b249ef 302 reply->content_length = clen;
62e76326 303
d8b249ef 304 reply->expires = expires;
62e76326 305
d8b249ef 306 reply->last_modified = lmt;
cb69b4c7 307}
308
6d38ef86 309void
310httpRedirectReply(HttpReply * reply, http_status status, const char *loc)
311{
312 HttpHeader *hdr;
ccf44862 313 http_version_t ver;
6d38ef86 314 assert(reply);
bffee5af 315 httpBuildVersion(&ver, 1, 0);
ccf44862 316 httpStatusLineSet(&reply->sline, ver, status, httpStatusString(status));
6d38ef86 317 hdr = &reply->header;
318 httpHeaderPutStr(hdr, HDR_SERVER, full_appname_string);
319 httpHeaderPutTime(hdr, HDR_DATE, squid_curtime);
320 httpHeaderPutInt(hdr, HDR_CONTENT_LENGTH, 0);
321 httpHeaderPutStr(hdr, HDR_LOCATION, loc);
322 reply->date = squid_curtime;
323 reply->content_length = 0;
324}
325
528b2c61 326/* compare the validators of two replies.
327 * 1 = they match
328 * 0 = they do not match
329 */
330int
62e76326 331httpReplyValidatorsMatch(HttpReply const * rep, HttpReply const * otherRep)
332{
528b2c61 333 String one,two;
334 assert (rep && otherRep);
335 /* Numbers first - easiest to check */
336 /* Content-Length */
337 /* TODO: remove -1 bypass */
62e76326 338
528b2c61 339 if (rep->content_length != otherRep->content_length
62e76326 340 && rep->content_length > -1 &&
341 otherRep->content_length > -1)
342 return 0;
343
528b2c61 344 /* ETag */
345 one = httpHeaderGetStrOrList(&rep->header, HDR_ETAG);
62e76326 346
528b2c61 347 two = httpHeaderGetStrOrList(&otherRep->header, HDR_ETAG);
62e76326 348
528b2c61 349 if (!one.buf() || !two.buf() || strcasecmp (one.buf(), two.buf())) {
62e76326 350 one.clean();
351 two.clean();
352 return 0;
528b2c61 353 }
62e76326 354
528b2c61 355 if (rep->last_modified != otherRep->last_modified)
62e76326 356 return 0;
357
528b2c61 358 /* MD5 */
359 one = httpHeaderGetStrOrList(&rep->header, HDR_CONTENT_MD5);
62e76326 360
528b2c61 361 two = httpHeaderGetStrOrList(&otherRep->header, HDR_CONTENT_MD5);
62e76326 362
528b2c61 363 if (strcasecmp (one.buf(), two.buf())) {
62e76326 364 one.clean();
365 two.clean();
366 return 0;
528b2c61 367 }
62e76326 368
528b2c61 369 return 1;
370}
371
372
cb69b4c7 373void
528b2c61 374httpReplyUpdateOnNotModified(HttpReply * rep, HttpReply const * freshRep)
cb69b4c7 375{
cb69b4c7 376 assert(rep && freshRep);
528b2c61 377 /* Can not update modified headers that don't match! */
378 assert (httpReplyValidatorsMatch(rep, freshRep));
d8b249ef 379 /* clean cache */
380 httpReplyHdrCacheClean(rep);
381 /* update raw headers */
c68e9c6b 382 httpHeaderUpdate(&rep->header, &freshRep->header,
62e76326 383 (const HttpHeaderMask *) &Denied304HeadersMask);
d8b249ef 384 /* init cache */
385 httpReplyHdrCacheInit(rep);
cb69b4c7 386}
387
cb69b4c7 388
d8b249ef 389/* internal routines */
cb69b4c7 390
d8b249ef 391/* internal function used by Destroy and Absorb */
392static void
393httpReplyDoDestroy(HttpReply * rep)
cb69b4c7 394{
0353e724 395 delete rep;
cb69b4c7 396}
397
d20b1cd0 398static time_t
399httpReplyHdrExpirationTime(const HttpReply * rep)
400{
401 /* The s-maxage and max-age directive takes priority over Expires */
62e76326 402
d20b1cd0 403 if (rep->cache_control) {
62e76326 404 if (rep->date >= 0) {
405 if (rep->cache_control->s_maxage >= 0)
406 return rep->date + rep->cache_control->s_maxage;
407
408 if (rep->cache_control->max_age >= 0)
409 return rep->date + rep->cache_control->max_age;
410 } else {
411 /*
412 * Conservatively handle the case when we have a max-age
413 * header, but no Date for reference?
414 */
415
416 if (rep->cache_control->s_maxage >= 0)
417 return squid_curtime;
418
419 if (rep->cache_control->max_age >= 0)
420 return squid_curtime;
421 }
d20b1cd0 422 }
62e76326 423
f66a9ef4 424 if (Config.onoff.vary_ignore_expire &&
62e76326 425 httpHeaderHas(&rep->header, HDR_VARY)) {
426 const time_t d = httpHeaderGetTime(&rep->header, HDR_DATE);
427 const time_t e = httpHeaderGetTime(&rep->header, HDR_EXPIRES);
428
429 if (d == e)
430 return -1;
f66a9ef4 431 }
62e76326 432
d20b1cd0 433 if (httpHeaderHas(&rep->header, HDR_EXPIRES)) {
62e76326 434 const time_t e = httpHeaderGetTime(&rep->header, HDR_EXPIRES);
435 /*
436 * HTTP/1.0 says that robust implementations should consider
437 * bad or malformed Expires header as equivalent to "expires
438 * immediately."
439 */
440 return e < 0 ? squid_curtime : e;
d20b1cd0 441 }
62e76326 442
d20b1cd0 443 return -1;
444}
445
d8b249ef 446/* sync this routine when you update HttpReply struct */
447static void
448httpReplyHdrCacheInit(HttpReply * rep)
cb69b4c7 449{
d8b249ef 450 const HttpHeader *hdr = &rep->header;
451 const char *str;
452 rep->content_length = httpHeaderGetInt(hdr, HDR_CONTENT_LENGTH);
453 rep->date = httpHeaderGetTime(hdr, HDR_DATE);
454 rep->last_modified = httpHeaderGetTime(hdr, HDR_LAST_MODIFIED);
d8b249ef 455 str = httpHeaderGetStr(hdr, HDR_CONTENT_TYPE);
62e76326 456
d8b249ef 457 if (str)
62e76326 458 rep->content_type.limitInit(str, strcspn(str, ";\t "));
d8b249ef 459 else
650c4b88 460 rep->content_type = String();
62e76326 461
d8b249ef 462 rep->cache_control = httpHeaderGetCc(hdr);
62e76326 463
d8b249ef 464 rep->content_range = httpHeaderGetContRange(hdr);
62e76326 465
99edd1c3 466 rep->keep_alive = httpMsgIsPersistent(rep->sline.version, &rep->header);
62e76326 467
d20b1cd0 468 /* be sure to set expires after date and cache-control */
469 rep->expires = httpReplyHdrExpirationTime(rep);
cb69b4c7 470}
471
d8b249ef 472/* sync this routine when you update HttpReply struct */
63259c34 473static void
d8b249ef 474httpReplyHdrCacheClean(HttpReply * rep)
2ac76861 475{
528b2c61 476 rep->content_type.clean();
62e76326 477
d8b249ef 478 if (rep->cache_control)
62e76326 479 httpHdrCcDestroy(rep->cache_control);
480
d8b249ef 481 if (rep->content_range)
62e76326 482 httpHdrContRangeDestroy(rep->content_range);
63259c34 483}
cb69b4c7 484
485/*
486 * parses a 0-terminating buffer into HttpReply.
487 * Returns:
528b2c61 488 * 1 -- success
cb69b4c7 489 * 0 -- need more data (partial parse)
490 * -1 -- parse error
491 */
492static int
2ac76861 493httpReplyParseStep(HttpReply * rep, const char *buf, int atEnd)
cb69b4c7 494{
495 const char *parse_start = buf;
496 const char *blk_start, *blk_end;
497 const char **parse_end_ptr = &blk_end;
498 assert(rep);
499 assert(parse_start);
500 assert(rep->pstate < psParsed);
501
502 *parse_end_ptr = parse_start;
62e76326 503
cb69b4c7 504 if (rep->pstate == psReadyToParseStartLine) {
62e76326 505 if (!httpReplyIsolateStart(&parse_start, &blk_start, &blk_end))
506 return 0;
507
508 if (!httpStatusLineParse(&rep->sline, blk_start, blk_end))
509 return httpReplyParseError(rep);
510
511 *parse_end_ptr = parse_start;
512
513 rep->hdr_sz = *parse_end_ptr - buf;
514
515 ++rep->pstate;
cb69b4c7 516 }
62e76326 517
cb69b4c7 518 if (rep->pstate == psReadyToParseHeaders) {
62e76326 519 if (!httpMsgIsolateHeaders(&parse_start, &blk_start, &blk_end)) {
520 if (atEnd)
521 blk_start = parse_start, blk_end = blk_start + strlen(blk_start);
522 else
523 return 0;
524 }
525
526 if (!httpHeaderParse(&rep->header, blk_start, blk_end))
527 return httpReplyParseError(rep);
528
529 httpReplyHdrCacheInit(rep);
530
531 *parse_end_ptr = parse_start;
532
533 rep->hdr_sz = *parse_end_ptr - buf;
534
535 ++rep->pstate;
cb69b4c7 536 }
62e76326 537
cb69b4c7 538 return 1;
539}
540
cb69b4c7 541/* handy: resets and returns -1 */
542static int
2ac76861 543httpReplyParseError(HttpReply * rep)
cb69b4c7 544{
545 assert(rep);
546 /* reset */
547 httpReplyReset(rep);
548 /* indicate an error */
549 rep->sline.status = HTTP_INVALID_HEADER;
550 return -1;
551}
552
553/* find first CRLF */
554static int
555httpReplyIsolateStart(const char **parse_start, const char **blk_start, const char **blk_end)
556{
557 int slen = strcspn(*parse_start, "\r\n");
62e76326 558
2ac76861 559 if (!(*parse_start)[slen]) /* no CRLF found */
62e76326 560 return 0;
cb69b4c7 561
562 *blk_start = *parse_start;
62e76326 563
cb69b4c7 564 *blk_end = *blk_start + slen;
62e76326 565
52639d06 566 while (**blk_end == '\r') /* CR */
62e76326 567 (*blk_end)++;
568
2ac76861 569 if (**blk_end == '\n') /* LF */
62e76326 570 (*blk_end)++;
cb69b4c7 571
572 *parse_start = *blk_end;
62e76326 573
cb69b4c7 574 return 1;
575}
35282fbf 576
577/*
578 * Returns the body size of a HTTP response
579 */
580int
528b2c61 581httpReplyBodySize(method_t method, HttpReply const * reply)
35282fbf 582{
583 if (METHOD_HEAD == method)
62e76326 584 return 0;
35282fbf 585 else if (reply->sline.status == HTTP_OK)
62e76326 586 (void) 0; /* common case, continue */
35282fbf 587 else if (reply->sline.status == HTTP_NO_CONTENT)
62e76326 588 return 0;
35282fbf 589 else if (reply->sline.status == HTTP_NOT_MODIFIED)
62e76326 590 return 0;
35282fbf 591 else if (reply->sline.status < HTTP_OK)
62e76326 592 return 0;
593
35282fbf 594 return reply->content_length;
595}
a560ee93 596
597/*
598 * Calculates the maximum size allowed for an HTTP response
599 */
600void
b671cc68 601httpReplyBodyBuildSize(request_t * request, HttpReply * reply, dlink_list * bodylist)
a560ee93 602{
603 body_size *bs;
4fb35c3c 604 ACLChecklist *checklist;
a560ee93 605 bs = (body_size *) bodylist->head;
62e76326 606
a560ee93 607 while (bs) {
62e76326 608 checklist = aclChecklistCreate(bs->access_list, request, NULL);
609 checklist->reply = reply;
610
611 if (1 != aclCheckFast(bs->access_list, checklist)) {
612 /* deny - skip this entry */
613 bs = (body_size *) bs->node.next;
614 } else {
615 /* Allow - use this entry */
616 reply->maxBodySize = bs->maxsize;
617 bs = NULL;
618 debug(58, 3) ("httpReplyBodyBuildSize: Setting maxBodySize to %ld\n", (long int) reply->maxBodySize);
619 }
620
621 delete checklist;
a560ee93 622 }
623}
0353e724 624
625MemPool *HttpReply::Pool(NULL);
626void *
627HttpReply::operator new (size_t byteCount)
628{
629 /* derived classes with different sizes must implement their own new */
630 assert (byteCount == sizeof (HttpReply));
631
632 if (!Pool)
633 Pool = memPoolCreate("HttpReply", sizeof (HttpReply));
634
635 return memPoolAlloc(Pool);
636}
637
638void
639HttpReply::operator delete (void *address)
640{
641 memPoolFree (Pool, address);
642}