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

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors