2019-03-01 06:54:03 +01:00
|
|
|
/*
|
|
|
|
* IXWebSocketHttpHeaders.h
|
|
|
|
* Author: Benjamin Sergeant
|
|
|
|
* Copyright (c) 2018 Machine Zone, Inc. All rights reserved.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "IXWebSocketHttpHeaders.h"
|
2019-09-23 19:25:23 +02:00
|
|
|
|
2019-03-01 06:54:03 +01:00
|
|
|
#include "IXSocket.h"
|
2019-04-16 17:51:57 +02:00
|
|
|
#include <algorithm>
|
|
|
|
#include <locale>
|
2019-03-01 06:54:03 +01:00
|
|
|
|
|
|
|
namespace ix
|
|
|
|
{
|
2019-09-23 19:25:23 +02:00
|
|
|
bool CaseInsensitiveLess::NocaseCompare::operator()(const unsigned char& c1,
|
|
|
|
const unsigned char& c2) const
|
2019-04-16 17:51:57 +02:00
|
|
|
{
|
|
|
|
#ifdef _WIN32
|
|
|
|
return std::tolower(c1, std::locale()) < std::tolower(c2, std::locale());
|
|
|
|
#else
|
|
|
|
return std::tolower(c1) < std::tolower(c2);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2019-09-23 19:25:23 +02:00
|
|
|
bool CaseInsensitiveLess::operator()(const std::string& s1, const std::string& s2) const
|
2019-04-16 17:51:57 +02:00
|
|
|
{
|
2019-09-23 19:25:23 +02:00
|
|
|
return std::lexicographical_compare(s1.begin(),
|
|
|
|
s1.end(), // source range
|
|
|
|
s2.begin(),
|
|
|
|
s2.end(), // dest range
|
|
|
|
NocaseCompare()); // comparison
|
2019-04-16 17:51:57 +02:00
|
|
|
}
|
|
|
|
|
2019-03-01 06:54:03 +01:00
|
|
|
std::pair<bool, WebSocketHttpHeaders> parseHttpHeaders(
|
2019-09-23 19:25:23 +02:00
|
|
|
std::shared_ptr<Socket> socket, const CancellationRequest& isCancellationRequested)
|
2019-03-01 06:54:03 +01:00
|
|
|
{
|
|
|
|
WebSocketHttpHeaders headers;
|
|
|
|
|
|
|
|
char line[1024];
|
|
|
|
int i;
|
|
|
|
|
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
int colon = 0;
|
|
|
|
|
2019-09-23 19:25:23 +02:00
|
|
|
for (i = 0; i < 2 || (i < 1023 && line[i - 2] != '\r' && line[i - 1] != '\n'); ++i)
|
2019-03-01 06:54:03 +01:00
|
|
|
{
|
2019-09-23 19:25:23 +02:00
|
|
|
if (!socket->readByte(line + i, isCancellationRequested))
|
2019-03-01 06:54:03 +01:00
|
|
|
{
|
|
|
|
return std::make_pair(false, headers);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (line[i] == ':' && colon == 0)
|
|
|
|
{
|
|
|
|
colon = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (line[0] == '\r' && line[1] == '\n')
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// line is a single header entry. split by ':', and add it to our
|
|
|
|
// header map. ignore lines with no colon.
|
|
|
|
if (colon > 0)
|
|
|
|
{
|
|
|
|
line[i] = '\0';
|
|
|
|
std::string lineStr(line);
|
|
|
|
// colon is ':', colon+1 is ' ', colon+2 is the start of the value.
|
|
|
|
// i is end of string (\0), i-colon is length of string minus key;
|
|
|
|
// subtract 1 for '\0', 1 for '\n', 1 for '\r',
|
|
|
|
// 1 for the ' ' after the ':', and total is -4
|
|
|
|
std::string name(lineStr.substr(0, colon));
|
|
|
|
std::string value(lineStr.substr(colon + 2, i - colon - 4));
|
|
|
|
|
|
|
|
headers[name] = value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return std::make_pair(true, headers);
|
|
|
|
}
|
2019-09-23 19:25:23 +02:00
|
|
|
} // namespace ix
|