Compare commits
8 commits
master
...
v1.5-stabl
Author | SHA1 | Date | |
---|---|---|---|
![]() |
4bc6f95974 | ||
![]() |
496e0af86e | ||
![]() |
40f4bc9c1c | ||
![]() |
edd3a2d6bb | ||
![]() |
88b9682e22 | ||
![]() |
6d5143548d | ||
![]() |
53ebe46d75 | ||
![]() |
26ba55a6fc |
8 changed files with 90 additions and 56 deletions
23
lib/client.c
23
lib/client.c
|
@ -516,18 +516,18 @@ lws_client_interpret_server_handshake(struct libwebsocket_context *context,
|
|||
* Now let's confirm it sent all the necessary headers
|
||||
*/
|
||||
|
||||
if (lws_hdr_total_length(wsi, WSI_TOKEN_ACCEPT) == 0) {
|
||||
lwsl_info("no ACCEPT\n");
|
||||
p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP);
|
||||
isErrorCodeReceived = 1;
|
||||
goto bail3;
|
||||
}
|
||||
|
||||
p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP);
|
||||
if (!p) {
|
||||
lwsl_info("no URI\n");
|
||||
goto bail3;
|
||||
}
|
||||
|
||||
if (lws_hdr_total_length(wsi, WSI_TOKEN_ACCEPT) == 0) {
|
||||
lwsl_info("no ACCEPT\n");
|
||||
isErrorCodeReceived = 1;
|
||||
goto bail3;
|
||||
}
|
||||
|
||||
if (p && strncmp(p, "101", 3)) {
|
||||
lwsl_warn(
|
||||
"lws_client_handshake: got bad HTTP response '%s'\n", p);
|
||||
|
@ -719,7 +719,7 @@ check_accept:
|
|||
|
||||
p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_ACCEPT);
|
||||
if (strcmp(p, wsi->u.hdr.ah->initial_handshake_hash_base64)) {
|
||||
lwsl_warn("lws_client_int_s_hs: accept %s wrong vs %s\n", p,
|
||||
lwsl_warn("lws_client_int_s_hs: accept '%s' wrong vs '%s'\n", p,
|
||||
wsi->u.hdr.ah->initial_handshake_hash_base64);
|
||||
goto bail2;
|
||||
}
|
||||
|
@ -767,6 +767,7 @@ check_accept:
|
|||
lwsl_err("Out of Mem allocating rx buffer %d\n", n);
|
||||
goto bail2;
|
||||
}
|
||||
wsi->u.ws.rx_ubuf_alloc = n;
|
||||
lwsl_info("Allocating client RX buffer %d\n", n);
|
||||
|
||||
if (setsockopt(wsi->sock, SOL_SOCKET, SO_SNDBUF, (const char *)&n, sizeof n)) {
|
||||
|
@ -804,7 +805,6 @@ check_accept:
|
|||
return 0;
|
||||
|
||||
bail3:
|
||||
lws_free2(wsi->u.ws.rx_user_buffer);
|
||||
close_reason = LWS_CLOSE_STATUS_NOSTATUS;
|
||||
|
||||
bail2:
|
||||
|
@ -822,10 +822,7 @@ bail2:
|
|||
|
||||
lwsl_info("closing connection due to bail2 connection error\n");
|
||||
|
||||
/* free up his parsing allocations */
|
||||
|
||||
lws_free2(wsi->u.hdr.ah);
|
||||
|
||||
/* closing will free up his parsing allocations */
|
||||
libwebsocket_close_and_free_session(context, wsi, close_reason);
|
||||
|
||||
return 1;
|
||||
|
|
|
@ -299,6 +299,8 @@ libwebsocket_context_destroy(struct libwebsocket_context *context)
|
|||
if (!context)
|
||||
return;
|
||||
|
||||
context->being_destroyed = 1;
|
||||
|
||||
#ifdef LWS_LATENCY
|
||||
if (context->worst_latency_info[0])
|
||||
lwsl_notice("Worst latency: %s\n", context->worst_latency_info);
|
||||
|
|
|
@ -388,7 +388,8 @@ libwebsockets_get_addresses(struct libwebsocket_context *context,
|
|||
if (addr4.sin_family == AF_UNSPEC)
|
||||
return -1;
|
||||
|
||||
lws_plat_inet_ntop(AF_INET, &addr4.sin_addr, rip, rip_len);
|
||||
if (lws_plat_inet_ntop(AF_INET, &addr4.sin_addr, rip, rip_len) == NULL)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -185,16 +185,27 @@ static int issue_char(struct libwebsocket *wsi, unsigned char c)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if( wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len >=
|
||||
if (wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len >=
|
||||
wsi->u.hdr.current_token_limit) {
|
||||
lwsl_warn("header %i exceeds limit\n", wsi->u.hdr.parser_state);
|
||||
return 1;
|
||||
};
|
||||
}
|
||||
|
||||
wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = c;
|
||||
if (c)
|
||||
wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len++;
|
||||
|
||||
/* Insert a null character when we *hit* the limit: */
|
||||
if (wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len == wsi->u.hdr.current_token_limit) {
|
||||
if (wsi->u.hdr.ah->pos == sizeof(wsi->u.hdr.ah->data)) {
|
||||
lwsl_warn("excessive header content 2\n");
|
||||
return -1;
|
||||
}
|
||||
wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = '\0';
|
||||
lwsl_warn("header %i exceeds limit %d\n",
|
||||
wsi->u.hdr.parser_state, wsi->u.hdr.current_token_limit);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -270,7 +281,8 @@ int libwebsocket_parse(
|
|||
case URIES_SEEN_PERCENT_H1:
|
||||
if (char_to_hex(c) < 0) {
|
||||
/* regurgitate */
|
||||
issue_char(wsi, '%');
|
||||
if (issue_char(wsi, '%') < 0)
|
||||
return -1;
|
||||
wsi->u.hdr.ues = URIES_IDLE;
|
||||
/* regurgitate + assess */
|
||||
if (libwebsocket_parse(context, wsi, wsi->u.hdr.esc_stash) < 0)
|
||||
|
@ -294,6 +306,8 @@ int libwebsocket_parse(
|
|||
|
||||
switch (wsi->u.hdr.ups) {
|
||||
case URIPS_IDLE:
|
||||
if (!c)
|
||||
return -1;
|
||||
/* issue the first / always */
|
||||
if (c == '/')
|
||||
wsi->u.hdr.ups = URIPS_SEEN_SLASH;
|
||||
|
@ -356,7 +370,8 @@ int libwebsocket_parse(
|
|||
|
||||
if (c == '?') { /* start of URI arguments */
|
||||
/* seal off uri header */
|
||||
wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = '\0';
|
||||
if (issue_char(wsi, '\0') < 0)
|
||||
return -1;
|
||||
|
||||
/* move to using WSI_TOKEN_HTTP_URI_ARGS */
|
||||
wsi->u.hdr.ah->next_frag_index++;
|
||||
|
@ -504,13 +519,8 @@ start_fragment:
|
|||
wsi->u.hdr.ah->frags[n].next_frag_index =
|
||||
wsi->u.hdr.ah->next_frag_index;
|
||||
|
||||
if (wsi->u.hdr.ah->pos == sizeof(wsi->u.hdr.ah->data)) {
|
||||
lwsl_warn("excessive header content\n");
|
||||
if (issue_char(wsi, ' ') < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = ' ';
|
||||
wsi->u.hdr.ah->frags[wsi->u.hdr.ah->next_frag_index].len++;
|
||||
break;
|
||||
|
||||
/* skipping arg part of a name we didn't recognize */
|
||||
|
@ -820,6 +830,10 @@ handle_first:
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (wsi->u.ws.rx_user_buffer_head + LWS_SEND_BUFFER_PRE_PADDING >= wsi->u.ws.rx_ubuf_alloc) {
|
||||
lwsl_err("Attempted overflow\n");
|
||||
return -1;
|
||||
}
|
||||
if (wsi->u.ws.all_zero_nonce)
|
||||
wsi->u.ws.rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
|
||||
(wsi->u.ws.rx_user_buffer_head++)] = c;
|
||||
|
|
|
@ -503,6 +503,8 @@ struct libwebsocket_context {
|
|||
#endif
|
||||
struct lws_token_limits *token_limits;
|
||||
void *user_space;
|
||||
|
||||
unsigned int being_destroyed:1;
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -776,6 +778,7 @@ struct _lws_header_related {
|
|||
struct _lws_websocket_related {
|
||||
char *rx_user_buffer;
|
||||
int rx_user_buffer_head;
|
||||
unsigned int rx_ubuf_alloc;
|
||||
unsigned char frame_masking_nonce_04[4];
|
||||
unsigned char frame_mask_index;
|
||||
size_t rx_packet_length;
|
||||
|
|
|
@ -270,8 +270,7 @@ handshake_0405(struct libwebsocket_context *context, struct libwebsocket *wsi)
|
|||
|
||||
|
||||
bail:
|
||||
/* free up his parsing allocations */
|
||||
lws_free_header_table(wsi);
|
||||
/* caller will free up his parsing allocations */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
72
lib/server.c
72
lib/server.c
|
@ -137,7 +137,14 @@ int lws_context_init_server(struct lws_context_creation_info *info,
|
|||
int
|
||||
_libwebsocket_rx_flow_control(struct libwebsocket *wsi)
|
||||
{
|
||||
struct libwebsocket_context *context = wsi->protocol->owning_server;
|
||||
struct libwebsocket_context *context;
|
||||
|
||||
if (!wsi)
|
||||
return 0;
|
||||
|
||||
context = wsi->protocol->owning_server;
|
||||
if (context->being_destroyed)
|
||||
return 0;
|
||||
|
||||
/* there is no pending change */
|
||||
if (!(wsi->rxflow_change_to & LWS_RXFLOW_PENDING_CHANGE))
|
||||
|
@ -340,6 +347,8 @@ int lws_handshake_server(struct libwebsocket_context *context,
|
|||
/* LWS_CONNMODE_WS_SERVING */
|
||||
|
||||
while (len--) {
|
||||
assert(wsi->mode == LWS_CONNMODE_HTTP_SERVING);
|
||||
|
||||
if (libwebsocket_parse(context, wsi, *(*buf)++)) {
|
||||
lwsl_info("libwebsocket_parse failed\n");
|
||||
goto bail_nuke_ah;
|
||||
|
@ -355,33 +364,39 @@ int lws_handshake_server(struct libwebsocket_context *context,
|
|||
|
||||
/* is this websocket protocol or normal http 1.0? */
|
||||
|
||||
if (!lws_hdr_total_length(wsi, WSI_TOKEN_UPGRADE) ||
|
||||
!lws_hdr_total_length(wsi, WSI_TOKEN_CONNECTION)) {
|
||||
|
||||
ah = wsi->u.hdr.ah;
|
||||
|
||||
lws_union_transition(wsi, LWS_CONNMODE_HTTP_SERVING_ACCEPTED);
|
||||
wsi->state = WSI_STATE_HTTP;
|
||||
wsi->u.http.fd = LWS_INVALID_FILE;
|
||||
|
||||
/* expose it at the same offset as u.hdr */
|
||||
wsi->u.http.ah = ah;
|
||||
|
||||
n = lws_http_action(context, wsi);
|
||||
|
||||
return n;
|
||||
if (lws_hdr_total_length(wsi, WSI_TOKEN_UPGRADE)) {
|
||||
if (!strcasecmp(lws_hdr_simple_ptr(wsi, WSI_TOKEN_UPGRADE),
|
||||
"websocket")) {
|
||||
lwsl_info("Upgrade to ws\n");
|
||||
goto upgrade_ws;
|
||||
}
|
||||
#ifdef LWS_USE_HTTP2
|
||||
if (!strcasecmp(lws_hdr_simple_ptr(wsi, WSI_TOKEN_UPGRADE),
|
||||
"h2c-14")) {
|
||||
lwsl_info("Upgrade to h2c-14\n");
|
||||
goto upgrade_h2c;
|
||||
}
|
||||
#endif
|
||||
lwsl_err("Unknown upgrade\n");
|
||||
/* dunno what he wanted to upgrade to */
|
||||
goto bail_nuke_ah;
|
||||
}
|
||||
|
||||
if (!strcasecmp(lws_hdr_simple_ptr(wsi, WSI_TOKEN_UPGRADE),
|
||||
"websocket"))
|
||||
goto upgrade_ws;
|
||||
#ifdef LWS_USE_HTTP2
|
||||
if (!strcasecmp(lws_hdr_simple_ptr(wsi, WSI_TOKEN_UPGRADE),
|
||||
"h2c-14"))
|
||||
goto upgrade_h2c;
|
||||
#endif
|
||||
/* dunno what he wanted to upgrade to */
|
||||
goto bail_nuke_ah;
|
||||
/* no upgrade ack... he remained as HTTP */
|
||||
|
||||
lwsl_info("No upgrade\n");
|
||||
|
||||
ah = wsi->u.hdr.ah;
|
||||
|
||||
lws_union_transition(wsi, LWS_CONNMODE_HTTP_SERVING_ACCEPTED);
|
||||
wsi->state = WSI_STATE_HTTP;
|
||||
wsi->u.http.fd = LWS_INVALID_FILE;
|
||||
|
||||
/* expose it at the same offset as u.hdr */
|
||||
wsi->u.http.ah = ah;
|
||||
|
||||
n = lws_http_action(context, wsi);
|
||||
return n;
|
||||
|
||||
#ifdef LWS_USE_HTTP2
|
||||
upgrade_h2c:
|
||||
|
@ -561,15 +576,16 @@ upgrade_ws:
|
|||
lwsl_err("Out of Mem allocating rx buffer %d\n", n);
|
||||
return 1;
|
||||
}
|
||||
wsi->u.ws.rx_ubuf_alloc = n;
|
||||
lwsl_info("Allocating RX buffer %d\n", n);
|
||||
|
||||
if (setsockopt(wsi->sock, SOL_SOCKET, SO_SNDBUF, (const char *)&n, sizeof n)) {
|
||||
lwsl_warn("Failed to set SNDBUF to %d", n);
|
||||
return 1;
|
||||
}
|
||||
lwsl_parser("accepted v%02d connection\n", wsi->ietf_spec_revision);
|
||||
|
||||
lwsl_parser("accepted v%02d connection\n",
|
||||
wsi->ietf_spec_revision);
|
||||
return 0;
|
||||
} /* while all chars are handled */
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -105,7 +105,7 @@ struct per_session_data__http {
|
|||
static void
|
||||
dump_handshake_info(struct libwebsocket *wsi)
|
||||
{
|
||||
int n = 0;
|
||||
int n = 0, len;
|
||||
char buf[256];
|
||||
const unsigned char *c;
|
||||
|
||||
|
@ -116,12 +116,14 @@ dump_handshake_info(struct libwebsocket *wsi)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!lws_hdr_total_length(wsi, n)) {
|
||||
len = lws_hdr_total_length(wsi, n);
|
||||
if (!len || len > sizeof(buf) - 1) {
|
||||
n++;
|
||||
continue;
|
||||
}
|
||||
|
||||
lws_hdr_copy(wsi, buf, sizeof buf, n);
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
|
||||
fprintf(stderr, " %s = %s\n", (char *)c, buf);
|
||||
n++;
|
||||
|
|
Loading…
Add table
Reference in a new issue