]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Synced with libecap changes related to FirstLine move to Message.
authorAlex Rousskov <rousskov@measurement-factory.com>
Sat, 27 Sep 2008 18:12:43 +0000 (12:12 -0600)
committerAlex Rousskov <rousskov@measurement-factory.com>
Sat, 27 Sep 2008 18:12:43 +0000 (12:12 -0600)
Migrating to a model where all message changes are done via transaction,
not the message itself. A message cannot handle many changes on its own
because it is not a job, and placing some changes in MessageRep and some
in XactionRep results in messy code.

src/eCAP/MessageRep.cc
src/eCAP/MessageRep.h

index b5fab20e388a57959d1ab5b60a9905e113a28c08..2995fda72d19ddd4aec3ebb3617a7259381e14dd 100644 (file)
@@ -22,22 +22,6 @@ Ecap::HeaderRep::HeaderRep(HttpMsg &aMessage): theHeader(aMessage.header),
 {
 }
 
-http_hdr_type
-Ecap::HeaderRep::TranslateHeaderId(const Name &name)
-{
-    if (name.assignedHostId())
-        return static_cast<http_hdr_type>(name.hostId());
-    return HDR_OTHER;
-}
-
-protocol_t
-Ecap::HeaderRep::TranslateProtocolId(const Name &name)
-{
-    if (name.assignedHostId())
-        return static_cast<protocol_t>(name.hostId());
-    return PROTO_NONE; // no PROTO_OTHER
-}
-
 bool
 Ecap::HeaderRep::hasAny(const Name &name) const
 {
@@ -101,22 +85,37 @@ Ecap::HeaderRep::parse(const Area &buf)
     Must(theMessage.parse(&mb, true, &error));
 }
 
+http_hdr_type
+Ecap::HeaderRep::TranslateHeaderId(const Name &name)
+{
+    if (name.assignedHostId())
+        return static_cast<http_hdr_type>(name.hostId());
+    return HDR_OTHER;
+}
+
+
+/* FirstLineRep */
+
+Ecap::FirstLineRep::FirstLineRep(HttpMsg &aMessage): theMessage(aMessage)
+{
+}
+
 libecap::Version
-Ecap::HeaderRep::version() const
+Ecap::FirstLineRep::version() const
 {
     return libecap::Version(theMessage.http_ver.major,
         theMessage.http_ver.minor);
 }
 
 void
-Ecap::HeaderRep::version(const libecap::Version &aVersion)
+Ecap::FirstLineRep::version(const libecap::Version &aVersion)
 {
     theMessage.http_ver.major = aVersion.majr;
     theMessage.http_ver.minor = aVersion.minr;
 }
 
 libecap::Name
