/*
- * DEBUG: section 93 eCAP Interface
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
*/
-#include "squid-old.h"
+
+/* DEBUG: section 93 eCAP Interface */
+
+#include "squid.h"
#include <libecap/common/area.h>
#include <libecap/common/delay.h>
#include <libecap/common/named_values.h>
#include <libecap/common/names.h>
#include <libecap/adapter/xaction.h>
-#include "HttpRequest.h"
-#include "HttpReply.h"
-#include "SquidTime.h"
#include "adaptation/Answer.h"
-#include "adaptation/ecap/XactionRep.h"
#include "adaptation/ecap/Config.h"
+#include "adaptation/ecap/XactionRep.h"
#include "adaptation/Initiator.h"
+#include "base/AsyncJobCalls.h"
#include "base/TextException.h"
+#include "format/Format.h"
+#include "HttpReply.h"
+#include "HttpRequest.h"
+#include "SquidTime.h"
CBDATA_NAMESPACED_CLASS_INIT(Adaptation::Ecap::XactionRep, XactionRep);
-
/// a libecap Visitor for converting adapter transaction options to HttpHeader
class OptionsExtractor: public libecap::NamedValueVisitor
{
};
Adaptation::Ecap::XactionRep::XactionRep(
- HttpMsg *virginHeader, HttpRequest *virginCause,
+ HttpMsg *virginHeader, HttpRequest *virginCause, AccessLogEntry::Pointer &alp,
const Adaptation::ServicePointer &aService):
- AsyncJob("Adaptation::Ecap::XactionRep"),
- Adaptation::Initiate("Adaptation::Ecap::XactionRep"),
- theService(aService),
- theVirginRep(virginHeader), theCauseRep(NULL),
- makingVb(opUndecided), proxyingAb(opUndecided),
- adaptHistoryId(-1),
- vbProductionFinished(false),
- abProductionFinished(false), abProductionAtEnd(false)
+ AsyncJob("Adaptation::Ecap::XactionRep"),
+ Adaptation::Initiate("Adaptation::Ecap::XactionRep"),
+ theService(aService),
+ theVirginRep(virginHeader), theCauseRep(NULL),
+ makingVb(opUndecided), proxyingAb(opUndecided),
+ adaptHistoryId(-1),
+ vbProductionFinished(false),
+ abProductionFinished(false), abProductionAtEnd(false),
+ al(alp)
{
if (virginCause)
theCauseRep = new MessageRep(virginCause);
} else
#endif
client_addr = request->client_addr;
- if (!client_addr.IsAnyAddr() && !client_addr.IsNoAddr()) {
+ if (!client_addr.isAnyAddr() && !client_addr.isNoAddr()) {
char ntoabuf[MAX_IPSTRLEN] = "";
- client_addr.NtoA(ntoabuf,MAX_IPSTRLEN);
+ client_addr.toStr(ntoabuf,MAX_IPSTRLEN);
return libecap::Area::FromTempBuffer(ntoabuf, strlen(ntoabuf));
}
}
if (request->auth_user_request != NULL) {
if (char const *name = request->auth_user_request->username())
return libecap::Area::FromTempBuffer(name, strlen(name));
+ else if (request->extacl_user.size() > 0)
+ return libecap::Area::FromTempBuffer(request->extacl_user.rawBuf(),
+ request->extacl_user.size());
}
#endif
return libecap::Area();
HttpReply *reply = dynamic_cast<HttpReply*>(theVirginRep.raw().header);
if (name.known()) { // must check to avoid empty names matching unset cfg
- typedef Adaptation::Config::MetaHeaders::iterator ACAMLI;
+ typedef Notes::iterator ACAMLI;
for (ACAMLI i = Adaptation::Config::metaHeaders.begin(); i != Adaptation::Config::metaHeaders.end(); ++i) {
- if (name == (*i)->name.termedBuf()) {
- if (const char *value = (*i)->match(request, reply))
+ if (name == (*i)->key.termedBuf()) {
+ if (const char *value = (*i)->match(request, reply, al))
return libecap::Area::FromTempString(value);
else
return libecap::Area();
Must(request);
HttpReply *reply = dynamic_cast<HttpReply*>(theVirginRep.raw().header);
- typedef Adaptation::Config::MetaHeaders::iterator ACAMLI;
+ typedef Notes::iterator ACAMLI;
for (ACAMLI i = Adaptation::Config::metaHeaders.begin(); i != Adaptation::Config::metaHeaders.end(); ++i) {
- const char *v;
- if (v = (*i)->match(request, reply)) {
- const libecap::Name name((*i)->name.termedBuf());
+ const char *v = (*i)->match(request, reply, al);
+ if (v) {
+ const libecap::Name name((*i)->key.termedBuf());
const libecap::Area value = libecap::Area::FromTempString(v);
visitor.visit(name, value);
}
if (!theVirginRep.raw().body_pipe)
makingVb = opNever; // there is nothing to deliver
- const HttpRequest *request = dynamic_cast<const HttpRequest*> (theCauseRep ?
- theCauseRep->raw().header : theVirginRep.raw().header);
+ HttpRequest *request = dynamic_cast<HttpRequest*> (theCauseRep ?
+ theCauseRep->raw().header : theVirginRep.raw().header);
Must(request);
+
+ HttpReply *reply = dynamic_cast<HttpReply*>(theVirginRep.raw().header);
+
Adaptation::History::Pointer ah = request->adaptLogHistory();
if (ah != NULL) {
// retrying=false because ecap never retries transactions
adaptHistoryId = ah->recordXactStart(service().cfg().key, current_time, false);
+ typedef Notes::iterator ACAMLI;
+ for (ACAMLI i = Adaptation::Config::metaHeaders.begin(); i != Adaptation::Config::metaHeaders.end(); ++i) {
+ const char *v = (*i)->match(request, reply, al);
+ if (v) {
+ if (ah->metaHeaders == NULL)
+ ah->metaHeaders = new NotePairs();
+ if (!ah->metaHeaders->hasPair((*i)->key.termedBuf(), v))
+ ah->metaHeaders->add((*i)->key.termedBuf(), v);
+ }
+ }
}
theMaster->start();
Adaptation::Initiate::swanSong();
}
+void
+Adaptation::Ecap::XactionRep::resume()
+{
+ // go async to gain exception protection and done()-based job destruction
+ typedef NullaryMemFunT<Adaptation::Ecap::XactionRep> Dialer;
+ AsyncCall::Pointer call = asyncCall(93, 5, "Adaptation::Ecap::XactionRep::doResume",
+ Dialer(this, &Adaptation::Ecap::XactionRep::doResume));
+ ScheduleCallHere(call);
+}
+
+/// the guts of libecap::host::Xaction::resume() API implementation
+/// which just goes async in Adaptation::Ecap::XactionRep::resume().
+void
+Adaptation::Ecap::XactionRep::doResume()
+{
+ Must(theMaster);
+ theMaster->resume();
+}
+
libecap::Message &
Adaptation::Ecap::XactionRep::virgin()
{
adaptedReq->adaptHistoryImport(*request);
}
-
void
Adaptation::Ecap::XactionRep::vbDiscard()
{
mustStop("adaptationAborted");
}
-bool
-Adaptation::Ecap::XactionRep::callable() const
-{
- return !done();
-}
-
void
Adaptation::Ecap::XactionRep::noteMoreBodySpaceAvailable(RefCount<BodyPipe> bp)
{
if (vbProductionFinished)
buf.append(".", 1);
-
buf.Printf(" A%d", static_cast<int>(proxyingAb));
if (proxyingAb == opOn) {
return buf.content();
}
+