This commit is contained in:
Andy Green 2017-11-06 10:05:04 +08:00
parent 79d2038fdf
commit ad07d95026
9 changed files with 206 additions and 163 deletions

View file

@ -143,7 +143,8 @@ int lws_h2_configure_if_upgraded(struct lws *wsi)
/* HTTP2 union */
lws_hpack_dynamic_size(wsi, wsi->u.h2.h2n->set.s[H2SET_HEADER_TABLE_SIZE]);
lws_hpack_dynamic_size(wsi,
wsi->u.h2.h2n->set.s[H2SET_HEADER_TABLE_SIZE]);
wsi->u.h2.tx_cr = 65535;
lwsl_info("%s: wsi %p: configured for h2\n", __func__, wsi);

View file

@ -468,7 +468,7 @@ lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason)
case LWSS_AWAITING_CLOSE_ACK:
goto just_kill_connection;
case LWSS_FLUSHING_STORED_SEND_BEFORE_CLOSE:
case LWSS_FLUSHING_SEND_BEFORE_CLOSE:
if (wsi->trunc_len) {
lws_callback_on_writable(wsi);
return;
@ -478,7 +478,7 @@ lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason)
default:
if (wsi->trunc_len) {
lwsl_info("%p: FLUSHING_STORED_SEND_BEFORE_CLOSE\n", wsi);
wsi->state = LWSS_FLUSHING_STORED_SEND_BEFORE_CLOSE;
wsi->state = LWSS_FLUSHING_SEND_BEFORE_CLOSE;
lws_set_timeout(wsi,
PENDING_FLUSH_STORED_SEND_BEFORE_CLOSE, 5);
return;
@ -760,7 +760,7 @@ just_kill_connection:
wsi->state_pre_close == LWSS_RETURNED_CLOSE_ALREADY ||
wsi->state_pre_close == LWSS_AWAITING_CLOSE_ACK ||
wsi->state_pre_close == LWSS_WAITING_TO_SEND_CLOSE_NOTIFICATION ||
wsi->state_pre_close == LWSS_FLUSHING_STORED_SEND_BEFORE_CLOSE ||
wsi->state_pre_close == LWSS_FLUSHING_SEND_BEFORE_CLOSE ||
(wsi->mode == LWSCM_WS_CLIENT &&
wsi->state_pre_close == LWSS_HTTP) ||
(wsi->mode == LWSCM_WS_SERVING &&

View file

@ -206,7 +206,8 @@ lws_ring_consume(struct lws_ring *ring, uint32_t *tail, void *dest,
}
/* n is how many bytes the whole fifo has for us */
n = (int)(lws_ring_get_count_waiting_elements(ring, tail) * ring->element_len);
n = (int)(lws_ring_get_count_waiting_elements(ring, tail) *
ring->element_len);
/* restrict n to how much we want to insert */
if ((size_t)n > max_count * ring->element_len)
@ -284,9 +285,10 @@ lws_ring_dump(struct lws_ring *ring, uint32_t *tail)
{
if (tail == NULL)
tail = &ring->oldest_tail;
lwsl_notice("ring %p: buflen %u, element_len %u, head %u, oldest_tail %u\n"
" free_elements: %u; for tail %u, waiting elements: %u\n",
lwsl_notice("ring %p: buflen %u, elem_len %u, head %u, oldest_tail %u\n"
" free_elems: %u; for tail %u, waiting elements: %u\n",
ring, ring->buflen, ring->element_len, ring->head,
ring->oldest_tail, (int)lws_ring_get_count_free_elements(ring),
*tail, (int)lws_ring_get_count_waiting_elements(ring, tail));
ring->oldest_tail,
(int)lws_ring_get_count_free_elements(ring), *tail,
(int)lws_ring_get_count_waiting_elements(ring, tail));
}

View file

@ -56,7 +56,7 @@ int lws_issue_raw(struct lws *wsi, unsigned char *buf, size_t len)
if (!len)
return 0;
/* just ignore sends after we cleared the truncation buffer */
if (wsi->state == LWSS_FLUSHING_STORED_SEND_BEFORE_CLOSE &&
if (wsi->state == LWSS_FLUSHING_SEND_BEFORE_CLOSE &&
!wsi->trunc_len)
return (int)len;
@ -137,7 +137,7 @@ handle_truncated_send:
lwsl_info("** %p partial send completed\n", wsi);
/* done with it, but don't free it */
n = (int)real_len;
if (wsi->state == LWSS_FLUSHING_STORED_SEND_BEFORE_CLOSE) {
if (wsi->state == LWSS_FLUSHING_SEND_BEFORE_CLOSE) {
lwsl_info("** %p signalling to close now\n", wsi);
return -1; /* retry closing now */
}

View file

@ -575,7 +575,7 @@ enum lws_connection_states {
LWSS_WAITING_TO_SEND_CLOSE_NOTIFICATION,
LWSS_RETURNED_CLOSE_ALREADY,
LWSS_AWAITING_CLOSE_ACK,
LWSS_FLUSHING_STORED_SEND_BEFORE_CLOSE,
LWSS_FLUSHING_SEND_BEFORE_CLOSE,
LWSS_SHUTDOWN,
LWSS_HTTP2_AWAIT_CLIENT_PREFACE,

View file

@ -184,25 +184,28 @@ lws_extension_server_handshake(struct lws *wsi, char **p, int budget)
args++;
po = opts;
while (po->name) {
lwsl_debug("'%s' '%s'\n", po->name, args);
/* only support arg-less options... */
if (po->type == EXTARG_NONE &&
!strncmp(args, po->name,
strlen(po->name))) {
oa.option_name = NULL;
oa.option_index = (int)(po - opts);
oa.start = NULL;
lwsl_debug("setting %s\n", po->name);
if (!ext->callback(
lws_get_context(wsi), ext, wsi,
LWS_EXT_CB_OPTION_SET,
wsi->act_ext_user[
wsi->count_act_ext],
&oa, (end - *p))) {
if (po->type != EXTARG_NONE ||
strncmp(args, po->name,
strlen(po->name))) {
po++;
continue;
}
oa.option_name = NULL;
oa.option_index = (int)(po - opts);
oa.start = NULL;
lwsl_debug("setting %s\n", po->name);
if (!ext->callback(
lws_get_context(wsi), ext, wsi,
LWS_EXT_CB_OPTION_SET,
wsi->act_ext_user[
wsi->count_act_ext],
&oa, (end - *p))) {
*p += lws_snprintf(*p, (end - *p), "; %s", po->name);
lwsl_debug("adding option %s\n", po->name);
}
*p += lws_snprintf(*p, (end - *p),
"; %s", po->name);
lwsl_debug("adding option %s\n",
po->name);
}
po++;
}
@ -211,8 +214,7 @@ lws_extension_server_handshake(struct lws *wsi, char **p, int budget)
}
wsi->count_act_ext++;
lwsl_parser("count_act_ext <- %d\n",
wsi->count_act_ext);
lwsl_parser("cnt_act_ext <- %d\n", wsi->count_act_ext);
ext++;
}
@ -321,7 +323,8 @@ handshake_0405(struct lws_context *context, struct lws *wsi)
/* okay send the handshake response accepting the connection */
lwsl_parser("issuing resp pkt %d len\n", lws_ptr_diff(p, response));
lwsl_parser("issuing resp pkt %d len\n",
lws_ptr_diff(p, response));
#if defined(DEBUG) && ! defined(LWS_WITH_ESP8266)
fwrite(response, 1, p - response, stderr);
#endif

View file

@ -1105,9 +1105,10 @@ lws_http_action(struct lws *wsi)
i.uri_replace_from = hit->origin;
i.uri_replace_to = hit->mountpoint;
lwsl_notice("proxying to %s port %d url %s, ssl %d, from %s, to %s\n",
i.address, i.port, i.path, i.ssl_connection,
i.uri_replace_from, i.uri_replace_to);
lwsl_notice("proxying to %s port %d url %s, ssl %d, "
"from %s, to %s\n",
i.address, i.port, i.path, i.ssl_connection,
i.uri_replace_from, i.uri_replace_to);
if (!lws_client_connect_via_info(&i)) {
lwsl_err("proxy connect fail\n");
@ -1146,7 +1147,8 @@ lws_http_action(struct lws *wsi)
args.max_len = hit->auth_mask;
args.final = 0; /* used to signal callback dealt with it */
n = wsi->protocol->callback(wsi, LWS_CALLBACK_CHECK_ACCESS_RIGHTS,
n = wsi->protocol->callback(wsi,
LWS_CALLBACK_CHECK_ACCESS_RIGHTS,
wsi->user_space, &args, 0);
if (n) {
lws_return_http_status(wsi, HTTP_STATUS_UNAUTHORIZED,
@ -1210,11 +1212,12 @@ lws_http_action(struct lws *wsi)
n = lws_http_serve(wsi, s, hit->origin, hit);
if (n) {
/*
* lws_return_http_status(wsi, HTTP_STATUS_NOT_FOUND, NULL);
* lws_return_http_status(wsi, HTTP_STATUS_NOT_FOUND, NULL);
*/
if (hit->protocol) {
const struct lws_protocols *pp = lws_vhost_name_to_protocol(
wsi->vhost, hit->protocol);
const struct lws_protocols *pp =
lws_vhost_name_to_protocol(
wsi->vhost, hit->protocol);
if (lws_bind_protocol(wsi, pp))
return 1;
@ -1434,38 +1437,39 @@ raw_transition:
if (lws_hdr_copy(wsi, ua, sizeof(ua) - 1,
WSI_TOKEN_HTTP_USER_AGENT) > 0) {
#ifdef LWS_WITH_ACCESS_LOG
char *uri_ptr = NULL;
int meth, uri_len;
#endif
ua[sizeof(ua) - 1] = '\0';
while (rej) {
if (strstr(ua, rej->name)) {
#ifdef LWS_WITH_ACCESS_LOG
char *uri_ptr = NULL;
int meth, uri_len;
#endif
if (!strstr(ua, rej->name)) {
rej = rej->next;
continue;
}
msg = strchr(rej->value, ' ');
if (msg)
msg++;
lws_return_http_status(wsi,
atoi(rej->value), msg);
msg = strchr(rej->value, ' ');
if (msg)
msg++;
lws_return_http_status(wsi,
atoi(rej->value), msg);
#ifdef LWS_WITH_ACCESS_LOG
meth = lws_http_get_uri_and_method(wsi,
&uri_ptr, &uri_len);
if (meth >= 0)
lws_prepare_access_log_info(wsi,
meth = lws_http_get_uri_and_method(wsi,
&uri_ptr, &uri_len);
if (meth >= 0)
lws_prepare_access_log_info(wsi,
uri_ptr, meth);
/* wsi close will do the log */
/* wsi close will do the log */
#endif
wsi->vhost->conn_stats.rejected++;
/*
* We don't want anything from
* this rejected guy. Follow
* the close flow, not the
* transaction complete flow.
*/
goto bail_nuke_ah;
}
rej = rej->next;
wsi->vhost->conn_stats.rejected++;
/*
* We don't want anything from
* this rejected guy. Follow
* the close flow, not the
* transaction complete flow.
*/
goto bail_nuke_ah;
}
}
}
@ -1483,14 +1487,16 @@ raw_transition:
/* is this websocket protocol or normal http 1.0? */
if (lws_hdr_total_length(wsi, WSI_TOKEN_UPGRADE)) {
if (!strcasecmp(lws_hdr_simple_ptr(wsi, WSI_TOKEN_UPGRADE),
if (!strcasecmp(lws_hdr_simple_ptr(wsi,
WSI_TOKEN_UPGRADE),
"websocket")) {
wsi->vhost->conn_stats.ws_upg++;
lwsl_info("Upgrade to ws\n");
goto upgrade_ws;
}
#ifdef LWS_WITH_HTTP2
if (!strcasecmp(lws_hdr_simple_ptr(wsi, WSI_TOKEN_UPGRADE),
if (!strcasecmp(lws_hdr_simple_ptr(wsi,
WSI_TOKEN_UPGRADE),
"h2c")) {
wsi->vhost->conn_stats.h2_upg++;
lwsl_info("Upgrade to h2c\n");
@ -1548,7 +1554,8 @@ upgrade_h2c:
wsi->u.http.ah = ah;
if (!wsi->u.h2.h2n) {
wsi->u.h2.h2n = lws_zalloc(sizeof(*wsi->u.h2.h2n), "h2n");
wsi->u.h2.h2n = lws_zalloc(sizeof(*wsi->u.h2.h2n),
"h2n");
if (!wsi->u.h2.h2n)
return 1;
}
@ -2313,7 +2320,8 @@ lws_server_socket_service(struct lws_context *context, struct lws *wsi,
ah->rxpos = 0;
switch (ah->rxlen) {
case 0:
lwsl_info("%s: read 0 len a\n", __func__);
lwsl_info("%s: read 0 len a\n",
__func__);
wsi->seen_zero_length_recv = 1;
lws_change_pollfd(wsi, LWS_POLLIN, 0);
goto try_pollout;
@ -2341,37 +2349,36 @@ lws_server_socket_service(struct lws_context *context, struct lws *wsi,
}
/* just ignore incoming if waiting for close */
if (wsi->state != LWSS_FLUSHING_STORED_SEND_BEFORE_CLOSE &&
wsi->state != LWSS_HTTP_ISSUING_FILE) {
/*
* otherwise give it to whoever wants it
* according to the connection state
*/
if (wsi->state == LWSS_FLUSHING_SEND_BEFORE_CLOSE ||
wsi->state == LWSS_HTTP_ISSUING_FILE)
goto try_pollout;
n = lws_read(wsi, ah->rx + ah->rxpos,
ah->rxlen - ah->rxpos);
if (n < 0) /* we closed wsi */
return 1;
/*
* otherwise give it to whoever wants it
* according to the connection state
*/
if (!wsi->u.hdr.ah)
break;
if ( wsi->u.hdr.ah->rxlen)
wsi->u.hdr.ah->rxpos += n;
lwsl_debug("%s: wsi %p: ah read rxpos %d, rxlen %d\n",
__func__, wsi, wsi->u.hdr.ah->rxpos,
wsi->u.hdr.ah->rxlen);
if (lws_header_table_is_in_detachable_state(wsi) &&
(wsi->mode != LWSCM_HTTP_SERVING &&
wsi->mode != LWSCM_HTTP_SERVING_ACCEPTED &&
wsi->mode != LWSCM_HTTP2_SERVING))
lws_header_table_detach(wsi, 1);
n = lws_read(wsi, ah->rx + ah->rxpos,
ah->rxlen - ah->rxpos);
if (n < 0) /* we closed wsi */
return 1;
if (!wsi->u.hdr.ah)
break;
}
if ( wsi->u.hdr.ah->rxlen)
wsi->u.hdr.ah->rxpos += n;
goto try_pollout;
lwsl_debug("%s: wsi %p: ah read rxpos %d, rxlen %d\n",
__func__, wsi, wsi->u.hdr.ah->rxpos,
wsi->u.hdr.ah->rxlen);
if (lws_header_table_is_in_detachable_state(wsi) &&
(wsi->mode != LWSCM_HTTP_SERVING &&
wsi->mode != LWSCM_HTTP_SERVING_ACCEPTED &&
wsi->mode != LWSCM_HTTP2_SERVING))
lws_header_table_detach(wsi, 1);
break;
}
len = lws_ssl_capable_read(wsi, pt->serv_buf,
@ -2393,8 +2400,9 @@ lws_server_socket_service(struct lws_context *context, struct lws *wsi,
if (wsi->mode == LWSCM_RAW) {
n = user_callback_handle_rxflow(wsi->protocol->callback,
wsi, LWS_CALLBACK_RAW_RX,
wsi->user_space, pt->serv_buf, len);
wsi, LWS_CALLBACK_RAW_RX,
wsi->user_space,
pt->serv_buf, len);
if (n < 0) {
lwsl_info("LWS_CALLBACK_RAW_RX_fail\n");
goto fail;
@ -2403,7 +2411,7 @@ lws_server_socket_service(struct lws_context *context, struct lws *wsi,
}
/* just ignore incoming if waiting for close */
if (wsi->state != LWSS_FLUSHING_STORED_SEND_BEFORE_CLOSE &&
if (wsi->state != LWSS_FLUSHING_SEND_BEFORE_CLOSE &&
wsi->state != LWSS_HTTP_ISSUING_FILE) {
/*
* this may want to send
@ -2522,17 +2530,17 @@ try_pollout:
#ifdef LWS_OPENSSL_SUPPORT
/*
* can we really accept it, with regards to SSL limit?
* another vhost may also have had POLLIN on his listener this
* round and used it up already
* another vhost may also have had POLLIN on his
* listener this round and used it up already
*/
if (wsi->vhost->use_ssl &&
context->simultaneous_ssl_restriction &&
context->simultaneous_ssl ==
context->simultaneous_ssl_restriction)
/* no... ignore it, he won't come again until we are
* below the simultaneous_ssl_restriction limit and
* POLLIN is enabled on him again
/*
* no... ignore it, he won't come again until
* we are below the simultaneous_ssl_restriction
* limit and POLLIN is enabled on him again
*/
break;
#endif
@ -2547,16 +2555,18 @@ try_pollout:
* we could, not accepting it due to PEER_LIMITS would
* block the connect queue for other legit peers.
*/
accept_fd = accept((int)pollfd->fd, (struct sockaddr *)&cli_addr,
accept_fd = accept((int)pollfd->fd,
(struct sockaddr *)&cli_addr,
&clilen);
lws_latency(context, wsi, "listener accept", (int)accept_fd,
accept_fd >= 0);
lws_latency(context, wsi, "listener accept",
(int)accept_fd, accept_fd >= 0);
if (accept_fd < 0) {
if (LWS_ERRNO == LWS_EAGAIN ||
LWS_ERRNO == LWS_EWOULDBLOCK) {
break;
}
lwsl_err("ERROR on accept: %s\n", strerror(LWS_ERRNO));
lwsl_err("ERROR on accept: %s\n",
strerror(LWS_ERRNO));
break;
}
@ -2579,14 +2589,16 @@ try_pollout:
accept_fd = (lws_sockfd_type)pollfd;
#endif
/*
* look at who we connected to and give user code a chance
* to reject based on client IP. There's no protocol selected
* yet so we issue this to protocols[0]
* look at who we connected to and give user code a
* chance to reject based on client IP. There's no
* protocol selected yet so we issue this to
* protocols[0]
*/
if ((wsi->vhost->protocols[0].callback)(wsi,
LWS_CALLBACK_FILTER_NETWORK_CONNECTION,
NULL, (void *)(lws_intptr_t)accept_fd, 0)) {
lwsl_debug("Callback denied network connection\n");
NULL,
(void *)(lws_intptr_t)accept_fd, 0)) {
lwsl_debug("Callback denied net connection\n");
compatible_close(accept_fd);
break;
}
@ -2635,7 +2647,7 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type,
unsigned char *response = pt->serv_buf + LWS_PRE;
unsigned char *p = response;
unsigned char *end = p + context->pt_serv_buf_size - LWS_PRE;
lws_filepos_t computed_total_content_length;
lws_filepos_t total_content_length;
int ret = 0, cclen = 8, n = HTTP_STATUS_OK;
lws_fop_flags_t fflags = LWS_O_RDONLY;
#if defined(LWS_WITH_RANGES)
@ -2663,7 +2675,7 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type,
}
}
wsi->u.http.filelen = lws_vfs_get_length(wsi->u.http.fop_fd);
computed_total_content_length = wsi->u.http.filelen;
total_content_length = wsi->u.http.filelen;
#if defined(LWS_WITH_RANGES)
ranges = lws_ranges_init(wsi, rp, wsi->u.http.filelen);
@ -2709,9 +2721,11 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type,
ranges < 2 &&
#endif
content_type && content_type[0])
if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE,
if (lws_add_http_header_by_token(wsi,
WSI_TOKEN_HTTP_CONTENT_TYPE,
(unsigned char *)content_type,
(int)strlen(content_type), &p, end))
(int)strlen(content_type),
&p, end))
return -1;
#if defined(LWS_WITH_RANGES)
@ -2720,9 +2734,12 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type,
sizeof(wsi->u.http.multipart_content_type) - 1);
wsi->u.http.multipart_content_type[
sizeof(wsi->u.http.multipart_content_type) - 1] = '\0';
if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE,
(unsigned char *)"multipart/byteranges; boundary=_lws",
20, &p, end))
if (lws_add_http_header_by_token(wsi,
WSI_TOKEN_HTTP_CONTENT_TYPE,
(unsigned char *)
"multipart/byteranges; "
"boundary=_lws",
20, &p, end))
return -1;
/*
@ -2737,8 +2754,8 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type,
* Precompute it for the main response header
*/
computed_total_content_length = (lws_filepos_t)rp->agg +
6 /* final _lws\r\n */;
total_content_length = (lws_filepos_t)rp->agg +
6 /* final _lws\r\n */;
lws_ranges_reset(rp);
while (lws_ranges_next(rp)) {
@ -2746,7 +2763,7 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type,
"bytes %llu-%llu/%llu",
rp->start, rp->end, rp->extent);
computed_total_content_length +=
total_content_length +=
6 /* header _lws\r\n */ +
/* Content-Type: xxx/xxx\r\n */
14 + strlen(content_type) + 2 +
@ -2760,12 +2777,13 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type,
}
if (ranges == 1) {
computed_total_content_length = (lws_filepos_t)rp->agg;
total_content_length = (lws_filepos_t)rp->agg;
n = lws_snprintf(cache_control, sizeof(cache_control),
"bytes %llu-%llu/%llu",
rp->start, rp->end, rp->extent);
if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CONTENT_RANGE,
if (lws_add_http_header_by_token(wsi,
WSI_TOKEN_HTTP_CONTENT_RANGE,
(unsigned char *)cache_control,
n, &p, end))
return -1;
@ -2780,7 +2798,7 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type,
if (!wsi->sending_chunked) {
if (lws_add_http_header_content_length(wsi,
computed_total_content_length,
total_content_length,
&p, end))
return -1;
} else {
@ -2843,9 +2861,6 @@ lws_interpret_incoming_packet(struct lws *wsi, unsigned char **buf, size_t len)
int m;
lwsl_parser("%s: received %d byte packet\n", __func__, (int)len);
#if 0
lwsl_hexdump(*buf, len);
#endif
/* let the rx protocol state machine have as much as it needs */
@ -2869,10 +2884,8 @@ lws_interpret_incoming_packet(struct lws *wsi, unsigned char **buf, size_t len)
/* account for what we're using in rxflow buffer */
if (wsi->rxflow_buffer) {
wsi->rxflow_pos++;
if (wsi->rxflow_pos > wsi->rxflow_len) {
lwsl_err("bumped rxflow buffer too far (%d / %d)", wsi->rxflow_pos, wsi->rxflow_len);
if (wsi->rxflow_pos > wsi->rxflow_len)
assert(0);
}
}
/* consume payload bytes efficiently */

View file

@ -105,7 +105,7 @@ lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd)
/* leave POLLOUT active either way */
goto bail_ok;
} else
if (wsi->state == LWSS_FLUSHING_STORED_SEND_BEFORE_CLOSE) {
if (wsi->state == LWSS_FLUSHING_SEND_BEFORE_CLOSE) {
wsi->socket_is_permanently_unusable = 1;
goto bail_die; /* retry closing now */
}
@ -435,24 +435,30 @@ user_service_go_again:
lwsl_debug("w=%p, *wsi2 = %p\n", w, *wsi2);
if (w == *wsi2) /* we are already last */
break;
w->u.h2.sibling_list = *wsi2; /* last points to us as new last */
*wsi2 = (*wsi2)->u.h2.sibling_list; /* guy pointing to us until now points to our old next */
w->u.h2.sibling_list->u.h2.sibling_list = NULL; /* we point to nothing because we are last */
w = w->u.h2.sibling_list; /* w becomes us */
/* last points to us as new last */
w->u.h2.sibling_list = *wsi2;
/* guy pointing to us until now points to
* our old next */
*wsi2 = (*wsi2)->u.h2.sibling_list;
/* we point to nothing because we are last */
w->u.h2.sibling_list->u.h2.sibling_list = NULL;
/* w becomes us */
w = w->u.h2.sibling_list;
break;
}
w = w->u.h2.sibling_list;
}
w->u.h2.requested_POLLOUT = 0;
lwsl_info("%s: child %p (state %d)\n", __func__, (*wsi2), (*wsi2)->state);
lwsl_info("%s: child %p (state %d)\n", __func__, (*wsi2),
(*wsi2)->state);
if (w->u.h2.pending_status_body) {
w->u.h2.send_END_STREAM = 1;
n = lws_write(w,
(uint8_t *)w->u.h2.pending_status_body + LWS_PRE,
strlen(w->u.h2.pending_status_body + LWS_PRE),
LWS_WRITE_HTTP_FINAL);
n = lws_write(w, (uint8_t *)w->u.h2.pending_status_body +
LWS_PRE,
strlen(w->u.h2.pending_status_body +
LWS_PRE), LWS_WRITE_HTTP_FINAL);
lws_free_set_NULL(w->u.h2.pending_status_body);
lws_close_free_wsi(w, LWS_CLOSE_STATUS_NOSTATUS);
wa = &wsi->u.h2.child_list;
@ -465,9 +471,9 @@ user_service_go_again:
/* >0 == completion, <0 == error
*
* We'll get a LWS_CALLBACK_HTTP_FILE_COMPLETION callback when
* it's done. That's the case even if we just completed the
* send, so wait for that.
* We'll get a LWS_CALLBACK_HTTP_FILE_COMPLETION
* callback when it's done. That's the case even if we
* just completed the send, so wait for that.
*/
n = lws_serve_http_file_fragment(w);
lwsl_debug("lws_serve_http_file_fragment says %d\n", n);
@ -1336,10 +1342,10 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd,
wsi->state == LWSS_HTTP2_ESTABLISHED_PRE_SETTINGS ||
wsi->state == LWSS_RETURNED_CLOSE_ALREADY ||
wsi->state == LWSS_WAITING_TO_SEND_CLOSE_NOTIFICATION ||
wsi->state == LWSS_FLUSHING_STORED_SEND_BEFORE_CLOSE)) &&
wsi->state == LWSS_FLUSHING_SEND_BEFORE_CLOSE)) &&
lws_handle_POLLOUT_event(wsi, pollfd)) {
if (wsi->state == LWSS_RETURNED_CLOSE_ALREADY)
wsi->state = LWSS_FLUSHING_STORED_SEND_BEFORE_CLOSE;
wsi->state = LWSS_FLUSHING_SEND_BEFORE_CLOSE;
lwsl_info("lws_service_fd: closing\n");
goto close_and_handled;
}

View file

@ -1,7 +1,7 @@
/*
* libwebsockets-test-client - libwebsockets test implementation
*
* Copyright (C) 2011-2016 Andy Green <andy@warmcat.com>
* Copyright (C) 2011-2017 Andy Green <andy@warmcat.com>
*
* This file is made available under the Creative Commons CC0 1.0
* Universal Public Domain Dedication.
@ -83,9 +83,12 @@ enum demo_protocols {
static uint8_t
lws_poly_rand(struct lws_poly_gen *p)
{
p->cyc[0] = (p->cyc[0] & 1) ? (p->cyc[0] >> 1) ^ 0xb4bcd35c : p->cyc[0] >> 1;
p->cyc[0] = (p->cyc[0] & 1) ? (p->cyc[0] >> 1) ^ 0xb4bcd35c : p->cyc[0] >> 1;
p->cyc[1] = (p->cyc[1] & 1) ? (p->cyc[1] >> 1) ^ 0x7a5bc2e3 : p->cyc[1] >> 1;
p->cyc[0] = p->cyc[0] & 1 ? (p->cyc[0] >> 1) ^ 0xb4bcd35c :
p->cyc[0] >> 1;
p->cyc[0] = p->cyc[0] & 1 ? (p->cyc[0] >> 1) ^ 0xb4bcd35c :
p->cyc[0] >> 1;
p->cyc[1] = p->cyc[1] & 1 ? (p->cyc[1] >> 1) ^ 0x7a5bc2e3 :
p->cyc[1] >> 1;
return p->cyc[0] ^ p->cyc[1];
}
@ -160,7 +163,8 @@ callback_dumb_increment(struct lws *wsi, enum lws_callback_reasons reason,
break;
case LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED:
if ((strcmp((const char *)in, "deflate-stream") == 0) && deny_deflate) {
if ((strcmp((const char *)in, "deflate-stream") == 0) &&
deny_deflate) {
lwsl_notice("denied deflate-stream extension\n");
return 1;
}
@ -240,7 +244,8 @@ callback_dumb_increment(struct lws *wsi, enum lws_callback_reasons reason,
return -1;
if (lws_add_http_header_by_token(wsi,
WSI_TOKEN_HTTP_CONTENT_TYPE,
(unsigned char *)"application/x-www-form-urlencoded", 33, p, end))
(unsigned char *)"application/x-www-form-urlencoded",
33, p, end))
return -1;
/* inform lws we have http body to send */
@ -251,7 +256,8 @@ callback_dumb_increment(struct lws *wsi, enum lws_callback_reasons reason,
case LWS_CALLBACK_CLIENT_HTTP_WRITEABLE:
strcpy(buf + LWS_PRE, "text=hello&send=Send+the+form");
n = lws_write(wsi, (unsigned char *)&buf[LWS_PRE], strlen(&buf[LWS_PRE]), LWS_WRITE_HTTP);
n = lws_write(wsi, (unsigned char *)&buf[LWS_PRE],
strlen(&buf[LWS_PRE]), LWS_WRITE_HTTP);
if (n < 0)
return -1;
/* we only had one thing to send, so inform lws we are done
@ -266,7 +272,8 @@ callback_dumb_increment(struct lws *wsi, enum lws_callback_reasons reason,
force_exit = 1;
break;
#if defined(LWS_OPENSSL_SUPPORT) && defined(LWS_HAVE_SSL_CTX_set1_param) && !defined(LWS_WITH_MBEDTLS)
#if defined(LWS_OPENSSL_SUPPORT) && defined(LWS_HAVE_SSL_CTX_set1_param) && \
!defined(LWS_WITH_MBEDTLS)
case LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS:
if (crl_path[0]) {
/* Enable CRL checking of the server certificate */
@ -274,13 +281,17 @@ callback_dumb_increment(struct lws *wsi, enum lws_callback_reasons reason,
X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
SSL_CTX_set1_param((SSL_CTX*)user, param);
X509_STORE *store = SSL_CTX_get_cert_store((SSL_CTX*)user);
X509_LOOKUP *lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
int n = X509_load_cert_crl_file(lookup, crl_path, X509_FILETYPE_PEM);
X509_LOOKUP *lookup = X509_STORE_add_lookup(store,
X509_LOOKUP_file());
int n = X509_load_cert_crl_file(lookup, crl_path,
X509_FILETYPE_PEM);
X509_VERIFY_PARAM_free(param);
if (n != 1) {
char errbuf[256];
n = ERR_get_error();
lwsl_err("LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS: SSL error: %s (%d)\n", ERR_error_string(n, errbuf), n);
lwsl_err("EXTRA_CLIENT_VERIFY_CERTS: "
"SSL error: %s (%d)\n",
ERR_error_string(n, errbuf), n);
return 1;
}
}
@ -345,7 +356,9 @@ callback_lws_mirror(struct lws *wsi, enum lws_callback_reasons reason,
break;
case LWS_CALLBACK_CLOSED:
lwsl_notice("mirror: LWS_CALLBACK_CLOSED mirror_lifetime=%d, rxb %d, rx_count %d\n", mirror_lifetime, rxb, rx_count);
lwsl_notice("mirror: LWS_CALLBACK_CLOSED mirror_lifetime=%d, "
"rxb %d, rx_count %d\n", mirror_lifetime, rxb,
rx_count);
wsi_mirror = NULL;
if (flag_echo)
force_exit = 1;
@ -377,7 +390,8 @@ callback_lws_mirror(struct lws *wsi, enum lws_callback_reasons reason,
}
for (n = 0; n < 1; n++) {
lws_get_random(lws_get_context(wsi), rands, sizeof(rands));
lws_get_random(lws_get_context(wsi), rands,
sizeof(rands));
l += sprintf((char *)&buf[LWS_PRE + l],
"c #%06X %u %u %u;",
rands[0] & 0xffffff, /* colour */
@ -421,7 +435,8 @@ callback_lws_mirror(struct lws *wsi, enum lws_callback_reasons reason,
rxb++;
}
if (rx_count == 0 && rxb == count_blocks) {
lwsl_notice("Everything received: errs %d\n", errs);
lwsl_notice("Everything received: errs %d\n",
errs);
force_exit = 1;
return -1;
}
@ -548,7 +563,8 @@ static int ratelimit_connects(unsigned int *last, unsigned int secs)
int main(int argc, char **argv)
{
int n = 0, m, ret = 0, port = 7681, use_ssl = 0, ietf_version = -1;
unsigned int rl_dumb = 0, rl_mirror = 0, do_ws = 1, pp_secs = 0, do_multi = 0;
unsigned int rl_dumb = 0, rl_mirror = 0, do_ws = 1, pp_secs = 0,
do_multi = 0;
struct lws_context_creation_info info;
struct lws_client_connect_info i;
struct lws_context *context;
@ -568,7 +584,8 @@ int main(int argc, char **argv)
goto usage;
while (n >= 0) {
n = getopt_long(argc, argv, "Sjnuv:hsp:d:lC:K:A:P:moe", options, NULL);
n = getopt_long(argc, argv, "Sjnuv:hsp:d:lC:K:A:P:moe", options,
NULL);
if (n < 0)
continue;
switch (n) {
@ -800,7 +817,8 @@ int main(int argc, char **argv)
if (m == 10) {
m = 0;
lwsl_notice("doing lws_callback_on_writable_all_protocol\n");
lws_callback_on_writable_all_protocol(context, &protocols[PROTOCOL_DUMB_INCREMENT]);
lws_callback_on_writable_all_protocol(context,
&protocols[PROTOCOL_DUMB_INCREMENT]);
}
}