#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/ecap/XactionRep.h"
+#include "adaptation/Answer.h"
#include "adaptation/ecap/Config.h"
+#include "adaptation/ecap/XactionRep.h"
#include "adaptation/Initiator.h"
#include "base/TextException.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
{
return clientIpValue();
if (name == libecap::metaUserName)
return usernameValue();
- if (name == Adaptation::Config::masterx_shared_name)
+ if (Adaptation::Config::masterx_shared_name && name == Adaptation::Config::masterx_shared_name)
return masterxSharedValue(name);
// TODO: metaServerIp, metaAuthenticatedUser, and metaAuthenticatedGroups
- return libecap::Area();
+
+ // If the name is unknown, metaValue returns an emtpy area
+ return metaValue(name);
}
void
visitor.visit(name, value);
}
+ visitEachMetaHeader(visitor);
+
// TODO: metaServerIp, metaAuthenticatedUser, and metaAuthenticatedGroups
}
} 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));
}
}
const libecap::Area
Adaptation::Ecap::XactionRep::usernameValue() const
{
+#if USE_AUTH
const HttpRequest *request = dynamic_cast<const HttpRequest*>(theCauseRep ?
theCauseRep->raw().header : theVirginRep.raw().header);
Must(request);
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.defined() && request->extacl_user.size())
+ return libecap::Area::FromTempBuffer(request->extacl_user.rawBuf(),
+ request->extacl_user.size());
}
+#endif
return libecap::Area();
}
return libecap::Area();
}
+const libecap::Area
+Adaptation::Ecap::XactionRep::metaValue(const libecap::Name &name) const
+{
+ HttpRequest *request = dynamic_cast<HttpRequest*>(theCauseRep ?
+ theCauseRep->raw().header : theVirginRep.raw().header);
+ Must(request);
+ HttpReply *reply = dynamic_cast<HttpReply*>(theVirginRep.raw().header);
+
+ if (name.known()) { // must check to avoid empty names matching unset cfg
+ typedef Notes::iterator ACAMLI;
+ for (ACAMLI i = Adaptation::Config::metaHeaders.begin(); i != Adaptation::Config::metaHeaders.end(); ++i) {
+ if (name == (*i)->key.termedBuf()) {
+ if (const char *value = (*i)->match(request, reply))
+ return libecap::Area::FromTempString(value);
+ else
+ return libecap::Area();
+ }
+ }
+ }
+
+ return libecap::Area();
+}
+
+void
+Adaptation::Ecap::XactionRep::visitEachMetaHeader(libecap::NamedValueVisitor &visitor) const
+{
+ HttpRequest *request = dynamic_cast<HttpRequest*>(theCauseRep ?
+ theCauseRep->raw().header : theVirginRep.raw().header);
+ Must(request);
+ HttpReply *reply = dynamic_cast<HttpReply*>(theVirginRep.raw().header);
+
+ typedef Notes::iterator ACAMLI;
+ for (ACAMLI i = Adaptation::Config::metaHeaders.begin(); i != Adaptation::Config::metaHeaders.end(); ++i) {
+ const char *v = (*i)->match(request, reply);
+ if (v) {
+ const libecap::Name name((*i)->key.termedBuf());
+ const libecap::Area value = libecap::Area::FromTempString(v);
+ visitor.visit(name, value);
+ }
+ }
+}
+
void
Adaptation::Ecap::XactionRep::start()
{
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);
+ 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();
adaptedReq->adaptHistoryImport(*request);
}
-
void
Adaptation::Ecap::XactionRep::vbDiscard()
{
if (vbProductionFinished)
buf.append(".", 1);
-
buf.Printf(" A%d", static_cast<int>(proxyingAb));
if (proxyingAb == opOn) {