]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/adaptation/ecap/XactionRep.cc
transaction_initiator ACL for detecting various unusual transactions
[thirdparty/squid.git] / src / adaptation / ecap / XactionRep.cc
index 30fb86cbd951c129c80d8d9e721443d7476c8b5c..660eea5c405d8bf294881cca22c2183a869f7d4e 100644 (file)
@@ -1,6 +1,13 @@
 /*
- * DEBUG: section 93    eCAP Interface
+ * Copyright (C) 1996-2017 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.
  */
+
+/* DEBUG: section 93    eCAP Interface */
+
 #include "squid.h"
 #include <libecap/common/area.h>
 #include <libecap/common/delay.h>
@@ -16,6 +23,7 @@
 #include "format/Format.h"
 #include "HttpReply.h"
 #include "HttpRequest.h"
+#include "MasterXaction.h"
 #include "SquidTime.h"
 
 CBDATA_NAMESPACED_CLASS_INIT(Adaptation::Ecap::XactionRep, XactionRep);
@@ -38,17 +46,17 @@ public:
 };
 
 Adaptation::Ecap::XactionRep::XactionRep(
-    HttpMsg *virginHeader, HttpRequest *virginCause, AccessLogEntry::Pointer &alp,
+    Http::Message *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),
-        al(alp)
+    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);
@@ -65,7 +73,7 @@ void
 Adaptation::Ecap::XactionRep::master(const AdapterXaction &x)
 {
     Must(!theMaster);
-    Must(x != NULL);
+    Must(x);
     theMaster = x;
 }
 
@@ -181,10 +189,11 @@ Adaptation::Ecap::XactionRep::metaValue(const libecap::Name &name) const
 
     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, al))
-                    return libecap::Area::FromTempString(value);
+        for (auto h: Adaptation::Config::metaHeaders) {
+            if (name == h->key().toStdString()) {
+                SBuf matched;
+                if (h->match(request, reply, al, matched))
+                    return libecap::Area::FromTempString(matched.toStdString());
                 else
                     return libecap::Area();
             }
@@ -202,12 +211,11 @@ Adaptation::Ecap::XactionRep::visitEachMetaHeader(libecap::NamedValueVisitor &vi
     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, al);
-        if (v) {
-            const libecap::Name name((*i)->key.termedBuf());
-            const libecap::Area value = libecap::Area::FromTempString(v);
+    for (auto h: Adaptation::Config::metaHeaders) {
+        SBuf matched;
+        if (h->match(request, reply, al, matched)) {
+            const libecap::Name name(h->key().toStdString());
+            const libecap::Area value = libecap::Area::FromTempString(matched.toStdString());
             visitor.visit(name, value);
         }
     }
@@ -231,14 +239,13 @@ Adaptation::Ecap::XactionRep::start()
     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) {
+        SBuf matched;
+        for (auto h: Adaptation::Config::metaHeaders) {
+            if (h->match(request, reply, al, matched)) {
                 if (ah->metaHeaders == NULL)
                     ah->metaHeaders = new NotePairs();
-                if (!ah->metaHeaders->hasPair((*i)->key.termedBuf(), v))
-                    ah->metaHeaders->add((*i)->key.termedBuf(), v);
+                if (!ah->metaHeaders->hasPair(h->key(), matched))
+                    ah->metaHeaders->add(h->key(), matched);
             }
         }
     }
@@ -252,7 +259,7 @@ Adaptation::Ecap::XactionRep::swanSong()
     // clear body_pipes, if any
     // this code does not maintain proxying* and canAccessVb states; should it?
 
-    if (theAnswerRep != NULL) {
+    if (theAnswerRep) {
         BodyPipe::Pointer body_pipe = answer().body_pipe;
         if (body_pipe != NULL) {
             Must(body_pipe->stillProducing(this));
@@ -311,7 +318,7 @@ Adaptation::Ecap::XactionRep::cause()
 libecap::Message &
 Adaptation::Ecap::XactionRep::adapted()
 {
-    Must(theAnswerRep != NULL);
+    Must(theAnswerRep);
     return *theAnswerRep;
 }
 
@@ -395,7 +402,7 @@ Adaptation::Ecap::XactionRep::useVirgin()
 
     preserveVb("useVirgin");
 
-    HttpMsg *clone = theVirginRep.raw().header->clone();
+    Http::Message *clone = theVirginRep.raw().header->clone();
     // check that clone() copies the pipe so that we do not have to
     Must(!theVirginRep.raw().header->body_pipe == !clone->body_pipe);
 
@@ -412,7 +419,8 @@ Adaptation::Ecap::XactionRep::useAdapted(const libecap::shared_ptr<libecap::Mess
     theAnswerRep = m;
     Must(proxyingAb == opUndecided);
 
-    HttpMsg *msg = answer().header;
+    Http::Message *msg = answer().header;
+    updateSources(msg);
     if (!theAnswerRep->body()) { // final, bodyless answer
         proxyingAb = opNever;
         updateHistory(msg);
@@ -450,7 +458,7 @@ Adaptation::Ecap::XactionRep::blockVirgin()
 /// Called just before sendAnswer() to record adapter meta-information
 /// which may affect answer processing and may be needed for logging.
 void
-Adaptation::Ecap::XactionRep::updateHistory(HttpMsg *adapted)
+Adaptation::Ecap::XactionRep::updateHistory(Http::Message *adapted)
 {
     if (!theMaster) // all updates rely on being able to query the adapter
         return;
@@ -692,7 +700,7 @@ Adaptation::Ecap::XactionRep::status() const
     buf.append(" [", 2);
 
     if (makingVb)
-        buf.Printf("M%d", static_cast<int>(makingVb));
+        buf.appendf("M%d", static_cast<int>(makingVb));
 
     const BodyPipePointer &vp = theVirginRep.raw().body_pipe;
     if (!vp)
@@ -705,7 +713,7 @@ Adaptation::Ecap::XactionRep::status() const
     if (vbProductionFinished)
         buf.append(".", 1);
 
-    buf.Printf(" A%d", static_cast<int>(proxyingAb));
+    buf.appendf(" A%d", static_cast<int>(proxyingAb));
 
     if (proxyingAb == opOn) {
         MessageRep *rep = dynamic_cast<MessageRep*>(theAnswerRep.get());
@@ -719,9 +727,24 @@ Adaptation::Ecap::XactionRep::status() const
             buf.append(" A?", 3);
     }
 
-    buf.Printf(" %s%u]", id.Prefix, id.value);
+    buf.appendf(" %s%u]", id.prefix(), id.value);
 
     buf.terminate();
 
     return buf.content();
 }
+
+void
+Adaptation::Ecap::XactionRep::updateSources(Http::Message *adapted)
+{
+    adapted->sources |= service().cfg().connectionEncryption ? Http::Message::srcEcaps : Http::Message::srcEcap;
+
+    // Update masterXaction object for adapted HTTP requests.
+    if (HttpRequest *adaptedReq = dynamic_cast<HttpRequest*>(adapted)) {
+        HttpRequest *request = dynamic_cast<HttpRequest*> (theCauseRep ?
+                               theCauseRep->raw().header : theVirginRep.raw().header);
+        Must(request);
+        adaptedReq->masterXaction = request->masterXaction;
+    }
+}
+