-Ecap::HeaderRep::protocol() const
+Ecap::FirstLineRep::protocol() const
 {
     // TODO: optimize?
     switch (theMessage.protocol) {
@@ -143,22 +142,30 @@ Ecap::HeaderRep::protocol() const
 }
 
 void
-Ecap::HeaderRep::protocol(const Name &p)
+Ecap::FirstLineRep::protocol(const Name &p)
 {
     // TODO: what happens if we fail to translate some protocol?
     theMessage.protocol = TranslateProtocolId(p);
 }
 
+protocol_t
+Ecap::FirstLineRep::TranslateProtocolId(const Name &name)
+{
+    if (name.assignedHostId())
+        return static_cast<protocol_t>(name.hostId());
+    return PROTO_NONE; // no PROTO_OTHER
+}
+
 
 /* RequestHeaderRep */
 
-Ecap::RequestHeaderRep::RequestHeaderRep(HttpRequest &aMessage):
-    HeaderRep(aMessage), theMessage(aMessage)
+Ecap::RequestLineRep::RequestLineRep(HttpRequest &aMessage):
+    FirstLineRep(aMessage), theMessage(aMessage)
 {
 }
 
 void
-Ecap::RequestHeaderRep::uri(const Area &aUri)
+Ecap::RequestLineRep::uri(const Area &aUri)
 {
     // TODO: if method is not set, urlPath will assume it is not connect;
     // Can we change urlParse API to remove the method parameter?
@@ -169,15 +176,15 @@ Ecap::RequestHeaderRep::uri(const Area &aUri)
     Must(ok);
 }
 
-Ecap::RequestHeaderRep::Area
-Ecap::RequestHeaderRep::uri() const
+Ecap::RequestLineRep::Area
+Ecap::RequestLineRep::uri() const
 {
     return Area::FromTempBuffer(theMessage.urlpath.buf(),
         theMessage.urlpath.size());
 }
 
 void
-Ecap::RequestHeaderRep::method(const Name &aMethod)
+Ecap::RequestLineRep::method(const Name &aMethod)
 {
     if (aMethod.assignedHostId()) {
         const int id = aMethod.hostId();
@@ -191,8 +198,8 @@ Ecap::RequestHeaderRep::method(const Name &aMethod)
     }
 }
 
-Ecap::RequestHeaderRep::Name
-Ecap::RequestHeaderRep::method() const
+Ecap::RequestLineRep::Name
+Ecap::RequestLineRep::method() const
 {
     switch (theMessage.method.id()) {
         case METHOD_GET: return libecap::methodGet;
@@ -206,42 +213,89 @@ Ecap::RequestHeaderRep::method() const
     }
 }
 
+libecap::Version
+Ecap::RequestLineRep::version() const
+{
+    return FirstLineRep::version();
+}
+
+void
+Ecap::RequestLineRep::version(const libecap::Version &aVersion)
+{
+    FirstLineRep::version(aVersion);
+}
+
+libecap::Name
+Ecap::RequestLineRep::protocol() const
+{
+    return FirstLineRep::protocol();
+}
+
+void
+Ecap::RequestLineRep::protocol(const Name &p)
+{
+    FirstLineRep::protocol(p);
+}
+
 
 /* ReplyHeaderRep */
 
-Ecap::ReplyHeaderRep::ReplyHeaderRep(HttpReply &aMessage):
-    HeaderRep(aMessage), theMessage(aMessage)
+Ecap::StatusLineRep::StatusLineRep(HttpReply &aMessage):
+    FirstLineRep(aMessage), theMessage(aMessage)
 {
 }
 
 void
-Ecap::ReplyHeaderRep::statusCode(int code)
+Ecap::StatusLineRep::statusCode(int code)
 {
     // TODO: why is .status a enum? Do we not support unknown statuses?
     theMessage.sline.status = static_cast<http_status>(code);
 }
 
 int
-Ecap::ReplyHeaderRep::statusCode() const
+Ecap::StatusLineRep::statusCode() const
 {
     // TODO: see statusCode(code) TODO above
     return static_cast<int>(theMessage.sline.status);
 }
 
 void
-Ecap::ReplyHeaderRep::reasonPhrase(const Area &)
+Ecap::StatusLineRep::reasonPhrase(const Area &)
 {
     // Squid does not support custom reason phrases
     theMessage.sline.reason = NULL;
 }
 
-Ecap::ReplyHeaderRep::Area
-Ecap::ReplyHeaderRep::reasonPhrase() const
+Ecap::StatusLineRep::Area
+Ecap::StatusLineRep::reasonPhrase() const
 {
     return theMessage.sline.reason ?
         Area::FromTempString(std::string(theMessage.sline.reason)) : Area();
 }
 
+libecap::Version
+Ecap::StatusLineRep::version() const
+{
+    return FirstLineRep::version();
+}
+
+void
+Ecap::StatusLineRep::version(const libecap::Version &aVersion)
+{
+    FirstLineRep::version(aVersion);
+}
+
+libecap::Name
+Ecap::StatusLineRep::protocol() const
+{
+    return FirstLineRep::protocol();
+}
+
+void
+Ecap::StatusLineRep::protocol(const Name &p)
+{
+    FirstLineRep::protocol(p);
+}
 
 /* BodyRep */
 
@@ -249,10 +303,18 @@ Ecap::BodyRep::BodyRep(const BodyPipe::Pointer &aBody): theBody(aBody)
 {
 }
 
+void
+Ecap::BodyRep::tie(const BodyPipe::Pointer &aBody)
+{
+    Must(!theBody);
+    Must(aBody != NULL);
+    theBody = aBody;
+}
+
 Ecap::BodyRep::BodySize
 Ecap::BodyRep::bodySize() const
 {
-    return BodySize(theBody->bodySize());
+    return !theBody ? BodySize() : BodySize(theBody->bodySize());
 }
 
 Ecap::BodyRep::size_type
@@ -267,19 +329,6 @@ Ecap::BodyRep::productionEnded() const
     return theBody->productionEnded();
 }
    
-void
-Ecap::BodyRep::bodySize(const Ecap::BodyRep::BodySize &size)
-{
-    Must(size.known());
-    theBody->setBodySize(size.value());
-}
-
-Ecap::BodyRep::size_type
-Ecap::BodyRep::append(const Ecap::BodyRep::Area &area)
-{
-    return theBody->putMoreData(area.start, area.size);
-}
-
 Ecap::BodyRep::Area
 Ecap::BodyRep::prefix(Ecap::BodyRep::size_type size) const
 {
@@ -288,30 +337,25 @@ Ecap::BodyRep::prefix(Ecap::BodyRep::size_type size) const
     return Area::FromTempBuffer(theBody->buf().content(), size);
 }
 
-void
-Ecap::BodyRep::consume(Ecap::BodyRep::size_type size)
-{
-    theBody->consume(size);
-}
-
 
 /* MessageRep */
 
-Ecap::MessageRep::MessageRep(Adaptation::Message &aMessage,
-    Ecap::XactionRep *aXaction):
-    theMessage(aMessage), theXaction(aXaction),
+Ecap::MessageRep::MessageRep(HttpMsg *rawHeader):
+    theMessage(rawHeader), theFirstLineRep(NULL),
     theHeaderRep(NULL), theBodyRep(NULL)
 {
     Must(theMessage.header); // we do not want to represent a missing message
 
     if (HttpRequest *req = dynamic_cast<HttpRequest*>(theMessage.header))
-        theHeaderRep = new RequestHeaderRep(*req);
+        theFirstLineRep = new RequestLineRep(*req);
     else
     if (HttpReply *rep = dynamic_cast<HttpReply*>(theMessage.header))
-        theHeaderRep = new ReplyHeaderRep(*rep);
+        theFirstLineRep = new StatusLineRep(*rep);
     else
            Must(false); // unknown message header type
 
+    theHeaderRep = new HeaderRep(*theMessage.header);
+
     if (theMessage.body_pipe != NULL)
         theBodyRep = new BodyRep(theMessage.body_pipe);
 }
@@ -319,6 +363,33 @@ Ecap::MessageRep::MessageRep(Adaptation::Message &aMessage,
 Ecap::MessageRep::~MessageRep()
 {
     delete theHeaderRep;
+    delete theBodyRep;
+}
+
+libecap::shared_ptr<libecap::Message>
+Ecap::MessageRep::clone() const
+{
+    HttpMsg *hdr = theMessage.header->clone();
+    hdr->body_pipe = NULL; // if any; TODO: remove pipe cloning from ::clone?
+    libecap::shared_ptr<libecap::Message> res(new MessageRep(hdr));
+
+    // restore indication of a body if needed, but not the pipe
+    if (theMessage.header->body_pipe != NULL)
+        res->addBody();
+
+    return res;
+}
+
+libecap::FirstLine &
+Ecap::MessageRep::firstLine()
+{
+    return *theFirstLineRep;
+}
+
+const libecap::FirstLine &
+Ecap::MessageRep::firstLine() const
+{
+    return *theFirstLineRep;
 }
 
 libecap::Header &
@@ -342,11 +413,18 @@ Ecap::MessageRep::body()
 void
 Ecap::MessageRep::addBody()
 {
-    Must(theXaction);
     Must(!theBodyRep);
+    Must(!theMessage.body_pipe); // set in tieBody()
+    theBodyRep = new BodyRep(NULL);
+}
+
+void
+Ecap::MessageRep::tieBody(Ecap::XactionRep *x)
+{
+    Must(theBodyRep != NULL); // addBody must be called first
     Must(!theMessage.body_pipe);
-    theMessage.body_pipe = new BodyPipe(theXaction);
-    theBodyRep = new BodyRep(theMessage.body_pipe);
+    theMessage.body_pipe = new BodyPipe(x);
+    theBodyRep->tie(theMessage.body_pipe);
 }
 
 const libecap::Body *Ecap::MessageRep::body() const
index c2532583cfead03abf343c409e9b3b82259924c3..9abef7d188f28188f64411dc9bad892ddffd2f9c 100644 (file)
@@ -34,14 +34,8 @@ public:
     virtual Area image() const;
     virtual void parse(const Area &buf); // throws on failures
 
-    virtual libecap::Version version() const;
-    virtual void version(const libecap::Version &aVersion);
-    virtual Name protocol() const;
-    virtual void protocol(const Name &aProtocol);
-
 protected:
     static http_hdr_type TranslateHeaderId(const Name &name);
-    static protocol_t TranslateProtocolId(const Name &name);
 
 private:
     HttpHeader &theHeader; // the header being translated to libecap
@@ -49,11 +43,36 @@ private:
 };
 
 
