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 | |
13 | namespace ix |
14 | { |
15 | std::pair<bool, WebSocketHttpHeaders> ( |
16 | std::unique_ptr<Socket>& socket, const CancellationRequest& isCancellationRequested) |
17 | { |
18 | WebSocketHttpHeaders ; |
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 | |