opal-up 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -25,139 +25,140 @@
25
25
  namespace uWS {
26
26
 
27
27
  struct proxy_hdr_v2 {
28
- uint8_t sig[12]; /* hex 0D 0A 0D 0A 00 0D 0A 51 55 49 54 0A */
29
- uint8_t ver_cmd; /* protocol version and command */
30
- uint8_t fam; /* protocol family and address */
31
- uint16_t len; /* number of following bytes part of the header */
28
+ uint8_t sig[12]; /* hex 0D 0A 0D 0A 00 0D 0A 51 55 49 54 0A */
29
+ uint8_t ver_cmd; /* protocol version and command */
30
+ uint8_t fam; /* protocol family and address */
31
+ uint16_t len; /* number of following bytes part of the header */
32
32
  };
33
33
 
34
34
  union proxy_addr {
35
- struct { /* for TCP/UDP over IPv4, len = 12 */
36
- uint32_t src_addr;
37
- uint32_t dst_addr;
38
- uint16_t src_port;
39
- uint16_t dst_port;
40
- } ipv4_addr;
41
- struct { /* for TCP/UDP over IPv6, len = 36 */
42
- uint8_t src_addr[16];
43
- uint8_t dst_addr[16];
44
- uint16_t src_port;
45
- uint16_t dst_port;
46
- } ipv6_addr;
35
+ struct { /* for TCP/UDP over IPv4, len = 12 */
36
+ uint32_t src_addr;
37
+ uint32_t dst_addr;
38
+ uint16_t src_port;
39
+ uint16_t dst_port;
40
+ } ipv4_addr;
41
+ struct { /* for TCP/UDP over IPv6, len = 36 */
42
+ uint8_t src_addr[16];
43
+ uint8_t dst_addr[16];
44
+ uint16_t src_port;
45
+ uint16_t dst_port;
46
+ } ipv6_addr;
47
47
  };
48
48
 
49
49
  /* Byte swap for little-endian systems */
50
50
  /* Todo: This functions should be shared with the one in WebSocketProtocol.h! */
51
- template <typename T>
52
- T _cond_byte_swap(T value) {
53
- uint32_t endian_test = 1;
54
- if (*((char *)&endian_test)) {
55
- union {
56
- T i;
57
- uint8_t b[sizeof(T)];
58
- } src = { value }, dst;
59
-
60
- for (unsigned int i = 0; i < sizeof(value); i++) {
61
- dst.b[i] = src.b[sizeof(value) - 1 - i];
62
- }
63
-
64
- return dst.i;
51
+ template <typename T> T _cond_byte_swap(T value) {
52
+ uint32_t endian_test = 1;
53
+ if (*((char *)&endian_test)) {
54
+ union {
55
+ T i;
56
+ uint8_t b[sizeof(T)];
57
+ } src = {value}, dst;
58
+
59
+ for (unsigned int i = 0; i < sizeof(value); i++) {
60
+ dst.b[i] = src.b[sizeof(value) - 1 - i];
65
61
  }
66
- return value;
62
+
63
+ return dst.i;
64
+ }
65
+ return value;
67
66
  }
68
67
 
69
68
  struct ProxyParser {
70
69
  private:
71
- union proxy_addr addr;
70
+ union proxy_addr addr;
72
71
 
73
- /* Default family of 0 signals no proxy address */
74
- uint8_t family = 0;
72
+ /* Default family of 0 signals no proxy address */
73
+ uint8_t family = 0;
75
74
 
76
75
  public:
77
- /* Returns 4 or 16 bytes source address */
78
- std::string_view getSourceAddress() {
79
-
80
- // UNSPEC family and protocol
81
- if (family == 0) {
82
- return {};
83
- }
84
-
85
- if ((family & 0xf0) >> 4 == 1) {
86
- /* Family 1 is INET4 */
87
- return {(char *) &addr.ipv4_addr.src_addr, 4};
88
- } else {
89
- /* Family 2 is INET6 */
90
- return {(char *) &addr.ipv6_addr.src_addr, 16};
91
- }
76
+ /* Returns 4 or 16 bytes source address */
77
+ std::string_view getSourceAddress() {
78
+
79
+ // UNSPEC family and protocol
80
+ if (family == 0) {
81
+ return {};
92
82
  }
93
83
 
94
- /* Returns [done, consumed] where done = false on failure */
95
- std::pair<bool, unsigned int> parse(std::string_view data) {
84
+ if ((family & 0xf0) >> 4 == 1) {
85
+ /* Family 1 is INET4 */
86
+ return {(char *)&addr.ipv4_addr.src_addr, 4};
87
+ } else {
88
+ /* Family 2 is INET6 */
89
+ return {(char *)&addr.ipv6_addr.src_addr, 16};
90
+ }
91
+ }
96
92
 
97
- /* We require at least four bytes to determine protocol */
98
- if (data.length() < 4) {
99
- return {false, 0};
100
- }
93
+ /* Returns [done, consumed] where done = false on failure */
94
+ std::pair<bool, unsigned int> parse(std::string_view data) {
101
95
 
102
- /* HTTP can never start with "\r\n\r\n", but PROXY always does */
103
- if (memcmp(data.data(), "\r\n\r\n", 4)) {
104
- /* This is HTTP, so be done */
105
- return {true, 0};
106
- }
96
+ /* We require at least four bytes to determine protocol */
97
+ if (data.length() < 4) {
98
+ return {false, 0};
99
+ }
107
100
 
108
- /* We assume we are parsing PROXY V2 here */
101
+ /* HTTP can never start with "\r\n\r\n", but PROXY always does */
102
+ if (memcmp(data.data(), "\r\n\r\n", 4)) {
103
+ /* This is HTTP, so be done */
104
+ return {true, 0};
105
+ }
109
106
 
110
- /* We require 16 bytes here */
111
- if (data.length() < 16) {
112
- return {false, 0};
113
- }
107
+ /* We assume we are parsing PROXY V2 here */
114
108
 
115
- /* Header is 16 bytes */
116
- struct proxy_hdr_v2 header;
117
- memcpy(&header, data.data(), 16);
109
+ /* We require 16 bytes here */
110
+ if (data.length() < 16) {
111
+ return {false, 0};
112
+ }
118
113
 
119
- if (memcmp(header.sig, "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A", 12)) {
120
- /* This is not PROXY protocol at all */
121
- return {false, 0};
122
- }
114
+ /* Header is 16 bytes */
115
+ struct proxy_hdr_v2 header;
116
+ memcpy(&header, data.data(), 16);
123
117
 
124
- /* We only support version 2 */
125
- if ((header.ver_cmd & 0xf0) >> 4 != 2) {
126
- return {false, 0};
127
- }
118
+ if (memcmp(header.sig, "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A",
119
+ 12)) {
120
+ /* This is not PROXY protocol at all */
121
+ return {false, 0};
122
+ }
128
123
 
129
- //printf("Version: %d\n", (header.ver_cmd & 0xf0) >> 4);
130
- //printf("Command: %d\n", (header.ver_cmd & 0x0f));
124
+ /* We only support version 2 */
125
+ if ((header.ver_cmd & 0xf0) >> 4 != 2) {
126
+ return {false, 0};
127
+ }
128
+
129
+ // printf("Version: %d\n", (header.ver_cmd & 0xf0) >> 4);
130
+ // printf("Command: %d\n", (header.ver_cmd & 0x0f));
131
131
 
132
- /* We get length in network byte order (todo: share this function with the rest) */
133
- uint16_t hostLength = _cond_byte_swap<uint16_t>(header.len);
132
+ /* We get length in network byte order (todo: share this function with the
133
+ * rest) */
134
+ uint16_t hostLength = _cond_byte_swap<uint16_t>(header.len);
134
135
 
135
- /* We must have all the data available */
136
- if (data.length() < 16u + hostLength) {
137
- return {false, 0};
138
- }
136
+ /* We must have all the data available */
137
+ if (data.length() < 16u + hostLength) {
138
+ return {false, 0};
139
+ }
139
140
 
140
- /* Payload cannot be more than sizeof proxy_addr */
141
- if (sizeof(proxy_addr) < hostLength) {
142
- return {false, 0};
143
- }
141
+ /* Payload cannot be more than sizeof proxy_addr */
142
+ if (sizeof(proxy_addr) < hostLength) {
143
+ return {false, 0};
144
+ }
144
145
 
145
- //printf("Family: %d\n", (header.fam & 0xf0) >> 4);
146
- //printf("Transport: %d\n", (header.fam & 0x0f));
146
+ // printf("Family: %d\n", (header.fam & 0xf0) >> 4);
147
+ // printf("Transport: %d\n", (header.fam & 0x0f));
147
148
 
148
- /* We have 0 family by default, and UNSPEC is 0 as well */
149
- family = header.fam;
149
+ /* We have 0 family by default, and UNSPEC is 0 as well */
150
+ family = header.fam;
150
151
 
151
- /* Copy payload */
152
- memcpy(&addr, data.data() + 16, hostLength);
152
+ /* Copy payload */
153
+ memcpy(&addr, data.data() + 16, hostLength);
153
154
 
154
- /* We consumed everything */
155
- return {true, 16 + hostLength};
156
- }
155
+ /* We consumed everything */
156
+ return {true, 16 + hostLength};
157
+ }
157
158
  };
158
159
 
159
- }
160
+ } // namespace uWS
160
161
 
161
162
  #endif
162
163
 
163
- #endif // UWS_PROXY_PARSER_H
164
+ #endif // UWS_PROXY_PARSER_H
@@ -24,97 +24,104 @@
24
24
 
25
25
  namespace uWS {
26
26
 
27
- /* Takes raw query including initial '?' sign. Will inplace decode, so input will mutate */
28
- static inline std::string_view getDecodedQueryValue(std::string_view key, std::string_view rawQuery) {
27
+ /* Takes raw query including initial '?' sign. Will inplace decode, so input
28
+ * will mutate */
29
+ static inline std::string_view getDecodedQueryValue(std::string_view key,
30
+ std::string_view rawQuery) {
31
+
32
+ /* Can't have a value without a key */
33
+ if (!key.length()) {
34
+ return {};
35
+ }
36
+
37
+ /* Start with the whole querystring including initial '?' */
38
+ std::string_view queryString = rawQuery;
39
+
40
+ /* List of key, value could be cached for repeated fetches similar to how
41
+ * headers are, todo! */
42
+ while (queryString.length()) {
43
+ /* Find boundaries of this statement */
44
+ std::string_view statement =
45
+ queryString.substr(1, queryString.find('&', 1) - 1);
46
+
47
+ /* Only bother if first char of key match (early exit) */
48
+ if (statement.length() && statement[0] == key[0]) {
49
+ /* Equal sign must be present and not in the end of statement */
50
+ auto equality = statement.find('=');
51
+ if (equality != std::string_view::npos) {
52
+
53
+ std::string_view statementKey = statement.substr(0, equality);
54
+ std::string_view statementValue = statement.substr(equality + 1);
55
+
56
+ /* String comparison */
57
+ if (key == statementKey) {
58
+
59
+ /* Decode value inplace, put null at end if before length of original
60
+ */
61
+ char *in = (char *)statementValue.data();
62
+
63
+ /* Write offset */
64
+ unsigned int out = 0;
65
+
66
+ /* Walk over all chars until end or null char, decoding in place */
67
+ for (unsigned int i = 0; i < statementValue.length() && in[i]; i++) {
68
+ /* Only bother with '%' */
69
+ if (in[i] == '%') {
70
+ /* Do we have enough data for two bytes hex? */
71
+ if (i + 2 >= statementValue.length()) {
72
+ return {};
73
+ }
74
+
75
+ /* Two bytes hex */
76
+ int hex1 = in[i + 1] - '0';
77
+ if (hex1 > 9) {
78
+ hex1 &= 223;
79
+ hex1 -= 7;
80
+ }
81
+
82
+ int hex2 = in[i + 2] - '0';
83
+ if (hex2 > 9) {
84
+ hex2 &= 223;
85
+ hex2 -= 7;
86
+ }
87
+
88
+ *((unsigned char *)&in[out]) = (unsigned char)(hex1 * 16 + hex2);
89
+ i += 2;
90
+ } else {
91
+ /* Is this even a rule? */
92
+ if (in[i] == '+') {
93
+ in[out] = ' ';
94
+ } else {
95
+ in[out] = in[i];
96
+ }
97
+ }
29
98
 
30
- /* Can't have a value without a key */
31
- if (!key.length()) {
32
- return {};
33
- }
99
+ /* We always only write one char */
100
+ out++;
101
+ }
34
102
 
35
- /* Start with the whole querystring including initial '?' */
36
- std::string_view queryString = rawQuery;
37
-
38
- /* List of key, value could be cached for repeated fetches similar to how headers are, todo! */
39
- while (queryString.length()) {
40
- /* Find boundaries of this statement */
41
- std::string_view statement = queryString.substr(1, queryString.find('&', 1) - 1);
42
-
43
- /* Only bother if first char of key match (early exit) */
44
- if (statement.length() && statement[0] == key[0]) {
45
- /* Equal sign must be present and not in the end of statement */
46
- auto equality = statement.find('=');
47
- if (equality != std::string_view::npos) {
48
-
49
- std::string_view statementKey = statement.substr(0, equality);
50
- std::string_view statementValue = statement.substr(equality + 1);
51
-
52
- /* String comparison */
53
- if (key == statementKey) {
54
-
55
- /* Decode value inplace, put null at end if before length of original */
56
- char *in = (char *) statementValue.data();
57
-
58
- /* Write offset */
59
- unsigned int out = 0;
60
-
61
- /* Walk over all chars until end or null char, decoding in place */
62
- for (unsigned int i = 0; i < statementValue.length() && in[i]; i++) {
63
- /* Only bother with '%' */
64
- if (in[i] == '%') {
65
- /* Do we have enough data for two bytes hex? */
66
- if (i + 2 >= statementValue.length()) {
67
- return {};
68
- }
69
-
70
- /* Two bytes hex */
71
- int hex1 = in[i + 1] - '0';
72
- if (hex1 > 9) {
73
- hex1 &= 223;
74
- hex1 -= 7;
75
- }
76
-
77
- int hex2 = in[i + 2] - '0';
78
- if (hex2 > 9) {
79
- hex2 &= 223;
80
- hex2 -= 7;
81
- }
82
-
83
- *((unsigned char *) &in[out]) = (unsigned char) (hex1 * 16 + hex2);
84
- i += 2;
85
- } else {
86
- /* Is this even a rule? */
87
- if (in[i] == '+') {
88
- in[out] = ' ';
89
- } else {
90
- in[out] = in[i];
91
- }
92
- }
93
-
94
- /* We always only write one char */
95
- out++;
96
- }
97
-
98
- /* If decoded string is shorter than original, put null char to stop next read */
99
- if (out < statementValue.length()) {
100
- in[out] = 0;
101
- }
102
-
103
- return statementValue.substr(0, out);
104
- }
105
- } else {
106
- /* This querystring is invalid, cannot parse it */
107
- return {nullptr, 0};
108
- }
109
- }
103
+ /* If decoded string is shorter than original, put null char to stop
104
+ * next read */
105
+ if (out < statementValue.length()) {
106
+ in[out] = 0;
107
+ }
110
108
 
111
- queryString.remove_prefix(statement.length() + 1);
109
+ return statementValue.substr(0, out);
112
110
  }
113
-
114
- /* Nothing found is given as nullptr, while empty string is given as some pointer to the given buffer */
111
+ } else {
112
+ /* This querystring is invalid, cannot parse it */
115
113
  return {nullptr, 0};
114
+ }
116
115
  }
117
116
 
117
+ queryString.remove_prefix(statement.length() + 1);
118
+ }
119
+
120
+ /* Nothing found is given as nullptr, while empty string is given as some
121
+ * pointer to the given buffer */
122
+ return {nullptr, 0};
118
123
  }
119
124
 
125
+ } // namespace uWS
126
+
120
127
  #endif