Skip to content

Commit

Permalink
HTTP headers should be compared case-insensitive
Browse files Browse the repository at this point in the history
IB-8163

Signed-off-by: Raul Metsma <[email protected]>
  • Loading branch information
metsma committed Aug 14, 2024
1 parent 79d7001 commit 5b45f0d
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 30 deletions.
31 changes: 14 additions & 17 deletions src/crypto/Connect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ Connect::Connect(const string &_url, string _method, int _timeout, const vector<
}
}

#if OPENSSL_VERSION_NUMBER > 0x30000000L
#if OPENSSL_VERSION_NUMBER < 0x30000000L
if(_timeout > 0)
{
int fd = BIO_get_fd(d, nullptr);
Expand Down Expand Up @@ -251,12 +251,6 @@ string Connect::decompress(const string &encoding, const string &data)
return out;
}

Connect::Result Connect::exec(initializer_list<pair<string_view,string_view>> headers,
const vector<unsigned char> &data)
{
return exec(headers, data.data(), data.size());
}

Connect::Result Connect::exec(initializer_list<pair<string_view,string_view>> headers,
const unsigned char *data, size_t size)
{
Expand Down Expand Up @@ -295,6 +289,10 @@ Connect::Result Connect::exec(initializer_list<pair<string_view,string_view>> he

stringstream stream(r.content);
string line;
auto to_lower = [](string str) {
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
return str;
};
while(getline(stream, line))
{
line.resize(max<size_t>(line.size() - 1, 0));
Expand All @@ -307,18 +305,17 @@ Connect::Result Connect::exec(initializer_list<pair<string_view,string_view>> he
}
size_t split = line.find(": ");
if(split != string::npos)
r.headers[line.substr(0, split)] = line.substr(split + 2);
r.headers[to_lower(line.substr(0, split))] = line.substr(split + 2);
else
r.headers[line] = string();
r.headers[to_lower(line)] = string();
}

pos = r.content.find("\r\n\r\n");
if(pos != string::npos)
r.content.erase(0, pos + 4);

const auto transfer_encoding = r.headers.find("Transfer-Encoding");
if(transfer_encoding != r.headers.cend() &&
transfer_encoding->second.find("chunked") != string::npos) {
if(const auto it = r.headers.find("transfer-encoding");
it != r.headers.cend() &&
it->second.find("chunked") != string::npos) {
pos = 0;
for(size_t chunkpos = r.content.find("\r\n", pos);
chunkpos != string::npos;
Expand All @@ -331,14 +328,14 @@ Connect::Result Connect::exec(initializer_list<pair<string_view,string_view>> he
}
}

const auto it = r.headers.find("Content-Encoding");
if(it != r.headers.cend())
if(const auto it = r.headers.find("content-encoding");
it != r.headers.cend())
r.content = decompress(it->second, r.content);

if(!r.isRedirect() || recursive > 3)
return r;
string location = r.headers.find("Location") == r.headers.cend() ? r.headers["location"] : r.headers["Location"];
string url = location.find("://") != string::npos ? location : baseurl + location;
string &location = r.headers["location"];
string url = location.find("://") != string::npos ? std::move(location) : baseurl + location;
Connect c(url, method, timeout);
c.recursive = recursive + 1;
return c.exec(headers);
Expand Down
7 changes: 5 additions & 2 deletions src/crypto/Connect.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,11 @@ class Connect
Connect(const std::string &url, std::string method = "POST",
int timeout = 0, const std::vector<X509Cert> &certs = {});
~Connect();
Result exec(std::initializer_list<std::pair<std::string_view,std::string_view>> headers,
const std::vector<unsigned char> &data);
inline Result exec(std::initializer_list<std::pair<std::string_view,std::string_view>> headers,
const std::vector<unsigned char> &data)
{
return exec(headers, data.data(), data.size());
}
Result exec(std::initializer_list<std::pair<std::string_view,std::string_view>> headers = {},
const unsigned char *data = nullptr, size_t size = 0);

Expand Down
17 changes: 8 additions & 9 deletions src/crypto/TSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ string TSL::fetch(const string &url, const string &path)
if(!r || r.content.empty())
THROW("HTTP status code is not 200 or content is empty");
ofstream(File::encodeName(path), fstream::binary|fstream::trunc) << r.content;
return r.headers["ETag"];
return r.headers["etag"];
}
catch(const Exception &)
{
Expand Down Expand Up @@ -254,13 +254,13 @@ TSL TSL::parseTSL(const string &url, const vector<X509Cert> &certs,
TSL tsl(path);
tsl.validate(certs);
valid = std::move(tsl);
DEBUG("TSL %s (%llu) signature is valid", territory.c_str(), tsl.sequenceNumber());
DEBUG("TSL %s (%llu) signature is valid", territory.c_str(), valid.sequenceNumber());

if(valid.isExpired())
{
if(!CONF(TSLAutoUpdate) && CONF(TSLAllowExpired))
return valid;
THROW("TSL %s (%llu) is expired", territory.c_str(), tsl.sequenceNumber());
THROW("TSL %s (%llu) is expired", territory.c_str(), valid.sequenceNumber());
}

if(CONF(TSLOnlineDigest) && (File::modifiedTime(path) < (time(nullptr) - (60 * 60 * 24))))
Expand Down Expand Up @@ -289,7 +289,7 @@ TSL TSL::parseTSL(const string &url, const vector<X509Cert> &certs,
filesystem::remove(filesystem::u8path(tmp), ec);

ofstream(File::encodeName(path + ".etag"), ofstream::trunc) << etag;
DEBUG("TSL %s (%llu) signature is valid", territory.c_str(), tsl.sequenceNumber());
DEBUG("TSL %s (%llu) signature is valid", territory.c_str(), valid.sequenceNumber());
} catch(const Exception &) {
ERR("TSL %s signature is invalid", territory.c_str());
if(!valid)
Expand Down Expand Up @@ -384,7 +384,7 @@ bool TSL::parseInfo(XMLNode info, Service &s)

string TSL::path() const
{
return get() && get()->name ? string(get()->name) : string();
return File::fromUriPath(to_string_view(get(), &xmlDoc::URL));
}

vector<string> TSL::pivotURLs() const
Expand Down Expand Up @@ -545,7 +545,7 @@ void TSL::validate(const vector<X509Cert> &certs, int recursion) const
{
string etag = fetch(urls[0], path);
ofstream(File::encodeName(path + ".etag"), ofstream::trunc) << etag;
pivot = TSL(std::move(path));
pivot = TSL(path);
}
pivot.validate(certs, recursion + 1);
validate(pivot.signingCerts(), recursion);
Expand All @@ -570,16 +570,15 @@ bool TSL::validateETag(const string &url)
return false;
}

auto it = r.headers.find("ETag");
auto it = r.headers.find("etag");
if(it == r.headers.cend())
return validateRemoteDigest(url);

DEBUG("Remote ETag: %s", it->second.c_str());
ifstream is(File::encodeName(path() + ".etag"));
if(!is.is_open())
THROW("Cached ETag does not exist");
string etag(it->second.size(), 0);
is.read(etag.data(), streamsize(etag.size()));
string etag(istreambuf_iterator<char>(is), {});
DEBUG("Cached ETag: %s", etag.c_str());
if(etag != it->second)
THROW("Remote ETag does not match");
Expand Down
5 changes: 3 additions & 2 deletions src/util/File.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@ string File::toUriPath(const string &path)
string File::fromUriPath(string_view path)
{
string ret;
ret.reserve(path.size());
char data[] = "00";
for(auto i = path.begin(); i != path.end(); ++i)
{
Expand All @@ -354,16 +355,16 @@ string File::fromUriPath(string_view path)
data[1] = *(++i);
ret += static_cast<char>(strtoul(data, nullptr, 16));
}
else {
else
ret += *i;
}
}
return ret;
}

vector<unsigned char> File::hexToBin(const string &in)
{
vector<unsigned char> out;
out.reserve(in.size() / 2);
char data[] = "00";
for(string::const_iterator i = in.cbegin(); distance(i, in.cend()) >= 2;)
{
Expand Down

0 comments on commit 5b45f0d

Please sign in to comment.