HttpReply.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9/* DEBUG: section 58 HTTP Reply (Response) */
10
11#include "squid.h"
12#include "acl/AclSizeLimit.h"
13#include "acl/FilledChecklist.h"
14#include "base/EnumIterator.h"
15#include "globals.h"
17#include "HttpBody.h"
18#include "HttpHdrCc.h"
19#include "HttpHdrContRange.h"
20#include "HttpHdrSc.h"
21#include "HttpReply.h"
22#include "HttpRequest.h"
23#include "MemBuf.h"
24#include "sbuf/Stream.h"
25#include "SquidConfig.h"
26#include "SquidMath.h"
27#include "Store.h"
28#include "StrList.h"
29
31 Http::Message(hoReply),
32 date(0),
33 last_modified(0),
34 expires(0),
35 surrogate_control(nullptr),
36 keep_alive(0),
37 protoPrefix("HTTP/"),
38 bodySizeMax(-2),
39 content_range(nullptr)
40{
41 init();
42}
43
45{
46 if (do_clean)
47 clean();
48}
49
50void
52{
54 sline.init();
56 do_clean = true;
57}
58
60{
61
62 // reset should not reset the protocol; could have made protoPrefix a
63 // virtual function instead, but it is not clear whether virtual methods
64 // are allowed with MEMPROXY_CLASS() and whether some cbdata void*
65 // conversions are not going to kill virtual tables
66 const String pfx = protoPrefix;
67 clean();
68 init();
69 protoPrefix = pfx;
70}
71
72void
74{
75 // we used to assert that the pipe is NULL, but now the message only
76 // points to a pipe that is owned and initiated by another object.
77 body_pipe = nullptr;
78
79 body.clear();
81 header.clean();
82 sline.clean();
83 bodySizeMax = -2; // hack: make calculatedBodySizeMax() false
84}
85
86void
88{
89 sline.packInto(&p);
90 header.packInto(&p);
91 p.append("\r\n", 2);
92}
93
94void
96{
97 MemBuf buf;
98 buf.init();
100 p.append(buf.content(), buf.contentSize());
101}
102
103void
105{
107 body.packInto(&buf);
108}
109
110/* create memBuf, create mem-based packer, pack, destroy packer, return MemBuf */
111MemBuf *
113{
114 MemBuf *mb = new MemBuf;
115 mb->init();
116 packInto(*mb);
117 return mb;
118}
119
122
124 rep->sline.set(Http::ProtocolVersion(), Http::scOkay, "Connection established");
125 return rep;
126}
127
130{
132
133 const HttpReplyPointer rv(new HttpReply);
134 int t;
136
137 /* rv->content_length; */
138 rv->date = date;
140 rv->expires = expires;
142 /* rv->content_range */
143 /* rv->keep_alive */
145
146 for (t = 0; ImsEntries[t] != Http::HdrType::OTHER; ++t) {
147 if ((e = header.findEntry(ImsEntries[t])))
148 rv->header.addEntry(e->clone());
149 }
150
151 if (cache_control)
152 rv->putCc(*cache_control);
153
154 /* rv->body */
155 return rv;
156}
157
158MemBuf *
160{
161 /* Not as efficient as skipping the header duplication,
162 * but easier to maintain
163 */
164 const auto temp = make304();
165 MemBuf *rv = temp->pack();
166 return rv;
167}
168
169void
170HttpReply::setHeaders(Http::StatusCode status, const char *reason,
171 const char *ctype, int64_t clen, time_t lmt, time_t expiresTime)
172{
173 HttpHeader *hdr;
174 sline.set(Http::ProtocolVersion(), status, reason);
175 hdr = &header;
179
180 if (ctype) {
182 content_type = ctype;
183 } else
185
186 if (clen >= 0)
188
189 if (expiresTime >= 0)
190 hdr->putTime(Http::HdrType::EXPIRES, expiresTime);
191
192 if (lmt > 0) /* this used to be lmt != 0 @?@ */
194
196
197 content_length = clen;
198
199 expires = expiresTime;
200
201 last_modified = lmt;
202}
203
204void
205HttpReply::redirect(Http::StatusCode status, const char *loc)
206{
207 HttpHeader *hdr;
208 sline.set(Http::ProtocolVersion(), status, nullptr);
209 hdr = &header;
215 content_length = 0;
216}
217
218/* compare the validators of two replies.
219 * 1 = they match
220 * 0 = they do not match
221 */
222int
224{
225 String one,two;
226 assert (otherRep);
227 /* Numbers first - easiest to check */
228 /* Content-Length */
229 /* TODO: remove -1 bypass */
230
231 if (content_length != otherRep->content_length
232 && content_length > -1 &&
233 otherRep->content_length > -1)
234 return 0;
235
236 /* ETag */
238
240
241 if (one.size()==0 || two.size()==0 || one.caseCmp(two)!=0 ) {
242 one.clean();
243 two.clean();
244 return 0;
245 }
246
247 if (last_modified != otherRep->last_modified)
248 return 0;
249
250 /* MD5 */
252
254
255 if (one.size()==0 || two.size()==0 || one.caseCmp(two)!=0 ) {
256 one.clean();
257 two.clean();
258 return 0;
259 }
260
261 return 1;
262}
263
266{
267 // If enough 304s do not update, then this expensive checking is cheaper
268 // than blindly storing reply prefix identical to the already stored one.
269 if (!header.needUpdate(&reply304.header))
270 return nullptr;
271
272 const Pointer cloned = clone();
273 cloned->header.update(&reply304.header);
274 cloned->hdrCacheClean();
275 cloned->header.compact();
276 cloned->hdrCacheInit();
277 return cloned;
278}
279
280/* internal routines */
281
282time_t
284{
285 /* The s-maxage and max-age directive takes priority over Expires */
286
287 if (cache_control) {
288 int maxAge = -1;
289 /*
290 * Conservatively handle the case when we have a max-age
291 * header, but no Date for reference?
292 */
293 if (cache_control->hasSMaxAge(&maxAge) || cache_control->hasMaxAge(&maxAge))
294 return (date >= 0) ? date + maxAge : squid_curtime;
295 }
296
299 const time_t d = header.getTime(Http::HdrType::DATE);
300 const time_t e = header.getTime(Http::HdrType::EXPIRES);
301
302 if (d == e)
303 return -1;
304 }
305
307 const time_t e = header.getTime(Http::HdrType::EXPIRES);
308 /*
309 * HTTP/1.0 says that robust implementations should consider
310 * bad or malformed Expires header as equivalent to "expires
311 * immediately."
312 */
313 return e < 0 ? squid_curtime : e;
314 }
315
316 return -1;
317}
318
319/* sync this routine when you update HttpReply struct */
320void
322{
324
331 header.getContRange() : nullptr;
332 keep_alive = persistent() ? 1 : 0;
333 const char *str = header.getStr(Http::HdrType::CONTENT_TYPE);
334
335 if (str)
336 content_type.assign(str, strcspn(str, ";\t "));
337 else
339
340 /* be sure to set expires after date and cache-control */
342}
343
344const HttpHdrContRange *
346{
348 return content_range;
349}
350
351/* sync this routine when you update HttpReply struct */
352void
354{
356
357 if (cache_control) {
358 delete cache_control;
359 cache_control = nullptr;
360 }
361
362 if (surrogate_control) {
363 delete surrogate_control;
364 surrogate_control = nullptr;
365 }
366
367 if (content_range) {
368 delete content_range;
369 content_range = nullptr;
370 }
371}
372
373/*
374 * Returns the body size of a HTTP response
375 */
376int64_t
378{
379 if (sline.version.major < 1)
380 return -1;
381 else if (method.id() == Http::METHOD_HEAD)
382 return 0;
383 else if (sline.status() == Http::scOkay)
384 (void) 0; /* common case, continue */
385 else if (sline.status() == Http::scNoContent)
386 return 0;
387 else if (sline.status() == Http::scNotModified)
388 return 0;
389 else if (sline.status() < Http::scOkay)
390 return 0;
391
392 return content_length;
393}
394
401bool
402HttpReply::sanityCheckStartLine(const char *buf, const size_t hdr_len, Http::StatusCode *error)
403{
404 // hack warning: using psize instead of size here due to type mismatches with MemBuf.
405
406 // content is long enough to possibly hold a reply
407 // 4 being magic size of a 3-digit number plus space delimiter
408 if (hdr_len < (size_t)(protoPrefix.psize() + 4)) {
409 if (hdr_len > 0) {
410 debugs(58, 3, "Too small reply header (" << hdr_len << " bytes)");
412 }
413 return false;
414 }
415
416 int pos;
417 // catch missing or mismatched protocol identifier
418 // allow special-case for ICY protocol (non-HTTP identifier) in response to faked HTTP request.
419 if (strncmp(buf, "ICY", 3) == 0) {
420 protoPrefix = "ICY";
421 pos = protoPrefix.psize();
422 } else {
423
424 if (protoPrefix.cmp(buf, protoPrefix.size()) != 0) {
425 debugs(58, 3, "missing protocol prefix (" << protoPrefix << ") in '" << buf << "'");
427 return false;
428 }
429
430 // catch missing or negative status value (negative '-' is not a digit)
431 pos = protoPrefix.psize();
432
433 // skip arbitrary number of digits and a dot in the version portion
434 while ((size_t)pos <= hdr_len && (*(buf+pos) == '.' || xisdigit(*(buf+pos)) ) ) ++pos;
435
436 // catch missing version info
437 if (pos == protoPrefix.psize()) {
438 debugs(58, 3, "missing protocol version numbers (ie. " << protoPrefix << "/1.0) in '" << buf << "'");
440 return false;
441 }
442 }
443
444 // skip arbitrary number of spaces...
445 while ((size_t)pos <= hdr_len && (char)*(buf+pos) == ' ') ++pos;
446
447 if ((size_t)pos < hdr_len && !xisdigit(*(buf+pos))) {
448 debugs(58, 3, "missing or invalid status number in '" << buf << "'");
450 return false;
451 }
452
453 return true;
454}
455
456bool
457HttpReply::parseFirstLine(const char *blk_start, const char *blk_end)
458{
459 return sline.parse(protoPrefix, blk_start, blk_end);
460}
461
462size_t
463HttpReply::parseTerminatedPrefix(const char * const terminatedBuf, const size_t bufSize)
464{
465 auto error = Http::scNone;
466 const bool eof = false; // TODO: Remove after removing atEnd from HttpHeader::parse()
467 if (parse(terminatedBuf, bufSize, eof, &error)) {
468 debugs(58, 7, "success after accumulating " << bufSize << " bytes and parsing " << hdr_sz);
470 Assure(hdr_sz > 0);
471 Assure(!Less(bufSize, hdr_sz)); // cannot parse more bytes than we have
472 return hdr_sz; // success
473 }
474
476 hdr_sz = 0;
477
478 if (error) {
479 throw TextException(ToSBuf("failed to parse HTTP headers",
480 Debug::Extra, "parser error code: ", error,
481 Debug::Extra, "accumulated unparsed bytes: ", bufSize,
482 Debug::Extra, "reply_header_max_size: ", Config.maxReplyHeaderSize),
483 Here());
484 }
485
486 debugs(58, 3, "need more bytes after accumulating " << bufSize << " out of " << Config.maxReplyHeaderSize);
487
488 // the parse() call above enforces Config.maxReplyHeaderSize limit
489 // XXX: Make this a strict comparison after fixing Http::Message::parse() enforcement
490 Assure(bufSize <= Config.maxReplyHeaderSize);
491 return 0; // parsed nothing, need more data
492}
493
494size_t
496{
497 return sline.packedLength() + header.len + 2;
498}
499
500void
502{
503 interpreter.applyStatusCodeRules(sline.status());
504}
505
506bool
508{
510 return Message::parseHeader(hp, clen);
511}
512
513/* handy: resets and returns -1 */
514int
516{
518 /* indicate an error in the status line */
520 return result;
521}
522
523/*
524 * Indicate whether or not we would usually expect an entity-body
525 * along with this response
526 */
527bool
528HttpReply::expectingBody(const HttpRequestMethod& req_method, int64_t& theSize) const
529{
530 bool expectBody = true;
531
532 if (req_method == Http::METHOD_HEAD)
533 expectBody = false;
534 else if (sline.status() == Http::scNoContent)
535 expectBody = false;
536 else if (sline.status() == Http::scNotModified)
537 expectBody = false;
538 // TODO: Consider assuming that gray-area 0xx responses have bodies, like 9xx responses.
539 else if (sline.status() < Http::scOkay)
540 expectBody = false;
541 else
542 expectBody = true;
543
544 if (expectBody) {
545 if (header.chunked())
546 theSize = -1;
547 else if (content_length >= 0)
548 theSize = content_length;
549 else
550 theSize = -1;
551 }
552
553 return expectBody;
554}
555
556bool
557HttpReply::receivedBodyTooLarge(HttpRequest& request, int64_t receivedSize)
558{
559 calcMaxBodySize(request);
560 debugs(58, 3, receivedSize << " >? " << bodySizeMax);
561 return bodySizeMax >= 0 && receivedSize > bodySizeMax;
562}
563
564bool
566{
567 calcMaxBodySize(request);
568 debugs(58, 7, "bodySizeMax=" << bodySizeMax);
569
570 if (bodySizeMax < 0) // no body size limit
571 return false;
572
573 int64_t expectedSize = -1;
574 if (!expectingBody(request.method, expectedSize))
575 return false;
576
577 debugs(58, 6, expectedSize << " >? " << bodySizeMax);
578
579 if (expectedSize < 0) // expecting body of an unknown length
580 return false;
581
582 return expectedSize > bodySizeMax;
583}
584
585void
587{
588 // hack: -2 is used as "we have not calculated max body size yet" state
589 if (bodySizeMax != -2) // already tried
590 return;
591 bodySizeMax = -1;
592
593 // short-circuit ACL testing if there are none configured
595 return;
596
597 ACLFilledChecklist ch(nullptr, &request, nullptr);
598 // XXX: cont-cast becomes irrelevant when checklist is HttpReply::Pointer
599 ch.reply = const_cast<HttpReply *>(this);
600 HTTPMSGLOCK(ch.reply);
601 for (AclSizeLimit *l = Config.ReplyBodySize; l; l = l -> next) {
602 /* if there is no ACL list or if the ACLs listed match use this size value */
603 if (!l->aclList || ch.fastCheck(l->aclList).allowed()) {
604 debugs(58, 4, "bodySizeMax=" << bodySizeMax);
605 bodySizeMax = l->size; // may be -1
606 break;
607 }
608 }
609}
610
611// XXX: check that this is sufficient for eCAP cloning
612HttpReply *
614{
615 HttpReply *rep = new HttpReply();
616 rep->sline = sline; // used in hdrCacheInit() call below
617 rep->header.append(&header);
618 rep->hdrCacheInit();
619 rep->hdr_sz = hdr_sz;
620 rep->http_ver = http_ver;
621 rep->pstate = pstate;
622 rep->body_pipe = body_pipe;
623
624 // keep_alive is handled in hdrCacheInit()
625 return rep;
626}
627
628bool
630{
631 const HttpReply *aRep = dynamic_cast<const HttpReply*>(aMsg);
632 if (!aRep)
633 return false;
634 keep_alive = aRep->keep_alive;
635 sources = aRep->sources;
636 return true;
637}
638
639bool
641{
642 if (!them || !them->date || !date)
643 return false;
644 return date < them->date;
645}
646
647void
651 debugs(58, 3, "Removing unexpected Content-Length header");
652}
653
#define Assure(condition)
Definition: Assure.h:35
#define Here()
source code location of the caller
Definition: Here.h:15
@ hoReply
Definition: HttpHeader.h:37
time_t squid_curtime
Definition: stub_libtime.cc:20
class SquidConfig Config
Definition: SquidConfig.cc:12
constexpr bool Less(const A a, const B b)
whether integer a is less than integer b, with correct overflow handling
Definition: SquidMath.h:48
void error(char *format,...)
#define assert(EX)
Definition: assert.h:17
Acl::Answer const & fastCheck()
Definition: Checklist.cc:332
representation of a class of Size-limit ACLs
Definition: AclSizeLimit.h:17
bool allowed() const
Definition: Acl.h:156
unsigned int major
major version number
static std::ostream & Extra(std::ostream &)
Definition: debug.cc:1313
void packInto(Packable *) const
Definition: HttpBody.cc:14
void clear()
clear the HttpBody content
Definition: HttpBody.h:35
bool hasSMaxAge(int32_t *val=nullptr) const
Definition: HttpHdrCc.h:127
bool hasMaxAge(int32_t *val=nullptr) const
Definition: HttpHdrCc.h:122
HttpHeaderEntry * clone() const
Definition: HttpHeader.cc:1507
void putStr(Http::HdrType id, const char *str)
Definition: HttpHeader.cc:996
bool chunked() const
Definition: HttpHeader.h:169
String getStrOrList(Http::HdrType id) const
Definition: HttpHeader.cc:823
void compact()
Definition: HttpHeader.cc:712
int delById(Http::HdrType id)
Definition: HttpHeader.cc:667
void update(const HttpHeader *fresh)
Definition: HttpHeader.cc:268
const char * getStr(Http::HdrType id) const
Definition: HttpHeader.cc:1164
bool needUpdate(const HttpHeader *fresh) const
Definition: HttpHeader.cc:245
void addEntry(HttpHeaderEntry *e)
Definition: HttpHeader.cc:737
HttpHdrContRange * getContRange() const
Definition: HttpHeader.cc:1262
void putInt64(Http::HdrType id, int64_t number)
Definition: HttpHeader.cc:978
time_t getTime(Http::HdrType id) const
Definition: HttpHeader.cc:1147
int has(Http::HdrType id) const
Definition: HttpHeader.cc:938
int64_t getInt64(Http::HdrType id) const
Definition: HttpHeader.cc:1134
void clean()
Definition: HttpHeader.cc:186
HttpHeaderEntry * findEntry(Http::HdrType id) const
Definition: HttpHeader.cc:603
void putTime(Http::HdrType id, time_t htime)
Definition: HttpHeader.cc:987
HttpHdrSc * getSc() const
Definition: HttpHeader.cc:1240
void packInto(Packable *p, bool mask_sensitive_info=false) const
Definition: HttpHeader.cc:540
void append(const HttpHeader *src)
Definition: HttpHeader.cc:232
bool parseFirstLine(const char *start, const char *end) override
Definition: HttpReply.cc:457
Http::StatusLine sline
Definition: HttpReply.h:56
size_t parseTerminatedPrefix(const char *, size_t)
Definition: HttpReply.cc:463
String content_type
Definition: HttpReply.h:46
void hdrCacheClean()
Definition: HttpReply.cc:353
MemBuf * pack() const
Definition: HttpReply.cc:112
time_t hdrExpirationTime()
Definition: HttpReply.cc:283
time_t last_modified
Definition: HttpReply.h:42
HttpHdrContRange * content_range
parsed Content-Range; nil for non-206 responses!
Definition: HttpReply.h:163
const HttpHdrContRange * contentRange() const
Definition: HttpReply.cc:345
int httpMsgParseError() override
Definition: HttpReply.cc:515
void configureContentLengthInterpreter(Http::ContentLengthInterpreter &) override
configures the interpreter as needed
Definition: HttpReply.cc:501
HttpReplyPointer make304() const
Definition: HttpReply.cc:129
bool olderThan(const HttpReply *them) const
Definition: HttpReply.cc:640
bool expectingBody(const HttpRequestMethod &, int64_t &) const override
Definition: HttpReply.cc:528
bool parseHeader(Http1::Parser &hp)
parses reply header using Parser
Definition: HttpReply.cc:507
HttpHdrSc * surrogate_control
Definition: HttpReply.h:48
void setHeaders(Http::StatusCode status, const char *reason, const char *ctype, int64_t clen, time_t lmt, time_t expires)
Definition: HttpReply.cc:170
void init()
Definition: HttpReply.cc:51
bool inheritProperties(const Http::Message *) override
Definition: HttpReply.cc:629
void calcMaxBodySize(HttpRequest &request) const
Definition: HttpReply.cc:586
int64_t bodySize(const HttpRequestMethod &) const
Definition: HttpReply.cc:377
size_t prefixLen() const
Definition: HttpReply.cc:495
MemBuf * packed304Reply() const
Definition: HttpReply.cc:159
HttpBody body
Definition: HttpReply.h:58
int64_t bodySizeMax
Definition: HttpReply.h:161
void removeIrrelevantContentLength()
Some response status codes prohibit sending Content-Length (RFC 7230 section 3.3.2).
Definition: HttpReply.cc:648
bool receivedBodyTooLarge(HttpRequest &, int64_t receivedBodySize)
Definition: HttpReply.cc:557
void redirect(Http::StatusCode, const char *)
Definition: HttpReply.cc:205
bool sanityCheckStartLine(const char *buf, const size_t hdr_len, Http::StatusCode *error) override
Definition: HttpReply.cc:402
int validatorsMatch(HttpReply const *other) const
Definition: HttpReply.cc:223
void hdrCacheInit() override
Definition: HttpReply.cc:321
void reset() override
Definition: HttpReply.cc:59
void packHeadersUsingSlowPacker(Packable &p) const
same as packHeadersUsingFastPacker() but assumes that p cannot quickly process small additions
Definition: HttpReply.cc:95
~HttpReply() override
Definition: HttpReply.cc:44
bool do_clean
Definition: HttpReply.h:62
void packInto(MemBuf &) const
Definition: HttpReply.cc:104
void packHeadersUsingFastPacker(Packable &p) const
Definition: HttpReply.cc:87
Pointer recreateOnNotModified(const HttpReply &reply304) const
Definition: HttpReply.cc:265
void clean()
Definition: HttpReply.cc:73
bool expectedBodyTooLarge(HttpRequest &request)
Definition: HttpReply.cc:565
time_t date
Definition: HttpReply.h:40
HttpReply * clone() const override
Definition: HttpReply.cc:613
static HttpReplyPointer MakeConnectionEstablished()
construct and return an HTTP/200 (Connection Established) response
Definition: HttpReply.cc:121
String protoPrefix
Definition: HttpReply.h:60
short int keep_alive
Definition: HttpReply.h:53
time_t expires
Definition: HttpReply.h:44
Http::MethodType id() const
Definition: RequestMethod.h:70
HttpRequestMethod method
Definition: HttpRequest.h:114
void applyStatusCodeRules(const StatusCode code)
prohibits Content-Length in 1xx and 204 responses
common parts of HttpRequest and HttpReply
Definition: Message.h:26
virtual void hdrCacheInit()
Definition: Message.cc:261
bool persistent() const
Definition: Message.cc:236
uint32_t sources
The message sources.
Definition: Message.h:99
virtual int httpMsgParseError()
Definition: Message.cc:221
@ psReadyToParseStartLine
Definition: Message.h:87
HttpHeader header
Definition: Message.h:74
int hdr_sz
Definition: Message.h:81
ParseState pstate
the current parsing state
Definition: Message.h:94
int64_t content_length
Definition: Message.h:83
bool parse(const char *buf, const size_t sz, bool eol, Http::StatusCode *error)
Definition: Message.cc:68
BodyPipe::Pointer body_pipe
optional pipeline to receive message body
Definition: Message.h:97
HttpHdrCc * cache_control
Definition: Message.h:76
void putCc(const HttpHdrCc &)
Definition: Message.cc:33
AnyP::ProtocolVersion http_ver
Definition: Message.h:72
bool parse(const String &protoPrefix, const char *start, const char *end)
Definition: StatusLine.cc:124
void init()
reset this status-line back to empty state
Definition: StatusLine.cc:22
void clean()
reset this status-line back to Internal Server Error state
Definition: StatusLine.cc:28
size_t packedLength() const
expected size of packInto() output
Definition: StatusLine.cc:50
void packInto(Packable *) const
pack fields into a Packable object
Definition: StatusLine.cc:86
AnyP::ProtocolVersion version
breakdown of protocol version label: (HTTP/ICY) and (0.9/1.0/1.1)
Definition: StatusLine.h:65
void set(const AnyP::ProtocolVersion &newVersion, Http::StatusCode newStatus, const char *newReason=nullptr)
Definition: StatusLine.cc:35
Http::StatusCode status() const
retrieve the status code for this status line
Definition: StatusLine.h:45
Definition: MemBuf.h:24
void init(mb_size_t szInit, mb_size_t szMax)
Definition: MemBuf.cc:93
char * content()
start of the added data
Definition: MemBuf.h:41
mb_size_t contentSize() const
available data size
Definition: MemBuf.h:47
virtual void append(const char *buf, int size)=0
Appends a c-string to existing packed data.
int vary_ignore_expire
Definition: SquidConfig.h:312
size_t maxReplyHeaderSize
Definition: SquidConfig.h:137
struct SquidConfig::@106 onoff
AclSizeLimit * ReplyBodySize
Definition: SquidConfig.h:138
int psize() const
Definition: SquidString.h:77
int cmp(char const *) const
Definition: String.cc:236
void clean()
Definition: String.cc:103
void assign(const char *str, int len)
Definition: String.cc:78
size_type size() const
Definition: SquidString.h:73
an std::runtime_error with thrower location info
Definition: TextException.h:21
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:194
char const * visible_appname_string
void HTTPMSGLOCK(Http::Message *a)
Definition: Message.h:161
Definition: forward.h:18
bool ProhibitsContentLength(const StatusCode sc)
whether this response status code prohibits sending Content-Length
Definition: StatusCode.h:96
StatusCode
Definition: StatusCode.h:20
@ scInvalidHeader
Definition: StatusCode.h:86
@ scNone
Definition: StatusCode.h:21
@ scNotModified
Definition: StatusCode.h:40
@ scOkay
Definition: StatusCode.h:26
@ scNoContent
Definition: StatusCode.h:30
@ scPartialContent
Definition: StatusCode.h:32
@ METHOD_HEAD
Definition: MethodType.h:28
@ CONTENT_LENGTH
AnyP::ProtocolVersion ProtocolVersion(unsigned int aMajor, unsigned int aMinor)
HTTP version label information.
SBuf ToSBuf(Args &&... args)
slowly stream-prints all arguments into a freshly allocated SBuf
Definition: Stream.h:63
#define xisdigit(x)
Definition: xis.h:18

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors