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 
50 void
52 {
53  hdrCacheInit();
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 
72 void
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();
80  hdrCacheClean();
81  header.clean();
82  sline.clean();
83  bodySizeMax = -2; // hack: make calculatedBodySizeMax() false
84 }
85 
86 void
88 {
89  sline.packInto(&p);
90  header.packInto(&p);
91  p.append("\r\n", 2);
92 }
93 
94 void
96 {
97  MemBuf buf;
98  buf.init();
100  p.append(buf.content(), buf.contentSize());
101 }
102 
103 void
105 {
107  body.packInto(&buf);
108 }
109 
110 /* create memBuf, create mem-based packer, pack, destroy packer, return MemBuf */
111 MemBuf *
113 {
114  MemBuf *mb = new MemBuf;
115  mb->init();
116  packInto(*mb);
117  return mb;
118 }
119 
122 
123  HttpReplyPointer rep(new HttpReply);
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;
135  HttpHeaderEntry *e;
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 
158 MemBuf *
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 
169 void
170 HttpReply::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;
177  hdr->putStr(Http::HdrType::MIME_VERSION, "1.0");
179 
180  if (ctype) {
181  hdr->putStr(Http::HdrType::CONTENT_TYPE, ctype);
182  content_type = ctype;
183  } else
184  content_type = String();
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 
204 void
205 HttpReply::redirect(Http::StatusCode status, const char *loc)
206 {
207  HttpHeader *hdr;
208  sline.set(Http::ProtocolVersion(), status, nullptr);
209  hdr = &header;
213  hdr->putStr(Http::HdrType::LOCATION, loc);
215  content_length = 0;
216 }
217 
218 /* compare the validators of two replies.
219  * 1 = they match
220  * 0 = they do not match
221  */
222 int
223 HttpReply::validatorsMatch(HttpReply const * otherRep) const
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 
282 time_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 */
320 void
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
338  content_type = String();
339 
340  /* be sure to set expires after date and cache-control */
342 }
343 
344 const HttpHdrContRange *
346 {
348  return content_range;
349 }
350 
351 /* sync this routine when you update HttpReply struct */
352 void
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  */
376 int64_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 
401 bool
402 HttpReply::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 
456 bool
457 HttpReply::parseFirstLine(const char *blk_start, const char *blk_end)
458 {
459  return sline.parse(protoPrefix, blk_start, blk_end);
460 }
461 
462 size_t
463 HttpReply::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 
494 size_t
496 {
497  return sline.packedLength() + header.len + 2;
498 }
499 
500 void
502 {
503  interpreter.applyStatusCodeRules(sline.status());
504 }
505 
506 bool
508 {
510  return Message::parseHeader(hp, clen);
511 }
512 
513 /* handy: resets and returns -1 */
514 int
516 {
517  int result(Http::Message::httpMsgParseError());
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  */
527 bool
528 HttpReply::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 
556 bool
557 HttpReply::receivedBodyTooLarge(HttpRequest& request, int64_t receivedSize)
558 {
559  calcMaxBodySize(request);
560  debugs(58, 3, receivedSize << " >? " << bodySizeMax);
561  return bodySizeMax >= 0 && receivedSize > bodySizeMax;
562 }
563 
564 bool
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 
585 void
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
594  if (!Config.ReplyBodySize)
595  return;
596 
597  ACLFilledChecklist ch(nullptr, &request);
598  ch.updateReply(this);
599  for (AclSizeLimit *l = Config.ReplyBodySize; l; l = l -> next) {
600  /* if there is no ACL list or if the ACLs listed match use this size value */
601  if (!l->aclList || ch.fastCheck(l->aclList).allowed()) {
602  debugs(58, 4, "bodySizeMax=" << bodySizeMax);
603  bodySizeMax = l->size; // may be -1
604  break;
605  }
606  }
607 }
608 
609 // XXX: check that this is sufficient for eCAP cloning
610 HttpReply *
612 {
613  HttpReply *rep = new HttpReply();
614  rep->sline = sline; // used in hdrCacheInit() call below
615  rep->header.append(&header);
616  rep->hdrCacheInit();
617  rep->hdr_sz = hdr_sz;
618  rep->http_ver = http_ver;
619  rep->pstate = pstate;
620  rep->body_pipe = body_pipe;
621 
622  // keep_alive is handled in hdrCacheInit()
623  return rep;
624 }
625 
626 bool
628 {
629  const HttpReply *aRep = dynamic_cast<const HttpReply*>(aMsg);
630  if (!aRep)
631  return false;
632  keep_alive = aRep->keep_alive;
633  sources = aRep->sources;
634  return true;
635 }
636 
637 bool
638 HttpReply::olderThan(const HttpReply *them) const
639 {
640  if (!them || !them->date || !date)
641  return false;
642  return date < them->date;
643 }
644 
645 void
649  debugs(58, 3, "Removing unexpected Content-Length header");
650 }
651 
int hdr_sz
Definition: Message.h:81
HttpReplyPointer make304() const
Definition: HttpReply.cc:129
bool parseFirstLine(const char *start, const char *end) override
Definition: HttpReply.cc:457
void append(const HttpHeader *src)
Definition: HttpHeader.cc:231
@ hoReply
Definition: HttpHeader.h:37
bool expectingBody(const HttpRequestMethod &, int64_t &) const override
Definition: HttpReply.cc:528
String content_type
Definition: HttpReply.h:46
unsigned int major
major version number
#define Here()
source code location of the caller
Definition: Here.h:15
bool expectedBodyTooLarge(HttpRequest &request)
Definition: HttpReply.cc:565
AnyP::ProtocolVersion http_ver
Definition: Message.h:72
@ METHOD_HEAD
Definition: MethodType.h:28
common parts of HttpRequest and HttpReply
Definition: Message.h:25
BodyPipe::Pointer body_pipe
optional pipeline to receive message body
Definition: Message.h:97
AclSizeLimit * ReplyBodySize
Definition: SquidConfig.h:138
bool do_clean
Definition: HttpReply.h:62
time_t hdrExpirationTime()
Definition: HttpReply.cc:283
const char * getStr(Http::HdrType id) const
Definition: HttpHeader.cc:1163
@ scNone
Definition: StatusCode.h:21
int psize() const
Definition: SquidString.h:77
HttpHeader header
Definition: Message.h:74
int64_t bodySizeMax
Definition: HttpReply.h:161
bool parse(const String &protoPrefix, const char *start, const char *end)
Definition: StatusLine.cc:124
representation of a class of Size-limit ACLs
Definition: AclSizeLimit.h:16
size_t packedLength() const
expected size of packInto() output
Definition: StatusLine.cc:50
void error(char *format,...)
int64_t bodySize(const HttpRequestMethod &) const
Definition: HttpReply.cc:377
HttpReply * clone() const override
Definition: HttpReply.cc:611
void init(mb_size_t szInit, mb_size_t szMax)
Definition: MemBuf.cc:93
size_t maxReplyHeaderSize
Definition: SquidConfig.h:137
virtual void append(const char *buf, int size)=0
Appends a c-string to existing packed data.
void packInto(Packable *) const
pack fields into a Packable object
Definition: StatusLine.cc:86
void init()
reset this status-line back to empty state
Definition: StatusLine.cc:22
bool needUpdate(const HttpHeader *fresh) const
Definition: HttpHeader.cc:244
struct SquidConfig::@97 onoff
int cmp(char const *) const
Definition: String.cc:236
void packHeadersUsingSlowPacker(Packable &p) const
same as packHeadersUsingFastPacker() but assumes that p cannot quickly process small additions
Definition: HttpReply.cc:95
void applyStatusCodeRules(const StatusCode code)
prohibits Content-Length in 1xx and 204 responses
Http::StatusLine sline
Definition: HttpReply.h:56
time_t last_modified
Definition: HttpReply.h:42
StatusCode
Definition: StatusCode.h:20
Definition: forward.h:17
String getStrOrList(Http::HdrType id) const
Definition: HttpHeader.cc:822
void calcMaxBodySize(HttpRequest &request) const
Definition: HttpReply.cc:586
MemBuf * packed304Reply() const
Definition: HttpReply.cc:159
void packHeadersUsingFastPacker(Packable &p) const
Definition: HttpReply.cc:87
@ CONTENT_LENGTH
void updateReply(const HttpReply::Pointer &)
bool chunked() const
Definition: HttpHeader.h:169
HttpBody body
Definition: HttpReply.h:58
bool persistent() const
Definition: Message.cc:236
void removeIrrelevantContentLength()
Some response status codes prohibit sending Content-Length (RFC 7230 section 3.3.2).
Definition: HttpReply.cc:646
virtual void hdrCacheInit()
Definition: Message.cc:261
Http::MethodType id() const
Definition: RequestMethod.h:70
time_t expires
Definition: HttpReply.h:44
mb_size_t contentSize() const
available data size
Definition: MemBuf.h:47
Http::StatusCode status() const
retrieve the status code for this status line
Definition: StatusLine.h:45
const Acl::Answer & fastCheck()
Definition: Checklist.cc:298
MemBuf * pack() const
Definition: HttpReply.cc:112
Definition: MemBuf.h:23
HttpHdrSc * getSc() const
Definition: HttpHeader.cc:1239
void reset() override
Definition: HttpReply.cc:59
@ scPartialContent
Definition: StatusCode.h:33
int delById(Http::HdrType id)
Definition: HttpHeader.cc:666
bool hasSMaxAge(int32_t *val=nullptr) const
Definition: HttpHdrCc.h:127
int vary_ignore_expire
Definition: SquidConfig.h:312
void set(const AnyP::ProtocolVersion &newVersion, Http::StatusCode newStatus, const char *newReason=nullptr)
Definition: StatusLine.cc:35
int64_t getInt64(Http::HdrType id) const
Definition: HttpHeader.cc:1133
void addEntry(HttpHeaderEntry *e)
Definition: HttpHeader.cc:736
time_t getTime(Http::HdrType id) const
Definition: HttpHeader.cc:1146
const char * visible_appname_string
void putTime(Http::HdrType id, time_t htime)
Definition: HttpHeader.cc:986
#define assert(EX)
Definition: assert.h:17
HttpHdrCc * cache_control
Definition: Message.h:76
#define xisdigit(x)
Definition: xis.h:18
void init()
Definition: HttpReply.cc:51
void redirect(Http::StatusCode, const char *)
Definition: HttpReply.cc:205
#define Assure(condition)
Definition: Assure.h:35
void packInto(Packable *p, bool mask_sensitive_info=false) const
Definition: HttpHeader.cc:539
bool inheritProperties(const Http::Message *) override
Definition: HttpReply.cc:627
bool olderThan(const HttpReply *them) const
Definition: HttpReply.cc:638
time_t squid_curtime
Definition: stub_libtime.cc:20
static std::ostream & Extra(std::ostream &)
Definition: debug.cc:1316
void packInto(MemBuf &) const
Definition: HttpReply.cc:104
int64_t content_length
Definition: Message.h:83
void packInto(Packable *) const
Definition: HttpBody.cc:14
time_t date
Definition: HttpReply.h:40
bool receivedBodyTooLarge(HttpRequest &, int64_t receivedBodySize)
Definition: HttpReply.cc:557
bool parseHeader(Http1::Parser &hp)
parses reply header using Parser
Definition: HttpReply.cc:507
int validatorsMatch(HttpReply const *other) const
Definition: HttpReply.cc:223
@ scNotModified
Definition: StatusCode.h:41
uint32_t sources
The message sources.
Definition: Message.h:99
HttpRequestMethod method
Definition: HttpRequest.h:114
HttpHeaderEntry * findEntry(Http::HdrType id) const
Definition: HttpHeader.cc:602
ParseState pstate
the current parsing state
Definition: Message.h:94
bool allowed() const
Definition: Acl.h:82
String protoPrefix
Definition: HttpReply.h:60
AnyP::ProtocolVersion version
breakdown of protocol version label: (HTTP/ICY) and (0.9/1.0/1.1)
Definition: StatusLine.h:65
void clean()
Definition: HttpReply.cc:73
bool ProhibitsContentLength(const StatusCode sc)
whether this response status code prohibits sending Content-Length
Definition: StatusCode.h:98
@ scNoContent
Definition: StatusCode.h:31
size_t prefixLen() const
Definition: HttpReply.cc:495
const HttpHdrContRange * contentRange() const
Definition: HttpReply.cc:345
an std::runtime_error with thrower location info
Definition: TextException.h:20
int has(Http::HdrType id) const
Definition: HttpHeader.cc:937
char * content()
start of the added data
Definition: MemBuf.h:41
bool hasMaxAge(int32_t *val=nullptr) const
Definition: HttpHdrCc.h:122
void putCc(const HttpHdrCc &)
Definition: Message.cc:33
size_t parseTerminatedPrefix(const char *, size_t)
Definition: HttpReply.cc:463
void putStr(Http::HdrType id, const char *str)
Definition: HttpHeader.cc:995
size_type size() const
Definition: SquidString.h:73
~HttpReply() override
Definition: HttpReply.cc:44
SBuf ToSBuf(Args &&... args)
slowly stream-prints all arguments into a freshly allocated SBuf
Definition: Stream.h:63
bool sanityCheckStartLine(const char *buf, const size_t hdr_len, Http::StatusCode *error) override
Definition: HttpReply.cc:402
void hdrCacheClean()
Definition: HttpReply.cc:353
void assign(const char *str, int len)
Definition: String.cc:78
static HttpReplyPointer MakeConnectionEstablished()
construct and return an HTTP/200 (Connection Established) response
Definition: HttpReply.cc:121
HttpHdrSc * surrogate_control
Definition: HttpReply.h:48
@ scInvalidHeader
Squid header parsing error.
Definition: StatusCode.h:88
HttpHdrContRange * content_range
parsed Content-Range; nil for non-206 responses!
Definition: HttpReply.h:163
void hdrCacheInit() override
Definition: HttpReply.cc:321
void compact()
Definition: HttpHeader.cc:711
void update(const HttpHeader *fresh)
Definition: HttpHeader.cc:267
virtual int httpMsgParseError()
Definition: Message.cc:221
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 configureContentLengthInterpreter(Http::ContentLengthInterpreter &) override
configures the interpreter as needed
Definition: HttpReply.cc:501
@ scOkay
Definition: StatusCode.h:27
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
HttpHdrContRange * getContRange() const
Definition: HttpHeader.cc:1261
void clear()
clear the HttpBody content
Definition: HttpBody.h:35
int httpMsgParseError() override
Definition: HttpReply.cc:515
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:192
short int keep_alive
Definition: HttpReply.h:53
void clean()
Definition: HttpHeader.cc:185
void clean()
reset this status-line back to Internal Server Error state
Definition: StatusLine.cc:28
void putInt64(Http::HdrType id, int64_t number)
Definition: HttpHeader.cc:977
HttpHeaderEntry * clone() const
Definition: HttpHeader.cc:1506
class SquidConfig Config
Definition: SquidConfig.cc:12
void clean()
Definition: String.cc:103
AnyP::ProtocolVersion ProtocolVersion(unsigned int aMajor, unsigned int aMinor)
HTTP version label information.
bool parse(const char *buf, const size_t sz, bool eol, Http::StatusCode *error)
Definition: Message.cc:68
@ psReadyToParseStartLine
Definition: Message.h:87
Pointer recreateOnNotModified(const HttpReply &reply304) const
Definition: HttpReply.cc:265

 

Introduction

Documentation

Support

Miscellaneous