HttpRequest.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 73 HTTP Request */
10 
11 #include "squid.h"
12 #include "AccessLogEntry.h"
13 #include "acl/AclSizeLimit.h"
14 #include "acl/FilledChecklist.h"
15 #include "CachePeer.h"
16 #include "client_side.h"
17 #include "client_side_request.h"
18 #include "dns/LookupDetails.h"
19 #include "Downloader.h"
20 #include "error/Detail.h"
21 #include "globals.h"
22 #include "http.h"
24 #include "http/one/RequestParser.h"
25 #include "http/Stream.h"
26 #include "HttpHdrCc.h"
27 #include "HttpHeaderRange.h"
28 #include "HttpRequest.h"
29 #include "log/Config.h"
30 #include "MemBuf.h"
31 #include "sbuf/StringConvert.h"
32 #include "SquidConfig.h"
33 #include "Store.h"
34 
35 #if USE_AUTH
36 #include "auth/UserRequest.h"
37 #endif
38 #if ICAP_CLIENT
40 #endif
41 
43  Http::Message(hoRequest),
44  masterXaction(mx)
45 {
46  assert(mx);
47  init();
48 }
49 
50 HttpRequest::HttpRequest(const HttpRequestMethod& aMethod, AnyP::ProtocolType aProtocol, const char *aSchemeImg, const char *aUrlpath, const MasterXaction::Pointer &mx) :
51  Http::Message(hoRequest),
52  masterXaction(mx)
53 {
54  assert(mx);
55  static unsigned int id = 1;
56  debugs(93,7, "constructed, this=" << this << " id=" << ++id);
57  init();
58  initHTTP(aMethod, aProtocol, aSchemeImg, aUrlpath);
59 }
60 
62 {
63  clean();
64  debugs(93,7, "destructed, this=" << this);
65 }
66 
67 void
68 HttpRequest::initHTTP(const HttpRequestMethod& aMethod, AnyP::ProtocolType aProtocol, const char *aSchemeImg, const char *aUrlpath)
69 {
70  method = aMethod;
71  url.setScheme(aProtocol, aSchemeImg);
72  url.path(aUrlpath);
73 }
74 
75 void
77 {
79  url.clear();
80 #if USE_AUTH
81  auth_user_request = nullptr;
82 #endif
83  flags = RequestFlags();
84  range = nullptr;
85  ims = -1;
86  imslen = 0;
87  lastmod = -1;
89  my_addr.setEmpty();
90  body_pipe = nullptr;
91  // hier
92  dnsWait = -1;
93  error.clear();
94  peer_login = nullptr; // not allocated/deallocated by this class
95  peer_domain = nullptr; // not allocated/deallocated by this class
96  peer_host = nullptr;
97  vary_headers = SBuf();
99  tag = null_string;
100 #if USE_AUTH
103 #endif
107 #if FOLLOW_X_FORWARDED_FOR
109 #endif /* FOLLOW_X_FORWARDED_FOR */
110 #if USE_ADAPTATION
111  adaptHistory_ = nullptr;
112 #endif
113 #if ICAP_CLIENT
114  icapHistory_ = nullptr;
115 #endif
116  rangeOffsetLimit = -2; //a value of -2 means not checked yet
117  forcedBodyContinuation = false;
118 }
119 
120 void
122 {
123  // we used to assert that the pipe is NULL, but now the request only
124  // points to a pipe that is owned and initiated by another object.
125  body_pipe = nullptr;
126 #if USE_AUTH
127  auth_user_request = nullptr;
128 #endif
130  url.clear();
131 
132  header.clean();
133 
134  if (cache_control) {
135  delete cache_control;
136  cache_control = nullptr;
137  }
138 
139  if (range) {
140  delete range;
141  range = nullptr;
142  }
143 
144  myportname.clean();
145 
146  theNotes = nullptr;
147 
148  tag.clean();
149 #if USE_AUTH
150  extacl_user.clean();
152 #endif
153  extacl_log.clean();
154 
156 
157  etag.clean();
158 
159 #if USE_ADAPTATION
160  adaptHistory_ = nullptr;
161 #endif
162 #if ICAP_CLIENT
163  icapHistory_ = nullptr;
164 #endif
165 }
166 
167 void
169 {
170  clean();
171  init();
172 }
173 
174 HttpRequest *
176 {
178  copy->method = method;
179  // TODO: move common cloning clone to Msg::copyTo() or copy ctor
180  copy->header.append(&header);
181  copy->hdrCacheInit();
182  copy->hdr_sz = hdr_sz;
183  copy->http_ver = http_ver;
184  copy->pstate = pstate; // TODO: should we assert a specific state here?
185  copy->body_pipe = body_pipe;
186 
187  copy->url = url;
188 
189  // range handled in hdrCacheInit()
190  copy->ims = ims;
191  copy->imslen = imslen;
192  copy->hier = hier; // Is it safe to copy? Should we?
193 
194  copy->error = error;
195 
196  // XXX: what to do with copy->peer_login?
197 
198  copy->lastmod = lastmod;
199  copy->etag = etag;
200  copy->vary_headers = vary_headers;
201  // XXX: what to do with copy->peer_domain?
202 
203  copy->tag = tag;
204  copy->extacl_log = extacl_log;
206 
207  const bool inheritWorked = copy->inheritProperties(this);
208  assert(inheritWorked);
209 
210  return copy;
211 }
212 
213 bool
215 {
216  const HttpRequest* aReq = dynamic_cast<const HttpRequest*>(aMsg);
217  if (!aReq)
218  return false;
219 
220  client_addr = aReq->client_addr;
221 #if FOLLOW_X_FORWARDED_FOR
223 #endif
224  my_addr = aReq->my_addr;
225 
226  dnsWait = aReq->dnsWait;
227 
228 #if USE_ADAPTATION
229  adaptHistory_ = aReq->adaptHistory();
230 #endif
231 #if ICAP_CLIENT
232  icapHistory_ = aReq->icapHistory();
233 #endif
234 
235  // This may be too conservative for the 204 No Content case
236  // may eventually need cloneNullAdaptationImmune() for that.
238 
239  error = aReq->error;
240 #if USE_AUTH
242  extacl_user = aReq->extacl_user;
244 #endif
245 
246  myportname = aReq->myportname;
247 
249 
250  // main property is which connection the request was received on (if any)
252 
253  downloader = aReq->downloader;
254 
255  theNotes = aReq->theNotes;
256 
257  sources = aReq->sources;
258  return true;
259 }
260 
267 bool
268 HttpRequest::sanityCheckStartLine(const char *buf, const size_t hdr_len, Http::StatusCode *scode)
269 {
270  // content is long enough to possibly hold a reply
271  // 2 being magic size of a 1-byte request method plus space delimiter
272  if (hdr_len < 2) {
273  // this is only a real error if the headers apparently complete.
274  if (hdr_len > 0) {
275  debugs(58, 3, "Too large request header (" << hdr_len << " bytes)");
276  *scode = Http::scInvalidHeader;
277  }
278  return false;
279  }
280 
281  /* See if the request buffer starts with a non-whitespace HTTP request 'method'. */
283  m.HttpRequestMethodXXX(buf);
284  if (m == Http::METHOD_NONE) {
285  debugs(73, 3, "HttpRequest::sanityCheckStartLine: did not find HTTP request method");
286  *scode = Http::scInvalidHeader;
287  return false;
288  }
289 
290  return true;
291 }
292 
293 bool
294 HttpRequest::parseFirstLine(const char *start, const char *end)
295 {
297 
298  if (method == Http::METHOD_NONE)
299  return false;
300 
301  // XXX: performance regression, strcspn() over the method bytes a second time.
302  // cheaper than allocate+copy+deallocate cycle to SBuf convert a piece of start.
303  const char *t = start + strcspn(start, w_space);
304 
305  start = t + strspn(t, w_space); // skip w_space after method
306 
307  const char *ver = findTrailingHTTPVersion(start, end);
308 
309  if (ver) {
310  end = ver - 1;
311 
312  while (xisspace(*end)) // find prev non-space
313  --end;
314 
315  ++end; // back to space
316 
317  if (2 != sscanf(ver + 5, "%d.%d", &http_ver.major, &http_ver.minor)) {
318  debugs(73, DBG_IMPORTANT, "ERROR: parseRequestLine: Invalid HTTP identifier.");
319  return false;
320  }
321  } else {
322  http_ver.major = 0;
323  http_ver.minor = 9;
324  }
325 
326  if (end < start) // missing URI
327  return false;
328 
329  return url.parse(method, SBuf(start, size_t(end-start)));
330 }
331 
332 /* swaps out request using httpRequestPack */
333 void
335 {
336  assert(e);
337  e->buffer();
338  pack(e);
339  e->flush();
340 }
341 
342 /* packs request-line and headers, appends <crlf> terminator */
343 void
345 {
346  assert(p);
347  /* pack request-line */
348  p->appendf(SQUIDSBUFPH " " SQUIDSBUFPH " HTTP/%d.%d\r\n",
351  /* headers */
352  header.packInto(p);
353  /* trailer */
354  p->append("\r\n", 2);
355 }
356 
357 /*
358  * A wrapper for debugObj()
359  */
360 void
361 httpRequestPack(void *obj, Packable *p)
362 {
363  HttpRequest *request = static_cast<HttpRequest*>(obj);
364  request->pack(p);
365 }
366 
367 /* returns the length of request line + headers + crlf */
368 int
370 {
371  return method.image().length() + 1 +
372  url.path().length() + 1 +
373  4 + 1 + 3 + 2 +
374  header.len + 2;
375 }
376 
377 /* sync this routine when you update HttpRequest struct */
378 void
380 {
382 
383  assert(!range);
384  range = header.getRange();
385 }
386 
387 #if ICAP_CLIENT
390 {
391  if (!icapHistory_) {
392  if (Log::TheConfig.hasIcapToken || IcapLogfileStatus == LOG_ENABLE) {
394  debugs(93,4, "made " << icapHistory_ << " for " << this);
395  }
396  }
397 
398  return icapHistory_;
399 }
400 #endif
401 
402 #if USE_ADAPTATION
404 HttpRequest::adaptHistory(bool createIfNone) const
405 {
406  if (!adaptHistory_ && createIfNone) {
408  debugs(93,4, "made " << adaptHistory_ << " for " << this);
409  }
410 
411  return adaptHistory_;
412 }
413 
416 {
417  return HttpRequest::adaptHistory(Log::TheConfig.hasAdaptToken);
418 }
419 
420 void
422 {
423  if (!adaptHistory_) {
424  adaptHistory_ = them.adaptHistory_; // may be nil
425  } else {
426  // check that histories did not diverge
427  Must(!them.adaptHistory_ || them.adaptHistory_ == adaptHistory_);
428  }
429 }
430 
431 #endif
432 
433 bool
435 {
436  return (range && range->specs.size() > 1);
437 }
438 
439 bool
441 {
442  return body_pipe != nullptr && body_pipe->consumedSize() > 0;
443 }
444 
445 void
447 {
448  // XXX: Saving two pointers to memory controlled by an independent object.
449  peer_login = peer.login;
450  peer_domain = peer.domain;
452  debugs(11, 4, this << " to " << peer);
453 }
454 
455 void
457 {
458  peer_login = nullptr;
459  peer_domain = nullptr;
460  flags.auth_no_keytab = false;
461  debugs(11, 4, this);
462 }
463 
464 void
466 {
467  debugs(11, 7, "old: " << error);
468  error.clear();
469 }
470 
471 void
472 HttpRequest::packFirstLineInto(Packable * p, bool full_uri) const
473 {
474  const SBuf tmp(full_uri ? effectiveRequestUri() : url.path());
475 
476  // form HTTP request-line
477  p->appendf(SQUIDSBUFPH " " SQUIDSBUFPH " HTTP/%d.%d\r\n",
479  SQUIDSBUFPRINT(tmp),
481 }
482 
483 /*
484  * Indicate whether or not we would expect an entity-body
485  * along with this request
486  */
487 bool
488 HttpRequest::expectingBody(const HttpRequestMethod &, int64_t &theSize) const
489 {
490  bool expectBody = false;
491 
492  /*
493  * Note: Checks for message validity is in clientIsContentLengthValid().
494  * this just checks if a entity-body is expected based on HTTP message syntax
495  */
496  if (header.chunked()) {
497  expectBody = true;
498  theSize = -1;
499  } else if (content_length >= 0) {
500  expectBody = true;
501  theSize = content_length;
502  } else {
503  expectBody = false;
504  // theSize undefined
505  }
506 
507  return expectBody;
508 }
509 
510 /*
511  * Create a Request from a URL and METHOD.
512  *
513  * If the METHOD is CONNECT, then a host:port pair is looked for instead of a URL.
514  * If the request cannot be created cleanly, NULL is returned
515  */
516 HttpRequest *
518 {
519  std::unique_ptr<HttpRequest> req(new HttpRequest(mx));
520  if (req->url.parse(method, url)) {
521  req->method = method;
522  return req.release();
523  }
524  return nullptr;
525 }
526 
527 HttpRequest *
528 HttpRequest::FromUrlXXX(const char * url, const MasterXaction::Pointer &mx, const HttpRequestMethod& method)
529 {
530  return FromUrl(SBuf(url), mx, method);
531 }
532 
537 bool
539 {
540  // Intercepted request with Host: header which cannot be trusted.
541  // Because it failed verification, or someone bypassed the security tests
542  // we cannot cache the response for sharing between clients.
543  // TODO: update cache to store for particular clients only (going to same Host: and destination IP)
545  return false;
546 
547  switch (url.getScheme()) {
548  case AnyP::PROTO_HTTP:
549  case AnyP::PROTO_HTTPS:
550  if (!method.respMaybeCacheable())
551  return false;
552 
553  // RFC 9111 section 5.2.1.5:
554  // "The no-store request directive indicates that a cache MUST NOT
555  // store any part of either this request or any response to it."
556  //
557  // NP: refresh_pattern ignore-no-store only applies to response messages
558  // this test is handling request message CC header.
560  return false;
561  break;
562 
563  //case AnyP::PROTO_FTP:
564  default:
565  break;
566  }
567 
568  return true;
569 }
570 
571 bool
573 {
574  return flags.ims ||
577 }
578 
579 void
581 {
582  if (dns.wait >= 0) { // known delay
583  if (dnsWait >= 0) { // have recorded DNS wait before
584  debugs(78, 7, this << " " << dnsWait << " += " << dns);
585  dnsWait += dns.wait;
586  } else {
587  debugs(78, 7, this << " " << dns);
588  dnsWait = dns.wait;
589  }
590  }
591 }
592 
593 int64_t
595 {
596  /* -2 is the starting value of rangeOffsetLimit.
597  * If it is -2, that means we haven't checked it yet.
598  * Otherwise, return the current value */
599  if (rangeOffsetLimit != -2)
600  return rangeOffsetLimit;
601 
602  rangeOffsetLimit = 0; // default value for rangeOffsetLimit
603 
604  ACLFilledChecklist ch(nullptr, this);
605  ch.src_addr = client_addr;
606  ch.my_addr = my_addr;
607 
608  for (AclSizeLimit *l = Config.rangeOffsetLimit; l; l = l -> next) {
609  /* if there is no ACL list or if the ACLs listed match use this limit value */
610  if (!l->aclList || ch.fastCheck(l->aclList).allowed()) {
611  rangeOffsetLimit = l->size; // may be -1
612  debugs(58, 4, rangeOffsetLimit);
613  break;
614  }
615  }
616 
617  return rangeOffsetLimit;
618 }
619 
620 void
621 HttpRequest::ignoreRange(const char *reason)
622 {
623  if (range) {
624  debugs(73, 3, static_cast<void*>(range) << " for " << reason);
625  delete range;
626  range = nullptr;
627  }
628  // Some callers also reset isRanged but it may not be safe for all callers:
629  // isRanged is used to determine whether a weak ETag comparison is allowed,
630  // and that check should not ignore the Range header if it was present.
631  // TODO: Some callers also delete HDR_RANGE, HDR_REQUEST_RANGE. Should we?
632 }
633 
634 bool
636 {
637  // old clients do not support 1xx unless they sent Expect: 100-continue
638  // (we reject all other Http::HdrType::EXPECT values so just check for Http::HdrType::EXPECT)
640  return false;
641 
642  // others must support 1xx control messages
643  return true;
644 }
645 
648 {
649  // RFC 7230 section 3.3.1:
650  // "
651  // A server that receives a request message with a transfer coding it
652  // does not understand SHOULD respond with 501 (Not Implemented).
653  // "
654  if (header.unsupportedTe())
655  return Http::scNotImplemented;
656 
657  // RFC 7230 section 3.3.3 #3 paragraph 3:
658  // Transfer-Encoding overrides Content-Length
659  if (header.chunked())
660  return Http::scNone;
661 
662  // RFC 7230 Section 3.3.3 #4:
663  // conflicting Content-Length(s) mean a message framing error
665  return Http::scBadRequest;
666 
667  // HTTP/1.0 requirements differ from HTTP/1.1
668  if (http_ver <= Http::ProtocolVersion(1,0)) {
669  const auto m = method.id();
670 
671  // RFC 1945 section 8.3:
672  // "
673  // A valid Content-Length is required on all HTTP/1.0 POST requests.
674  // "
675  // RFC 1945 Appendix D.1.1:
676  // "
677  // The fundamental difference between the POST and PUT requests is
678  // reflected in the different meaning of the Request-URI.
679  // "
680  if (m == Http::METHOD_POST || m == Http::METHOD_PUT)
682 
683  // RFC 1945 section 7.2:
684  // "
685  // An entity body is included with a request message only when the
686  // request method calls for one.
687  // "
688  // section 8.1-2: GET and HEAD do not define ('call for') an entity
689  if (m == Http::METHOD_GET || m == Http::METHOD_HEAD)
691  // appendix D1.1.2-4: DELETE, LINK, UNLINK do not define ('call for') an entity
694 
695  // other methods are not defined in RFC 1945
696  // assume they support an (optional) entity
697  return Http::scNone;
698  }
699 
700  // RFC 7230 section 3.3
701  // "
702  // The presence of a message body in a request is signaled by a
703  // Content-Length or Transfer-Encoding header field. Request message
704  // framing is independent of method semantics, even if the method does
705  // not define any use for a message body.
706  // "
707  return Http::scNone;
708 }
709 
710 bool
712 {
714  return Message::parseHeader(hp, clen);
715 }
716 
717 bool
718 HttpRequest::parseHeader(const char *buffer, const size_t size)
719 {
721  return header.parse(buffer, size, clen);
722 }
723 
726 {
728  return clientConnectionManager.get();
729  return nullptr;
730 }
731 
732 const SBuf
734 {
735  if (store_id.size() != 0) {
736  debugs(73, 3, "sent back store_id: " << store_id);
737  return StringToSBuf(store_id);
738  }
739  debugs(73, 3, "sent back effectiveRequestUrl: " << effectiveRequestUri());
740  return effectiveRequestUri();
741 }
742 
743 const SBuf &
745 {
747  return url.authority(true); // host:port
748  return url.absolute();
749 }
750 
753 {
754  if (!theNotes)
755  theNotes = new NotePairs;
756  return theNotes;
757 }
758 
759 void
760 UpdateRequestNotes(ConnStateData *csd, HttpRequest &request, NotePairs const &helperNotes)
761 {
762  // Tag client connection if the helper responded with clt_conn_tag=tag.
763  const char *cltTag = "clt_conn_tag";
764  if (const char *connTag = helperNotes.findFirst(cltTag)) {
765  if (csd) {
766  csd->notes()->remove(cltTag);
767  csd->notes()->add(cltTag, connTag);
768  }
769  }
770  request.notes()->replaceOrAdd(&helperNotes);
771 }
772 
773 void
775 {
777 
778  if (!clientConnectionManager.valid())
779  return;
780 
782  if (port) {
783  myportname = port->name;
784  flags.ignoreCc = port->ignore_cc;
785  }
786 
787  if (auto clientConnection = clientConnectionManager->clientConnection) {
788  client_addr = clientConnection->remote; // XXX: remove request->client_addr member.
789 #if FOLLOW_X_FORWARDED_FOR
790  // indirect client gets stored here because it is an HTTP header result (from X-Forwarded-For:)
791  // not details about the TCP connection itself
792  indirect_client_addr = clientConnection->remote;
793 #endif /* FOLLOW_X_FORWARDED_FOR */
794  my_addr = clientConnection->local;
795 
796  flags.intercepted = ((clientConnection->flags & COMM_INTERCEPTION) != 0);
797  flags.interceptTproxy = ((clientConnection->flags & COMM_TRANSPARENT) != 0 ) ;
798  const bool proxyProtocolPort = port ? port->flags.proxySurrogate : false;
799  if (flags.interceptTproxy && !proxyProtocolPort) {
802  checklist.al = al;
803  checklist.syncAle(this, nullptr);
804  flags.spoofClientIp = checklist.fastCheck().allowed();
805  } else
806  flags.spoofClientIp = true;
807  } else
808  flags.spoofClientIp = false;
809  }
810 }
811 
812 char *
814 {
816 }
817 
819 template <typename Filter>
820 static const Ip::Address *
822 {
823  return (port && isGood(port->s)) ? &port->s : nullptr;
824 }
825 
827 template <typename Filter>
828 static const Ip::Address *
830 {
831  return (conn && isGood(conn->local)) ? &conn->local : nullptr;
832 }
833 
834 template <typename Filter>
835 const Ip::Address *
836 FindGoodListeningPortAddress(const HttpRequest *callerRequest, const AccessLogEntry *ale, const Filter filter)
837 {
838  // Check all sources of usable listening port information, giving
839  // HttpRequest and masterXaction a preference over ALE.
840 
841  const HttpRequest *request = callerRequest;
842  if (!request && ale)
843  request = ale->request;
844  if (!request)
845  return nullptr; // not enough information
846 
847  auto ip = FindGoodListeningPortAddressInPort(request->masterXaction->squidPort, filter);
848  if (!ip && ale)
849  ip = FindGoodListeningPortAddressInPort(ale->cache.port, filter);
850 
851  // XXX: also handle PROXY protocol here when we have a flag to identify such request
852  if (ip || request->flags.interceptTproxy || request->flags.intercepted)
853  return ip;
854 
855  /* handle non-intercepted cases that were not handled above */
857  if (!ip && ale)
859  return ip; // may still be nil
860 }
861 
862 const Ip::Address *
863 FindListeningPortAddress(const HttpRequest *callerRequest, const AccessLogEntry *ale)
864 {
865  return FindGoodListeningPortAddress(callerRequest, ale, [](const Ip::Address &address) {
866  // FindListeningPortAddress() callers do not want INADDR_ANY addresses
867  return !address.isAnyAddr();
868  });
869 }
870 
872 FindListeningPortNumber(const HttpRequest *callerRequest, const AccessLogEntry *ale)
873 {
874  const auto ip = FindGoodListeningPortAddress(callerRequest, ale, [](const Ip::Address &address) {
875  return address.port() > 0;
876  });
877 
878  if (!ip)
879  return std::nullopt;
880 
881  Assure(ip->port() > 0);
882  return ip->port();
883 }
int hdr_sz
Definition: Message.h:81
bool bodyNibbled() const
Definition: HttpRequest.cc:440
void append(const HttpHeader *src)
Definition: HttpHeader.cc:231
void replaceOrAdd(const NotePairs *src)
Definition: Notes.cc:405
Cbc * get() const
a temporary valid raw Cbc pointer or NULL
Definition: CbcPointer.h:159
AnyP::Port FindListeningPortNumber(const HttpRequest *callerRequest, const AccessLogEntry *ale)
Definition: HttpRequest.cc:872
AnyP::PortCfgPointer squidPort
the listening port which originated this transaction
Definition: MasterXaction.h:63
char * peer_host
Definition: HttpRequest.h:165
static HttpRequest * FromUrl(const SBuf &url, const MasterXaction::Pointer &, const HttpRequestMethod &method=Http::METHOD_GET)
Definition: HttpRequest.cc:517
const char * findTrailingHTTPVersion(const char *uriAndHTTPVersion, const char *end)
unsigned int major
major version number
HttpHdrRange * getRange() const
Definition: HttpHeader.cc:1220
bool conflictingContentLength() const
Definition: HttpHeader.h:113
AnyP::ProtocolVersion http_ver
Definition: Message.h:72
bool unsupportedTe() const
whether message used an unsupported and/or invalid Transfer-Encoding
Definition: HttpHeader.h:172
void ignoreRange(const char *reason)
forgets about the cached Range header (for a reason)
Definition: HttpRequest.cc:621
void appendf(const char *fmt,...) PRINTF_FORMAT_ARG2
Append operation with printf-style arguments.
Definition: Packable.h:61
@ METHOD_HEAD
Definition: MethodType.h:28
AnyP::Uri url
the request URI
Definition: HttpRequest.h:115
common parts of HttpRequest and HttpReply
Definition: Message.h:25
bool interceptTproxy
Set for requests handled by a "tproxy" port.
Definition: RequestFlags.h:70
@ METHOD_UNLINK
Definition: MethodType.h:36
BodyPipe::Pointer body_pipe
optional pipeline to receive message body
Definition: Message.h:97
char * canonicalCleanUrl() const
Definition: HttpRequest.cc:813
bool parseHeader(Http1::Parser &hp)
Definition: HttpRequest.cc:711
const char * findFirst(const char *noteKey) const
Definition: Notes.cc:302
bool spoofClientIp
Definition: RequestFlags.h:74
Ip::Address src_addr
@ scBadRequest
Definition: StatusCode.h:45
struct SquidConfig::@98 accessList
@ scNone
Definition: StatusCode.h:21
HttpHeader header
Definition: Message.h:74
RequestFlags flags
Definition: HttpRequest.h:141
void clearError()
clear error details, useful for retries/repeats
Definition: HttpRequest.cc:465
@ scLengthRequired
Definition: StatusCode.h:56
representation of a class of Size-limit ACLs
Definition: AclSizeLimit.h:16
bool isAnyAddr() const
Definition: Address.cc:190
int64_t getRangeOffsetLimit()
Definition: HttpRequest.cc:594
AclSizeLimit * rangeOffsetLimit
Definition: SquidConfig.h:458
CbcPointer< Downloader > downloader
The Downloader object which initiated the HTTP request if any.
Definition: HttpRequest.h:235
unsigned int minor
minor version number
bool pinned
this connection was pinned
Definition: client_side.h:146
char * login
Definition: CachePeer.h:202
int parse(const char *header_start, size_t len, Http::ContentLengthInterpreter &interpreter)
Definition: HttpHeader.cc:349
bool parse(const HttpRequestMethod &, const SBuf &url)
Definition: Uri.cc:295
Definition: SBuf.h:93
virtual void append(const char *buf, int size)=0
Appends a c-string to existing packed data.
bool expectingBody(const HttpRequestMethod &unused, int64_t &) const override
Definition: HttpRequest.cc:488
~HttpRequest() override
Definition: HttpRequest.cc:61
void httpRequestPack(void *obj, Packable *p)
Definition: HttpRequest.cc:361
bool hostVerified
Definition: RequestFlags.h:68
LogConfig TheConfig
Definition: Config.cc:15
bool maybeCacheable()
Definition: HttpRequest.cc:538
#define LOG_ENABLE
Definition: defines.h:60
Auth::UserRequest::Pointer auth_user_request
Definition: HttpRequest.h:127
AccessLogEntry::Pointer al
info for the future access.log, and external ACL
const SBuf & image() const
int dnsWait
sum of DNS lookup delays in milliseconds, for dt
Definition: HttpRequest.h:159
StatusCode
Definition: StatusCode.h:20
void hdrCacheInit() override
Definition: HttpRequest.cc:379
Definition: forward.h:17
bool multipartRangeRequest() const
Definition: HttpRequest.cc:434
bool respMaybeCacheable() const
bool auth_no_keytab
Definition: RequestFlags.h:32
#define w_space
bool conditional() const
has at least one recognized If-* header
Definition: HttpRequest.cc:572
String extacl_user
Definition: HttpRequest.h:178
Adaptation::History::Pointer adaptHistory_
per-HTTP transaction info
Definition: HttpRequest.h:119
static int port
Definition: ldap_backend.cc:70
Error error
the first transaction problem encountered (or falsy)
Definition: HttpRequest.h:161
void clear()
Definition: SBuf.cc:175
void syncAle(HttpRequest *adaptedRequest, const char *logUri) const override
assigns uninitialized adapted_request and url ALE components
bool auth_no_keytab
Definition: CachePeer.h:147
bool chunked() const
Definition: HttpHeader.h:169
char * domain
Forced domain.
Definition: CachePeer.h:215
String myportname
Definition: HttpRequest.h:174
void init()
Definition: HttpRequest.cc:76
#define COMM_INTERCEPTION
Definition: Connection.h:51
ProtocolType
Definition: ProtocolType.h:23
HttpRequest * request
#define COMM_TRANSPARENT
Definition: Connection.h:50
time_t lastmod
Definition: HttpRequest.h:167
virtual void hdrCacheInit()
Definition: Message.cc:261
Http::MethodType id() const
Definition: RequestMethod.h:70
String etag
A strong etag of the cached entry. Used for refreshing that entry.
Definition: HttpRequest.h:191
void clean()
Definition: HttpRequest.cc:121
void clear()
Definition: Uri.h:43
int size
Definition: ModDevPoll.cc:69
Comm::ConnectionPointer tcpClient
the client TCP connection which originated this transaction
Definition: MasterXaction.h:66
#define SQUIDSBUFPRINT(s)
Definition: SBuf.h:32
@ scNotImplemented
Definition: StatusCode.h:74
void recordLookup(const Dns::LookupDetails &detail)
Definition: HttpRequest.cc:580
int wait
msecs spent waiting for the lookup (if any) or -1 (if none)
Definition: LookupDetails.h:40
Ip::Address indirect_client_addr
Definition: HttpRequest.h:152
char * peer_login
Definition: HttpRequest.h:163
const Acl::Answer & fastCheck()
Definition: Checklist.cc:298
unsigned short port() const
Definition: Address.cc:798
@ METHOD_DELETE
Definition: MethodType.h:32
ConnStateData * pinnedConnection()
Definition: HttpRequest.cc:725
SBuf StringToSBuf(const String &s)
create a new SBuf from a String by copying contents
Definition: StringConvert.h:17
Ip::Address local
Definition: Connection.h:146
bool canHandle1xx() const
whether the client is likely to be able to handle a 1xx reply
Definition: HttpRequest.cc:635
@ METHOD_CONNECT
Definition: MethodType.h:29
Comm::ConnectionPointer tcpClient
TCP/IP level details about the client connection.
static const Ip::Address * FindGoodListeningPortAddressInPort(const AnyP::PortCfgPointer &port, const Filter isGood)
a helper for handling PortCfg cases of FindListeningPortAddress()
Definition: HttpRequest.cc:821
char * peer_domain
Definition: HttpRequest.h:172
Adaptation::Icap::History::Pointer icapHistory() const
Returns possibly nil history, creating it if icap logging is enabled.
Definition: HttpRequest.cc:389
acl_access * spoof_client_ip
Definition: SquidConfig.h:399
HttpRequest(const MasterXaction::Pointer &)
Definition: HttpRequest.cc:42
NotePairs::Pointer notes()
MasterXaction::Pointer masterXaction
the master transaction this request belongs to. Never nil.
Definition: HttpRequest.h:238
#define assert(EX)
Definition: assert.h:17
bool intercepted
Definition: RequestFlags.h:66
HttpHdrCc * cache_control
Definition: Message.h:76
class AccessLogEntry::CacheDetails cache
@ METHOD_POST
Definition: MethodType.h:26
HierarchyLogEntry hier
Definition: HttpRequest.h:157
void buffer() override
Definition: store.cc:1601
@ METHOD_PUT
Definition: MethodType.h:27
encapsulates DNS lookup results
Definition: LookupDetails.h:22
SBuf vary_headers
The variant second-stage cache key. Generated from Vary header pattern for this request.
Definition: HttpRequest.h:170
const AnyP::UriScheme & getScheme() const
Definition: Uri.h:58
#define Assure(condition)
Definition: Assure.h:35
Ip::Address my_addr
Definition: HttpRequest.h:155
void flush() override
Definition: store.cc:1612
void HttpRequestMethodXXX(char const *)
Adaptation::Icap::History::Pointer icapHistory_
per-HTTP transaction info
Definition: HttpRequest.h:122
HttpHdrRange * range
Definition: HttpRequest.h:143
void packInto(Packable *p, bool mask_sensitive_info=false) const
Definition: HttpHeader.cc:539
void initHTTP(const HttpRequestMethod &aMethod, AnyP::ProtocolType aProtocol, const char *schemeImage, const char *aUrlpath)
Definition: HttpRequest.cc:68
const char * null_string
int IcapLogfileStatus
Definition: icap_log.cc:20
SBuf & authority(bool requirePort=false) const
Definition: Uri.cc:689
Http::StatusCode checkEntityFraming() const
Definition: HttpRequest.cc:647
int prefixLen() const
Definition: HttpRequest.cc:369
HttpRequest * clone() const override
Definition: HttpRequest.cc:175
size_type length() const
Returns the number of bytes stored in SBuf.
Definition: SBuf.h:419
String extacl_log
Definition: HttpRequest.h:182
Comm::ConnectionPointer clientConnection
Definition: Server.h:100
void setEmpty()
Fast reset of the stored content to what would be after default constructor.
Definition: Address.cc:204
bool parseFirstLine(const char *start, const char *end) override
Definition: HttpRequest.cc:294
int64_t content_length
Definition: Message.h:83
uint32_t sources
The message sources.
Definition: Message.h:99
Adaptation::History::Pointer adaptHistory(bool createIfNone=false) const
Returns possibly nil history, creating it if requested.
Definition: HttpRequest.cc:404
const Ip::Address * FindListeningPortAddress(const HttpRequest *callerRequest, const AccessLogEntry *ale)
Definition: HttpRequest.cc:863
Adaptation::History::Pointer adaptLogHistory() const
Returns possibly nil history, creating it if adapt. logging is enabled.
Definition: HttpRequest.cc:415
@ PROTO_AUTHORITY_FORM
Definition: ProtocolType.h:40
struct ConnStateData::@36 pinning
SBuf & absolute() const
Definition: Uri.cc:711
@ PROTO_HTTPS
Definition: ProtocolType.h:27
HttpRequestMethod method
Definition: HttpRequest.h:114
void path(const char *p)
Definition: Uri.h:96
@ PROTO_HTTP
Definition: ProtocolType.h:25
std::vector< HttpHdrRangeSpec * > specs
ParseState pstate
the current parsing state
Definition: Message.h:94
bool allowed() const
Definition: Acl.h:82
void prepForPeering(const CachePeer &peer)
get ready to be sent to the given cache_peer, including originserver
Definition: HttpRequest.cc:446
static const Ip::Address * FindGoodListeningPortAddressInConn(const Comm::ConnectionPointer &conn, const Filter isGood)
a helper for handling Connection cases of FindListeningPortAddress()
Definition: HttpRequest.cc:829
collects information about ICAP processing related to an HTTP transaction
Definition: History.h:23
bool inheritProperties(const Http::Message *) override
Definition: HttpRequest.cc:214
bool forcedBodyContinuation
whether we have responded with HTTP 100 or FTP 150 already
Definition: HttpRequest.h:194
int has(Http::HdrType id) const
Definition: HttpHeader.cc:937
const SBuf storeId()
Definition: HttpRequest.cc:733
size_type size() const
Definition: SquidString.h:73
@ METHOD_NONE
Definition: MethodType.h:22
AnyP::PortCfgPointer port
const Ip::Address * FindGoodListeningPortAddress(const HttpRequest *callerRequest, const AccessLogEntry *ale, const Filter filter)
Definition: HttpRequest.cc:836
std::optional< KnownPort > Port
validated/supported port number (if any)
Definition: UriScheme.h:26
static HttpRequest * FromUrlXXX(const char *url, const MasterXaction::Pointer &, const HttpRequestMethod &method=Http::METHOD_GET)
Definition: HttpRequest.cc:528
#define Must(condition)
Definition: TextException.h:75
int64_t rangeOffsetLimit
Definition: HttpRequest.h:263
void manager(const CbcPointer< ConnStateData > &aMgr, const AccessLogEntryPointer &al)
associates the request with a from-client connection manager
Definition: HttpRequest.cc:774
void packFirstLineInto(Packable *p, bool full_uri) const override
Definition: HttpRequest.cc:472
void remove(const char *key)
Definition: Notes.cc:323
#define DBG_IMPORTANT
Definition: Stream.h:38
AnyP::Port port
destination port of the request that caused serverConnection
Definition: client_side.h:145
struct CachePeer::@27 options
time_t ims
Definition: HttpRequest.h:145
void add(const SBuf &key, const SBuf &value)
Definition: Notes.cc:317
String extacl_message
Definition: HttpRequest.h:184
@ scInvalidHeader
Squid header parsing error.
Definition: StatusCode.h:88
char * urlCanonicalCleanWithoutRequest(const SBuf &url, const HttpRequestMethod &method, const AnyP::UriScheme &scheme)
Definition: Uri.cc:747
collects information about adaptations related to a master transaction
Definition: History.h:24
void prepForDirect()
get ready to be sent directly to an origin server, excluding originserver
Definition: HttpRequest.cc:456
#define xisspace(x)
Definition: xis.h:15
void swapOut(StoreEntry *e)
Definition: HttpRequest.cc:334
void setScheme(const AnyP::ProtocolType &p, const char *str)
convert the URL scheme to that given
Definition: Uri.h:61
@ METHOD_GET
Definition: MethodType.h:25
const SBuf & effectiveRequestUri() const
RFC 7230 section 5.5 - Effective Request URI.
Definition: HttpRequest.cc:744
NotePairs::Pointer notes()
Definition: HttpRequest.cc:752
Ip::Address client_addr
Definition: HttpRequest.h:149
bool hasNoStore() const
Definition: HttpHdrCc.h:102
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:192
void clear()
switch to the default "no error information" state
Definition: Error.h:53
String tag
Definition: HttpRequest.h:176
@ hoRequest
Definition: HttpHeader.h:36
void reset() override
Definition: HttpRequest.cc:168
RequestFlags cloneAdaptationImmune() const
Definition: RequestFlags.cc:21
void adaptHistoryImport(const HttpRequest &them)
Makes their history ours, throwing on conflicts.
Definition: HttpRequest.cc:421
String extacl_passwd
Definition: HttpRequest.h:180
String store_id
Definition: HttpRequest.h:139
void clean()
Definition: HttpHeader.cc:185
bool sanityCheckStartLine(const char *buf, const size_t hdr_len, Http::StatusCode *error) override
Definition: HttpRequest.cc:268
uint64_t consumedSize() const
Definition: BodyPipe.h:111
@ METHOD_LINK
Definition: MethodType.h:35
NotePairs::Pointer theNotes
Definition: HttpRequest.h:267
#define SQUIDSBUFPH
Definition: SBuf.h:31
CbcPointer< ConnStateData > clientConnectionManager
Definition: HttpRequest.h:232
void pack(Packable *p) const
Definition: HttpRequest.cc:344
class SquidConfig Config
Definition: SquidConfig.cc:12
void UpdateRequestNotes(ConnStateData *csd, HttpRequest &request, NotePairs const &helperNotes)
Definition: HttpRequest.cc:760
void clean()
Definition: String.cc:103
AnyP::ProtocolVersion ProtocolVersion(unsigned int aMajor, unsigned int aMinor)
HTTP version label information.
@ psReadyToParseStartLine
Definition: Message.h:87

 

Introduction

Documentation

Support

Miscellaneous