-// Translates Squid HttpRequest into libecap::Header + libecap::RequestLine.
-class RequestHeaderRep: public HeaderRep, public libecap::RequestLine
+// Helps translate Squid HttpMsg into libecap::FirstLine (see children).
+class FirstLineRep
 {
 public:
-    RequestHeaderRep(HttpRequest &aMessage);
+    typedef libecap::Name Name;
+
+public:
+    FirstLineRep(HttpMsg &aMessage);
+
+    libecap::Version version() const;
+    void version(const libecap::Version &aVersion);
+    Name protocol() const;
+    void protocol(const Name &aProtocol);
+
+protected:
+    static protocol_t TranslateProtocolId(const Name &name);
+
+private:
+    HttpMsg &theMessage; // the message which first line is being translated
+};
+
+// Translates Squid HttpRequest into libecap::RequestLine.
+class RequestLineRep: public libecap::RequestLine, public FirstLineRep
+{
+public:
+//    typedef libecap::Name Name;
+    typedef libecap::Area Area;
+
+public:
+    RequestLineRep(HttpRequest &aMessage);
 
     virtual void uri(const Area &aUri);
     virtual Area uri() const;
@@ -61,15 +80,24 @@ public:
     virtual void method(const Name &aMethod);
     virtual Name method() const;
 
+    virtual libecap::Version version() const;
+    virtual void version(const libecap::Version &aVersion);
+    virtual Name protocol() const;
+    virtual void protocol(const Name &aProtocol);
+
 private:
     HttpRequest &theMessage; // the request header being translated to libecap
 };
 
-// Translates Squid HttpReply into libecap::Header + libecap::StatusLine.
-class ReplyHeaderRep: public HeaderRep, public libecap::StatusLine
+// Translates Squid HttpReply into libecap::StatusLine.
+class StatusLineRep: public libecap::StatusLine, public FirstLineRep
 {
 public:
-    ReplyHeaderRep(HttpReply &aMessage);
+    typedef libecap::Name Name;
+    typedef libecap::Area Area;
+
+public:
+    StatusLineRep(HttpReply &aMessage);
 
     virtual void statusCode(int code);
     virtual int statusCode() const;
@@ -77,33 +105,34 @@ public:
     virtual void reasonPhrase(const Area &phrase);
     virtual Area reasonPhrase() const;
 
+    virtual libecap::Version version() const;
+    virtual void version(const libecap::Version &aVersion);
+    virtual Name protocol() const;
+    virtual void protocol(const Name &aProtocol);
+
 private:
     HttpReply &theMessage; // the request header being translated to libecap
 };
 
 
-// Translates Squid HttpMsg into libecap::Body.
+// Translates Squid BodyPipe into libecap::Body.
 class BodyRep: public libecap::Body
 {
 public:
     typedef libecap::Area Area;
     typedef libecap::BodySize BodySize;
+    using libecap::Body::size_type;
 
 public:
-    BodyRep(const BodyPipe::Pointer &aBody);
+    BodyRep(const BodyPipe::Pointer &aBody); // using NULL pointer? see tie()
 
-    // stats
+    void tie(const BodyPipe::Pointer &aBody); // late binding if !theBody;
+
+    // libecap::Body API
     virtual BodySize bodySize() const;
     virtual size_type consumedSize() const;
-    virtual bool productionEnded() const; // producedSize will not grow
-   
-    // called by producers
-    virtual void bodySize(const BodySize &size); // throws if already !
-    virtual size_type append(const Area &area); // throws on overflow
-
-    // called by consumers
+    virtual bool productionEnded() const;
     virtual Area prefix(size_type size) const;
-    virtual void consume(size_type size);
 
 private:
     BodyPipe::Pointer theBody; // the body being translated to libecap
@@ -113,21 +142,30 @@ private:
 class MessageRep: public libecap::Message
 {
 public:
-    MessageRep(Adaptation::Message &aMessage, Ecap::XactionRep *aXaction);
+    explicit MessageRep(HttpMsg *rawHeader);
     virtual ~MessageRep();
 
+       virtual libecap::shared_ptr<libecap::Message> clone() const;
+
+       virtual libecap::FirstLine &firstLine();
+       virtual const libecap::FirstLine &firstLine() const;
+
     virtual libecap::Header &header();
     virtual const libecap::Header &header() const;
 
     virtual void addBody();
     virtual libecap::Body *body();
     virtual const libecap::Body *body() const;
+       void tieBody(Ecap::XactionRep *x); // to a specific transaction
+
+       Adaptation::Message &raw() { return theMessage; } // for host access
+       const Adaptation::Message &raw() const { return theMessage; } // for host
 
 private:
-    Adaptation::Message &theMessage; // the message being translated to libecap
-    Ecap::XactionRep *theXaction; // host transaction managing the translation
-    HeaderRep *theHeaderRep;
-    BodyRep *theBodyRep;
+    Adaptation::Message theMessage; // the message being translated to libecap
+    libecap::FirstLine *theFirstLineRep; // request or status line wrapper
+    HeaderRep *theHeaderRep; // header wrapper
+    BodyRep *theBodyRep; // body wrapper
 };
 
 } // namespace Ecap;