ietf_version_or_minus_one = SPEC_LATEST_SUPPORTED;
wsi->ietf_spec_revision = ietf_version_or_minus_one;
- wsi->name_buffer_pos = 0;
+ wsi->u.hdr.name_buffer_pos = 0;
wsi->user_space = NULL;
wsi->state = WSI_STATE_CLIENT_UNCONNECTED;
- wsi->pings_vs_pongs = 0;
+ wsi->u.ws.pings_vs_pongs = 0;
wsi->protocol = NULL;
wsi->pending_timeout = NO_PENDING_TIMEOUT;
#ifndef LWS_NO_EXTENSIONS
switch (wsi->ietf_spec_revision) {
case 13:
- wsi->opcode = c & 0xf;
- wsi->rsv = (c & 0x70);
- wsi->final = !!((c >> 7) & 1);
- switch (wsi->opcode) {
+ wsi->u.ws.opcode = c & 0xf;
+ wsi->u.ws.rsv = (c & 0x70);
+ wsi->u.ws.final = !!((c >> 7) & 1);
+ switch (wsi->u.ws.opcode) {
case LWS_WS_OPCODE_07__TEXT_FRAME:
case LWS_WS_OPCODE_07__BINARY_FRAME:
- wsi->frame_is_binary = wsi->opcode == LWS_WS_OPCODE_07__BINARY_FRAME;
+ wsi->u.ws.frame_is_binary = wsi->u.ws.opcode == LWS_WS_OPCODE_07__BINARY_FRAME;
break;
}
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN;
case LWS_RXPS_04_FRAME_HDR_LEN:
- wsi->this_frame_masked = !!(c & 0x80);
+ wsi->u.ws.this_frame_masked = !!(c & 0x80);
switch (c & 0x7f) {
case 126:
/* control frames are not allowed to have big lengths */
- if (wsi->opcode & 8)
+ if (wsi->u.ws.opcode & 8)
goto illegal_ctl_length;
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_2;
break;
case 127:
/* control frames are not allowed to have big lengths */
- if (wsi->opcode & 8)
+ if (wsi->u.ws.opcode & 8)
goto illegal_ctl_length;
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_8;
break;
default:
- wsi->rx_packet_length = c;
- if (wsi->this_frame_masked)
+ wsi->u.ws.rx_packet_length = c;
+ if (wsi->u.ws.this_frame_masked)
wsi->lws_rx_parse_state =
LWS_RXPS_07_COLLECT_FRAME_KEY_1;
else {
break;
case LWS_RXPS_04_FRAME_HDR_LEN16_2:
- wsi->rx_packet_length = c << 8;
+ wsi->u.ws.rx_packet_length = c << 8;
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_1;
break;
case LWS_RXPS_04_FRAME_HDR_LEN16_1:
- wsi->rx_packet_length |= c;
- if (wsi->this_frame_masked)
+ wsi->u.ws.rx_packet_length |= c;
+ if (wsi->u.ws.this_frame_masked)
wsi->lws_rx_parse_state =
LWS_RXPS_07_COLLECT_FRAME_KEY_1;
else {
- if (wsi->rx_packet_length)
+ if (wsi->u.ws.rx_packet_length)
wsi->lws_rx_parse_state =
LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
else {
return -1;
}
#if defined __LP64__
- wsi->rx_packet_length = ((size_t)c) << 56;
+ wsi->u.ws.rx_packet_length = ((size_t)c) << 56;
#else
- wsi->rx_packet_length = 0;
+ wsi->u.ws.rx_packet_length = 0;
#endif
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_7;
break;
case LWS_RXPS_04_FRAME_HDR_LEN64_7:
#if defined __LP64__
- wsi->rx_packet_length |= ((size_t)c) << 48;
+ wsi->u.ws.rx_packet_length |= ((size_t)c) << 48;
#endif
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_6;
break;
case LWS_RXPS_04_FRAME_HDR_LEN64_6:
#if defined __LP64__
- wsi->rx_packet_length |= ((size_t)c) << 40;
+ wsi->u.ws.rx_packet_length |= ((size_t)c) << 40;
#endif
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_5;
break;
case LWS_RXPS_04_FRAME_HDR_LEN64_5:
#if defined __LP64__
- wsi->rx_packet_length |= ((size_t)c) << 32;
+ wsi->u.ws.rx_packet_length |= ((size_t)c) << 32;
#endif
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_4;
break;
case LWS_RXPS_04_FRAME_HDR_LEN64_4:
- wsi->rx_packet_length |= ((size_t)c) << 24;
+ wsi->u.ws.rx_packet_length |= ((size_t)c) << 24;
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_3;
break;
case LWS_RXPS_04_FRAME_HDR_LEN64_3:
- wsi->rx_packet_length |= ((size_t)c) << 16;
+ wsi->u.ws.rx_packet_length |= ((size_t)c) << 16;
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_2;
break;
case LWS_RXPS_04_FRAME_HDR_LEN64_2:
- wsi->rx_packet_length |= ((size_t)c) << 8;
+ wsi->u.ws.rx_packet_length |= ((size_t)c) << 8;
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_1;
break;
case LWS_RXPS_04_FRAME_HDR_LEN64_1:
- wsi->rx_packet_length |= (size_t)c;
- if (wsi->this_frame_masked)
+ wsi->u.ws.rx_packet_length |= (size_t)c;
+ if (wsi->u.ws.this_frame_masked)
wsi->lws_rx_parse_state =
LWS_RXPS_07_COLLECT_FRAME_KEY_1;
else {
- if (wsi->rx_packet_length)
+ if (wsi->u.ws.rx_packet_length)
wsi->lws_rx_parse_state =
LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
else {
break;
case LWS_RXPS_07_COLLECT_FRAME_KEY_1:
- wsi->frame_masking_nonce_04[0] = c;
+ wsi->u.ws.frame_masking_nonce_04[0] = c;
if (c)
- wsi->all_zero_nonce = 0;
+ wsi->u.ws.all_zero_nonce = 0;
wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_2;
break;
case LWS_RXPS_07_COLLECT_FRAME_KEY_2:
- wsi->frame_masking_nonce_04[1] = c;
+ wsi->u.ws.frame_masking_nonce_04[1] = c;
if (c)
- wsi->all_zero_nonce = 0;
+ wsi->u.ws.all_zero_nonce = 0;
wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_3;
break;
case LWS_RXPS_07_COLLECT_FRAME_KEY_3:
- wsi->frame_masking_nonce_04[2] = c;
+ wsi->u.ws.frame_masking_nonce_04[2] = c;
if (c)
- wsi->all_zero_nonce = 0;
+ wsi->u.ws.all_zero_nonce = 0;
wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_4;
break;
case LWS_RXPS_07_COLLECT_FRAME_KEY_4:
- wsi->frame_masking_nonce_04[3] = c;
+ wsi->u.ws.frame_masking_nonce_04[3] = c;
if (c)
- wsi->all_zero_nonce = 0;
+ wsi->u.ws.all_zero_nonce = 0;
- if (wsi->rx_packet_length)
+ if (wsi->u.ws.rx_packet_length)
wsi->lws_rx_parse_state =
LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
else {
break;
case LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED:
- if ((!wsi->this_frame_masked) || wsi->all_zero_nonce)
- wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
- (wsi->rx_user_buffer_head++)] = c;
+ if ((!wsi->u.ws.this_frame_masked) || 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;
else
- wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
- (wsi->rx_user_buffer_head++)] =
- c ^ wsi->frame_masking_nonce_04[(wsi->frame_mask_index++) & 3];
+ wsi->u.ws.rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
+ (wsi->u.ws.rx_user_buffer_head++)] =
+ c ^ wsi->u.ws.frame_masking_nonce_04[(wsi->u.ws.frame_mask_index++) & 3];
- if (--wsi->rx_packet_length == 0) {
+ if (--wsi->u.ws.rx_packet_length == 0) {
wsi->lws_rx_parse_state = LWS_RXPS_NEW;
goto spill;
}
- if (wsi->rx_user_buffer_head != MAX_USER_RX_BUFFER)
+ if (wsi->u.ws.rx_user_buffer_head != MAX_USER_RX_BUFFER)
break;
spill:
* layer? If so service it and hide it from the user callback
*/
- switch (wsi->opcode) {
+ switch (wsi->u.ws.opcode) {
case LWS_WS_OPCODE_07__CLOSE:
/* is this an acknowledgement of our close? */
if (wsi->state == WSI_STATE_AWAITING_CLOSE_ACK) {
lwsl_parser("seen server's close ack\n");
return -1;
}
- lwsl_parser("client sees server close packet len = %d\n", wsi->rx_user_buffer_head);
+ lwsl_parser("client sees server close packet len = %d\n", wsi->u.ws.rx_user_buffer_head);
/* parrot the close packet payload back */
n = libwebsocket_write(wsi, (unsigned char *)
- &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
- wsi->rx_user_buffer_head, LWS_WRITE_CLOSE);
+ &wsi->u.ws.rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
+ wsi->u.ws.rx_user_buffer_head, LWS_WRITE_CLOSE);
lwsl_parser("client writing close ack returned %d\n", n);
wsi->state = WSI_STATE_RETURNED_CLOSE_ALREADY;
/* close the connection */
lwsl_info("client received ping, doing pong\n");
/* parrot the ping packet payload back as a pong*/
n = libwebsocket_write(wsi, (unsigned char *)
- &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
- wsi->rx_user_buffer_head, LWS_WRITE_PONG);
+ &wsi->u.ws.rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
+ wsi->u.ws.rx_user_buffer_head, LWS_WRITE_PONG);
handled = 1;
break;
case LWS_WS_OPCODE_07__PONG:
lwsl_info("client receied pong\n");
- lwsl_hexdump(&wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
- wsi->rx_user_buffer_head);
+ lwsl_hexdump(&wsi->u.ws.rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
+ wsi->u.ws.rx_user_buffer_head);
/* keep the statistics... */
- wsi->pings_vs_pongs--;
+ wsi->u.ws.pings_vs_pongs--;
/* issue it */
callback_action = LWS_CALLBACK_CLIENT_RECEIVE_PONG;
default:
- lwsl_parser("Reserved opcode 0x%2X\n", wsi->opcode);
+ lwsl_parser("Reserved opcode 0x%2X\n", wsi->u.ws.opcode);
#ifndef LWS_NO_EXTENSIONS
/*
* It's something special we can't understand here.
* state machine.
*/
- eff_buf.token = &wsi->rx_user_buffer[
+ eff_buf.token = &wsi->u.ws.rx_user_buffer[
LWS_SEND_BUFFER_PRE_PADDING];
- eff_buf.token_len = wsi->rx_user_buffer_head;
+ eff_buf.token_len = wsi->u.ws.rx_user_buffer_head;
for (n = 0; n < wsi->count_active_extensions; n++) {
m = wsi->active_extensions[n]->callback(
{
#endif
lwsl_ext("Unhandled extended opcode "
- "0x%x - ignoring frame\n", wsi->opcode);
- wsi->rx_user_buffer_head = 0;
+ "0x%x - ignoring frame\n", wsi->u.ws.opcode);
+ wsi->u.ws.rx_user_buffer_head = 0;
return 0;
}
if (handled)
goto already_done;
- eff_buf.token = &wsi->rx_user_buffer[
+ eff_buf.token = &wsi->u.ws.rx_user_buffer[
LWS_SEND_BUFFER_PRE_PADDING];
- eff_buf.token_len = wsi->rx_user_buffer_head;
+ eff_buf.token_len = wsi->u.ws.rx_user_buffer_head;
#ifndef LWS_NO_EXTENSIONS
for (n = 0; n < wsi->count_active_extensions; n++) {
m = wsi->active_extensions[n]->callback(
}
}
already_done:
- wsi->rx_user_buffer_head = 0;
+ wsi->u.ws.rx_user_buffer_head = 0;
break;
default:
lwsl_err("client rx illegal state\n");
return 0;
}
- wsi->parser_state = WSI_TOKEN_NAME_PART;
- wsi->lextable_pos = 0;
+ wsi->u.hdr.parser_state = WSI_TOKEN_NAME_PART;
+ wsi->u.hdr.lextable_pos = 0;
wsi->mode = LWS_CONNMODE_WS_CLIENT_WAITING_SERVER_REPLY;
libwebsocket_set_timeout(wsi,
PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE, AWAITING_TIMEOUT);
*/
len = 1;
- while (wsi->parser_state != WSI_PARSING_COMPLETE && len > 0) {
+ while (wsi->u.hdr.parser_state != WSI_PARSING_COMPLETE && len > 0) {
#ifdef LWS_OPENSSL_SUPPORT
if (wsi->use_ssl)
len = SSL_read(wsi->ssl, &c, 1);
* not complete just wait for next packet coming in this state
*/
- if (wsi->parser_state != WSI_PARSING_COMPLETE)
+ if (wsi->u.hdr.parser_state != WSI_PARSING_COMPLETE)
break;
/*
*/
if (strcmp(wsi->utf8_token[WSI_TOKEN_ACCEPT].token,
- wsi->initial_handshake_hash_base64)) {
+ wsi->u.hdr.initial_handshake_hash_base64)) {
lwsl_warn("libwebsocket_client_handshake server "
"sent bad ACCEPT '%s' vs computed '%s'\n",
wsi->utf8_token[WSI_TOKEN_ACCEPT].token,
- wsi->initial_handshake_hash_base64);
+ wsi->u.hdr.initial_handshake_hash_base64);
goto bail2;
}
wsi->state = WSI_STATE_ESTABLISHED;
wsi->mode = LWS_CONNMODE_WS_CLIENT;
+ /* union transition */
+ memset(&wsi->u, 0, sizeof wsi->u);
+
lwsl_debug("handshake OK for protocol %s\n", wsi->protocol->name);
/* call him back to inform him he is up */
SHA1(buf, strlen((char *)buf), (unsigned char *)hash);
lws_b64_encode_string(hash, 20,
- wsi->initial_handshake_hash_base64,
- sizeof wsi->initial_handshake_hash_base64);
+ wsi->u.hdr.initial_handshake_hash_base64,
+ sizeof wsi->u.hdr.initial_handshake_hash_base64);
/* done with these now */
break;
case LWS_EXT_CALLBACK_PAYLOAD_RX:
- if (!(wsi->rsv & 0x40))
+ if (!(wsi->u.ws.rsv & 0x40))
return 0;
/*
*/
current_payload = eff_buf->token_len;
- remaining_payload = wsi->rx_packet_length;
+ remaining_payload = wsi->u.ws.rx_packet_length;
if (remaining_payload) {
total_payload = conn->buf_pre_used +
current_payload +
case WSI_STATE_HTTP_ISSUING_FILE:
case WSI_STATE_HTTP:
wsi->state = WSI_STATE_HTTP_HEADERS;
- wsi->parser_state = WSI_TOKEN_NAME_PART;
- wsi->lextable_pos = 0;
+ wsi->u.hdr.parser_state = WSI_TOKEN_NAME_PART;
+ wsi->u.hdr.lextable_pos = 0;
/* fallthru */
case WSI_STATE_HTTP_HEADERS:
for (n = 0; n < len; n++)
libwebsocket_parse(wsi, *buf++);
- if (wsi->parser_state != WSI_PARSING_COMPLETE)
+ if (wsi->u.hdr.parser_state != WSI_PARSING_COMPLETE)
break;
lwsl_parser("seem to be serving, mode is %d\n", wsi->mode);
wsi->mode = LWS_CONNMODE_WS_SERVING;
+ /* union transition */
+ memset(&wsi->u, 0, sizeof wsi->u);
+
lwsl_parser("accepted v%02d connection\n",
wsi->ietf_spec_revision);
#endif
if (old_state == WSI_STATE_DEAD_SOCKET)
return;
- wsi->close_reason = reason;
+ wsi->u.ws.close_reason = reason;
#ifndef LWS_NO_EXTENSIONS
/*
if (wsi->c_address)
free(wsi->c_address);
#endif
- if (wsi->rxflow_buffer)
- free(wsi->rxflow_buffer);
+ if (wsi->u.ws.rxflow_buffer)
+ free(wsi->u.ws.rxflow_buffer);
/* lwsl_info("closing fd=%d\n", wsi->sock); */
struct libwebsocket_context *context = wsi->protocol->owning_server;
int n;
- if (!(wsi->rxflow_change_to & 2))
+ if (!(wsi->u.ws.rxflow_change_to & 2))
return 0;
- wsi->rxflow_change_to &= ~2;
+ wsi->u.ws.rxflow_change_to &= ~2;
- lwsl_info("rxflow: wsi %p change_to %d\n", wsi, wsi->rxflow_change_to);
+ lwsl_info("rxflow: wsi %p change_to %d\n", wsi, wsi->u.ws.rxflow_change_to);
/* if we're letting it come again, did we interrupt anything? */
- if ((wsi->rxflow_change_to & 1) && wsi->rxflow_buffer) {
+ if ((wsi->u.ws.rxflow_change_to & 1) && wsi->u.ws.rxflow_buffer) {
n = libwebsocket_interpret_incoming_packet(wsi, NULL, 0);
if (n < 0) {
libwebsocket_close_and_free_session(context, wsi, LWS_CLOSE_STATUS_NOSTATUS);
return 0;
}
- if (wsi->rxflow_change_to & 1)
+ if (wsi->u.ws.rxflow_change_to & 1)
context->fds[wsi->position_in_fds_table].events |= POLLIN;
else
context->fds[wsi->position_in_fds_table].events &= ~POLLIN;
- if (wsi->rxflow_change_to & 1)
+ if (wsi->u.ws.rxflow_change_to & 1)
/* external POLL support via protocol 0 */
context->protocols[0].callback(context, wsi,
LWS_CALLBACK_SET_MODE_POLL_FD,
int
libwebsocket_rx_flow_control(struct libwebsocket *wsi, int enable)
{
- wsi->rxflow_change_to = 2 | !!enable;
+ wsi->u.ws.rxflow_change_to = 2 | !!enable;
return 0;
}
int
libwebsocket_is_final_fragment(struct libwebsocket *wsi)
{
- return wsi->final;
+ return wsi->u.ws.final;
}
unsigned char
libwebsocket_get_reserved_bits(struct libwebsocket *wsi)
{
- return wsi->rsv;
+ return wsi->u.ws.rsv;
}
void *
/* fetch the per-frame nonce */
n = libwebsockets_get_random(wsi->protocol->owning_server,
- wsi->frame_masking_nonce_04, 4);
+ wsi->u.ws.frame_masking_nonce_04, 4);
if (n != 4) {
lwsl_parser("Unable to read from random device %s %d\n",
SYSTEM_RANDOM_FILEPATH, n);
}
/* start masking from first byte of masking key buffer */
- wsi->frame_mask_index = 0;
+ wsi->u.ws.frame_mask_index = 0;
return 0;
}
* we can do this because we demand post-buf
*/
- if (wsi->close_reason) {
+ if (wsi->u.ws.close_reason) {
/* reason codes count as data bytes */
buf -= 2;
- buf[0] = wsi->close_reason >> 8;
- buf[1] = wsi->close_reason;
+ buf[0] = wsi->u.ws.close_reason >> 8;
+ buf[1] = wsi->u.ws.close_reason;
len += 2;
}
break;
case LWS_WRITE_PING:
n = LWS_WS_OPCODE_07__PING;
- wsi->pings_vs_pongs++;
+ wsi->u.ws.pings_vs_pongs++;
break;
case LWS_WRITE_PONG:
n = LWS_WS_OPCODE_07__PONG;
* in v7, just mask the payload
*/
for (n = 4; n < (int)len + 4; n++)
- dropmask[n] = dropmask[n] ^ wsi->frame_masking_nonce_04[(wsi->frame_mask_index++) & 3];
+ dropmask[n] = dropmask[n] ^ wsi->u.ws.frame_masking_nonce_04[(wsi->u.ws.frame_mask_index++) & 3];
if (dropmask)
/* copy the frame nonce into place */
memcpy(dropmask,
- wsi->frame_masking_nonce_04, 4);
+ wsi->u.ws.frame_masking_nonce_04, 4);
}
send_raw:
char *p = buf;
int n, m;
- strncpy(wsi->filepath, file, sizeof wsi->filepath);
- wsi->filepath[sizeof(wsi->filepath) - 1] = '\0';
+ strncpy(wsi->u.http.filepath, file, sizeof wsi->u.http.filepath);
+ wsi->u.http.filepath[sizeof(wsi->u.http.filepath) - 1] = '\0';
#ifdef WIN32
- fd = open(wsi->filepath, O_RDONLY | _O_BINARY);
+ fd = open(wsi->u.http.filepath, O_RDONLY | _O_BINARY);
#else
- fd = open(wsi->filepath, O_RDONLY);
+ fd = open(wsi->u.http.filepath, O_RDONLY);
#endif
if (fd < 1) {
p += sprintf(p, "HTTP/1.0 400 Bad\x0d\x0a"
}
fstat(fd, &stat_buf);
- wsi->filelen = stat_buf.st_size;
+ wsi->u.http.filelen = stat_buf.st_size;
p += sprintf(p, "HTTP/1.0 200 OK\x0d\x0a"
"Server: libwebsockets\x0d\x0a"
"Content-Type: %s\x0d\x0a"
return n;
}
- wsi->filepos = 0;
+ wsi->u.http.filepos = 0;
wsi->state = WSI_STATE_HTTP_ISSUING_FILE;
while (!lws_send_pipe_choked(wsi)) {
n = read(fd, buf, sizeof buf);
if (n > 0) {
- wsi->filepos += n;
+ wsi->u.http.filepos += n;
m = libwebsocket_write(wsi, (unsigned char *)buf, n, LWS_WRITE_HTTP);
if (m) {
close(fd);
return -1;
}
- if (n < sizeof(buf) || wsi->filepos == wsi->filelen) {
+ if (n < sizeof(buf) || wsi->u.http.filepos == wsi->u.http.filelen) {
/* oh, we were able to finish here! */
wsi->state = WSI_STATE_HTTP;
close(fd);
if (wsi->protocol->callback(context, wsi, LWS_CALLBACK_HTTP_FILE_COMPLETION, wsi->user_space,
- wsi->filepath, wsi->filepos)) {
+ wsi->u.http.filepath, wsi->u.http.filepos)) {
lwsl_info("closing connecton after file_completion returned nonzero\n");
libwebsocket_close_and_free_session(context, wsi, LWS_CLOSE_STATUS_NOSTATUS);
}
int n;
#ifdef WIN32
- fd = open(wsi->filepath, O_RDONLY | _O_BINARY);
+ fd = open(wsi->u.http.filepath, O_RDONLY | _O_BINARY);
#else
- fd = open(wsi->filepath, O_RDONLY);
+ fd = open(wsi->u.http.filepath, O_RDONLY);
#endif
if (fd < 1)
return -1;
- lseek(fd, wsi->filepos, SEEK_SET);
+ lseek(fd, wsi->u.http.filepos, SEEK_SET);
while (!lws_send_pipe_choked(wsi)) {
n = read(fd, buf, sizeof buf);
if (n > 0) {
libwebsocket_write(wsi, (unsigned char *)buf, n, LWS_WRITE_HTTP);
- wsi->filepos += n;
+ wsi->u.http.filepos += n;
}
if (n < 0) {
return -1;
}
- if (n < sizeof(buf) || wsi->filepos == wsi->filelen) {
+ if (n < sizeof(buf) || wsi->u.http.filepos == wsi->u.http.filelen) {
wsi->state = WSI_STATE_HTTP;
close(fd);
return 0;
{
int n;
- switch (wsi->parser_state) {
+ switch (wsi->u.hdr.parser_state) {
case WSI_TOKEN_GET_URI:
case WSI_TOKEN_HOST:
case WSI_TOKEN_CONNECTION:
case WSI_TOKEN_HTTP:
case WSI_TOKEN_MUXURL:
- lwsl_parser("WSI_TOKEN_(%d) '%c'\n", wsi->parser_state, c);
+ lwsl_parser("WSI_TOKEN_(%d) '%c'\n", wsi->u.hdr.parser_state, c);
/* collect into malloc'd buffers */
/* optional space swallow */
- if (!wsi->utf8_token[wsi->parser_state].token_len && c == ' ')
+ if (!wsi->utf8_token[wsi->u.hdr.parser_state].token_len && c == ' ')
break;
/* special case space terminator for get-uri */
- if (wsi->parser_state == WSI_TOKEN_GET_URI && c == ' ') {
- wsi->utf8_token[wsi->parser_state].token[
- wsi->utf8_token[wsi->parser_state].token_len] = '\0';
-// lwsl_parser("uri '%s'\n", wsi->utf8_token[wsi->parser_state].token);
- wsi->parser_state = WSI_TOKEN_SKIPPING;
+ if (wsi->u.hdr.parser_state == WSI_TOKEN_GET_URI && c == ' ') {
+ wsi->utf8_token[wsi->u.hdr.parser_state].token[
+ wsi->utf8_token[wsi->u.hdr.parser_state].token_len] = '\0';
+// lwsl_parser("uri '%s'\n", wsi->utf8_token[wsi->u.hdr.parser_state].token);
+ wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
break;
}
/* allocate appropriate memory */
- if (wsi->utf8_token[wsi->parser_state].token_len ==
- wsi->current_alloc_len - 1) {
+ if (wsi->utf8_token[wsi->u.hdr.parser_state].token_len ==
+ wsi->u.hdr.current_alloc_len - 1) {
/* need to extend */
- wsi->current_alloc_len += LWS_ADDITIONAL_HDR_ALLOC;
- if (wsi->current_alloc_len >= LWS_MAX_HEADER_LEN) {
+ wsi->u.hdr.current_alloc_len += LWS_ADDITIONAL_HDR_ALLOC;
+ if (wsi->u.hdr.current_alloc_len >= LWS_MAX_HEADER_LEN) {
/* it's waaay to much payload, fail it */
- strcpy(wsi->utf8_token[wsi->parser_state].token,
+ strcpy(wsi->utf8_token[wsi->u.hdr.parser_state].token,
"!!! Length exceeded maximum supported !!!");
- wsi->parser_state = WSI_TOKEN_SKIPPING;
+ wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
break;
}
- wsi->utf8_token[wsi->parser_state].token = (char *)
- realloc(wsi->utf8_token[wsi->parser_state].token,
- wsi->current_alloc_len);
- if (wsi->utf8_token[wsi->parser_state].token == NULL) {
+ wsi->utf8_token[wsi->u.hdr.parser_state].token = (char *)
+ realloc(wsi->utf8_token[wsi->u.hdr.parser_state].token,
+ wsi->u.hdr.current_alloc_len);
+ if (wsi->utf8_token[wsi->u.hdr.parser_state].token == NULL) {
lwsl_err("Out of mem\n");
return -1;
}
}
/* bail at EOL */
- if (wsi->parser_state != WSI_TOKEN_CHALLENGE && c == '\x0d') {
- wsi->utf8_token[wsi->parser_state].token[
- wsi->utf8_token[wsi->parser_state].token_len] = '\0';
- wsi->parser_state = WSI_TOKEN_SKIPPING_SAW_CR;
+ if (wsi->u.hdr.parser_state != WSI_TOKEN_CHALLENGE && c == '\x0d') {
+ wsi->utf8_token[wsi->u.hdr.parser_state].token[
+ wsi->utf8_token[wsi->u.hdr.parser_state].token_len] = '\0';
+ wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING_SAW_CR;
lwsl_parser("*\n");
break;
}
- wsi->utf8_token[wsi->parser_state].token[
- wsi->utf8_token[wsi->parser_state].token_len++] = c;
+ wsi->utf8_token[wsi->u.hdr.parser_state].token[
+ wsi->utf8_token[wsi->u.hdr.parser_state].token_len++] = c;
/* per-protocol end of headers management */
- if (wsi->parser_state != WSI_TOKEN_CHALLENGE)
+ if (wsi->u.hdr.parser_state != WSI_TOKEN_CHALLENGE)
break;
/* -76 has no version header ... server */
if (!wsi->utf8_token[WSI_TOKEN_VERSION].token_len &&
wsi->mode != LWS_CONNMODE_WS_CLIENT_WAITING_SERVER_REPLY &&
- wsi->utf8_token[wsi->parser_state].token_len != 8)
+ wsi->utf8_token[wsi->u.hdr.parser_state].token_len != 8)
break;
/* -76 has no version header ... client */
if (!wsi->utf8_token[WSI_TOKEN_VERSION].token_len &&
wsi->mode == LWS_CONNMODE_WS_CLIENT_WAITING_SERVER_REPLY &&
- wsi->utf8_token[wsi->parser_state].token_len != 16)
+ wsi->utf8_token[wsi->u.hdr.parser_state].token_len != 16)
break;
/* <= 03 has old handshake with version header needs 8 bytes */
if (wsi->utf8_token[WSI_TOKEN_VERSION].token_len &&
atoi(wsi->utf8_token[WSI_TOKEN_VERSION].token) < 4 &&
- wsi->utf8_token[wsi->parser_state].token_len != 8)
+ wsi->utf8_token[wsi->u.hdr.parser_state].token_len != 8)
break;
/* no payload challenge in 01 + */
/* For any supported protocol we have enough payload */
lwsl_parser("Setting WSI_PARSING_COMPLETE\n");
- wsi->parser_state = WSI_PARSING_COMPLETE;
+ wsi->u.hdr.parser_state = WSI_PARSING_COMPLETE;
break;
case WSI_INIT_TOKEN_MUXURL:
- wsi->parser_state = WSI_TOKEN_MUXURL;
- wsi->current_alloc_len = LWS_INITIAL_HDR_ALLOC;
+ wsi->u.hdr.parser_state = WSI_TOKEN_MUXURL;
+ wsi->u.hdr.current_alloc_len = LWS_INITIAL_HDR_ALLOC;
- wsi->utf8_token[wsi->parser_state].token = (char *)
- malloc(wsi->current_alloc_len);
- if (wsi->utf8_token[wsi->parser_state].token == NULL) {
+ wsi->utf8_token[wsi->u.hdr.parser_state].token = (char *)
+ malloc(wsi->u.hdr.current_alloc_len);
+ if (wsi->utf8_token[wsi->u.hdr.parser_state].token == NULL) {
lwsl_err("Out of mem\n");
return -1;
}
- wsi->utf8_token[wsi->parser_state].token_len = 0;
+ wsi->utf8_token[wsi->u.hdr.parser_state].token_len = 0;
break;
/* collecting and checking a name part */
case WSI_TOKEN_NAME_PART:
lwsl_parser("WSI_TOKEN_NAME_PART '%c'\n", c);
- if (wsi->name_buffer_pos == sizeof(wsi->name_buffer) - 1) {
+ if (wsi->u.hdr.name_buffer_pos == sizeof(wsi->u.hdr.name_buffer) - 1) {
/* name bigger than we can handle, skip until next */
- wsi->parser_state = WSI_TOKEN_SKIPPING;
+ wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
break;
}
- wsi->name_buffer[wsi->name_buffer_pos++] = c;
- wsi->name_buffer[wsi->name_buffer_pos] = '\0';
+ wsi->u.hdr.name_buffer[wsi->u.hdr.name_buffer_pos++] = c;
+ wsi->u.hdr.name_buffer[wsi->u.hdr.name_buffer_pos] = '\0';
- wsi->lextable_pos = lextable_decode(wsi->lextable_pos, c);
- if (lextable[wsi->lextable_pos + 1] == 0) {
+ wsi->u.hdr.lextable_pos = lextable_decode(wsi->u.hdr.lextable_pos, c);
+ if (lextable[wsi->u.hdr.lextable_pos + 1] == 0) {
- n = lextable[wsi->lextable_pos] & 0x7f;
+ n = lextable[wsi->u.hdr.lextable_pos] & 0x7f;
- lwsl_parser("known hdr '%s'\n", wsi->name_buffer);
+ lwsl_parser("known hdr '%s'\n", wsi->u.hdr.name_buffer);
/*
* WSORIGIN is protocol equiv to ORIGIN,
if (n == WSI_TOKEN_SWORIGIN)
n = WSI_TOKEN_ORIGIN;
- wsi->parser_state = (enum lws_token_indexes) (WSI_TOKEN_GET_URI + n);
+ wsi->u.hdr.parser_state = (enum lws_token_indexes) (WSI_TOKEN_GET_URI + n);
n = WSI_TOKEN_COUNT;
/* If the header has been seen already, just append */
- if (!wsi->utf8_token[wsi->parser_state].token) {
+ if (!wsi->utf8_token[wsi->u.hdr.parser_state].token) {
- wsi->current_alloc_len = LWS_INITIAL_HDR_ALLOC;
- wsi->utf8_token[wsi->parser_state].token = (char *)
- malloc(wsi->current_alloc_len);
- if (wsi->utf8_token[wsi->parser_state].token == NULL) {
+ wsi->u.hdr.current_alloc_len = LWS_INITIAL_HDR_ALLOC;
+ wsi->utf8_token[wsi->u.hdr.parser_state].token = (char *)
+ malloc(wsi->u.hdr.current_alloc_len);
+ if (wsi->utf8_token[wsi->u.hdr.parser_state].token == NULL) {
lwsl_err("Out of mem\n");
return -1;
}
- wsi->utf8_token[wsi->parser_state].token_len = 0;
+ wsi->utf8_token[wsi->u.hdr.parser_state].token_len = 0;
}
}
/* colon delimiter means we just don't know this name */
- if (wsi->parser_state == WSI_TOKEN_NAME_PART) {
+ if (wsi->u.hdr.parser_state == WSI_TOKEN_NAME_PART) {
if (c == ':') {
lwsl_parser("skipping unknown header '%s'\n",
- wsi->name_buffer);
- wsi->parser_state = WSI_TOKEN_SKIPPING;
+ wsi->u.hdr.name_buffer);
+ wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
break;
}
if (c == ' ' &&
!wsi->utf8_token[WSI_TOKEN_GET_URI].token_len) {
lwsl_parser("unknown method '%s'\n",
- wsi->name_buffer);
- wsi->parser_state = WSI_TOKEN_GET_URI;
- wsi->current_alloc_len = LWS_INITIAL_HDR_ALLOC;
+ wsi->u.hdr.name_buffer);
+ wsi->u.hdr.parser_state = WSI_TOKEN_GET_URI;
+ wsi->u.hdr.current_alloc_len = LWS_INITIAL_HDR_ALLOC;
wsi->utf8_token[WSI_TOKEN_GET_URI].token =
- (char *)malloc(wsi->current_alloc_len);
+ (char *)malloc(wsi->u.hdr.current_alloc_len);
if (wsi->utf8_token[WSI_TOKEN_GET_URI].token == NULL) {
lwsl_err("Out of mem\n");
return -1;
}
}
- if (wsi->parser_state != WSI_TOKEN_CHALLENGE)
+ if (wsi->u.hdr.parser_state != WSI_TOKEN_CHALLENGE)
break;
/* don't look for payload when it can just be http headers */
/* they're HTTP headers, not websocket upgrade! */
lwsl_parser("Setting WSI_PARSING_COMPLETE "
"from http headers\n");
- wsi->parser_state = WSI_PARSING_COMPLETE;
+ wsi->u.hdr.parser_state = WSI_PARSING_COMPLETE;
}
/* 04 version has no packet content after end of hdrs */
if (wsi->utf8_token[WSI_TOKEN_VERSION].token_len &&
atoi(wsi->utf8_token[WSI_TOKEN_VERSION].token) >= 4) {
lwsl_parser("04 header completed\n");
- wsi->parser_state = WSI_PARSING_COMPLETE;
+ wsi->u.hdr.parser_state = WSI_PARSING_COMPLETE;
wsi->utf8_token[WSI_TOKEN_CHALLENGE].token_len = 0;
free(wsi->utf8_token[WSI_TOKEN_CHALLENGE].token);
wsi->utf8_token[WSI_TOKEN_CHALLENGE].token = NULL;
/* client parser? */
lwsl_parser("04 header completed\n");
- wsi->parser_state = WSI_PARSING_COMPLETE;
+ wsi->u.hdr.parser_state = WSI_PARSING_COMPLETE;
break;
case WSI_TOKEN_SKIPPING:
lwsl_parser("WSI_TOKEN_SKIPPING '%c'\n", c);
if (c == '\x0d')
- wsi->parser_state = WSI_TOKEN_SKIPPING_SAW_CR;
+ wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING_SAW_CR;
break;
case WSI_TOKEN_SKIPPING_SAW_CR:
lwsl_parser("WSI_TOKEN_SKIPPING_SAW_CR '%c'\n", c);
if (c == '\x0a') {
- wsi->parser_state = WSI_TOKEN_NAME_PART;
- wsi->lextable_pos = 0;
+ wsi->u.hdr.parser_state = WSI_TOKEN_NAME_PART;
+ wsi->u.hdr.lextable_pos = 0;
} else
- wsi->parser_state = WSI_TOKEN_SKIPPING;
- wsi->name_buffer_pos = 0;
+ wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
+ wsi->u.hdr.name_buffer_pos = 0;
break;
/* we're done, ignore anything else */
case WSI_PARSING_COMPLETE:
int lws_frame_is_binary(struct libwebsocket *wsi)
{
- return wsi->frame_is_binary;
+ return wsi->u.ws.frame_is_binary;
}
int
/*
* no prepended frame key any more
*/
- wsi->all_zero_nonce = 1;
+ wsi->u.ws.all_zero_nonce = 1;
goto handle_first;
default:
}
break;
case LWS_RXPS_04_MASK_NONCE_1:
- wsi->frame_masking_nonce_04[1] = c;
+ wsi->u.ws.frame_masking_nonce_04[1] = c;
if (c)
- wsi->all_zero_nonce = 0;
+ wsi->u.ws.all_zero_nonce = 0;
wsi->lws_rx_parse_state = LWS_RXPS_04_MASK_NONCE_2;
break;
case LWS_RXPS_04_MASK_NONCE_2:
- wsi->frame_masking_nonce_04[2] = c;
+ wsi->u.ws.frame_masking_nonce_04[2] = c;
if (c)
- wsi->all_zero_nonce = 0;
+ wsi->u.ws.all_zero_nonce = 0;
wsi->lws_rx_parse_state = LWS_RXPS_04_MASK_NONCE_3;
break;
case LWS_RXPS_04_MASK_NONCE_3:
- wsi->frame_masking_nonce_04[3] = c;
+ wsi->u.ws.frame_masking_nonce_04[3] = c;
if (c)
- wsi->all_zero_nonce = 0;
+ wsi->u.ws.all_zero_nonce = 0;
/*
* start from the zero'th byte in the XOR key buffer since
* this is the start of a frame with a new key
*/
- wsi->frame_mask_index = 0;
+ wsi->u.ws.frame_mask_index = 0;
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_1;
break;
* FIN (b7)
*/
- wsi->opcode = c & 0xf;
- wsi->rsv = c & 0x70;
- wsi->final = !!((c >> 7) & 1);
- switch (wsi->opcode) {
+ wsi->u.ws.opcode = c & 0xf;
+ wsi->u.ws.rsv = c & 0x70;
+ wsi->u.ws.final = !!((c >> 7) & 1);
+ switch (wsi->u.ws.opcode) {
case LWS_WS_OPCODE_07__TEXT_FRAME:
case LWS_WS_OPCODE_07__BINARY_FRAME:
- wsi->frame_is_binary = wsi->opcode == LWS_WS_OPCODE_07__BINARY_FRAME;
+ wsi->u.ws.frame_is_binary = wsi->u.ws.opcode == LWS_WS_OPCODE_07__BINARY_FRAME;
break;
}
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN;
case LWS_RXPS_04_FRAME_HDR_LEN:
- wsi->this_frame_masked = !!(c & 0x80);
+ wsi->u.ws.this_frame_masked = !!(c & 0x80);
switch (c & 0x7f) {
case 126:
/* control frames are not allowed to have big lengths */
- if (wsi->opcode & 8)
+ if (wsi->u.ws.opcode & 8)
goto illegal_ctl_length;
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_2;
break;
case 127:
/* control frames are not allowed to have big lengths */
- if (wsi->opcode & 8)
+ if (wsi->u.ws.opcode & 8)
goto illegal_ctl_length;
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_8;
break;
default:
- wsi->rx_packet_length = c & 0x7f;
- if (wsi->this_frame_masked)
+ wsi->u.ws.rx_packet_length = c & 0x7f;
+ if (wsi->u.ws.this_frame_masked)
wsi->lws_rx_parse_state =
LWS_RXPS_07_COLLECT_FRAME_KEY_1;
else
break;
case LWS_RXPS_04_FRAME_HDR_LEN16_2:
- wsi->rx_packet_length = c << 8;
+ wsi->u.ws.rx_packet_length = c << 8;
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_1;
break;
case LWS_RXPS_04_FRAME_HDR_LEN16_1:
- wsi->rx_packet_length |= c;
- if (wsi->this_frame_masked)
+ wsi->u.ws.rx_packet_length |= c;
+ if (wsi->u.ws.this_frame_masked)
wsi->lws_rx_parse_state =
LWS_RXPS_07_COLLECT_FRAME_KEY_1;
else
return -1;
}
#if defined __LP64__
- wsi->rx_packet_length = ((size_t)c) << 56;
+ wsi->u.ws.rx_packet_length = ((size_t)c) << 56;
#else
- wsi->rx_packet_length = 0;
+ wsi->u.ws.rx_packet_length = 0;
#endif
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_7;
break;
case LWS_RXPS_04_FRAME_HDR_LEN64_7:
#if defined __LP64__
- wsi->rx_packet_length |= ((size_t)c) << 48;
+ wsi->u.ws.rx_packet_length |= ((size_t)c) << 48;
#endif
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_6;
break;
case LWS_RXPS_04_FRAME_HDR_LEN64_6:
#if defined __LP64__
- wsi->rx_packet_length |= ((size_t)c) << 40;
+ wsi->u.ws.rx_packet_length |= ((size_t)c) << 40;
#endif
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_5;
break;
case LWS_RXPS_04_FRAME_HDR_LEN64_5:
#if defined __LP64__
- wsi->rx_packet_length |= ((size_t)c) << 32;
+ wsi->u.ws.rx_packet_length |= ((size_t)c) << 32;
#endif
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_4;
break;
case LWS_RXPS_04_FRAME_HDR_LEN64_4:
- wsi->rx_packet_length |= ((size_t)c) << 24;
+ wsi->u.ws.rx_packet_length |= ((size_t)c) << 24;
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_3;
break;
case LWS_RXPS_04_FRAME_HDR_LEN64_3:
- wsi->rx_packet_length |= ((size_t)c) << 16;
+ wsi->u.ws.rx_packet_length |= ((size_t)c) << 16;
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_2;
break;
case LWS_RXPS_04_FRAME_HDR_LEN64_2:
- wsi->rx_packet_length |= ((size_t)c) << 8;
+ wsi->u.ws.rx_packet_length |= ((size_t)c) << 8;
wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_1;
break;
case LWS_RXPS_04_FRAME_HDR_LEN64_1:
- wsi->rx_packet_length |= ((size_t)c);
- if (wsi->this_frame_masked)
+ wsi->u.ws.rx_packet_length |= ((size_t)c);
+ if (wsi->u.ws.this_frame_masked)
wsi->lws_rx_parse_state =
LWS_RXPS_07_COLLECT_FRAME_KEY_1;
else
break;
case LWS_RXPS_07_COLLECT_FRAME_KEY_1:
- wsi->frame_masking_nonce_04[0] = c;
+ wsi->u.ws.frame_masking_nonce_04[0] = c;
if (c)
- wsi->all_zero_nonce = 0;
+ wsi->u.ws.all_zero_nonce = 0;
wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_2;
break;
case LWS_RXPS_07_COLLECT_FRAME_KEY_2:
- wsi->frame_masking_nonce_04[1] = c;
+ wsi->u.ws.frame_masking_nonce_04[1] = c;
if (c)
- wsi->all_zero_nonce = 0;
+ wsi->u.ws.all_zero_nonce = 0;
wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_3;
break;
case LWS_RXPS_07_COLLECT_FRAME_KEY_3:
- wsi->frame_masking_nonce_04[2] = c;
+ wsi->u.ws.frame_masking_nonce_04[2] = c;
if (c)
- wsi->all_zero_nonce = 0;
+ wsi->u.ws.all_zero_nonce = 0;
wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_4;
break;
case LWS_RXPS_07_COLLECT_FRAME_KEY_4:
- wsi->frame_masking_nonce_04[3] = c;
+ wsi->u.ws.frame_masking_nonce_04[3] = c;
if (c)
- wsi->all_zero_nonce = 0;
+ wsi->u.ws.all_zero_nonce = 0;
wsi->lws_rx_parse_state =
LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED;
- wsi->frame_mask_index = 0;
+ wsi->u.ws.frame_mask_index = 0;
break;
case LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED:
- if (wsi->all_zero_nonce)
- wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
- (wsi->rx_user_buffer_head++)] = c;
+ 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;
else
- wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
- (wsi->rx_user_buffer_head++)] =
- c ^ wsi->frame_masking_nonce_04[(wsi->frame_mask_index++) & 3];
+ wsi->u.ws.rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING +
+ (wsi->u.ws.rx_user_buffer_head++)] =
+ c ^ wsi->u.ws.frame_masking_nonce_04[(wsi->u.ws.frame_mask_index++) & 3];
- if (--wsi->rx_packet_length == 0) {
+ if (--wsi->u.ws.rx_packet_length == 0) {
wsi->lws_rx_parse_state = LWS_RXPS_NEW;
goto spill;
}
- if (wsi->rx_user_buffer_head != MAX_USER_RX_BUFFER)
+ if (wsi->u.ws.rx_user_buffer_head != MAX_USER_RX_BUFFER)
break;
spill:
/*
lwsl_parser("spill on %s\n", wsi->protocol->name);
- switch (wsi->opcode) {
+ switch (wsi->u.ws.opcode) {
case LWS_WS_OPCODE_07__CLOSE:
/* is this an acknowledgement of our close? */
if (wsi->state == WSI_STATE_AWAITING_CLOSE_ACK) {
lwsl_parser("server sees client close packet\n");
/* parrot the close packet payload back */
n = libwebsocket_write(wsi, (unsigned char *)
- &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
- wsi->rx_user_buffer_head, LWS_WRITE_CLOSE);
+ &wsi->u.ws.rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING],
+ wsi->u.ws.rx_user_buffer_head, LWS_WRITE_CLOSE);
if (n)
lwsl_info("write of close ack failed %d\n", n);
wsi->state = WSI_STATE_RETURNED_CLOSE_ALREADY;
return -1;
case LWS_WS_OPCODE_07__PING:
- lwsl_info("received %d byte ping, sending pong\n", wsi->rx_user_buffer_head);
- lwsl_hexdump(&wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING], wsi->rx_user_buffer_head);
+ lwsl_info("received %d byte ping, sending pong\n", wsi->u.ws.rx_user_buffer_head);
+ lwsl_hexdump(&wsi->u.ws.rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING], wsi->u.ws.rx_user_buffer_head);
/* parrot the ping packet payload back as a pong */
n = libwebsocket_write(wsi, (unsigned char *)
- &wsi->rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING], wsi->rx_user_buffer_head, LWS_WRITE_PONG);
+ &wsi->u.ws.rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING], wsi->u.ws.rx_user_buffer_head, LWS_WRITE_PONG);
/* ... then just drop it */
- wsi->rx_user_buffer_head = 0;
+ wsi->u.ws.rx_user_buffer_head = 0;
return 0;
case LWS_WS_OPCODE_07__PONG:
/* keep the statistics... */
- wsi->pings_vs_pongs--;
+ wsi->u.ws.pings_vs_pongs--;
/* ... then just drop it */
- wsi->rx_user_buffer_head = 0;
+ wsi->u.ws.rx_user_buffer_head = 0;
return 0;
case LWS_WS_OPCODE_07__TEXT_FRAME:
default:
#ifndef LWS_NO_EXTENSIONS
- lwsl_parser("passing opcode %x up to exts\n", wsi->opcode);
+ lwsl_parser("passing opcode %x up to exts\n", wsi->u.ws.opcode);
/*
* It's something special we can't understand here.
* state machine.
*/
- eff_buf.token = &wsi->rx_user_buffer[
+ eff_buf.token = &wsi->u.ws.rx_user_buffer[
LWS_SEND_BUFFER_PRE_PADDING];
- eff_buf.token_len = wsi->rx_user_buffer_head;
+ eff_buf.token_len = wsi->u.ws.rx_user_buffer_head;
handled = 0;
for (n = 0; n < wsi->count_active_extensions; n++) {
if (!handled)
#endif
lwsl_ext("Unhandled extended opcode "
- "0x%x - ignoring frame\n", wsi->opcode);
+ "0x%x - ignoring frame\n", wsi->u.ws.opcode);
- wsi->rx_user_buffer_head = 0;
+ wsi->u.ws.rx_user_buffer_head = 0;
return 0;
}
* so it can be sent straight out again using libwebsocket_write
*/
- eff_buf.token = &wsi->rx_user_buffer[
+ eff_buf.token = &wsi->u.ws.rx_user_buffer[
LWS_SEND_BUFFER_PRE_PADDING];
- eff_buf.token_len = wsi->rx_user_buffer_head;
+ eff_buf.token_len = wsi->u.ws.rx_user_buffer_head;
#ifndef LWS_NO_EXTENSIONS
for (n = 0; n < wsi->count_active_extensions; n++) {
m = wsi->active_extensions[n]->callback(
lwsl_err("No callback on payload spill!\n");
}
- wsi->rx_user_buffer_head = 0;
+ wsi->u.ws.rx_user_buffer_head = 0;
break;
}
{
size_t n;
int m;
- int clear_rxflow = !!wsi->rxflow_buffer;
+ int clear_rxflow = !!wsi->u.ws.rxflow_buffer;
struct libwebsocket_context *context = wsi->protocol->owning_server;
#if 0
lwsl_hexdump(buf, len);
#endif
- if (buf && wsi->rxflow_buffer)
+ if (buf && wsi->u.ws.rxflow_buffer)
lwsl_err("!!!! libwebsocket_interpret_incoming_packet: was pending rxflow, data loss\n");
/* let the rx protocol state machine have as much as it needs */
n = 0;
if (!buf) {
- lwsl_info("dumping stored rxflow buffer len %d pos=%d\n", wsi->rxflow_len, wsi->rxflow_pos);
- buf = wsi->rxflow_buffer;
- n = wsi->rxflow_pos;
- len = wsi->rxflow_len;
+ lwsl_info("dumping stored rxflow buffer len %d pos=%d\n", wsi->u.ws.rxflow_len, wsi->u.ws.rxflow_pos);
+ buf = wsi->u.ws.rxflow_buffer;
+ n = wsi->u.ws.rxflow_pos;
+ len = wsi->u.ws.rxflow_len;
/* let's pretend he's already allowing input */
context->fds[wsi->position_in_fds_table].events |= POLLIN;
}
while (n < len) {
if (!(context->fds[wsi->position_in_fds_table].events & POLLIN)) {
/* his RX is flowcontrolled */
- if (!wsi->rxflow_buffer) { /* a new rxflow in effect, buffer it and warn caller */
+ if (!wsi->u.ws.rxflow_buffer) { /* a new rxflow in effect, buffer it and warn caller */
lwsl_info("new rxflow input buffer len %d\n", len - n);
- wsi->rxflow_buffer = (unsigned char *)malloc(len - n);
- wsi->rxflow_len = len - n;
- wsi->rxflow_pos = 0;
- memcpy(wsi->rxflow_buffer, buf + n, len - n);
+ wsi->u.ws.rxflow_buffer = (unsigned char *)malloc(len - n);
+ wsi->u.ws.rxflow_len = len - n;
+ wsi->u.ws.rxflow_pos = 0;
+ memcpy(wsi->u.ws.rxflow_buffer, buf + n, len - n);
} else {
lwsl_info("re-using rxflow input buffer\n");
/* rxflow while we were spilling previous rxflow buffer */
- wsi->rxflow_pos = n;
+ wsi->u.ws.rxflow_pos = n;
}
return 1;
}
if (clear_rxflow) {
lwsl_info("flow: clearing it\n");
- free(wsi->rxflow_buffer);
- wsi->rxflow_buffer = NULL;
+ free(wsi->u.ws.rxflow_buffer);
+ wsi->u.ws.rxflow_buffer = NULL;
context->fds[wsi->position_in_fds_table].events &= ~POLLIN;
}
size_t
libwebsockets_remaining_packet_payload(struct libwebsocket *wsi)
{
- return wsi->rx_packet_length;
+ return wsi->u.ws.rx_packet_length;
}
* other APIs to get information out of it.
*/
-struct libwebsocket {
- const struct libwebsocket_protocols *protocol;
-#ifndef LWS_NO_EXTENSIONS
- struct libwebsocket_extension *
- active_extensions[LWS_MAX_EXTENSIONS_ACTIVE];
- void *active_extensions_user[LWS_MAX_EXTENSIONS_ACTIVE];
- int count_active_extensions;
- char extension_data_pending;
- struct libwebsocket *extension_handles;
- struct libwebsocket *candidate_children_list;
-#endif
- enum lws_connection_states state;
+struct _lws_http_mode_related {
+ char filepath[PATH_MAX];
+ unsigned long filepos;
+ unsigned long filelen;
+};
+struct _lws_header_related {
char name_buffer[LWS_MAX_HEADER_NAME_LENGTH];
int name_buffer_pos;
int lextable_pos;
- int current_alloc_len;
enum lws_token_indexes parser_state;
- struct lws_tokens utf8_token[WSI_TOKEN_COUNT];
- int ietf_spec_revision;
+ int current_alloc_len;
+#ifndef LWS_NO_CLIENT
+ char initial_handshake_hash_base64[30];
+#endif
+};
+
+struct _lws_websocket_related {
char rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING + MAX_USER_RX_BUFFER +
LWS_SEND_BUFFER_POST_PADDING];
int rx_user_buffer_head;
- enum libwebsocket_write_protocol rx_frame_type;
-#ifndef LWS_NO_FORK
- int protocol_index_for_broadcast_proxy;
-#endif
- enum pending_timeout pending_timeout;
- unsigned long pending_timeout_limit;
-
- int sock;
- int position_in_fds_table;
- unsigned char *rxflow_buffer;
- int rxflow_len;
- int rxflow_pos;
- int rxflow_change_to;
-
- enum lws_rx_parse_state lws_rx_parse_state;
-
- /* 04 protocol specific */
-
unsigned char masking_key_04[20];
unsigned char frame_masking_nonce_04[4];
unsigned char frame_mask_04[20];
unsigned char final;
unsigned char rsv;
int frame_is_binary:1;
-
int pings_vs_pongs;
char all_zero_nonce;
-
enum lws_close_status close_reason;
-
- /* 07 specific */
+ unsigned char *rxflow_buffer;
+ int rxflow_len;
+ int rxflow_pos;
+ int rxflow_change_to;
char this_frame_masked;
+};
+
+struct libwebsocket {
+
+ /* lifetime members */
+
+ const struct libwebsocket_protocols *protocol;
+#ifndef LWS_NO_EXTENSIONS
+ struct libwebsocket_extension *
+ active_extensions[LWS_MAX_EXTENSIONS_ACTIVE];
+ void *active_extensions_user[LWS_MAX_EXTENSIONS_ACTIVE];
+ int count_active_extensions;
+ char extension_data_pending;
+ struct libwebsocket *extension_handles;
+ struct libwebsocket *candidate_children_list;
+#endif
+ int ietf_spec_revision;
enum connection_mode mode;
+ enum lws_connection_states state;
+ enum lws_rx_parse_state lws_rx_parse_state;
+
+ enum pending_timeout pending_timeout;
+ unsigned long pending_timeout_limit;
+
+ int sock;
+ int position_in_fds_table;
+
+ void *user_space;
+
+ /* members with mutually exclusive lifetimes are unionized */
+
+ union u {
+ struct _lws_http_mode_related http;
+ struct _lws_header_related hdr;
+ struct _lws_websocket_related ws;
+ } u;
+
+ struct lws_tokens utf8_token[WSI_TOKEN_COUNT];
+
+ enum libwebsocket_write_protocol rx_frame_type;
+#ifndef LWS_NO_FORK
+ int protocol_index_for_broadcast_proxy;
+#endif
#ifndef LWS_NO_CLIENT
- /* client support */
- char initial_handshake_hash_base64[30];
char *c_path;
char *c_host;
char *c_origin;
SSL *ssl;
BIO *client_bio;
int use_ssl;
-#endif
-
- /* http send file */
- char filepath[PATH_MAX];
- unsigned long filepos;
- unsigned long filelen;
-
- void *user_space;
+#endif
};
extern int
free(response);
wsi->state = WSI_STATE_ESTABLISHED;
wsi->lws_rx_parse_state = LWS_RXPS_NEW;
- wsi->rx_packet_length = 0;
+ wsi->u.ws.rx_packet_length = 0;
/* notify user code that we're ready to roll */
/* intialize the instance struct */
new_wsi->state = WSI_STATE_HTTP;
- new_wsi->name_buffer_pos = 0;
+ new_wsi->u.hdr.name_buffer_pos = 0;
new_wsi->mode = LWS_CONNMODE_HTTP_SERVING;
for (n = 0; n < WSI_TOKEN_COUNT; n++) {
else
if (wsi->state == WSI_STATE_HTTP && wsi->protocol->callback)
if (user_callback_handle_rxflow(wsi->protocol->callback, context, wsi, LWS_CALLBACK_HTTP_FILE_COMPLETION, wsi->user_space,
- wsi->filepath, wsi->filepos))
+ wsi->u.http.filepath, wsi->u.http.filepos))
libwebsocket_close_and_free_session(context, wsi, LWS_CLOSE_STATUS_NOSTATUS);
break;