{
}
-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
{
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) {
}
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?
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();
}
}
-Ecap::RequestHeaderRep::Name
-Ecap::RequestHeaderRep::method() const
+Ecap::RequestLineRep::Name
+Ecap::RequestLineRep::method() const
{
switch (theMessage.method.id()) {
case METHOD_GET: return libecap::methodGet;
}
}
+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 */
{
}
+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
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
{
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);
}
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 &
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
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
};
-// 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;
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;
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
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;