Eray Aslan <eray.aslan@caf.com.tr>
Eray Aslan <eraya@a21an.org>
Eric Stern <estern@logisense.com>
+ Eric Walters <walters.w.eric@gmail.com>
Erik Hofman <erik.hofman@a1.nl>
Eugene Gladchenko <eugene@donpac.ru>
Evan Jones <ejones@uwaterloo.ca>
/* DEBUG: section 55 HTTP Header */
#include "squid.h"
+#include "base/Assure.h"
#include "base/CharacterSet.h"
#include "base/EnumIterator.h"
#include "base/Raw.h"
if (!strVia.isEmpty())
strVia.append(", ", 2);
strVia.append(buf);
- // XXX: putStr() still suffers from String size limits
- Must(strVia.length() < String::SizeMaxXXX());
- delById(Http::HdrType::VIA);
- putStr(Http::HdrType::VIA, strVia.c_str());
+ updateOrAddStr(Http::HdrType::VIA, strVia);
}
}
addEntry(new HttpHeaderEntry(Http::HdrType::OTHER, SBuf(name), value));
}
+void
+HttpHeader::updateOrAddStr(const Http::HdrType id, const SBuf &newValue)
+{
+ assert(any_registered_header(id));
+ assert(Http::HeaderLookupTable.lookup(id).type == Http::HdrFieldType::ftStr);
+
+ // XXX: HttpHeaderEntry::value suffers from String size limits
+ Assure(newValue.length() < String::SizeMaxXXX());
+
+ if (!CBIT_TEST(mask, id)) {
+ auto newValueCopy = newValue; // until HttpHeaderEntry::value becomes SBuf
+ addEntry(new HttpHeaderEntry(id, SBuf(), newValueCopy.c_str()));
+ return;
+ }
+
+ auto foundSameName = false;
+ for (auto &e: entries) {
+ if (!e || e->id != id)
+ continue;
+
+ if (foundSameName) {
+ // get rid of this repeated same-name entry
+ delete e;
+ e = nullptr;
+ continue;
+ }
+
+ if (newValue.cmp(e->value.termedBuf()) != 0)
+ e->value.assign(newValue.rawContent(), newValue.plength());
+
+ foundSameName = true;
+ // continue to delete any repeated same-name entries
+ }
+ assert(foundSameName);
+ debugs(55, 5, "synced: " << Http::HeaderLookupTable.lookup(id).name << ": " << newValue);
+}
+
int
HttpHeader::getInt(Http::HdrType id) const
{
void putRange(const HttpHdrRange * range);
void putSc(HttpHdrSc *sc);
void putExt(const char *name, const char *value);
+
+ /// Ensures that the header has the given field, removing or replacing any
+ /// same-name fields with conflicting values as needed.
+ void updateOrAddStr(Http::HdrType, const SBuf &);
+
int getInt(Http::HdrType id) const;
int64_t getInt64(Http::HdrType id) const;
time_t getTime(Http::HdrType id) const;
*/
if (!Config.errorDirectory) {
/* We 'negotiated' this ONLY from the Accept-Language. */
- rep->header.delById(Http::HdrType::VARY);
- rep->header.putStr(Http::HdrType::VARY, "Accept-Language");
+ static const SBuf acceptLanguage("Accept-Language");
+ rep->header.updateOrAddStr(Http::HdrType::VARY, acceptLanguage);
}
/* add the Content-Language header according to RFC section 14.12 */
HttpRequest *const request = http->request;
assert(request != nullptr);
HttpHeader &header = request->header;
- header.delById(Http::HdrType::FTP_COMMAND);
- header.putStr(Http::HdrType::FTP_COMMAND, "PASV");
- header.delById(Http::HdrType::FTP_ARGUMENTS);
- header.putStr(Http::HdrType::FTP_ARGUMENTS, "");
+ static const SBuf pasvValue("PASV");
+ header.updateOrAddStr(Http::HdrType::FTP_COMMAND, pasvValue);
+ static const SBuf emptyValue("");
+ header.updateOrAddStr(Http::HdrType::FTP_ARGUMENTS, emptyValue);
debugs(9, 5, "client data command converted to fake PASV");
}
// some code still uses Host directly so normalize it using the previously
// sanitized URL authority value.
// For now preserve the case where Host is completely absent. That matters.
- if (const auto x = request->header.delById(Http::HOST)) {
- debugs(33, 5, "normalize " << x << " Host header using " << request->url.authority());
- SBuf tmp(request->url.authority());
- request->header.putStr(Http::HOST, tmp.c_str());
- }
+ if (request->header.has(Http::HdrType::HOST))
+ request->header.updateOrAddStr(Http::HdrType::HOST, request->url.authority());
// TODO: We fill request notes here until we find a way to verify whether
// no ACL checking is performed before ClientHttpRequest::doCallouts().
void HttpHeader::putRange(const HttpHdrRange *) STUB
void HttpHeader::putSc(HttpHdrSc *) STUB
void HttpHeader::putExt(const char *, const char *) STUB
+void HttpHeader::updateOrAddStr(Http::HdrType, const SBuf &) STUB
int HttpHeader::getInt(Http::HdrType) const STUB_RETVAL(0)
int64_t HttpHeader::getInt64(Http::HdrType) const STUB_RETVAL(0)
time_t HttpHeader::getTime(Http::HdrType) const STUB_RETVAL(0)