unionize header token array
This reduces the size of struct libwebscocket from 4840 to 4552 on x86_64 There are also big benefits on malloc pool fragmentation and allocation, the header allocations only exist between the first peer communication and websocket connection establishment for both server and client. Signed-off-by: Andy Green <andy.green@linaro.org>
This commit is contained in:
parent
a2b3a36e44
commit
68a672bb44
7 changed files with 95 additions and 96 deletions
|
@ -271,8 +271,8 @@ libwebsocket_client_connect(struct libwebsocket_context *context,
|
||||||
wsi->c_callback = context->protocols[0].callback;
|
wsi->c_callback = context->protocols[0].callback;
|
||||||
|
|
||||||
for (n = 0; n < WSI_TOKEN_COUNT; n++) {
|
for (n = 0; n < WSI_TOKEN_COUNT; n++) {
|
||||||
wsi->utf8_token[n].token = NULL;
|
wsi->u.hdr.hdrs[n].token = NULL;
|
||||||
wsi->utf8_token[n].token_len = 0;
|
wsi->u.hdr.hdrs[n].token_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef LWS_NO_EXTENSIONS
|
#ifndef LWS_NO_EXTENSIONS
|
||||||
|
|
62
lib/client.c
62
lib/client.c
|
@ -368,42 +368,42 @@ lws_client_interpret_server_handshake(struct libwebsocket_context *context,
|
||||||
*/
|
*/
|
||||||
#if 0
|
#if 0
|
||||||
lwsl_parser("WSI_TOKEN_HTTP: %d\n",
|
lwsl_parser("WSI_TOKEN_HTTP: %d\n",
|
||||||
wsi->utf8_token[WSI_TOKEN_HTTP].token_len);
|
wsi->u.hdr.hdrs[WSI_TOKEN_HTTP].token_len);
|
||||||
lwsl_parser("WSI_TOKEN_UPGRADE: %d\n",
|
lwsl_parser("WSI_TOKEN_UPGRADE: %d\n",
|
||||||
wsi->utf8_token[WSI_TOKEN_UPGRADE].token_len);
|
wsi->u.hdr.hdrs[WSI_TOKEN_UPGRADE].token_len);
|
||||||
lwsl_parser("WSI_TOKEN_CONNECTION: %d\n",
|
lwsl_parser("WSI_TOKEN_CONNECTION: %d\n",
|
||||||
wsi->utf8_token[WSI_TOKEN_CONNECTION].token_len);
|
wsi->u.hdr.hdrs[WSI_TOKEN_CONNECTION].token_len);
|
||||||
lwsl_parser("WSI_TOKEN_ACCEPT: %d\n",
|
lwsl_parser("WSI_TOKEN_ACCEPT: %d\n",
|
||||||
wsi->utf8_token[WSI_TOKEN_ACCEPT].token_len);
|
wsi->u.hdr.hdrs[WSI_TOKEN_ACCEPT].token_len);
|
||||||
lwsl_parser("WSI_TOKEN_NONCE: %d\n",
|
lwsl_parser("WSI_TOKEN_NONCE: %d\n",
|
||||||
wsi->utf8_token[WSI_TOKEN_NONCE].token_len);
|
wsi->u.hdr.hdrs[WSI_TOKEN_NONCE].token_len);
|
||||||
lwsl_parser("WSI_TOKEN_PROTOCOL: %d\n",
|
lwsl_parser("WSI_TOKEN_PROTOCOL: %d\n",
|
||||||
wsi->utf8_token[WSI_TOKEN_PROTOCOL].token_len);
|
wsi->u.hdr.hdrs[WSI_TOKEN_PROTOCOL].token_len);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
strtolower(wsi->utf8_token[WSI_TOKEN_HTTP].token);
|
strtolower(wsi->u.hdr.hdrs[WSI_TOKEN_HTTP].token);
|
||||||
if (strncmp(wsi->utf8_token[WSI_TOKEN_HTTP].token, "101", 3)) {
|
if (strncmp(wsi->u.hdr.hdrs[WSI_TOKEN_HTTP].token, "101", 3)) {
|
||||||
lwsl_warn("libwebsocket_client_handshake "
|
lwsl_warn("libwebsocket_client_handshake "
|
||||||
"server sent bad HTTP response '%s'\n",
|
"server sent bad HTTP response '%s'\n",
|
||||||
wsi->utf8_token[WSI_TOKEN_HTTP].token);
|
wsi->u.hdr.hdrs[WSI_TOKEN_HTTP].token);
|
||||||
goto bail3;
|
goto bail3;
|
||||||
}
|
}
|
||||||
|
|
||||||
strtolower(wsi->utf8_token[WSI_TOKEN_UPGRADE].token);
|
strtolower(wsi->u.hdr.hdrs[WSI_TOKEN_UPGRADE].token);
|
||||||
if (strcmp(wsi->utf8_token[WSI_TOKEN_UPGRADE].token,
|
if (strcmp(wsi->u.hdr.hdrs[WSI_TOKEN_UPGRADE].token,
|
||||||
"websocket")) {
|
"websocket")) {
|
||||||
lwsl_warn("libwebsocket_client_handshake server "
|
lwsl_warn("libwebsocket_client_handshake server "
|
||||||
"sent bad Upgrade header '%s'\n",
|
"sent bad Upgrade header '%s'\n",
|
||||||
wsi->utf8_token[WSI_TOKEN_UPGRADE].token);
|
wsi->u.hdr.hdrs[WSI_TOKEN_UPGRADE].token);
|
||||||
goto bail3;
|
goto bail3;
|
||||||
}
|
}
|
||||||
|
|
||||||
strtolower(wsi->utf8_token[WSI_TOKEN_CONNECTION].token);
|
strtolower(wsi->u.hdr.hdrs[WSI_TOKEN_CONNECTION].token);
|
||||||
if (strcmp(wsi->utf8_token[WSI_TOKEN_CONNECTION].token,
|
if (strcmp(wsi->u.hdr.hdrs[WSI_TOKEN_CONNECTION].token,
|
||||||
"upgrade")) {
|
"upgrade")) {
|
||||||
lwsl_warn("libwebsocket_client_handshake server "
|
lwsl_warn("libwebsocket_client_handshake server "
|
||||||
"sent bad Connection hdr '%s'\n",
|
"sent bad Connection hdr '%s'\n",
|
||||||
wsi->utf8_token[WSI_TOKEN_CONNECTION].token);
|
wsi->u.hdr.hdrs[WSI_TOKEN_CONNECTION].token);
|
||||||
goto bail3;
|
goto bail3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,7 +420,7 @@ lws_client_interpret_server_handshake(struct libwebsocket_context *context,
|
||||||
* of protocols we offered
|
* of protocols we offered
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!wsi->utf8_token[WSI_TOKEN_PROTOCOL].token_len) {
|
if (!wsi->u.hdr.hdrs[WSI_TOKEN_PROTOCOL].token_len) {
|
||||||
|
|
||||||
lwsl_info("lws_client_interpret_server_handshake "
|
lwsl_info("lws_client_interpret_server_handshake "
|
||||||
"WSI_TOKEN_PROTOCOL is null\n");
|
"WSI_TOKEN_PROTOCOL is null\n");
|
||||||
|
@ -436,10 +436,10 @@ lws_client_interpret_server_handshake(struct libwebsocket_context *context,
|
||||||
}
|
}
|
||||||
|
|
||||||
while (*pc && !okay) {
|
while (*pc && !okay) {
|
||||||
if ((!strncmp(pc, wsi->utf8_token[WSI_TOKEN_PROTOCOL].token,
|
if ((!strncmp(pc, wsi->u.hdr.hdrs[WSI_TOKEN_PROTOCOL].token,
|
||||||
wsi->utf8_token[WSI_TOKEN_PROTOCOL].token_len)) &&
|
wsi->u.hdr.hdrs[WSI_TOKEN_PROTOCOL].token_len)) &&
|
||||||
(pc[wsi->utf8_token[WSI_TOKEN_PROTOCOL].token_len] == ',' ||
|
(pc[wsi->u.hdr.hdrs[WSI_TOKEN_PROTOCOL].token_len] == ',' ||
|
||||||
pc[wsi->utf8_token[WSI_TOKEN_PROTOCOL].token_len] == '\0')) {
|
pc[wsi->u.hdr.hdrs[WSI_TOKEN_PROTOCOL].token_len] == '\0')) {
|
||||||
okay = 1;
|
okay = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -457,7 +457,7 @@ lws_client_interpret_server_handshake(struct libwebsocket_context *context,
|
||||||
if (!okay) {
|
if (!okay) {
|
||||||
lwsl_err("libwebsocket_client_handshake server "
|
lwsl_err("libwebsocket_client_handshake server "
|
||||||
"sent bad protocol '%s'\n",
|
"sent bad protocol '%s'\n",
|
||||||
wsi->utf8_token[WSI_TOKEN_PROTOCOL].token);
|
wsi->u.hdr.hdrs[WSI_TOKEN_PROTOCOL].token);
|
||||||
goto bail2;
|
goto bail2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -467,7 +467,7 @@ lws_client_interpret_server_handshake(struct libwebsocket_context *context,
|
||||||
n = 0;
|
n = 0;
|
||||||
wsi->protocol = NULL;
|
wsi->protocol = NULL;
|
||||||
while (context->protocols[n].callback && !wsi->protocol) { /* Stop after finding first one?? */
|
while (context->protocols[n].callback && !wsi->protocol) { /* Stop after finding first one?? */
|
||||||
if (strcmp(wsi->utf8_token[WSI_TOKEN_PROTOCOL].token,
|
if (strcmp(wsi->u.hdr.hdrs[WSI_TOKEN_PROTOCOL].token,
|
||||||
context->protocols[n].name) == 0) {
|
context->protocols[n].name) == 0) {
|
||||||
wsi->protocol = &context->protocols[n];
|
wsi->protocol = &context->protocols[n];
|
||||||
wsi->c_callback = wsi->protocol->callback;
|
wsi->c_callback = wsi->protocol->callback;
|
||||||
|
@ -479,7 +479,7 @@ lws_client_interpret_server_handshake(struct libwebsocket_context *context,
|
||||||
lwsl_err("libwebsocket_client_handshake server "
|
lwsl_err("libwebsocket_client_handshake server "
|
||||||
"requested protocol '%s', which we "
|
"requested protocol '%s', which we "
|
||||||
"said we supported but we don't!\n",
|
"said we supported but we don't!\n",
|
||||||
wsi->utf8_token[WSI_TOKEN_PROTOCOL].token);
|
wsi->u.hdr.hdrs[WSI_TOKEN_PROTOCOL].token);
|
||||||
goto bail2;
|
goto bail2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,7 +488,7 @@ check_extensions:
|
||||||
#ifndef LWS_NO_EXTENSIONS
|
#ifndef LWS_NO_EXTENSIONS
|
||||||
/* instantiate the accepted extensions */
|
/* instantiate the accepted extensions */
|
||||||
|
|
||||||
if (!wsi->utf8_token[WSI_TOKEN_EXTENSIONS].token_len) {
|
if (!wsi->u.hdr.hdrs[WSI_TOKEN_EXTENSIONS].token_len) {
|
||||||
lwsl_ext("no client extenstions allowed by server\n");
|
lwsl_ext("no client extenstions allowed by server\n");
|
||||||
goto check_accept;
|
goto check_accept;
|
||||||
}
|
}
|
||||||
|
@ -498,7 +498,7 @@ check_extensions:
|
||||||
* and go through matching them or identifying bogons
|
* and go through matching them or identifying bogons
|
||||||
*/
|
*/
|
||||||
|
|
||||||
c = wsi->utf8_token[WSI_TOKEN_EXTENSIONS].token;
|
c = wsi->u.hdr.hdrs[WSI_TOKEN_EXTENSIONS].token;
|
||||||
n = 0;
|
n = 0;
|
||||||
while (more) {
|
while (more) {
|
||||||
|
|
||||||
|
@ -580,11 +580,11 @@ check_accept:
|
||||||
* Confirm his accept token is the one we precomputed
|
* Confirm his accept token is the one we precomputed
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (strcmp(wsi->utf8_token[WSI_TOKEN_ACCEPT].token,
|
if (strcmp(wsi->u.hdr.hdrs[WSI_TOKEN_ACCEPT].token,
|
||||||
wsi->u.hdr.initial_handshake_hash_base64)) {
|
wsi->u.hdr.initial_handshake_hash_base64)) {
|
||||||
lwsl_warn("libwebsocket_client_handshake server "
|
lwsl_warn("libwebsocket_client_handshake server "
|
||||||
"sent bad ACCEPT '%s' vs computed '%s'\n",
|
"sent bad ACCEPT '%s' vs computed '%s'\n",
|
||||||
wsi->utf8_token[WSI_TOKEN_ACCEPT].token,
|
wsi->u.hdr.hdrs[WSI_TOKEN_ACCEPT].token,
|
||||||
wsi->u.hdr.initial_handshake_hash_base64);
|
wsi->u.hdr.initial_handshake_hash_base64);
|
||||||
goto bail2;
|
goto bail2;
|
||||||
}
|
}
|
||||||
|
@ -610,8 +610,8 @@ check_accept:
|
||||||
/* free up his parsing allocations */
|
/* free up his parsing allocations */
|
||||||
|
|
||||||
for (n = 0; n < WSI_TOKEN_COUNT; n++)
|
for (n = 0; n < WSI_TOKEN_COUNT; n++)
|
||||||
if (wsi->utf8_token[n].token)
|
if (wsi->u.hdr.hdrs[n].token)
|
||||||
free(wsi->utf8_token[n].token);
|
free(wsi->u.hdr.hdrs[n].token);
|
||||||
|
|
||||||
/* mark him as being alive */
|
/* mark him as being alive */
|
||||||
|
|
||||||
|
@ -663,8 +663,8 @@ bail2:
|
||||||
/* free up his parsing allocations */
|
/* free up his parsing allocations */
|
||||||
|
|
||||||
for (n = 0; n < WSI_TOKEN_COUNT; n++)
|
for (n = 0; n < WSI_TOKEN_COUNT; n++)
|
||||||
if (wsi->utf8_token[n].token)
|
if (wsi->u.hdr.hdrs[n].token)
|
||||||
free(wsi->utf8_token[n].token);
|
free(wsi->u.hdr.hdrs[n].token);
|
||||||
|
|
||||||
libwebsocket_close_and_free_session(context, wsi,
|
libwebsocket_close_and_free_session(context, wsi,
|
||||||
LWS_CLOSE_STATUS_PROTOCOL_ERR);
|
LWS_CLOSE_STATUS_PROTOCOL_ERR);
|
||||||
|
|
|
@ -113,15 +113,15 @@ libwebsocket_read(struct libwebsocket_context *context,
|
||||||
|
|
||||||
/* is this websocket protocol or normal http 1.0? */
|
/* is this websocket protocol or normal http 1.0? */
|
||||||
|
|
||||||
if (!wsi->utf8_token[WSI_TOKEN_UPGRADE].token_len ||
|
if (!wsi->u.hdr.hdrs[WSI_TOKEN_UPGRADE].token_len ||
|
||||||
!wsi->utf8_token[WSI_TOKEN_CONNECTION].token_len) {
|
!wsi->u.hdr.hdrs[WSI_TOKEN_CONNECTION].token_len) {
|
||||||
wsi->state = WSI_STATE_HTTP;
|
wsi->state = WSI_STATE_HTTP;
|
||||||
if (wsi->protocol->callback)
|
if (wsi->protocol->callback)
|
||||||
if (wsi->protocol->callback(context, wsi,
|
if (wsi->protocol->callback(context, wsi,
|
||||||
LWS_CALLBACK_HTTP,
|
LWS_CALLBACK_HTTP,
|
||||||
wsi->user_space,
|
wsi->user_space,
|
||||||
wsi->utf8_token[WSI_TOKEN_GET_URI].token,
|
wsi->u.hdr.hdrs[WSI_TOKEN_GET_URI].token,
|
||||||
wsi->utf8_token[WSI_TOKEN_GET_URI].token_len)) {
|
wsi->u.hdr.hdrs[WSI_TOKEN_GET_URI].token_len)) {
|
||||||
lwsl_info("LWS_CALLBACK_HTTP wanted to close\n");
|
lwsl_info("LWS_CALLBACK_HTTP wanted to close\n");
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
@ -139,12 +139,12 @@ libwebsocket_read(struct libwebsocket_context *context,
|
||||||
|
|
||||||
while (wsi->protocol->callback) {
|
while (wsi->protocol->callback) {
|
||||||
|
|
||||||
if (wsi->utf8_token[WSI_TOKEN_PROTOCOL].token == NULL) {
|
if (wsi->u.hdr.hdrs[WSI_TOKEN_PROTOCOL].token == NULL) {
|
||||||
if (wsi->protocol->name == NULL)
|
if (wsi->protocol->name == NULL)
|
||||||
break;
|
break;
|
||||||
} else
|
} else
|
||||||
if (wsi->protocol->name && strcmp(
|
if (wsi->protocol->name && strcmp(
|
||||||
wsi->utf8_token[WSI_TOKEN_PROTOCOL].token,
|
wsi->u.hdr.hdrs[WSI_TOKEN_PROTOCOL].token,
|
||||||
wsi->protocol->name) == 0)
|
wsi->protocol->name) == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -154,14 +154,14 @@ libwebsocket_read(struct libwebsocket_context *context,
|
||||||
/* we didn't find a protocol he wanted? */
|
/* we didn't find a protocol he wanted? */
|
||||||
|
|
||||||
if (wsi->protocol->callback == NULL) {
|
if (wsi->protocol->callback == NULL) {
|
||||||
if (wsi->utf8_token[WSI_TOKEN_PROTOCOL].token == NULL) {
|
if (wsi->u.hdr.hdrs[WSI_TOKEN_PROTOCOL].token == NULL) {
|
||||||
lwsl_info("[no protocol] "
|
lwsl_info("[no protocol] "
|
||||||
"mapped to protocol 0 handler\n");
|
"mapped to protocol 0 handler\n");
|
||||||
wsi->protocol = &context->protocols[0];
|
wsi->protocol = &context->protocols[0];
|
||||||
} else {
|
} else {
|
||||||
lwsl_err("Requested protocol %s "
|
lwsl_err("Requested protocol %s "
|
||||||
"not supported\n",
|
"not supported\n",
|
||||||
wsi->utf8_token[WSI_TOKEN_PROTOCOL].token);
|
wsi->u.hdr.hdrs[WSI_TOKEN_PROTOCOL].token);
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -173,7 +173,7 @@ libwebsocket_read(struct libwebsocket_context *context,
|
||||||
|
|
||||||
if ((wsi->protocol->callback)(wsi->protocol->owning_server, wsi,
|
if ((wsi->protocol->callback)(wsi->protocol->owning_server, wsi,
|
||||||
LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION,
|
LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION,
|
||||||
&wsi->utf8_token[0], NULL, 0)) {
|
&wsi->u.hdr.hdrs[0], NULL, 0)) {
|
||||||
lwsl_warn("User code denied connection\n");
|
lwsl_warn("User code denied connection\n");
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
@ -204,8 +204,8 @@ libwebsocket_read(struct libwebsocket_context *context,
|
||||||
/* free up his parsing allocations... these are gone... */
|
/* free up his parsing allocations... these are gone... */
|
||||||
|
|
||||||
for (n = 0; n < WSI_TOKEN_COUNT; n++)
|
for (n = 0; n < WSI_TOKEN_COUNT; n++)
|
||||||
if (wsi->utf8_token[n].token)
|
if (wsi->u.hdr.hdrs[n].token)
|
||||||
free(wsi->utf8_token[n].token);
|
free(wsi->u.hdr.hdrs[n].token);
|
||||||
|
|
||||||
wsi->mode = LWS_CONNMODE_WS_SERVING;
|
wsi->mode = LWS_CONNMODE_WS_SERVING;
|
||||||
|
|
||||||
|
|
|
@ -337,34 +337,34 @@ int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c)
|
||||||
|
|
||||||
/* collect into malloc'd buffers */
|
/* collect into malloc'd buffers */
|
||||||
/* optional space swallow */
|
/* optional space swallow */
|
||||||
if (!wsi->utf8_token[wsi->u.hdr.parser_state].token_len && c == ' ')
|
if (!wsi->u.hdr.hdrs[wsi->u.hdr.parser_state].token_len && c == ' ')
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* special case space terminator for get-uri */
|
/* special case space terminator for get-uri */
|
||||||
if (wsi->u.hdr.parser_state == WSI_TOKEN_GET_URI && c == ' ') {
|
if (wsi->u.hdr.parser_state == WSI_TOKEN_GET_URI && c == ' ') {
|
||||||
wsi->utf8_token[wsi->u.hdr.parser_state].token[
|
wsi->u.hdr.hdrs[wsi->u.hdr.parser_state].token[
|
||||||
wsi->utf8_token[wsi->u.hdr.parser_state].token_len] = '\0';
|
wsi->u.hdr.hdrs[wsi->u.hdr.parser_state].token_len] = '\0';
|
||||||
// lwsl_parser("uri '%s'\n", wsi->utf8_token[wsi->u.hdr.parser_state].token);
|
// lwsl_parser("uri '%s'\n", wsi->u.hdr.hdrs[wsi->u.hdr.parser_state].token);
|
||||||
wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
|
wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allocate appropriate memory */
|
/* allocate appropriate memory */
|
||||||
if (wsi->utf8_token[wsi->u.hdr.parser_state].token_len ==
|
if (wsi->u.hdr.hdrs[wsi->u.hdr.parser_state].token_len ==
|
||||||
wsi->u.hdr.current_alloc_len - 1) {
|
wsi->u.hdr.current_alloc_len - 1) {
|
||||||
/* need to extend */
|
/* need to extend */
|
||||||
wsi->u.hdr.current_alloc_len += LWS_ADDITIONAL_HDR_ALLOC;
|
wsi->u.hdr.current_alloc_len += LWS_ADDITIONAL_HDR_ALLOC;
|
||||||
if (wsi->u.hdr.current_alloc_len >= LWS_MAX_HEADER_LEN) {
|
if (wsi->u.hdr.current_alloc_len >= LWS_MAX_HEADER_LEN) {
|
||||||
/* it's waaay to much payload, fail it */
|
/* it's waaay to much payload, fail it */
|
||||||
strcpy(wsi->utf8_token[wsi->u.hdr.parser_state].token,
|
strcpy(wsi->u.hdr.hdrs[wsi->u.hdr.parser_state].token,
|
||||||
"!!! Length exceeded maximum supported !!!");
|
"!!! Length exceeded maximum supported !!!");
|
||||||
wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
|
wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
wsi->utf8_token[wsi->u.hdr.parser_state].token = (char *)
|
wsi->u.hdr.hdrs[wsi->u.hdr.parser_state].token = (char *)
|
||||||
realloc(wsi->utf8_token[wsi->u.hdr.parser_state].token,
|
realloc(wsi->u.hdr.hdrs[wsi->u.hdr.parser_state].token,
|
||||||
wsi->u.hdr.current_alloc_len);
|
wsi->u.hdr.current_alloc_len);
|
||||||
if (wsi->utf8_token[wsi->u.hdr.parser_state].token == NULL) {
|
if (wsi->u.hdr.hdrs[wsi->u.hdr.parser_state].token == NULL) {
|
||||||
lwsl_err("Out of mem\n");
|
lwsl_err("Out of mem\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -372,15 +372,15 @@ int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c)
|
||||||
|
|
||||||
/* bail at EOL */
|
/* bail at EOL */
|
||||||
if (wsi->u.hdr.parser_state != WSI_TOKEN_CHALLENGE && c == '\x0d') {
|
if (wsi->u.hdr.parser_state != WSI_TOKEN_CHALLENGE && c == '\x0d') {
|
||||||
wsi->utf8_token[wsi->u.hdr.parser_state].token[
|
wsi->u.hdr.hdrs[wsi->u.hdr.parser_state].token[
|
||||||
wsi->utf8_token[wsi->u.hdr.parser_state].token_len] = '\0';
|
wsi->u.hdr.hdrs[wsi->u.hdr.parser_state].token_len] = '\0';
|
||||||
wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING_SAW_CR;
|
wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING_SAW_CR;
|
||||||
lwsl_parser("*\n");
|
lwsl_parser("*\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
wsi->utf8_token[wsi->u.hdr.parser_state].token[
|
wsi->u.hdr.hdrs[wsi->u.hdr.parser_state].token[
|
||||||
wsi->utf8_token[wsi->u.hdr.parser_state].token_len++] = c;
|
wsi->u.hdr.hdrs[wsi->u.hdr.parser_state].token_len++] = c;
|
||||||
|
|
||||||
/* per-protocol end of headers management */
|
/* per-protocol end of headers management */
|
||||||
|
|
||||||
|
@ -393,13 +393,13 @@ int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c)
|
||||||
wsi->u.hdr.parser_state = WSI_TOKEN_MUXURL;
|
wsi->u.hdr.parser_state = WSI_TOKEN_MUXURL;
|
||||||
wsi->u.hdr.current_alloc_len = LWS_INITIAL_HDR_ALLOC;
|
wsi->u.hdr.current_alloc_len = LWS_INITIAL_HDR_ALLOC;
|
||||||
|
|
||||||
wsi->utf8_token[wsi->u.hdr.parser_state].token = (char *)
|
wsi->u.hdr.hdrs[wsi->u.hdr.parser_state].token = (char *)
|
||||||
malloc(wsi->u.hdr.current_alloc_len);
|
malloc(wsi->u.hdr.current_alloc_len);
|
||||||
if (wsi->utf8_token[wsi->u.hdr.parser_state].token == NULL) {
|
if (wsi->u.hdr.hdrs[wsi->u.hdr.parser_state].token == NULL) {
|
||||||
lwsl_err("Out of mem\n");
|
lwsl_err("Out of mem\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
wsi->utf8_token[wsi->u.hdr.parser_state].token_len = 0;
|
wsi->u.hdr.hdrs[wsi->u.hdr.parser_state].token_len = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* collecting and checking a name part */
|
/* collecting and checking a name part */
|
||||||
|
@ -417,7 +417,7 @@ int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c)
|
||||||
wsi->u.hdr.lextable_pos = lextable_decode(wsi->u.hdr.lextable_pos, c);
|
wsi->u.hdr.lextable_pos = lextable_decode(wsi->u.hdr.lextable_pos, c);
|
||||||
if (wsi->u.hdr.lextable_pos < 0) {
|
if (wsi->u.hdr.lextable_pos < 0) {
|
||||||
/* this is not a header we know about */
|
/* this is not a header we know about */
|
||||||
if (wsi->utf8_token[WSI_TOKEN_GET_URI].token_len) {
|
if (wsi->u.hdr.hdrs[WSI_TOKEN_GET_URI].token_len) {
|
||||||
/* if not the method, just skip it all */
|
/* if not the method, just skip it all */
|
||||||
wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
|
wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
|
||||||
break;
|
break;
|
||||||
|
@ -428,9 +428,9 @@ int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c)
|
||||||
/* treat it as GET */
|
/* treat it as GET */
|
||||||
wsi->u.hdr.parser_state = WSI_TOKEN_GET_URI;
|
wsi->u.hdr.parser_state = WSI_TOKEN_GET_URI;
|
||||||
wsi->u.hdr.current_alloc_len = LWS_INITIAL_HDR_ALLOC;
|
wsi->u.hdr.current_alloc_len = LWS_INITIAL_HDR_ALLOC;
|
||||||
wsi->utf8_token[WSI_TOKEN_GET_URI].token =
|
wsi->u.hdr.hdrs[WSI_TOKEN_GET_URI].token =
|
||||||
(char *)malloc(wsi->u.hdr.current_alloc_len);
|
(char *)malloc(wsi->u.hdr.current_alloc_len);
|
||||||
if (wsi->utf8_token[WSI_TOKEN_GET_URI].token == NULL) {
|
if (wsi->u.hdr.hdrs[WSI_TOKEN_GET_URI].token == NULL) {
|
||||||
lwsl_err("Out of mem\n");
|
lwsl_err("Out of mem\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -457,25 +457,25 @@ int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c)
|
||||||
n = WSI_TOKEN_COUNT;
|
n = WSI_TOKEN_COUNT;
|
||||||
|
|
||||||
/* If the header has been seen already, just append */
|
/* If the header has been seen already, just append */
|
||||||
if (!wsi->utf8_token[wsi->u.hdr.parser_state].token) {
|
if (!wsi->u.hdr.hdrs[wsi->u.hdr.parser_state].token) {
|
||||||
|
|
||||||
wsi->u.hdr.current_alloc_len = LWS_INITIAL_HDR_ALLOC;
|
wsi->u.hdr.current_alloc_len = LWS_INITIAL_HDR_ALLOC;
|
||||||
wsi->utf8_token[wsi->u.hdr.parser_state].token = (char *)
|
wsi->u.hdr.hdrs[wsi->u.hdr.parser_state].token = (char *)
|
||||||
malloc(wsi->u.hdr.current_alloc_len);
|
malloc(wsi->u.hdr.current_alloc_len);
|
||||||
if (wsi->utf8_token[wsi->u.hdr.parser_state].token == NULL) {
|
if (wsi->u.hdr.hdrs[wsi->u.hdr.parser_state].token == NULL) {
|
||||||
lwsl_err("Out of mem\n");
|
lwsl_err("Out of mem\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
wsi->utf8_token[wsi->u.hdr.parser_state].token_len = 0;
|
wsi->u.hdr.hdrs[wsi->u.hdr.parser_state].token_len = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wsi->u.hdr.parser_state == WSI_TOKEN_CHALLENGE) {
|
if (wsi->u.hdr.parser_state == WSI_TOKEN_CHALLENGE) {
|
||||||
if (wsi->utf8_token[WSI_TOKEN_CHALLENGE].token) {
|
if (wsi->u.hdr.hdrs[WSI_TOKEN_CHALLENGE].token) {
|
||||||
free(wsi->utf8_token[WSI_TOKEN_CHALLENGE].token);
|
free(wsi->u.hdr.hdrs[WSI_TOKEN_CHALLENGE].token);
|
||||||
wsi->utf8_token[WSI_TOKEN_CHALLENGE].token = NULL;
|
wsi->u.hdr.hdrs[WSI_TOKEN_CHALLENGE].token = NULL;
|
||||||
}
|
}
|
||||||
wsi->utf8_token[WSI_TOKEN_CHALLENGE].token_len = 0;
|
wsi->u.hdr.hdrs[WSI_TOKEN_CHALLENGE].token_len = 0;
|
||||||
goto set_parsing_complete;
|
goto set_parsing_complete;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -510,13 +510,13 @@ int libwebsocket_parse(struct libwebsocket *wsi, unsigned char c)
|
||||||
|
|
||||||
set_parsing_complete:
|
set_parsing_complete:
|
||||||
|
|
||||||
if (wsi->utf8_token[WSI_TOKEN_UPGRADE].token_len) {
|
if (wsi->u.hdr.hdrs[WSI_TOKEN_UPGRADE].token_len) {
|
||||||
if (!wsi->utf8_token[WSI_TOKEN_VERSION].token_len) {
|
if (!wsi->u.hdr.hdrs[WSI_TOKEN_VERSION].token_len) {
|
||||||
// lwsl_info("Missing Version Header\n");
|
// lwsl_info("Missing Version Header\n");
|
||||||
// return 1;
|
// return 1;
|
||||||
} else
|
} else
|
||||||
wsi->ietf_spec_revision =
|
wsi->ietf_spec_revision =
|
||||||
atoi(wsi->utf8_token[WSI_TOKEN_VERSION].token);
|
atoi(wsi->u.hdr.hdrs[WSI_TOKEN_VERSION].token);
|
||||||
|
|
||||||
lwsl_parser("v%02d headers completed\n", wsi->ietf_spec_revision);
|
lwsl_parser("v%02d headers completed\n", wsi->ietf_spec_revision);
|
||||||
}
|
}
|
||||||
|
|
|
@ -304,6 +304,7 @@ struct _lws_http_mode_related {
|
||||||
struct _lws_header_related {
|
struct _lws_header_related {
|
||||||
char name_buffer[LWS_MAX_HEADER_NAME_LENGTH];
|
char name_buffer[LWS_MAX_HEADER_NAME_LENGTH];
|
||||||
int name_buffer_pos;
|
int name_buffer_pos;
|
||||||
|
struct lws_tokens hdrs[WSI_TOKEN_COUNT];
|
||||||
int lextable_pos;
|
int lextable_pos;
|
||||||
enum lws_token_indexes parser_state;
|
enum lws_token_indexes parser_state;
|
||||||
int current_alloc_len;
|
int current_alloc_len;
|
||||||
|
@ -374,8 +375,6 @@ struct libwebsocket {
|
||||||
struct _lws_header_related hdr;
|
struct _lws_header_related hdr;
|
||||||
struct _lws_websocket_related ws;
|
struct _lws_websocket_related ws;
|
||||||
} u;
|
} u;
|
||||||
|
|
||||||
struct lws_tokens utf8_token[WSI_TOKEN_COUNT];
|
|
||||||
|
|
||||||
enum libwebsocket_write_protocol rx_frame_type;
|
enum libwebsocket_write_protocol rx_frame_type;
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,8 @@
|
||||||
#include "private-libwebsockets.h"
|
#include "private-libwebsockets.h"
|
||||||
|
|
||||||
#define LWS_CPYAPP(ptr, str) { strcpy(ptr, str); ptr += strlen(str); }
|
#define LWS_CPYAPP(ptr, str) { strcpy(ptr, str); ptr += strlen(str); }
|
||||||
#define LWS_CPYAPP_TOKEN(ptr, tok) { strcpy(p, wsi->utf8_token[tok].token); \
|
#define LWS_CPYAPP_TOKEN(ptr, tok) { strcpy(p, wsi->u.hdr.hdrs[tok].token); \
|
||||||
p += wsi->utf8_token[tok].token_len; }
|
p += wsi->u.hdr.hdrs[tok].token_len; }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Perform the newer BASE64-encoded handshake scheme
|
* Perform the newer BASE64-encoded handshake scheme
|
||||||
|
@ -48,26 +48,26 @@ handshake_0405(struct libwebsocket_context *context, struct libwebsocket *wsi)
|
||||||
int more = 1;
|
int more = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!wsi->utf8_token[WSI_TOKEN_HOST].token_len ||
|
if (!wsi->u.hdr.hdrs[WSI_TOKEN_HOST].token_len ||
|
||||||
!wsi->utf8_token[WSI_TOKEN_KEY].token_len) {
|
!wsi->u.hdr.hdrs[WSI_TOKEN_KEY].token_len) {
|
||||||
lwsl_parser("handshake_04 missing pieces\n");
|
lwsl_parser("handshake_04 missing pieces\n");
|
||||||
/* completed header processing, but missing some bits */
|
/* completed header processing, but missing some bits */
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wsi->utf8_token[WSI_TOKEN_KEY].token_len >=
|
if (wsi->u.hdr.hdrs[WSI_TOKEN_KEY].token_len >=
|
||||||
MAX_WEBSOCKET_04_KEY_LEN) {
|
MAX_WEBSOCKET_04_KEY_LEN) {
|
||||||
lwsl_warn("Client sent handshake key longer "
|
lwsl_warn("Client sent handshake key longer "
|
||||||
"than max supported %d\n", MAX_WEBSOCKET_04_KEY_LEN);
|
"than max supported %d\n", MAX_WEBSOCKET_04_KEY_LEN);
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(accept_buf, wsi->utf8_token[WSI_TOKEN_KEY].token);
|
strcpy(accept_buf, wsi->u.hdr.hdrs[WSI_TOKEN_KEY].token);
|
||||||
strcpy(accept_buf + wsi->utf8_token[WSI_TOKEN_KEY].token_len,
|
strcpy(accept_buf + wsi->u.hdr.hdrs[WSI_TOKEN_KEY].token_len,
|
||||||
websocket_magic_guid_04);
|
websocket_magic_guid_04);
|
||||||
|
|
||||||
SHA1((unsigned char *)accept_buf,
|
SHA1((unsigned char *)accept_buf,
|
||||||
wsi->utf8_token[WSI_TOKEN_KEY].token_len +
|
wsi->u.hdr.hdrs[WSI_TOKEN_KEY].token_len +
|
||||||
strlen(websocket_magic_guid_04), hash);
|
strlen(websocket_magic_guid_04), hash);
|
||||||
|
|
||||||
accept_len = lws_b64_encode_string((char *)hash, 20, accept_buf,
|
accept_len = lws_b64_encode_string((char *)hash, 20, accept_buf,
|
||||||
|
@ -87,9 +87,9 @@ handshake_0405(struct libwebsocket_context *context, struct libwebsocket *wsi)
|
||||||
/* make a buffer big enough for everything */
|
/* make a buffer big enough for everything */
|
||||||
|
|
||||||
response = (char *)malloc(256 +
|
response = (char *)malloc(256 +
|
||||||
wsi->utf8_token[WSI_TOKEN_UPGRADE].token_len +
|
wsi->u.hdr.hdrs[WSI_TOKEN_UPGRADE].token_len +
|
||||||
wsi->utf8_token[WSI_TOKEN_CONNECTION].token_len +
|
wsi->u.hdr.hdrs[WSI_TOKEN_CONNECTION].token_len +
|
||||||
wsi->utf8_token[WSI_TOKEN_PROTOCOL].token_len);
|
wsi->u.hdr.hdrs[WSI_TOKEN_PROTOCOL].token_len);
|
||||||
if (!response) {
|
if (!response) {
|
||||||
lwsl_err("Out of memory for response buffer\n");
|
lwsl_err("Out of memory for response buffer\n");
|
||||||
goto bail;
|
goto bail;
|
||||||
|
@ -103,7 +103,7 @@ handshake_0405(struct libwebsocket_context *context, struct libwebsocket *wsi)
|
||||||
strcpy(p, accept_buf);
|
strcpy(p, accept_buf);
|
||||||
p += accept_len;
|
p += accept_len;
|
||||||
|
|
||||||
if (wsi->utf8_token[WSI_TOKEN_PROTOCOL].token) {
|
if (wsi->u.hdr.hdrs[WSI_TOKEN_PROTOCOL].token) {
|
||||||
LWS_CPYAPP(p, "\x0d\x0aSec-WebSocket-Protocol: ");
|
LWS_CPYAPP(p, "\x0d\x0aSec-WebSocket-Protocol: ");
|
||||||
LWS_CPYAPP_TOKEN(p, WSI_TOKEN_PROTOCOL);
|
LWS_CPYAPP_TOKEN(p, WSI_TOKEN_PROTOCOL);
|
||||||
}
|
}
|
||||||
|
@ -114,16 +114,16 @@ handshake_0405(struct libwebsocket_context *context, struct libwebsocket *wsi)
|
||||||
* enable on this connection, and give him back the list
|
* enable on this connection, and give him back the list
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (wsi->utf8_token[WSI_TOKEN_EXTENSIONS].token_len) {
|
if (wsi->u.hdr.hdrs[WSI_TOKEN_EXTENSIONS].token_len) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* break down the list of client extensions
|
* break down the list of client extensions
|
||||||
* and go through them
|
* and go through them
|
||||||
*/
|
*/
|
||||||
|
|
||||||
c = wsi->utf8_token[WSI_TOKEN_EXTENSIONS].token;
|
c = wsi->u.hdr.hdrs[WSI_TOKEN_EXTENSIONS].token;
|
||||||
lwsl_parser("wsi->utf8_token[WSI_TOKEN_EXTENSIONS].token = %s\n",
|
lwsl_parser("wsi->u.hdr.hdrs[WSI_TOKEN_EXTENSIONS].token = %s\n",
|
||||||
wsi->utf8_token[WSI_TOKEN_EXTENSIONS].token);
|
wsi->u.hdr.hdrs[WSI_TOKEN_EXTENSIONS].token);
|
||||||
wsi->count_active_extensions = 0;
|
wsi->count_active_extensions = 0;
|
||||||
n = 0;
|
n = 0;
|
||||||
while (more) {
|
while (more) {
|
||||||
|
@ -273,8 +273,8 @@ bail:
|
||||||
/* free up his parsing allocations */
|
/* free up his parsing allocations */
|
||||||
|
|
||||||
for (n = 0; n < WSI_TOKEN_COUNT; n++)
|
for (n = 0; n < WSI_TOKEN_COUNT; n++)
|
||||||
if (wsi->utf8_token[n].token)
|
if (wsi->u.hdr.hdrs[n].token)
|
||||||
free(wsi->utf8_token[n].token);
|
free(wsi->u.hdr.hdrs[n].token);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,8 +106,8 @@ libwebsocket_create_new_server_wsi(struct libwebsocket_context *context)
|
||||||
new_wsi->mode = LWS_CONNMODE_HTTP_SERVING;
|
new_wsi->mode = LWS_CONNMODE_HTTP_SERVING;
|
||||||
|
|
||||||
for (n = 0; n < WSI_TOKEN_COUNT; n++) {
|
for (n = 0; n < WSI_TOKEN_COUNT; n++) {
|
||||||
new_wsi->utf8_token[n].token = NULL;
|
new_wsi->u.hdr.hdrs[n].token = NULL;
|
||||||
new_wsi->utf8_token[n].token_len = 0;
|
new_wsi->u.hdr.hdrs[n].token_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Add table
Reference in a new issue