/*
- * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ * 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.
#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),
+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.size() > 0 ?
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()));
}
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)
{
}
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:
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
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):
+Adaptation::Ecap::MessageRep::MessageRep(Http::Message *rawHeader):
theMessage(rawHeader), theFirstLineRep(NULL),
theHeaderRep(NULL), theBodyRep(NULL)
{
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));