HttpRequest.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2025 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  vary_headers = SBuf();
98  tag = null_string;
99 #if USE_AUTH
102 #endif
106 #if FOLLOW_X_FORWARDED_FOR
108 #endif /* FOLLOW_X_FORWARDED_FOR */
109 #if USE_ADAPTATION
110  adaptHistory_ = nullptr;
111 #endif
112 #if ICAP_CLIENT
113  icapHistory_ = nullptr;
114 #endif
115  rangeOffsetLimit = -2; //a value of -2 means not checked yet
116  forcedBodyContinuation = false;
117 }
118 
119 void
121 {
122  // we used to assert that the pipe is NULL, but now the request only
123  // points to a pipe that is owned and initiated by another object.
124  body_pipe = nullptr;
125 #if USE_AUTH
126  auth_user_request = nullptr;
127 #endif
129  url.clear();
130 
131  header.clean();
132 
133  if (cache_control) {
134  delete cache_control;
135  cache_control = nullptr;
136  }
137 
138  if (range) {
139  delete range;
140  range = nullptr;
141  }
142 
143  myportname.clean();
144 
145  theNotes = nullptr;
146 
147  tag.clean();
148 #if USE_AUTH
149  extacl_user.clean();
151 #endif
152  extacl_log.clean();
153 
155 
156  etag.clean();
157 
158 #if USE_ADAPTATION
159  adaptHistory_ = nullptr;
160 #endif
161 #if ICAP_CLIENT
162  icapHistory_ = nullptr;
163 #endif
164 }
165 
166 void
168 {
169  clean();
170  init();
171 }
172 
173 HttpRequest *
175 {
177  copy->method = method;
178  // TODO: move common cloning clone to Msg::copyTo() or copy ctor
179  copy->header.append(&header);
180  copy->hdrCacheInit();
181  copy->hdr_sz = hdr_sz;
182  copy->http_ver = http_ver;
183  copy->pstate = pstate; // TODO: should we assert a specific state here?
184  copy->body_pipe = body_pipe;
185 
186  copy->url = url;
187 
188  // range handled in hdrCacheInit()
189  copy->ims = ims;
190  copy->imslen = imslen;
191  copy->hier = hier; // Is it safe to copy? Should we?
192 
193  copy->error = error;
194 
195  // XXX: what to do with copy->peer_login?
196 
197  copy->lastmod = lastmod;
198  copy->etag = etag;
199  copy->vary_headers = vary_headers;
200  // XXX: what to do with copy->peer_domain?
201 
202  copy->tag = tag;
203  copy->extacl_log = extacl_log;
205 
206  const bool inheritWorked = copy->inheritProperties(this);
207  assert(inheritWorked);
208 
209  return copy;
210 }
211 
212 bool
214 {
215  const HttpRequest* aReq = dynamic_cast<const HttpRequest*>(aMsg);
216  if (!aReq)
217  return false;
218 
219  client_addr = aReq->client_addr;
220 #if FOLLOW_X_FORWARDED_FOR
222 #endif
223  my_addr = aReq->my_addr;
224 
225  dnsWait = aReq->dnsWait;
226 
227 #if USE_ADAPTATION
228  adaptHistory_ = aReq->adaptHistory();
229 #endif
230 #if ICAP_CLIENT
231  icapHistory_ = aReq->icapHistory();
232 #endif
233 
234  // This may be too conservative for the 204 No Content case
235  // may eventually need cloneNullAdaptationImmune() for that.
237 
238  error = aReq->error;
239 #if USE_AUTH
241  extacl_user = aReq->extacl_user;
243 #endif
244 
245  myportname = aReq->myportname;
246 
248 
249  // main property is which connection the request was received on (if any)
251 
252  downloader = aReq->downloader;
253 
254  theNotes = aReq->theNotes;
255 
256  sources = aReq->sources;
257  return true;
258 }
259 
266 bool
267 HttpRequest::sanityCheckStartLine(const char *buf, const size_t hdr_len, Http::StatusCode *scode)
268 {
269  // content is long enough to possibly hold a reply
270  // 2 being magic size of a 1-byte request method plus space delimiter
271  if (hdr_len < 2) {
272  // this is only a real error if the headers apparently complete.
273  if (hdr_len > 0) {
274  debugs(58, 3, "Too large request header (" << hdr_len << " bytes)");
275  *scode = Http::scInvalidHeader;
276  }
277  return false;
278  }
279 
280  /* See if the request buffer starts with a non-whitespace HTTP request 'method'. */
282  m.HttpRequestMethodXXX(buf);
283  if (m == Http::METHOD_NONE) {
284  debugs(73, 3, "HttpRequest::sanityCheckStartLine: did not find HTTP request method");
285  *scode = Http::scInvalidHeader;
286  return false;
287  }
288 
289  return true;
290 }
291 
292 bool
293 HttpRequest::parseFirstLine(const char *start, const char *end)
294 {
296 
297  if (method == Http::METHOD_NONE)
298  return false;
299 
300  // XXX: performance regression, strcspn() over the method bytes a second time.
301  // cheaper than allocate+copy+deallocate cycle to SBuf convert a piece of start.
302  const char *t = start + strcspn(start, w_space);
303 
304  start = t + strspn(t, w_space); // skip w_space after method
305 
306  const char *ver = findTrailingHTTPVersion(start, end);
307 
308  if (ver) {
309  end = ver - 1;
310 
311  while (xisspace(*end)) // find prev non-space
312  --end;
313 
314  ++end; // back to space
315 
316  if (2 != sscanf(ver + 5, "%d.%d", &http_ver.major, &http_ver.minor)) {
317  debugs(73, DBG_IMPORTANT, "ERROR: parseRequestLine: Invalid HTTP identifier.");
318  return false;
319  }
320  } else {
321  http_ver.major = 0;
322  http_ver.minor = 9;
323  }
324 
325  if (end < start) // missing URI
326  return false;
327 
328  return url.parse(method, SBuf(start, size_t(end-start)));
329 }
330 
331 /* swaps out request using httpRequestPack */
332 void
334 {
335  assert(e);
336  e->buffer();
337  pack(e);
338  e->flush();
339 }
340 
341 /* packs request-line and headers, appends <crlf> terminator */
342 void
344 {
345  assert(p);
346  /* pack request-line */
347  p->appendf(SQUIDSBUFPH " " SQUIDSBUFPH " HTTP/%d.%d\r\n",
350  /* headers */
351  header.packInto(p);
352  /* trailer */
353  p->append("\r\n", 2);
354 }
355 
356 /*
357  * A wrapper for debugObj()
358  */
359 void
360 httpRequestPack(void *obj, Packable *p)
361 {
362  HttpRequest *request = static_cast<HttpRequest*>(obj);
363  request->pack(p);
364 }
365 
366 /* returns the length of request line + headers + crlf */
367 int
369 {
370  return method.image().length() + 1 +
371  url.path().length() + 1 +
372  4 + 1 + 3 + 2 +
373  header.len + 2;
374 }
375 
376 /* sync this routine when you update HttpRequest struct */
377 void
379 {
381 
382  assert(!range);
383  range = header.getRange();
384 }
385 
386 #if ICAP_CLIENT
389 {
390  if (!icapHistory_) {
391  if (Log::TheConfig.hasIcapToken || IcapLogfileStatus == LOG_ENABLE) {
393  debugs(93,4, "made " << icapHistory_ << " for " << this);
394  }
395  }
396 
397  return icapHistory_;
398 }
399 #endif
400 
401 #if USE_ADAPTATION
403 HttpRequest::adaptHistory(bool createIfNone) const
404 {
405  if (!adaptHistory_ && createIfNone) {
407  debugs(93,4, "made " << adaptHistory_ << " for " << this);
408  }
409 
410  return adaptHistory_;
411 }
412 
415 {
416  return HttpRequest::adaptHistory(Log::TheConfig.hasAdaptToken);
417 }
418 
419 void
421 {
422  if (!adaptHistory_) {
423  adaptHistory_ = them.adaptHistory_; // may be nil
424  } else {
425  // check that histories did not diverge
426  Must(!them.adaptHistory_ || them.adaptHistory_ == adaptHistory_);
427  }
428 }
429 
430 #endif
431 
432 bool
434 {
435  return (range && range->specs.size() > 1);
436 }
437 
438 bool
440 {
441  return body_pipe != nullptr && body_pipe->consumedSize() > 0;
442 }
443 
444 void
446 {
447  // XXX: Saving two pointers to memory controlled by an independent object.
448  peer_login = peer.login;
449  peer_domain = peer.domain;
451  debugs(11, 4, this << " to " << peer);
452 }
453 
454 void
456 {
457  peer_login = nullptr;
458  peer_domain = nullptr;
459  flags.auth_no_keytab = false;
460  debugs(11, 4, this);
461 }
462 
463 void
465 {
466  debugs(11, 7, "old: " << error);
467  error.clear();
468 }
469 
470 void
471 HttpRequest::packFirstLineInto(Packable * p, bool full_uri) const
472 {
473  const SBuf tmp(full_uri ? effectiveRequestUri() : url.path());
474 
475  // form HTTP request-line
476  p->appendf(SQUIDSBUFPH " " SQUIDSBUFPH " HTTP/%d.%d\r\n",
478  SQUIDSBUFPRINT(tmp),
480 }
481 
482 /*
483  * Indicate whether or not we would expect an entity-body
484  * along with this request
485  */
486 bool
487 HttpRequest::expectingBody(const HttpRequestMethod &, int64_t &theSize) const
488 {
489  bool expectBody = false;
490 
491  /*
492  * Note: Checks for message validity is in clientIsContentLengthValid().
493  * this just checks if a entity-body is expected based on HTTP message syntax
494  */
495  if (header.chunked()) {
496  expectBody = true;
497  theSize = -1;
498  } else if (content_length >= 0) {
499  expectBody = true;
500  theSize = content_length;
501  } else {
502  expectBody = false;
503  // theSize undefined
504  }
505 
506  return expectBody;
507 }
508 
509 /*
510  * Create a Request from a URL and METHOD.
511  *
512  * If the METHOD is CONNECT, then a host:port pair is looked for instead of a URL.
513  * If the request cannot be created cleanly, NULL is returned
514  */
515 HttpRequest *
517 {
518  std::unique_ptr<HttpRequest> req(new HttpRequest(mx));
519  if (req->url.parse(method, url)) {
520  req->method = method;
521  return req.release();
522  }
523  return nullptr;
524 }
525 
526 HttpRequest *
527 HttpRequest::FromUrlXXX(const char * url, const MasterXaction::Pointer &mx, const HttpRequestMethod& method)
528 {
529  return FromUrl(SBuf(url), mx, method);
530 }
531 
536 bool
538 {
539  // Intercepted request with Host: header which cannot be trusted.
540  // Because it failed verification, or someone bypassed the security tests
541  // we cannot cache the response for sharing between clients.
542  // TODO: update cache to store for particular clients only (going to same Host: and destination IP)
544  return false;
545 
546  switch (url.getScheme()) {
547  case AnyP::PROTO_HTTP:
548  case AnyP::PROTO_HTTPS:
549  if (!method.respMaybeCacheable())
550  return false;
551 
552  // RFC 9111 section 5.2.1.5:
553  // "The no-store request directive indicates that a cache MUST NOT
554  // store any part of either this request or any response to it."
555  //
556  // NP: refresh_pattern ignore-no-store only applies to response messages
557  // this test is handling request message CC header.
559  return false;
560  break;
561 
562  //case AnyP::PROTO_FTP:
563  default:
564  break;
565  }
566 
567  return true;
568 }
569 
570 bool
572 {
573  return flags.ims ||
576 }
577 
578 void
580 {
581  if (dns.wait >= 0) { // known delay
582  if (dnsWait >= 0) { // have recorded DNS wait before
583  debugs(78, 7, this << " " << dnsWait << " += " << dns);
584  dnsWait += dns.wait;
585  } else {
586  debugs(78, 7, this << " " << dns);
587  dnsWait = dns.wait;
588  }
589  }
590 }
591 
592 int64_t
594 {
595  /* -2 is the starting value of rangeOffsetLimit.
596  * If it is -2, that means we haven't checked it yet.
597  * Otherwise, return the current value */
598  if (rangeOffsetLimit != -2)
599  return rangeOffsetLimit;
600 
601  rangeOffsetLimit = 0; // default value for rangeOffsetLimit
602 
603  ACLFilledChecklist ch(nullptr, this);
604  ch.src_addr = client_addr;
605  ch.my_addr = my_addr;
606 
607  for (AclSizeLimit *l = Config.rangeOffsetLimit; l; l = l -> next) {
608  /* if there is no ACL list or if the ACLs listed match use this limit value */
609  if (!l->aclList || ch.fastCheck(l->aclList).allowed()) {
610  rangeOffsetLimit = l->size; // may be -1
611  debugs(58, 4, rangeOffsetLimit);
612  break;
613  }
614  }
615 
616  return rangeOffsetLimit;
617 }
618 
619 void
620 HttpRequest::ignoreRange(const char *reason)
621 {
622  if (range) {
623  debugs(73, 3, static_cast<void*>(range) << " for " << reason);
624  delete range;
625  range = nullptr;
626  }
627  // Some callers also reset isRanged but it may not be safe for all callers:
628  // isRanged is used to determine whether a weak ETag comparison is allowed,
629  // and that check should not ignore the Range header if it was present.
630  // TODO: Some callers also delete HDR_RANGE, HDR_REQUEST_RANGE. Should we?
631 }
632 
633 bool
635 {
636  // old clients do not support 1xx unless they sent Expect: 100-continue
637  // (we reject all other Http::HdrType::EXPECT values so just check for Http::HdrType::EXPECT)
639  return false;
640 
641  // others must support 1xx control messages
642  return true;
643 }
644 
647 {
648  // RFC 7230 section 3.3.1:
649  // "
650  // A server that receives a request message with a transfer coding it
651  // does not understand SHOULD respond with 501 (Not Implemented).
652  // "
653  if (header.unsupportedTe())
654  return Http::scNotImplemented;
655 
656  // RFC 7230 section 3.3.3 #3 paragraph 3:
657  // Transfer-Encoding overrides Content-Length
658  if (header.chunked())
659  return Http::scNone;
660 
661  // RFC 7230 Section 3.3.3 #4:
662  // conflicting Content-Length(s) mean a message framing error
664  return Http::scBadRequest;
665 
666  // HTTP/1.0 requirements differ from HTTP/1.1
667  if (http_ver <= Http::ProtocolVersion(1,0)) {
668  const auto m = method.id();
669 
670  // RFC 1945 section 8.3:
671  // "
672  // A valid Content-Length is required on all HTTP/1.0 POST requests.
673  // "
674  // RFC 1945 Appendix D.1.1:
675  // "
676  // The fundamental difference between the POST and PUT requests is
677  // reflected in the different meaning of the Request-URI.
678  // "
679  if (m == Http::METHOD_POST || m == Http::METHOD_PUT)
681 
682  // RFC 1945 section 7.2:
683  // "
684  // An entity body is included with a request message only when the
685  // request method calls for one.
686  // "
687  // section 8.1-2: GET and HEAD do not define ('call for') an entity
688  if (m == Http::METHOD_GET || m == Http::METHOD_HEAD)
690  // appendix D1.1.2-4: DELETE, LINK, UNLINK do not define ('call for') an entity
693 
694  // other methods are not defined in RFC 1945
695  // assume they support an (optional) entity
696  return Http::scNone;
697  }
698 
699  // RFC 7230 section 3.3
700  // "
701  // The presence of a message body in a request is signaled by a
702  // Content-Length or Transfer-Encoding header field. Request message
703  // framing is independent of method semantics, even if the method does
704  // not define any use for a message body.
705  // "
706  return Http::scNone;
707 }
708 
709 bool
711 {
713  return Message::parseHeader(hp, clen);
714 }
715 
716 bool
717 HttpRequest::parseHeader(const char *buffer, const size_t size)
718 {
720  return header.parse(buffer, size, clen);
721 }
722 
725 {
727  return clientConnectionManager.get();
728  return nullptr;
729 }
730 
731 const SBuf
733 {
734  if (store_id.size() != 0) {
735  debugs(73, 3, "sent back store_id: " << store_id);
736  return StringToSBuf(store_id);
737  }
738  debugs(73, 3, "sent back effectiveRequestUrl: " << effectiveRequestUri());
739  return effectiveRequestUri();
740 }
741 
742 const SBuf &
744 {
746  return url.authority(true); // host:port
747  return url.absolute();
748 }
749 
752 {
753  if (!theNotes)
754  theNotes = new NotePairs;
755  return theNotes;
756 }
757 
758 void
759 UpdateRequestNotes(ConnStateData *csd, HttpRequest &request, NotePairs const &helperNotes)
760 {
761  // Tag client connection if the helper responded with clt_conn_tag=tag.
762  const char *cltTag = "clt_conn_tag";
763  if (const char *connTag = helperNotes.findFirst(cltTag)) {
764  if (csd) {
765  csd->notes()->remove(cltTag);
766  csd->notes()->add(cltTag, connTag);
767  }
768  }
769  request.notes()->replaceOrAdd(&helperNotes);
770 }
771 
772 void
774 {
776 
777  if (!clientConnectionManager.valid())
778  return;
779 
781  if (port) {
782  myportname = port->name;
783  flags.ignoreCc = port->ignore_cc;
784  }
785 
786  if (auto clientConnection = clientConnectionManager->clientConnection) {
787  client_addr = clientConnection->remote; // XXX: remove request->client_addr member.
788 #if FOLLOW_X_FORWARDED_FOR
789  // indirect client gets stored here because it is an HTTP header result (from X-Forwarded-For:)
790  // not details about the TCP connection itself
791  indirect_client_addr = clientConnection->remote;
792 #endif /* FOLLOW_X_FORWARDED_FOR */
793  my_addr = clientConnection->local;
794 
795  flags.intercepted = ((clientConnection->flags & COMM_INTERCEPTION) != 0);
796  flags.interceptTproxy = ((clientConnection->flags & COMM_TRANSPARENT) != 0 ) ;
797  const bool proxyProtocolPort = port ? port->flags.proxySurrogate : false;
798  if (flags.interceptTproxy && !proxyProtocolPort) {
801  checklist.al = al;
802  checklist.syncAle(this, nullptr);
803  flags.spoofClientIp = checklist.fastCheck().allowed();
804  } else
805  flags.spoofClientIp = true;
806  } else
807  flags.spoofClientIp = false;
808  }
809 }
810 
811 char *
813 {
815 }
816 
818 template <typename Filter>
819 static const Ip::Address *
821 {
822  return (port && isGood(port->s)) ? &port->s : nullptr;
823 }
824 
826 template <typename Filter>
827 static const Ip::Address *
829 {
830  return (conn && isGood(conn->local)) ? &conn->local : nullptr;
831 }
832 
833 template <typename Filter>
834 const Ip::Address *
835 FindGoodListeningPortAddress(const HttpRequest *callerRequest, const AccessLogEntry *ale, const Filter filter)
836 {
837  // Check all sources of usable listening port information, giving
838  // HttpRequest and masterXaction a preference over ALE.
839 
840  const HttpRequest *request = callerRequest;
841  if (!request && ale)
842  request = ale->request;
843  if (!request)
844  return nullptr; // not enough information
845 
846  auto ip = FindGoodListeningPortAddressInPort(request->masterXaction->squidPort, filter);
847  if (!ip && ale)
848  ip = FindGoodListeningPortAddressInPort(ale->cache.port, filter);
849 
850  // XXX: also handle PROXY protocol here when we have a flag to identify such request
851  if (ip || request->flags.interceptTproxy || request->flags.intercepted)
852  return ip;
853 
854  /* handle non-intercepted cases that were not handled above */
856  if (!ip && ale)
858  return ip; // may still be nil
859 }
860 
861 const Ip::Address *
862 FindListeningPortAddress(const HttpRequest *callerRequest, const AccessLogEntry *ale)
863 {
864  return FindGoodListeningPortAddress(callerRequest, ale, [](const Ip::Address &address) {
865  // FindListeningPortAddress() callers do not want INADDR_ANY addresses
866  return !address.isAnyAddr();
867  });
868 }
869 
871 FindListeningPortNumber(const HttpRequest *callerRequest, const AccessLogEntry *ale)
872 {
873  const auto ip = FindGoodListeningPortAddress(callerRequest, ale, [](const Ip::Address &address) {
874  return address.port() > 0;
875  });
876 
877  if (!ip)
878  return std::nullopt;
879 
880  Assure(ip->port() > 0);
881  return ip->port();
882 }
int hdr_sz
Definition: Message.h:81
bool bodyNibbled() const
Definition: HttpRequest.cc:439
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:871
AnyP::PortCfgPointer squidPort
the listening port which originated this transaction
Definition: MasterXaction.h:63
static HttpRequest * FromUrl(const SBuf &url, const MasterXaction::Pointer &, const HttpRequestMethod &method=Http::METHOD_GET)
Definition: HttpRequest.cc:516
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:620
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:812
bool parseHeader(Http1::Parser &hp)
Definition: HttpRequest.cc:710
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:464
@ 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:593
AclSizeLimit * rangeOffsetLimit
Definition: SquidConfig.h:458
CbcPointer< Downloader > downloader
The Downloader object which initiated the HTTP request if any.
Definition: HttpRequest.h:233
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:487
~HttpRequest() override
Definition: HttpRequest.cc:61
void httpRequestPack(void *obj, Packable *p)
Definition: HttpRequest.cc:360
bool hostVerified
Definition: RequestFlags.h:68
LogConfig TheConfig
Definition: Config.cc:15
bool maybeCacheable()
Definition: HttpRequest.cc:537
#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:378
Definition: forward.h:17
bool multipartRangeRequest() const
Definition: HttpRequest.cc:433
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:571
String extacl_user
Definition: HttpRequest.h:176
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:172
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:165
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:189
void clean()
Definition: HttpRequest.cc:120
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:579
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:724
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:149
bool canHandle1xx() const
whether the client is likely to be able to handle a 1xx reply
Definition: HttpRequest.cc:634
@ 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:820
char * peer_domain
Definition: HttpRequest.h:170
Adaptation::Icap::History::Pointer icapHistory() const
Returns possibly nil history, creating it if icap logging is enabled.
Definition: HttpRequest.cc:388
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:236
#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:168
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:646
int prefixLen() const
Definition: HttpRequest.cc:368
HttpRequest * clone() const override
Definition: HttpRequest.cc:174
size_type length() const
Returns the number of bytes stored in SBuf.
Definition: SBuf.h:419
String extacl_log
Definition: HttpRequest.h:180
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:293
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:403
const Ip::Address * FindListeningPortAddress(const HttpRequest *callerRequest, const AccessLogEntry *ale)
Definition: HttpRequest.cc:862
Adaptation::History::Pointer adaptLogHistory() const
Returns possibly nil history, creating it if adapt. logging is enabled.
Definition: HttpRequest.cc:414
@ 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:445
static const Ip::Address * FindGoodListeningPortAddressInConn(const Comm::ConnectionPointer &conn, const Filter isGood)
a helper for handling Connection cases of FindListeningPortAddress()
Definition: HttpRequest.cc:828
collects information about ICAP processing related to an HTTP transaction
Definition: History.h:23
bool inheritProperties(const Http::Message *) override
Definition: HttpRequest.cc:213
bool forcedBodyContinuation
whether we have responded with HTTP 100 or FTP 150 already
Definition: HttpRequest.h:192
int has(Http::HdrType id) const
Definition: HttpHeader.cc:937
const SBuf storeId()
Definition: HttpRequest.cc:732
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:835
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:527
#define Must(condition)
Definition: TextException.h:75
int64_t rangeOffsetLimit
Definition: HttpRequest.h:261
void manager(const CbcPointer< ConnStateData > &aMgr, const AccessLogEntryPointer &al)
associates the request with a from-client connection manager
Definition: HttpRequest.cc:773
void packFirstLineInto(Packable *p, bool full_uri) const override
Definition: HttpRequest.cc:471
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:182
@ 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:455
#define xisspace(x)
Definition: xis.h:15
void swapOut(StoreEntry *e)
Definition: HttpRequest.cc:333
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:743
NotePairs::Pointer notes()
Definition: HttpRequest.cc:751
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:174
@ hoRequest
Definition: HttpHeader.h:36
void reset() override
Definition: HttpRequest.cc:167
RequestFlags cloneAdaptationImmune() const
Definition: RequestFlags.cc:21
void adaptHistoryImport(const HttpRequest &them)
Makes their history ours, throwing on conflicts.
Definition: HttpRequest.cc:420
String extacl_passwd
Definition: HttpRequest.h:178
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:267
uint64_t consumedSize() const
Definition: BodyPipe.h:111
@ METHOD_LINK
Definition: MethodType.h:35
NotePairs::Pointer theNotes
Definition: HttpRequest.h:265
#define SQUIDSBUFPH
Definition: SBuf.h:31
CbcPointer< ConnStateData > clientConnectionManager
Definition: HttpRequest.h:230
void pack(Packable *p) const
Definition: HttpRequest.cc:343
class SquidConfig Config
Definition: SquidConfig.cc:12
void UpdateRequestNotes(ConnStateData *csd, HttpRequest &request, NotePairs const &helperNotes)
Definition: HttpRequest.cc:759
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