/*
- * DEBUG: section 93 eCAP Interface
+ * Copyright (C) 1996-2021 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 "BodyPipe.h"
#include "HttpReply.h"
#include "adaptation/ecap/MessageRep.h"
#include "adaptation/ecap/XactionRep.h"
#include "base/TextException.h"
-#include "URL.h"
/* HeaderRep */
-Adaptation::Ecap::HeaderRep::HeaderRep(HttpMsg &aMessage): theHeader(aMessage.header),
- theMessage(aMessage)
+Adaptation::Ecap::HeaderRep::HeaderRep(Http::Message &aMessage): theHeader(aMessage.header),
+ theMessage(aMessage)
{
}
bool
Adaptation::Ecap::HeaderRep::hasAny(const Name &name) const
{
- const http_hdr_type squidId = TranslateHeaderId(name);
- // XXX: optimize to remove getByName: we do not need the value here
- return squidId == HDR_OTHER ?
- theHeader.getByName(name.image().c_str()).size() > 0:
- (bool)theHeader.has(squidId);
+ const Http::HdrType squidId = TranslateHeaderId(name);
+ return squidId == Http::HdrType::OTHER ?
+ theHeader.hasNamed(name.image().c_str(), name.image().size()) :
+ static_cast<bool>(theHeader.has(squidId));
}
Adaptation::Ecap::HeaderRep::Value
Adaptation::Ecap::HeaderRep::value(const Name &name) const
{
- const http_hdr_type squidId = TranslateHeaderId(name);
- const String value = squidId == HDR_OTHER ?
+ const Http::HdrType squidId = TranslateHeaderId(name);
+ const String value = squidId == Http::HdrType::OTHER ?
theHeader.getByName(name.image().c_str()) :
theHeader.getStrOrList(squidId);
- return value.defined() ?
+ return value.size() > 0 ?
Value::FromTempString(value.termedBuf()) : Value();
}
void
Adaptation::Ecap::HeaderRep::add(const Name &name, const Value &value)
{
- const http_hdr_type squidId = TranslateHeaderId(name); // HDR_OTHER OK
- HttpHeaderEntry *e = new HttpHeaderEntry(squidId, name.image().c_str(),
+ const Http::HdrType squidId = TranslateHeaderId(name); // Http::HdrType::OTHER OK
+ HttpHeaderEntry *e = new HttpHeaderEntry(squidId, SBuf(name.image()),
value.toString().c_str());
theHeader.addEntry(e);
- if (squidId == HDR_CONTENT_LENGTH)
- theMessage.content_length = theHeader.getInt64(HDR_CONTENT_LENGTH);
+ if (squidId == Http::HdrType::CONTENT_LENGTH)
+ theMessage.content_length = theHeader.getInt64(Http::HdrType::CONTENT_LENGTH);
}
void
Adaptation::Ecap::HeaderRep::removeAny(const Name &name)
{
- const http_hdr_type squidId = TranslateHeaderId(name);
- if (squidId == HDR_OTHER)
+ const Http::HdrType squidId = TranslateHeaderId(name);
+ if (squidId == Http::HdrType::OTHER)
theHeader.delByName(name.image().c_str());
else
theHeader.delById(squidId);
- if (squidId == HDR_CONTENT_LENGTH)
- theMessage.content_length = theHeader.getInt64(HDR_CONTENT_LENGTH);
+ if (squidId == Http::HdrType::CONTENT_LENGTH)
+ theMessage.content_length = theHeader.getInt64(Http::HdrType::CONTENT_LENGTH);
}
void
{
HttpHeaderPos pos = HttpHeaderInitPos;
while (HttpHeaderEntry *e = theHeader.getEntry(&pos)) {
- const Name name(e->name.termedBuf()); // optimize: find std Names
+ const Name name(std::string(e->name.rawContent(), e->name.length())); // optimize: find std Names
name.assignHostId(e->id);
visitor.visit(name, Value(e->value.rawBuf(), e->value.size()));
}
{
MemBuf mb;
mb.init();
-
- Packer p;
- packerToMemInit(&p, &mb);
- theMessage.packInto(&p, true);
- packerClean(&p);
+ theMessage.packInto(&mb, true);
return Area::FromTempBuffer(mb.content(), mb.contentSize());
}
void
Adaptation::Ecap::HeaderRep::parse(const Area &buf)
{
- MemBuf mb;
- mb.init();
- mb.append(buf.start, buf.size);
Http::StatusCode error;
- Must(theMessage.parse(&mb, true, &error));
+ Must(theMessage.parse(buf.start, buf.size, true, &error));
}
-http_hdr_type
+Http::HdrType
Adaptation::Ecap::HeaderRep::TranslateHeaderId(const Name &name)
{
if (name.assignedHostId())
- return static_cast<http_hdr_type>(name.hostId());
- return HDR_OTHER;
+ return static_cast<Http::HdrType>(name.hostId());
+ return Http::HdrType::OTHER;
}
/* FirstLineRep */
-Adaptation::Ecap::FirstLineRep::FirstLineRep(HttpMsg &aMessage): theMessage(aMessage)
+Adaptation::Ecap::FirstLineRep::FirstLineRep(Http::Message &aMessage): theMessage(aMessage)
{
}
Adaptation::Ecap::FirstLineRep::protocol() const
{
// TODO: optimize?
- switch (theMessage.protocol) {
+ switch (theMessage.http_ver.protocol) {
case AnyP::PROTO_HTTP:
return libecap::protocolHttp;
case AnyP::PROTO_HTTPS:
#endif
case AnyP::PROTO_CACHE_OBJECT:
return protocolCacheObj;
- case AnyP::PROTO_INTERNAL:
- return protocolInternal;
case AnyP::PROTO_ICY:
return protocolIcy;
case AnyP::PROTO_COAP:
case AnyP::PROTO_COAPS: // use 'unknown' until libecap supports coap:// and coaps://
+ // other protocols defined in Squid but not libecap use 'unknown'
+ case AnyP::PROTO_AUTHORITY_FORM:
+ case AnyP::PROTO_SSL:
+ case AnyP::PROTO_TLS:
case AnyP::PROTO_UNKNOWN:
return protocolUnknown; // until we remember the protocol image
case AnyP::PROTO_NONE:
Adaptation::Ecap::FirstLineRep::protocol(const Name &p)
{
// TODO: what happens if we fail to translate some protocol?
- theMessage.protocol = TranslateProtocolId(p);
+ theMessage.http_ver.protocol = TranslateProtocolId(p);
}
AnyP::ProtocolType
/* RequestHeaderRep */
Adaptation::Ecap::RequestLineRep::RequestLineRep(HttpRequest &aMessage):
- FirstLineRep(aMessage), theMessage(aMessage)
+ FirstLineRep(aMessage), theMessage(aMessage)
{
}
void
Adaptation::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?
- // TODO: optimize: urlPath should take constant URL buffer
- char *buf = xstrdup(aUri.toString().c_str());
- const bool ok = urlParse(theMessage.method, buf, &theMessage);
- xfree(buf);
+ // TODO: if method is not set, AnyP::Uri::parse will assume it is not connect;
+ // Can we change AnyP::Uri::parse API to remove the method parameter?
+ const auto ok = theMessage.url.parse(theMessage.method, SBuf(aUri.toString()));
Must(ok);
}
Adaptation::Ecap::RequestLineRep::Area
Adaptation::Ecap::RequestLineRep::uri() const
{
- const char *fullUrl = urlCanonical(&theMessage);
- Must(fullUrl);
+ const SBuf &fullUrl = theMessage.effectiveRequestUri();
+ // XXX: effectiveRequestUri() cannot return NULL or even empty string, some other problem?
+ Must(!fullUrl.isEmpty());
// optimize: avoid copying by having an Area::Detail that locks theMessage
- return Area::FromTempBuffer(fullUrl, strlen(fullUrl));
+ return Area::FromTempBuffer(fullUrl.rawContent(), fullUrl.length());
}
void
theMessage.method = HttpRequestMethod(static_cast<Http::MethodType>(id));
} else {
const std::string &image = aMethod.image();
- theMessage.method = HttpRequestMethod(image.data(),
- image.data() + image.size());
+ theMessage.method.HttpRequestMethodXXX(image.c_str());
}
}
case Http::METHOD_TRACE:
return libecap::methodTrace;
default:
- return Name(theMessage.method.image());
+ return Name(theMessage.method.image().toStdString());
}
}
/* ReplyHeaderRep */
Adaptation::Ecap::StatusLineRep::StatusLineRep(HttpReply &aMessage):
- FirstLineRep(aMessage), theMessage(aMessage)
+ FirstLineRep(aMessage), theMessage(aMessage)
{
}
void
Adaptation::Ecap::StatusLineRep::statusCode(int code)
{
- theMessage.sline.set(theMessage.sline.version, static_cast<Http::StatusCode>(code), theMessage.sline.reason());
+ theMessage.sline.set(theMessage.sline.version, static_cast<Http::StatusCode>(code), nullptr);
}
int
}
void
-Adaptation::Ecap::StatusLineRep::reasonPhrase(const Area &str)
+Adaptation::Ecap::StatusLineRep::reasonPhrase(const Area &)
{
- theMessage.sline.set(theMessage.sline.version, theMessage.sline.status(), str.toString().c_str());
+ // Squid does not support external custom reason phrases so we have
+ // to just reset it (in case there was a custom internal reason set)
+ theMessage.sline.resetReason();
}
Adaptation::Ecap::StatusLineRep::Area
Adaptation::Ecap::BodyRep::BodySize
Adaptation::Ecap::BodyRep::bodySize() const
{
- return !theBody ? BodySize() : BodySize(theBody->bodySize());
+ return (theBody != nullptr && theBody->bodySizeKnown()) ? BodySize(theBody->bodySize()) : BodySize();
}
/* MessageRep */
-Adaptation::Ecap::MessageRep::MessageRep(HttpMsg *rawHeader):
- theMessage(rawHeader), theFirstLineRep(NULL),
- theHeaderRep(NULL), theBodyRep(NULL)
+Adaptation::Ecap::MessageRep::MessageRep(Http::Message *rawHeader):
+ theMessage(rawHeader), theFirstLineRep(NULL),
+ theHeaderRep(NULL), theBodyRep(NULL)
{
Must(theMessage.header); // we do not want to represent a missing message
libecap::shared_ptr<libecap::Message>
Adaptation::Ecap::MessageRep::clone() const
{
- HttpMsg *hdr = theMessage.header->clone();
+ Http::Message *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));
{
return theBodyRep;
}
+