XactionRep.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 93 eCAP Interface */
10 
11 #include "squid.h"
12 #include "adaptation/Answer.h"
13 #include "adaptation/ecap/Config.h"
15 #include "adaptation/Initiator.h"
16 #include "base/AsyncJobCalls.h"
17 #include "base/TextException.h"
18 #include "format/Format.h"
19 #include "HttpReply.h"
20 #include "MasterXaction.h"
21 #include "sbuf/StringConvert.h"
22 
23 #if HAVE_LIBECAP_COMMON_AREA_H
24 #include <libecap/common/area.h>
25 #endif
26 #if HAVE_LIBECAP_COMMON_DELAY_H
27 #include <libecap/common/delay.h>
28 #endif
29 #if HAVE_LIBECAP_COMMON_NAMED_VALUES_H
30 #include <libecap/common/named_values.h>
31 #endif
32 #if HAVE_LIBECAP_COMMON_NAMES_H
33 #include <libecap/common/names.h>
34 #endif
35 
37 
39 class OptionsExtractor: public libecap::NamedValueVisitor
40 {
41 public:
42  typedef libecap::Name Name;
43  typedef libecap::Area Area;
44 
45  OptionsExtractor(HttpHeader &aMeta): meta(aMeta) {}
46 
47  // libecap::NamedValueVisitor API
48  void visit(const Name &name, const Area &value) override {
49  meta.putExt(name.image().c_str(), value.toString().c_str());
50  }
51 
53 };
54 
56  Http::Message *virginHeader, HttpRequest *virginCause, AccessLogEntry::Pointer &alp,
57  const Adaptation::ServicePointer &aService):
58  AsyncJob("Adaptation::Ecap::XactionRep"),
59  Adaptation::Initiate("Adaptation::Ecap::XactionRep"),
60  theService(aService),
61  theVirginRep(virginHeader), theCauseRep(nullptr),
62  makingVb(opUndecided), proxyingAb(opUndecided),
63  adaptHistoryId(-1),
64  vbProductionFinished(false),
65  abProductionFinished(false), abProductionAtEnd(false),
66  al(alp)
67 {
68  if (virginCause)
69  theCauseRep = new MessageRep(virginCause);
70 }
71 
73 {
74  assert(!theMaster);
75  delete theCauseRep;
76  theAnswerRep.reset();
77 }
78 
79 void
81 {
82  Must(!theMaster);
83  Must(x);
84  theMaster = x;
85 }
86 
89 {
90  Must(theService != nullptr);
91  return *theService;
92 }
93 
94 const libecap::Area
95 Adaptation::Ecap::XactionRep::option(const libecap::Name &name) const
96 {
97  if (name == libecap::metaClientIp)
98  return clientIpValue();
99  if (name == libecap::metaUserName)
100  return usernameValue();
102  return masterxSharedValue(name);
103 
104  // TODO: metaServerIp, metaAuthenticatedUser, and metaAuthenticatedGroups
105 
106  // If the name is unknown, metaValue returns an empty area
107  return metaValue(name);
108 }
109 
110 void
111 Adaptation::Ecap::XactionRep::visitEachOption(libecap::NamedValueVisitor &visitor) const
112 {
113  if (const libecap::Area value = clientIpValue())
114  visitor.visit(libecap::metaClientIp, value);
115  if (const libecap::Area value = usernameValue())
116  visitor.visit(libecap::metaUserName, value);
117 
119  const libecap::Name name(Adaptation::Config::masterx_shared_name);
120  if (const libecap::Area value = masterxSharedValue(name))
121  visitor.visit(name, value);
122  }
123 
124  visitEachMetaHeader(visitor);
125 
126  // TODO: metaServerIp, metaAuthenticatedUser, and metaAuthenticatedGroups
127 }
128 
129 const libecap::Area
131 {
132  const HttpRequest *request = dynamic_cast<const HttpRequest*>(theCauseRep ?
133  theCauseRep->raw().header : theVirginRep.raw().header);
134  Must(request);
135  // TODO: move this logic into HttpRequest::clientIp(bool) and
136  // HttpRequest::clientIpString(bool) and reuse everywhere
137  if (TheConfig.send_client_ip && request) {
138  Ip::Address client_addr;
139 #if FOLLOW_X_FORWARDED_FOR
141  client_addr = request->indirect_client_addr;
142  } else
143 #endif
144  client_addr = request->client_addr;
145  if (!client_addr.isAnyAddr() && !client_addr.isNoAddr()) {
146  char ntoabuf[MAX_IPSTRLEN] = "";
147  client_addr.toStr(ntoabuf,MAX_IPSTRLEN);
148  return libecap::Area::FromTempBuffer(ntoabuf, strlen(ntoabuf));
149  }
150  }
151  return libecap::Area();
152 }
153 
154 const libecap::Area
156 {
157 #if USE_AUTH
158  const HttpRequest *request = dynamic_cast<const HttpRequest*>(theCauseRep ?
159  theCauseRep->raw().header : theVirginRep.raw().header);
160  Must(request);
161  if (request->auth_user_request != nullptr) {
162  if (char const *name = request->auth_user_request->username())
163  return libecap::Area::FromTempBuffer(name, strlen(name));
164  else if (request->extacl_user.size() > 0)
165  return libecap::Area::FromTempBuffer(request->extacl_user.rawBuf(),
166  request->extacl_user.size());
167  }
168 #endif
169  return libecap::Area();
170 }
171 
172 const libecap::Area
173 Adaptation::Ecap::XactionRep::masterxSharedValue(const libecap::Name &sharedName) const
174 {
175  const HttpRequest *request = dynamic_cast<const HttpRequest*>(theCauseRep ?
176  theCauseRep->raw().header : theVirginRep.raw().header);
177  Must(request);
178  if (sharedName.known()) { // must check to avoid empty names matching unset cfg
179  Adaptation::History::Pointer ah = request->adaptHistory(false);
180  if (ah != nullptr) {
181  String name, value;
182  if (ah->getXxRecord(name, value))
183  return libecap::Area::FromTempBuffer(value.rawBuf(), value.size());
184  }
185  }
186  return libecap::Area();
187 }
188 
189 const libecap::Area
190 Adaptation::Ecap::XactionRep::metaValue(const libecap::Name &name) const
191 {
192  HttpRequest *request = dynamic_cast<HttpRequest*>(theCauseRep ?
193  theCauseRep->raw().header : theVirginRep.raw().header);
194  Must(request);
195  HttpReply *reply = dynamic_cast<HttpReply*>(theVirginRep.raw().header);
196 
197  if (name.known()) { // must check to avoid empty names matching unset cfg
198  for (const auto &h: Adaptation::Config::metaHeaders()) {
199  if (name == h->key().toStdString()) {
200  SBuf matched;
201  if (h->match(request, reply, al, matched))
202  return libecap::Area::FromTempString(matched.toStdString());
203  else
204  return libecap::Area();
205  }
206  }
207  }
208 
209  return libecap::Area();
210 }
211 
212 void
213 Adaptation::Ecap::XactionRep::visitEachMetaHeader(libecap::NamedValueVisitor &visitor) const
214 {
215  HttpRequest *request = dynamic_cast<HttpRequest*>(theCauseRep ?
216  theCauseRep->raw().header : theVirginRep.raw().header);
217  Must(request);
218  HttpReply *reply = dynamic_cast<HttpReply*>(theVirginRep.raw().header);
219 
220  for (const auto &h: Adaptation::Config::metaHeaders()) {
221  SBuf matched;
222  if (h->match(request, reply, al, matched)) {
223  const libecap::Name name(h->key().toStdString());
224  const libecap::Area value = libecap::Area::FromTempString(matched.toStdString());
225  visitor.visit(name, value);
226  }
227  }
228 }
229 
230 void
232 {
233  Must(theMaster);
234 
235  if (!theVirginRep.raw().body_pipe)
236  makingVb = opNever; // there is nothing to deliver
237 
238  HttpRequest *request = dynamic_cast<HttpRequest*> (theCauseRep ?
239  theCauseRep->raw().header : theVirginRep.raw().header);
240  Must(request);
241 
242  HttpReply *reply = dynamic_cast<HttpReply*>(theVirginRep.raw().header);
243 
245  if (ah != nullptr) {
246  // retrying=false because ecap never retries transactions
247  adaptHistoryId = ah->recordXactStart(service().cfg().key, current_time, false);
248  SBuf matched;
249  for (const auto &h: Adaptation::Config::metaHeaders()) {
250  if (h->match(request, reply, al, matched)) {
251  if (ah->metaHeaders == nullptr)
252  ah->metaHeaders = new NotePairs();
253  if (!ah->metaHeaders->hasPair(h->key(), matched))
254  ah->metaHeaders->add(h->key(), matched);
255  }
256  }
257  }
258 
259  theMaster->start();
260 }
261 
262 void
264 {
265  // clear body_pipes, if any
266  // this code does not maintain proxying* and canAccessVb states; should it?
267 
268  if (theAnswerRep) {
269  BodyPipe::Pointer body_pipe = answer().body_pipe;
270  if (body_pipe != nullptr) {
271  Must(body_pipe->stillProducing(this));
272  stopProducingFor(body_pipe, false);
273  }
274  }
275 
276  BodyPipe::Pointer &body_pipe = theVirginRep.raw().body_pipe;
277  if (body_pipe != nullptr && body_pipe->stillConsuming(this))
278  stopConsumingFrom(body_pipe);
279 
280  terminateMaster();
281 
282  const HttpRequest *request = dynamic_cast<const HttpRequest*>(theCauseRep ?
283  theCauseRep->raw().header : theVirginRep.raw().header);
284  Must(request);
286  if (ah != nullptr && adaptHistoryId >= 0)
287  ah->recordXactFinish(adaptHistoryId);
288 
290 }
291 
292 void
294 {
295  // go async to gain exception protection and done()-based job destruction
297  AsyncCall::Pointer call = asyncCall(93, 5, "Adaptation::Ecap::XactionRep::doResume",
299  ScheduleCallHere(call);
300 }
301 
304 void
306 {
307  Must(theMaster);
308  theMaster->resume();
309 }
310 
311 libecap::Message &
313 {
314  return theVirginRep;
315 }
316 
317 const libecap::Message &
319 {
320  Must(theCauseRep != nullptr);
321  return *theCauseRep;
322 }
323 
324 libecap::Message &
326 {
327  Must(theAnswerRep);
328  return *theAnswerRep;
329 }
330 
333 {
334  MessageRep *rep = dynamic_cast<MessageRep*>(theAnswerRep.get());
335  Must(rep);
336  return rep->raw();
337 }
338 
339 void
341 {
342  if (theMaster) {
343  AdapterXaction x = theMaster;
344  theMaster.reset();
345  x->stop();
346  }
347 }
348 
349 bool
351 {
352  return makingVb >= opComplete && proxyingAb >= opComplete &&
354 }
355 
356 // stops receiving virgin and enables auto-consumption, dropping any vb bytes
357 void
359 {
360  debugs(93,4, "sink for " << reason << "; status:" << status());
361 
362  // we reset raw().body_pipe when we are done, so use this one for checking
363  const BodyPipePointer &permPipe = theVirginRep.raw().header->body_pipe;
364  if (permPipe != nullptr)
365  permPipe->enableAutoConsumption();
366 
367  forgetVb(reason);
368 }
369 
370 // stops receiving virgin but preserves it for others to use
371 void
373 {
374  debugs(93,4, "preserve for " << reason << "; status:" << status());
375 
376  // we reset raw().body_pipe when we are done, so use this one for checking
377  const BodyPipePointer &permPipe = theVirginRep.raw().header->body_pipe;
378  if (permPipe != nullptr) {
379  // if libecap consumed, we cannot preserve
380  Must(!permPipe->consumedSize());
381  }
382 
383  forgetVb(reason);
384 }
385 
386 // disassociates us from vb; the last step of sinking or preserving vb
387 void
389 {
390  debugs(93,9, "forget vb " << reason << "; status:" << status());
391 
392  BodyPipePointer &p = theVirginRep.raw().body_pipe;
393  if (p != nullptr && p->stillConsuming(this))
394  stopConsumingFrom(p);
395 
396  if (makingVb == opUndecided)
397  makingVb = opNever;
398  else if (makingVb == opOn)
399  makingVb = opComplete;
400 }
401 
402 void
404 {
405  debugs(93,3, status());
406  Must(proxyingAb == opUndecided);
407  proxyingAb = opNever;
408 
409  preserveVb("useVirgin");
410 
411  Http::Message *clone = theVirginRep.raw().header->clone();
412  // check that clone() copies the pipe so that we do not have to
413  Must(!theVirginRep.raw().header->body_pipe == !clone->body_pipe);
414 
415  updateHistory(clone);
416  sendAnswer(Answer::Forward(clone));
417  Must(done());
418 }
419 
420 void
421 Adaptation::Ecap::XactionRep::useAdapted(const libecap::shared_ptr<libecap::Message> &m)
422 {
423  debugs(93,3, status());
424  Must(m);
425  theAnswerRep = m;
426  Must(proxyingAb == opUndecided);
427 
428  Http::Message *msg = answer().header;
429  updateSources(msg);
430  if (!theAnswerRep->body()) { // final, bodyless answer
431  proxyingAb = opNever;
432  updateHistory(msg);
433  sendAnswer(Answer::Forward(msg));
434  } else { // got answer headers but need to handle body
435  proxyingAb = opOn;
436  Must(!msg->body_pipe); // only host can set body pipes
437  MessageRep *rep = dynamic_cast<MessageRep*>(theAnswerRep.get());
438  Must(rep);
439  rep->tieBody(this); // sets us as a producer
440  Must(msg->body_pipe != nullptr); // check tieBody
441 
442  updateHistory(msg);
443  sendAnswer(Answer::Forward(msg));
444 
445  debugs(93,4, "adapter will produce body" << status());
446  theMaster->abMake(); // libecap will produce
447  }
448 }
449 
450 void
452 {
453  debugs(93,3, status());
454  Must(proxyingAb == opUndecided);
455  proxyingAb = opNever;
456 
457  sinkVb("blockVirgin");
458 
459  updateHistory(nullptr);
460  sendAnswer(Answer::Block(StringToSBuf(service().cfg().key)));
461  Must(done());
462 }
463 
466 void
468 {
469  if (!theMaster) // all updates rely on being able to query the adapter
470  return;
471 
472  const HttpRequest *request = dynamic_cast<const HttpRequest*>(theCauseRep ?
473  theCauseRep->raw().header : theVirginRep.raw().header);
474  Must(request);
475 
476  // TODO: move common ICAP/eCAP logic to Adaptation::Xaction or similar
477  // TODO: optimize Area-to-String conversion
478 
479  // update the cross-transactional database if needed
480  if (const char *xxNameStr = Adaptation::Config::masterx_shared_name) {
481  Adaptation::History::Pointer ah = request->adaptHistory(true);
482  if (ah != nullptr) {
483  libecap::Name xxName(xxNameStr); // TODO: optimize?
484  if (const libecap::Area val = theMaster->option(xxName))
485  ah->updateXxRecord(xxNameStr, val.toString().c_str());
486  }
487  }
488 
489  // update the adaptation plan if needed
490  if (service().cfg().routing) {
491  if (const libecap::Area services = theMaster->option(libecap::metaNextServices)) {
492  Adaptation::History::Pointer ah = request->adaptHistory(true);
493  if (ah != nullptr)
494  ah->updateNextServices(services.toString().c_str());
495  }
496  } // TODO: else warn (occasionally!) if we got libecap::metaNextServices
497 
498  // Store received meta headers for adapt::<last_h logformat code use.
499  // If we already have stored headers from a previous adaptation transaction
500  // related to the same master transction, they will be replaced.
502  if (ah != nullptr) {
503  HttpHeader meta(hoReply);
504  OptionsExtractor extractor(meta);
505  theMaster->visitEachOption(extractor);
506  ah->recordMeta(&meta);
507  }
508 
509  // Add just-created history to the adapted/cloned request that lacks it.
510  if (HttpRequest *adaptedReq = dynamic_cast<HttpRequest*>(adapted))
511  adaptedReq->adaptHistoryImport(*request);
512 }
513 
514 void
516 {
517  Must(makingVb == opUndecided);
518  // if adapter does not need vb, we do not need to send it
519  sinkVb("vbDiscard");
520  Must(makingVb == opNever);
521 }
522 
523 void
525 {
526  Must(makingVb == opUndecided);
527  BodyPipePointer &p = theVirginRep.raw().body_pipe;
528  Must(p != nullptr);
529  Must(p->setConsumerIfNotLate(this)); // to deliver vb, we must receive vb
530  makingVb = opOn;
531 }
532 
533 void
535 {
536  Must(makingVb == opOn);
537  // if adapter does not need vb, we do not need to receive it
538  sinkVb("vbStopMaking");
539  Must(makingVb == opComplete);
540 }
541 
542 void
544 {
545  Must(makingVb == opOn); // cannot make more if done proxying
546  // we cannot guarantee more vb, but we can check that there is a chance
547  const BodyPipePointer &p = theVirginRep.raw().body_pipe;
548  Must(p != nullptr && p->stillConsuming(this)); // we are plugged in
549  Must(!p->productionEnded() && p->mayNeedMoreData()); // and may get more
550 }
551 
552 libecap::Area
553 Adaptation::Ecap::XactionRep::vbContent(libecap::size_type o, libecap::size_type s)
554 {
555  // We may not be makingVb yet. It should be OK, but see vbContentShift().
556 
557  const BodyPipePointer &p = theVirginRep.raw().body_pipe;
558  Must(p != nullptr);
559 
560  // TODO: make MemBuf use size_t?
561  const size_t haveSize = static_cast<size_t>(p->buf().contentSize());
562 
563  // convert to Squid types; XXX: check for overflow
564  const uint64_t offset = static_cast<uint64_t>(o);
565  Must(offset <= haveSize); // equal iff at the end of content
566 
567  // nsize means no size limit: all content starting from offset
568  const size_t size = s == libecap::nsize ?
569  haveSize - offset : static_cast<size_t>(s);
570 
571  // XXX: optimize by making theBody a shared_ptr (see Area::FromTemp*() src)
572  return libecap::Area::FromTempBuffer(p->buf().content() + offset,
573  min(static_cast<size_t>(haveSize - offset), size));
574 }
575 
576 void
578 {
579  // We may not be makingVb yet. It should be OK now, but if BodyPipe
580  // consume() requirements change, we would have to return empty vbContent
581  // until the adapter registers as a consumer
582 
583  BodyPipePointer &p = theVirginRep.raw().body_pipe;
584  Must(p != nullptr);
585  const size_t size = static_cast<size_t>(n); // XXX: check for overflow
586  const size_t haveSize = static_cast<size_t>(p->buf().contentSize()); // TODO: make MemBuf use size_t?
587  p->consume(min(size, haveSize));
588 }
589 
590 void
592 {
593  Must(proxyingAb == opOn && !abProductionFinished);
594  abProductionFinished = true;
595  abProductionAtEnd = atEnd; // store until ready to stop producing ourselves
596  debugs(93,5, "adapted body production ended");
597  moveAbContent();
598 }
599 
600 void
602 {
603  Must(proxyingAb == opOn && !abProductionFinished);
604  moveAbContent();
605 }
606 
607 #if 0 /* XXX: implement */
608 void
609 Adaptation::Ecap::XactionRep::setAdaptedBodySize(const libecap::BodySize &size)
610 {
611  Must(answer().body_pipe != NULL);
612  if (size.known())
613  answer().body_pipe->setBodySize(size.value());
614  // else the piped body size is unknown by default
615 }
616 #endif
617 
618 void
620 {
621  debugs(93,3, "adapter needs time: " <<
622  d.state << '/' << d.progress);
623  // XXX: set timeout?
624 }
625 
626 void
628 {
629  tellQueryAborted(true); // should eCAP support retries?
630  mustStop("adaptationAborted");
631 }
632 
633 void
635 {
636  Must(proxyingAb == opOn);
637  moveAbContent();
638 }
639 
640 void
642 {
643  Must(proxyingAb == opOn);
644  stopProducingFor(answer().body_pipe, false);
645  Must(theMaster);
646  theMaster->abStopMaking();
647  proxyingAb = opComplete;
648 }
649 
650 void
652 {
653  Must(makingVb == opOn); // or we would not be registered as a consumer
654  Must(theMaster);
655  theMaster->noteVbContentAvailable();
656 }
657 
658 void
660 {
661  Must(makingVb == opOn); // or we would not be registered as a consumer
662  Must(theMaster);
663  theMaster->noteVbContentDone(true);
664  vbProductionFinished = true;
665 }
666 
667 void
669 {
670  Must(makingVb == opOn); // or we would not be registered as a consumer
671  Must(theMaster);
672  theMaster->noteVbContentDone(false);
673  vbProductionFinished = true;
674 }
675 
676 void
678 {
679  mustStop("initiator aborted");
680 }
681 
682 // get content from the adapter and put it into the adapted pipe
683 void
685 {
686  Must(proxyingAb == opOn);
687  const libecap::Area c = theMaster->abContent(0, libecap::nsize);
688  debugs(93,5, "up to " << c.size << " bytes");
689  if (c.size == 0 && abProductionFinished) { // no ab now and in the future
690  stopProducingFor(answer().body_pipe, abProductionAtEnd);
691  proxyingAb = opComplete;
692  debugs(93,5, "last adapted body data retrieved");
693  } else if (c.size > 0) {
694  if (const size_t used = answer().body_pipe->putMoreData(c.start, c.size))
695  theMaster->abContentShift(used);
696  }
697 }
698 
699 const char *
701 {
702  static MemBuf buf;
703  buf.reset();
704 
705  buf.append(" [", 2);
706 
707  if (makingVb)
708  buf.appendf("M%d", static_cast<int>(makingVb));
709 
710  const BodyPipePointer &vp = theVirginRep.raw().body_pipe;
711  if (!vp)
712  buf.append(" !V", 3);
713  else if (vp->stillConsuming(const_cast<XactionRep*>(this)))
714  buf.append(" Vc", 3);
715  else
716  buf.append(" V?", 3);
717 
718  if (vbProductionFinished)
719  buf.append(".", 1);
720 
721  buf.appendf(" A%d", static_cast<int>(proxyingAb));
722 
723  if (proxyingAb == opOn) {
724  MessageRep *rep = dynamic_cast<MessageRep*>(theAnswerRep.get());
725  Must(rep);
726  const BodyPipePointer &ap = rep->raw().body_pipe;
727  if (!ap)
728  buf.append(" !A", 3);
729  else if (ap->stillProducing(const_cast<XactionRep*>(this)))
730  buf.append(" Ap", 3);
731  else
732  buf.append(" A?", 3);
733  }
734 
735  buf.appendf(" %s%u]", id.prefix(), id.value);
736 
737  buf.terminate();
738 
739  return buf.content();
740 }
741 
742 void
744 {
745  adapted->sources |= service().cfg().connectionEncryption ? Http::Message::srcEcaps : Http::Message::srcEcap;
746 
747  // Update masterXaction object for adapted HTTP requests.
748  if (HttpRequest *adaptedReq = dynamic_cast<HttpRequest*>(adapted)) {
749  HttpRequest *request = dynamic_cast<HttpRequest*> (theCauseRep ?
750  theCauseRep->raw().header : theVirginRep.raw().header);
751  Must(request);
752  adaptedReq->masterXaction = request->masterXaction;
753  }
754 }
755 
void visitEachOption(libecap::NamedValueVisitor &visitor) const override
Definition: XactionRep.cc:111
const MemBuf & buf() const
Definition: BodyPipe.h:137
void useAdapted(const libecap::shared_ptr< libecap::Message > &msg) override
Definition: XactionRep.cc:421
libecap::Message & virgin() override
Definition: XactionRep.cc:312
@ hoReply
Definition: HttpHeader.h:37
bool stillProducing(const Producer::Pointer &producer) const
Definition: BodyPipe.h:121
void terminate()
Definition: MemBuf.cc:241
void appendf(const char *fmt,...) PRINTF_FORMAT_ARG2
Append operation with printf-style arguments.
Definition: Packable.h:61
const char * rawBuf() const
Definition: SquidString.h:86
void visit(const Name &name, const Area &value) override
Definition: XactionRep.cc:48
common parts of HttpRequest and HttpReply
Definition: Message.h:25
BodyPipe::Pointer body_pipe
optional pipeline to receive message body
Definition: Message.h:97
void noteBodyProducerAborted(RefCount< BodyPipe > bp) override
Definition: XactionRep.cc:668
void swanSong() override
Definition: Initiate.cc:62
libecap::Area vbContent(libecap::size_type offset, libecap::size_type size) override
Definition: XactionRep.cc:553
HttpHeader header
Definition: Message.h:74
const libecap::Area option(const libecap::Name &name) const override
Definition: XactionRep.cc:95
void sinkVb(const char *reason)
Definition: XactionRep.cc:358
bool doneAll() const override
whether positive goal has been reached
Definition: XactionRep.cc:350
static int send_client_ip
Definition: Config.h:47
void updateXxRecord(const char *name, const String &value)
sets or resets a cross-transactional database record
Definition: History.cc:105
bool isAnyAddr() const
Definition: Address.cc:190
@ srcEcap
eCAP service that uses insecure libraries/daemons
Definition: Message.h:42
void updateNextServices(const String &services)
sets or resets next services for the Adaptation::Iterator to notice
Definition: History.cc:121
#define ScheduleCallHere(call)
Definition: AsyncCall.h:166
Definition: SBuf.h:93
void enableAutoConsumption()
start or continue consuming when producing without consumer
Definition: BodyPipe.cc:316
static int use_indirect_client
Definition: Config.h:49
Auth::UserRequest::Pointer auth_user_request
Definition: HttpRequest.h:127
void updateSources(Http::Message *adapted)
Definition: XactionRep.cc:743
void preserveVb(const char *reason)
Definition: XactionRep.cc:372
a libecap Visitor for converting adapter transaction options to HttpHeader
Definition: XactionRep.cc:39
bool getXxRecord(String &name, String &value) const
returns true and fills the record fields iff there is a db record
Definition: History.cc:111
Adaptation::Message & raw()
Definition: MessageRep.h:171
static Answer Block(const SBuf &aRule)
create an akBlock answer
Definition: Answer.cc:35
bool setConsumerIfNotLate(const Consumer::Pointer &aConsumer)
Definition: BodyPipe.cc:228
String extacl_user
Definition: HttpRequest.h:178
RefCount< AsyncCallT< Dialer > > asyncCall(int aDebugSection, int aDebugLevel, const char *aName, const Dialer &aDialer)
Definition: AsyncCall.h:156
const char * status() const override
internal cleanup; do not call directly
Definition: XactionRep.cc:700
char * toStr(char *buf, const unsigned int blen, int force=AF_UNSPEC) const
Definition: Address.cc:812
const libecap::Message & cause() override
Definition: XactionRep.cc:318
void consume(size_t size)
Definition: BodyPipe.cc:309
void noteAbContentDone(bool atEnd) override
Definition: XactionRep.cc:591
void vbMakeMore() override
Definition: XactionRep.cc:543
void noteMoreBodyDataAvailable(RefCount< BodyPipe > bp) override
Definition: XactionRep.cc:651
const libecap::Area clientIpValue() const
Definition: XactionRep.cc:130
#define MAX_IPSTRLEN
Length of buffer that needs to be allocated to old a null-terminated IP-string.
Definition: forward.h:25
void recordXactFinish(int hid)
record the end of a xact identified by its history ID
Definition: History.cc:61
mb_size_t contentSize() const
available data size
Definition: MemBuf.h:47
int size
Definition: ModDevPoll.cc:69
struct timeval current_time
the current UNIX time in timeval {seconds, microseconds} format
Definition: gadgets.cc:18
void append(const char *c, int sz) override
Definition: MemBuf.cc:209
#define NULL
Definition: types.h:145
virtual bool doneAll() const
whether positive goal has been reached
Definition: AsyncJob.cc:112
static Notes & metaHeaders()
The list of configured meta headers.
Definition: Config.cc:35
void blockVirgin() override
Definition: XactionRep.cc:451
Ip::Address indirect_client_addr
Definition: HttpRequest.h:152
const char * username() const
Definition: UserRequest.cc:32
Definition: MemBuf.h:23
SBuf StringToSBuf(const String &s)
create a new SBuf from a String by copying contents
Definition: StringConvert.h:17
void start() override
called by AsyncStart; do not call directly
Definition: XactionRep.cc:231
libecap::shared_ptr< libecap::adapter::Xaction > AdapterXaction
Definition: XactionRep.h:44
XactionRep(Http::Message *virginHeader, HttpRequest *virginCause, AccessLogEntry::Pointer &alp, const Adaptation::ServicePointer &service)
Definition: XactionRep.cc:55
void noteBodyConsumerAborted(RefCount< BodyPipe > bp) override
Definition: XactionRep.cc:641
Config TheConfig
Definition: Config.cc:16
const libecap::Area usernameValue() const
Definition: XactionRep.cc:155
CBDATA_NAMESPACED_CLASS_INIT(Adaptation::Ecap::XactionRep, XactionRep)
void putExt(const char *name, const char *value)
Definition: HttpHeader.cc:1075
void noteAbContentAvailable() override
Definition: XactionRep.cc:601
MasterXaction::Pointer masterXaction
the master transaction this request belongs to. Never nil.
Definition: HttpRequest.h:238
void noteInitiatorAborted() override
Definition: XactionRep.cc:677
OptionsExtractor(HttpHeader &aMeta)
Definition: XactionRep.cc:45
bool stillConsuming(const Consumer::Pointer &consumer) const
Definition: BodyPipe.h:132
#define assert(EX)
Definition: assert.h:17
std::string toStdString() const
std::string export function
Definition: SBuf.h:585
void vbStopMaking() override
Definition: XactionRep.cc:534
void updateHistory(Http::Message *adapted)
Definition: XactionRep.cc:467
const libecap::Area masterxSharedValue(const libecap::Name &name) const
Definition: XactionRep.cc:173
void visitEachMetaHeader(libecap::NamedValueVisitor &visitor) const
Return the adaptation meta headers and their values.
Definition: XactionRep.cc:213
void forgetVb(const char *reason)
Definition: XactionRep.cc:388
NotePairs::Pointer metaHeaders
Definition: History.h:66
void master(const AdapterXaction &aMaster)
Definition: XactionRep.cc:80
bool isNoAddr() const
Definition: Address.cc:304
libecap::Area Area
Definition: XactionRep.cc:43
void tieBody(Ecap::XactionRep *x)
Definition: MessageRep.cc:442
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
Adaptation::History::Pointer adaptLogHistory() const
Returns possibly nil history, creating it if adapt. logging is enabled.
Definition: HttpRequest.cc:415
static Answer Forward(Http::Message *aMsg)
create an akForward answer
Definition: Answer.cc:26
HttpHeader & meta
where to put extracted options
Definition: XactionRep.cc:52
void adaptationAborted() override
Definition: XactionRep.cc:627
const libecap::Area metaValue(const libecap::Name &name) const
Return the adaptation meta header value for the given header "name".
Definition: XactionRep.cc:190
bool productionEnded() const
Definition: BodyPipe.h:113
bool hasPair(const SBuf &key, const SBuf &value) const
Definition: Notes.cc:370
void vbContentShift(libecap::size_type size) override
Definition: XactionRep.cc:577
libecap::Name Name
Definition: XactionRep.cc:42
char * content()
start of the added data
Definition: MemBuf.h:41
bool mayNeedMoreData() const
Definition: BodyPipe.h:118
size_type size() const
Definition: SquidString.h:73
BodyPipePointer body_pipe
Definition: Message.h:46
Adaptation::Message & answer()
Definition: XactionRep.cc:332
#define Must(condition)
Definition: TextException.h:75
void reset()
Definition: MemBuf.cc:129
void noteBodyProductionEnded(RefCount< BodyPipe > bp) override
Definition: XactionRep.cc:659
void add(const SBuf &key, const SBuf &value)
Definition: Notes.cc:317
static char * masterx_shared_name
Definition: Config.h:45
@ srcEcaps
eCAP service that is considered secure; currently unused
Definition: Message.h:36
libecap::Message & adapted() override
Definition: XactionRep.cc:325
void adaptationDelayed(const libecap::Delay &) override
Definition: XactionRep.cc:619
void recordMeta(const HttpHeader *lm)
store the last meta header fields received from the adaptation service
Definition: History.cc:140
int recordXactStart(const String &serviceId, const timeval &when, bool retrying)
record the start of a xact, return xact history ID
Definition: History.cc:51
Ip::Address client_addr
Definition: HttpRequest.h:149
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:192
const A & min(A const &lhs, A const &rhs)
void noteMoreBodySpaceAvailable(RefCount< BodyPipe > bp) override
Definition: XactionRep.cc:634
uint64_t consumedSize() const
Definition: BodyPipe.h:111

 

Introduction

Documentation

Support

Miscellaneous