1/*
2 * IXWebSocketHttpHeaders.h
3 * Author: Benjamin Sergeant
4 * Copyright (c) 2018 Machine Zone, Inc. All rights reserved.
5 */
6
7#include "IXWebSocketHttpHeaders.h"
8
9#include "IXSocket.h"
10#include <algorithm>
11#include <locale>
12
13namespace ix
14{
15 std::pair<bool, WebSocketHttpHeaders> parseHttpHeaders(
16 std::unique_ptr<Socket>& socket, const CancellationRequest& isCancellationRequested)
17 {
18 WebSocketHttpHeaders headers;
19
20 char line[1024];
21 int i;
22
23 while (true)
24 {
25 int colon = 0;
26
27 for (i = 0; i < 2 || (i < 1023 && line[i - 2] != '\r' && line[i - 1] != '\n'); ++i)
28 {
29 if (!socket->readByte(line + i, isCancellationRequested))
30 {
31 return std::make_pair(false, headers);
32 }
33
34 if (line[i] == ':' && colon == 0)
35 {
36 colon = i;
37 }
38 }
39 if (line[0] == '\r' && line[1] == '\n')
40 {
41 break;
42 }
43
44 // line is a single header entry. split by ':', and add it to our
45 // header map. ignore lines with no colon.
46 if (colon > 0)
47 {
48 line[i] = '\0';
49 std::string lineStr(line);
50 // colon is ':', usually colon+1 is ' ', and colon+2 is the start of the value.
51 // some webservers do not put a space after the colon character, so
52 // the start of the value might be farther than colon+2.
53 // The spec says that space after the : should be discarded.
54 // i is end of string (\0), i-colon is length of string minus key;
55 // subtract 1 for '\0', 1 for '\n', 1 for '\r',
56 // 1 for the ' ' after the ':', and total is -4
57 // since we use an std::string later on and don't account for '\0',
58 // plus the optional first space, total is -2
59 int start = colon + 1;
60 while (lineStr[start] == ' ')
61 {
62 start++;
63 }
64
65 std::string name(lineStr.substr(0, colon));
66 std::string value(lineStr.substr(start, lineStr.size() - start - 2));
67
68 headers[name] = value;
69 }
70 }
71
72 return std::make_pair(true, headers);
73 }
74} // namespace ix
75