1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00
This commit is contained in:
Andy Green 2017-09-23 12:55:21 +08:00
parent 91166ecb2a
commit c52a6267ab
19 changed files with 507 additions and 554 deletions

View file

@ -1,7 +1,7 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010-2014 Andy Green <andy@warmcat.com>
* Copyright (C) 2010-2017 Andy Green <andy@warmcat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -108,7 +108,8 @@ int lws_client_rx_sm(struct lws *wsi, unsigned char c)
return -1;
}
wsi->u.ws.final = !!((c >> 7) & 1);
lwsl_ext("%s: This RX frame Final %d\n", __func__, wsi->u.ws.final);
lwsl_ext("%s: This RX frame Final %d\n", __func__,
wsi->u.ws.final);
if (wsi->u.ws.owed_a_fin &&
(wsi->u.ws.opcode == LWSWSOPC_TEXT_FRAME ||
@ -122,7 +123,7 @@ int lws_client_rx_sm(struct lws *wsi, unsigned char c)
}
if ((wsi->u.ws.opcode & 8) && !wsi->u.ws.final) {
lwsl_info("control message cannot be fragmented\n");
lwsl_info("control msg can't be fragmented\n");
return -1;
}
if (!wsi->u.ws.final)
@ -140,7 +141,7 @@ int lws_client_rx_sm(struct lws *wsi, unsigned char c)
default:
lwsl_err("unknown spec version %02d\n",
wsi->ietf_spec_revision);
wsi->ietf_spec_revision);
break;
}
break;
@ -399,7 +400,8 @@ spill:
* we do not care about how it went, we are closing
* immediately afterwards
*/
lws_write(wsi, (unsigned char *)&wsi->u.ws.rx_ubuf[LWS_PRE],
lws_write(wsi, (unsigned char *)
&wsi->u.ws.rx_ubuf[LWS_PRE],
wsi->u.ws.rx_ubuf_head,
LWS_WRITE_CLOSE);
wsi->state = LWSS_RETURNED_CLOSE_ALREADY;
@ -449,8 +451,9 @@ ping_drop:
lwsl_hexdump(&wsi->u.ws.rx_ubuf[LWS_PRE],
wsi->u.ws.rx_ubuf_head);
if (wsi->pending_timeout == PENDING_TIMEOUT_WS_PONG_CHECK_GET_PONG) {
lwsl_info("received expected PONG on wsi %p\n", wsi);
if (wsi->pending_timeout ==
PENDING_TIMEOUT_WS_PONG_CHECK_GET_PONG) {
lwsl_info("%p: received expected PONG\n", wsi);
lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
}
@ -478,9 +481,10 @@ ping_drop:
if (lws_ext_cb_active(wsi,
LWS_EXT_CB_EXTENDED_PAYLOAD_RX,
&eff_buf, 0) <= 0) { /* not handle or fail */
lwsl_ext("Unhandled ext opc 0x%x\n", wsi->u.ws.opcode);
&eff_buf, 0) <= 0) {
/* not handled or failed */
lwsl_ext("Unhandled ext opc 0x%x\n",
wsi->u.ws.opcode);
wsi->u.ws.rx_ubuf_head = 0;
return 0;
@ -516,7 +520,7 @@ drain_extension:
lwsl_ext("post inflate eff_buf len %d\n", eff_buf.token_len);
if (rx_draining_ext && !eff_buf.token_len) {
lwsl_err(" --- ignoring zero drain result, ending drain\n");
lwsl_debug(" --- ending drain on 0 read result\n");
goto already_done;
}
@ -530,7 +534,8 @@ drain_extension:
if (!wsi->u.ws.rx_packet_length && wsi->u.ws.final &&
wsi->u.ws.utf8 && !n) {
lwsl_info("FINAL utf8 error\n");
utf8_fail: lwsl_info("utf8 error\n");
utf8_fail:
lwsl_info("utf8 error\n");
return -1;
}
}
@ -585,6 +590,7 @@ already_done:
illegal_ctl_length:
lwsl_warn("Control frame asking for extended length is illegal\n");
/* kill the connection */
return -1;
}

View file

@ -1,7 +1,7 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010-2015 Andy Green <andy@warmcat.com>
* Copyright (C) 2010-2017 Andy Green <andy@warmcat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -51,8 +51,8 @@ static const char * const mount_protocols[] = {
};
LWS_VISIBLE void *
lws_protocol_vh_priv_zalloc(struct lws_vhost *vhost, const struct lws_protocols *prot,
int size)
lws_protocol_vh_priv_zalloc(struct lws_vhost *vhost,
const struct lws_protocols *prot, int size)
{
int n = 0;
@ -82,7 +82,8 @@ lws_protocol_vh_priv_zalloc(struct lws_vhost *vhost, const struct lws_protocols
}
LWS_VISIBLE void *
lws_protocol_vh_priv_get(struct lws_vhost *vhost, const struct lws_protocols *prot)
lws_protocol_vh_priv_get(struct lws_vhost *vhost,
const struct lws_protocols *prot)
{
int n = 0;
@ -116,7 +117,6 @@ lws_vhost_protocol_options(struct lws_vhost *vh, const char *name)
return NULL;
while (pvo) {
// lwsl_notice("%s: '%s' '%s'\n", __func__, pvo->name, name);
if (!strcmp(pvo->name, name))
return pvo;
pvo = pvo->next;
@ -193,15 +193,15 @@ lws_protocol_init(struct lws_context *context)
}
/*
* inform all the protocols that they are doing their one-time
* initialization if they want to.
* inform all the protocols that they are doing their
* one-time initialization if they want to.
*
* NOTE the wsi is all zeros except for the context, vh and
* protocol ptrs so lws_get_context(wsi) etc can work
* NOTE the wsi is all zeros except for the context, vh
* + protocol ptrs so lws_get_context(wsi) etc can work
*/
if (vh->protocols[n].callback(&wsi,
LWS_CALLBACK_PROTOCOL_INIT, NULL,
(void *)pvo, 0))
LWS_CALLBACK_PROTOCOL_INIT, NULL,
(void *)pvo, 0))
return 1;
}
@ -222,6 +222,7 @@ LWS_VISIBLE int
lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason,
void *user, void *in, size_t len)
{
struct lws_ssl_info *si;
#ifdef LWS_WITH_CGI
struct lws_cgi_args *args;
#endif
@ -249,7 +250,8 @@ lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason,
case LWS_CALLBACK_HTTP_WRITEABLE:
#ifdef LWS_WITH_CGI
if (wsi->reason_bf & (LWS_CB_REASON_AUX_BF__CGI_HEADERS | LWS_CB_REASON_AUX_BF__CGI)) {
if (wsi->reason_bf & (LWS_CB_REASON_AUX_BF__CGI_HEADERS |
LWS_CB_REASON_AUX_BF__CGI)) {
n = lws_cgi_write_split_stdout_headers(wsi);
if (n < 0) {
lwsl_debug("LWS_CB_REASON_AUX_BF__CGI forcing close\n");
@ -277,13 +279,13 @@ lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason,
if (wsi->reason_bf & LWS_CB_REASON_AUX_BF__PROXY) {
char *px = buf + LWS_PRE;
int lenx = sizeof(buf) - LWS_PRE;
/*
* our sink is writeable and our source has something
* to read. So read a lump of source material of
* suitable size to send or what's available, whichever
* is the smaller.
*/
wsi->reason_bf &= ~LWS_CB_REASON_AUX_BF__PROXY;
if (!lws_get_child(wsi))
break;
@ -296,7 +298,6 @@ lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason,
#if defined(LWS_WITH_HTTP_PROXY)
case LWS_CALLBACK_RECEIVE_CLIENT_HTTP:
//lwsl_err("LWS_CALLBACK_RECEIVE_CLIENT_HTTP: wsi %p\n", wsi);
assert(lws_get_parent(wsi));
if (!lws_get_parent(wsi))
break;
@ -305,7 +306,6 @@ lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason,
break;
case LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ:
//lwsl_err("LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ len %d\n", (int)len);
assert(lws_get_parent(wsi));
n = lws_write(lws_get_parent(wsi), (unsigned char *)in,
len, LWS_WRITE_HTTP);
@ -316,13 +316,12 @@ lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason,
case LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP: {
unsigned char *p, *end;
char ctype[64], ctlen = 0;
//lwsl_err("LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP\n");
p = (unsigned char *)buf + LWS_PRE;
end = p + sizeof(buf) - LWS_PRE;
if (lws_add_http_header_status(lws_get_parent(wsi), HTTP_STATUS_OK, &p, end))
if (lws_add_http_header_status(lws_get_parent(wsi),
HTTP_STATUS_OK, &p, end))
return 1;
if (lws_add_http_header_by_token(lws_get_parent(wsi),
WSI_TOKEN_HTTP_SERVER,
@ -330,25 +329,21 @@ lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason,
13, &p, end))
return 1;
ctlen = lws_hdr_copy(wsi, ctype, sizeof(ctype), WSI_TOKEN_HTTP_CONTENT_TYPE);
ctlen = lws_hdr_copy(wsi, ctype, sizeof(ctype),
WSI_TOKEN_HTTP_CONTENT_TYPE);
if (ctlen > 0) {
if (lws_add_http_header_by_token(lws_get_parent(wsi),
WSI_TOKEN_HTTP_CONTENT_TYPE,
(unsigned char *)ctype, ctlen, &p, end))
return 1;
}
#if 0
if (lws_add_http_header_content_length(lws_get_parent(wsi),
file_len, &p, end))
return 1;
#endif
if (lws_finalize_http_header(lws_get_parent(wsi), &p, end))
return 1;
*p = '\0';
// lwsl_info("%s\n", buf + LWS_PRE);
n = lws_write(lws_get_parent(wsi), (unsigned char *)buf + LWS_PRE,
n = lws_write(lws_get_parent(wsi),
(unsigned char *)buf + LWS_PRE,
p - ((unsigned char *)buf + LWS_PRE),
LWS_WRITE_HTTP_HEADERS);
if (n < 0)
@ -393,10 +388,11 @@ lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason,
case LWS_CALLBACK_CGI_TERMINATED:
lwsl_debug("LWS_CALLBACK_CGI_TERMINATED: %d %" PRIu64 "\n",
wsi->cgi->explicitly_chunked, (uint64_t)wsi->cgi->content_length);
wsi->cgi->explicitly_chunked,
(uint64_t)wsi->cgi->content_length);
if (!wsi->cgi->explicitly_chunked && !wsi->cgi->content_length) {
/* send terminating chunk */
lwsl_debug("LWS_CALLBACK_CGI_TERMINATED: looking to send terminating chunk\n");
lwsl_debug("LWS_CALLBACK_CGI_TERMINATED: ending\n");
wsi->reason_bf |= LWS_CB_REASON_AUX_BF__CGI_CHUNK_END;
lws_callback_on_writable(wsi);
lws_set_timeout(wsi, PENDING_TIMEOUT_CGI, 3);
@ -416,13 +412,11 @@ lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason,
#endif
case LWS_CALLBACK_SSL_INFO:
{
struct lws_ssl_info *si = in;
si = in;
(void)si;
lwsl_notice("LWS_CALLBACK_SSL_INFO: where: 0x%x, ret: 0x%x\n",
si->where, si->ret);
}
(void)si;
lwsl_notice("LWS_CALLBACK_SSL_INFO: where: 0x%x, ret: 0x%x\n",
si->where, si->ret);
break;
default:
@ -578,7 +572,8 @@ lws_create_vhost(struct lws_context *context,
} else
#endif
lwsl_notice("Creating Vhost '%s' port %d, %d protocols, IPv6 %s\n",
vh->name, info->port, vh->count_protocols, LWS_IPV6_ENABLED(vh) ? "on" : "off");
vh->name, info->port, vh->count_protocols,
LWS_IPV6_ENABLED(vh) ? "on" : "off");
mounts = info->mounts;
while (mounts) {
@ -597,7 +592,8 @@ lws_create_vhost(struct lws_context *context,
break;
}
if (n == vh->count_protocols)
lwsl_err("ignoring unknown interpret protocol %s\n", pvo->value);
lwsl_err("ignoring unknown interpret protocol %s\n",
pvo->value);
pvo = pvo->next;
}
@ -688,7 +684,8 @@ lws_create_vhost(struct lws_context *context,
#ifdef LWS_WITH_ACCESS_LOG
if (info->log_filepath) {
vh->log_fd = open(info->log_filepath, O_CREAT | O_APPEND | O_RDWR, 0600);
vh->log_fd = open(info->log_filepath,
O_CREAT | O_APPEND | O_RDWR, 0600);
if (vh->log_fd == (int)LWS_INVALID_FILE) {
lwsl_err("unable to open log filepath %s\n",
info->log_filepath);
@ -780,7 +777,6 @@ lws_create_context(struct lws_context_creation_info *info)
lwsl_info(" LWS_DEF_HEADER_LEN : %u\n", LWS_DEF_HEADER_LEN);
lwsl_info(" LWS_MAX_PROTOCOLS : %u\n", LWS_MAX_PROTOCOLS);
lwsl_info(" LWS_MAX_SMP : %u\n", LWS_MAX_SMP);
lwsl_info(" SPEC_LATEST_SUPPORTED : %u\n", SPEC_LATEST_SUPPORTED);
lwsl_info(" sizeof (*info) : %ld\n", (long)sizeof(*info));
#if defined(LWS_WITH_STATS)
lwsl_info(" LWS_WITH_STATS : on\n");
@ -1259,7 +1255,8 @@ lws_vhost_destroy2(struct lws_vhost *vh)
/* if we are still on deferred free list, remove ourselves */
lws_start_foreach_llp(struct lws_deferred_free **, pdf, context->deferred_free_list) {
lws_start_foreach_llp(struct lws_deferred_free **, pdf,
context->deferred_free_list) {
if ((*pdf)->payload == vh) {
df = *pdf;
*pdf = df->next;
@ -1270,7 +1267,8 @@ lws_vhost_destroy2(struct lws_vhost *vh)
/* remove ourselves from the pending destruction list */
lws_start_foreach_llp(struct lws_vhost **, pv, context->vhost_pending_destruction_list) {
lws_start_foreach_llp(struct lws_vhost **, pv,
context->vhost_pending_destruction_list) {
if ((*pv) == vh) {
*pv = (*pv)->vhost_next;
break;
@ -1338,12 +1336,13 @@ lws_check_deferred_free(struct lws_context *context, int force)
struct lws_deferred_free *df;
time_t now = lws_now_secs();
lws_start_foreach_llp(struct lws_deferred_free **, pdf, context->deferred_free_list) {
lws_start_foreach_llp(struct lws_deferred_free **, pdf,
context->deferred_free_list) {
if (now > (*pdf)->deadline || force) {
df = *pdf;
*pdf = df->next;
/* finalize vh destruction */
lwsl_notice("doing deferred vh %p destroy\n", df->payload);
lwsl_notice("deferred vh %p destroy\n", df->payload);
lws_vhost_destroy2(df->payload);
lws_free(df);
continue; /* after deletion we already point to next */
@ -1384,7 +1383,8 @@ lws_context_destroy(struct lws_context *context)
return;
}
if (context->being_destroyed1) {
lwsl_notice("%s: ctx %p: already being destroyed\n", __func__, context);
lwsl_notice("%s: ctx %p: already being destroyed\n",
__func__, context);
return;
}
@ -1503,7 +1503,8 @@ lws_context_destroy2(struct lws_context *context)
#if defined(LWS_WITH_PEER_LIMITS)
for (n = 0; n < context->pl_hash_elements; n++) {
lws_start_foreach_llp(struct lws_peer **, peer, context->pl_hash_table[n]) {
lws_start_foreach_llp(struct lws_peer **, peer,
context->pl_hash_table[n]) {
struct lws_peer *df = *peer;
*peer = df->next;
lws_free(df);

View file

@ -1,7 +1,7 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010-2015 Andy Green <andy@warmcat.com>
* Copyright (C) 2010-2017 Andy Green <andy@warmcat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -66,8 +66,6 @@ lws_read(struct lws *wsi, unsigned char *buf, lws_filepos_t len)
lws_filepos_t body_chunk_len;
size_t n;
lwsl_debug("%s: incoming len %d state %d\n", __func__, (int)len, wsi->state);
switch (wsi->state) {
#ifdef LWS_USE_HTTP2
case LWSS_HTTP2_AWAIT_CLIENT_PREFACE:
@ -103,6 +101,7 @@ lws_read(struct lws *wsi, unsigned char *buf, lws_filepos_t len)
case LWSS_HTTP:
wsi->hdr_parsing_completed = 0;
/* fallthru */
case LWSS_HTTP_HEADERS:
@ -206,9 +205,13 @@ http_postbody:
/* he sent all the content in time */
postbody_completion:
#ifdef LWS_WITH_CGI
/* if we're running a cgi, we can't let him off the hook just because he sent his POST data */
/*
* If we're running a cgi, we can't let him off the
* hook just because he sent his POST data
*/
if (wsi->cgi)
lws_set_timeout(wsi, PENDING_TIMEOUT_CGI, wsi->context->timeout_secs);
lws_set_timeout(wsi, PENDING_TIMEOUT_CGI,
wsi->context->timeout_secs);
else
#endif
lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
@ -255,7 +258,6 @@ read_ok:
return buf - oldbuf;
bail:
//lwsl_notice("closing connection at lws_read bail:\n");
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
return -1;

View file

@ -1,7 +1,7 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010-2013 Andy Green <andy@warmcat.com>
* Copyright (C) 2010-2017 Andy Green <andy@warmcat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -87,7 +87,8 @@ lws_add_http_header_by_token(struct lws *wsi, enum lws_token_indexes token,
const unsigned char *name;
#ifdef LWS_USE_HTTP2
if (wsi->mode == LWSCM_HTTP2_SERVING)
return lws_add_http2_header_by_token(wsi, token, value, length, p, end);
return lws_add_http2_header_by_token(wsi, token, value,
length, p, end);
#endif
name = lws_token_to_string(token);
if (!name)
@ -292,9 +293,8 @@ lws_http_redirect(struct lws *wsi, int code, const unsigned char *loc, int len,
loc, len, p, end))
return -1;
/*
* if we're going with http/1.1 and keepalive,
* we have to give fake content metadata so the
* client knows we completed the transaction and
* if we're going with http/1.1 and keepalive, we have to give fake
* content metadata so the client knows we completed the transaction and
* it can do the redirect...
*/
if (lws_add_http_header_by_token(wsi,
@ -310,8 +310,7 @@ lws_http_redirect(struct lws *wsi, int code, const unsigned char *loc, int len,
if (lws_finalize_http_header(wsi, p, end))
return -1;
n = lws_write(wsi, start, *p - start,
LWS_WRITE_HTTP_HEADERS);
n = lws_write(wsi, start, *p - start, LWS_WRITE_HTTP_HEADERS);
return n;
}

View file

@ -1,7 +1,7 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010-2014 Andy Green <andy@warmcat.com>
* Copyright (C) 2010-2017 Andy Green <andy@warmcat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -43,6 +43,7 @@ lws_accept_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
eventfd.fd = watcher->fd;
eventfd.events = 0;
eventfd.revents = EV_NONE;
if (revents & EV_READ) {
eventfd.events |= LWS_POLLIN;
eventfd.revents |= LWS_POLLIN;
@ -51,6 +52,7 @@ lws_accept_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
eventfd.events |= LWS_POLLOUT;
eventfd.revents |= LWS_POLLOUT;
}
lws_service_fd(context, &eventfd);
}
@ -97,8 +99,8 @@ lws_ev_initloop(struct lws_context *context, struct ev_loop *loop, int tsi)
while (vh) {
if (vh->lserv_wsi) {
vh->lserv_wsi->w_read.context = context;
ev_io_init(w_accept, lws_accept_cb, vh->lserv_wsi->desc.sockfd,
EV_READ);
ev_io_init(w_accept, lws_accept_cb,
vh->lserv_wsi->desc.sockfd, EV_READ);
}
vh = vh->vhost_next;
}

View file

@ -1,7 +1,7 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010-2014 Andy Green <andy@warmcat.com>
* Copyright (C) 2010-2017 Andy Green <andy@warmcat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -23,227 +23,213 @@
void lws_feature_status_libevent(struct lws_context_creation_info *info)
{
if (lws_check_opt(info->options, LWS_SERVER_OPTION_LIBEVENT))
lwsl_info("libevent support compiled in and enabled\n");
else
lwsl_info("libevent support compiled in but disabled\n");
if (lws_check_opt(info->options, LWS_SERVER_OPTION_LIBEVENT))
lwsl_info("libevent support compiled in and enabled\n");
else
lwsl_info("libevent support compiled in but disabled\n");
}
static void
lws_event_cb(evutil_socket_t sock_fd, short revents, void *ctx)
{
struct lws_io_watcher *lws_io = (struct lws_io_watcher *)ctx;
struct lws_context *context = lws_io->context;
struct lws_pollfd eventfd;
struct lws_io_watcher *lws_io = (struct lws_io_watcher *)ctx;
struct lws_context *context = lws_io->context;
struct lws_pollfd eventfd;
if (revents & EV_TIMEOUT)
return;
if (revents & EV_TIMEOUT)
return;
/* !!! EV_CLOSED doesn't exist in libevent2 */
#if LIBEVENT_VERSION_NUMBER < 0x02000000
if (revents & EV_CLOSED)
{
event_del(lws_io->event_watcher);
event_free(lws_io->event_watcher);
return;
}
#endif
/* !!! EV_CLOSED doesn't exist in libevent2 */
#if LIBEVENT_VERSION_NUMBER < 0x02000000
if (revents & EV_CLOSED) {
event_del(lws_io->event_watcher);
event_free(lws_io->event_watcher);
return;
}
#endif
eventfd.fd = sock_fd;
eventfd.events = 0;
eventfd.revents = 0;
if (revents & EV_READ)
{
eventfd.events |= LWS_POLLIN;
eventfd.revents |= LWS_POLLIN;
}
if (revents & EV_WRITE)
{
eventfd.events |= LWS_POLLOUT;
eventfd.revents |= LWS_POLLOUT;
}
lws_service_fd(context, &eventfd);
eventfd.fd = sock_fd;
eventfd.events = 0;
eventfd.revents = 0;
if (revents & EV_READ) {
eventfd.events |= LWS_POLLIN;
eventfd.revents |= LWS_POLLIN;
}
if (revents & EV_WRITE) {
eventfd.events |= LWS_POLLOUT;
eventfd.revents |= LWS_POLLOUT;
}
lws_service_fd(context, &eventfd);
}
LWS_VISIBLE void
lws_event_sigint_cb(evutil_socket_t sock_fd, short revents, void *ctx)
{
struct lws_context_per_thread *pt = ctx;
if (!pt->ev_loop_foreign)
event_base_loopbreak(pt->io_loop_event_base);
struct lws_context_per_thread *pt = ctx;
if (!pt->ev_loop_foreign)
event_base_loopbreak(pt->io_loop_event_base);
}
LWS_VISIBLE int
lws_event_sigint_cfg(struct lws_context *context, int use_event_sigint,
lws_event_signal_cb_t *cb)
lws_event_signal_cb_t *cb)
{
context->use_ev_sigint = use_event_sigint;
if (cb)
context->lws_event_sigint_cb = cb;
else
context->lws_event_sigint_cb = &lws_event_sigint_cb;
context->use_ev_sigint = use_event_sigint;
if (cb)
context->lws_event_sigint_cb = cb;
else
context->lws_event_sigint_cb = &lws_event_sigint_cb;
return 0;
return 0;
}
LWS_VISIBLE int
lws_event_initloop(struct lws_context *context, struct event_base *loop,
int tsi)
int tsi)
{
if (!loop)
{
context->pt[tsi].io_loop_event_base = event_base_new();
}
else
{
context->pt[tsi].ev_loop_foreign = 1;
context->pt[tsi].io_loop_event_base = loop;
}
struct lws_vhost *vh = context->vhost_list;
/*
* Initialize all events with the listening sockets
* and register a callback for read operations
*/
struct lws_vhost *vh = context->vhost_list;
while (vh)
{
if (vh->lserv_wsi)
{
vh->lserv_wsi->w_read.context = context;
vh->lserv_wsi->w_read.event_watcher = event_new(
loop,
vh->lserv_wsi->desc.sockfd,
(EV_READ | EV_PERSIST),
lws_event_cb,
&vh->lserv_wsi->w_read);
event_add(vh->lserv_wsi->w_read.event_watcher, NULL);
}
vh = vh->vhost_next;
}
if (!loop)
context->pt[tsi].io_loop_event_base = event_base_new();
else {
context->pt[tsi].ev_loop_foreign = 1;
context->pt[tsi].io_loop_event_base = loop;
}
/* Register the signal watcher unless the user says not to */
if (context->use_ev_sigint)
{
struct event *w_sigint = evsignal_new(loop, SIGINT,
context->lws_event_sigint_cb, &context->pt[tsi]);
context->pt[tsi].w_sigint.event_watcher = w_sigint;
event_add(w_sigint, NULL);
}
/*
* Initialize all events with the listening sockets
* and register a callback for read operations
*/
return 0;
while (vh) {
if (vh->lserv_wsi) {
vh->lserv_wsi->w_read.context = context;
vh->lserv_wsi->w_read.event_watcher = event_new(
loop, vh->lserv_wsi->desc.sockfd,
(EV_READ | EV_PERSIST), lws_event_cb,
&vh->lserv_wsi->w_read);
event_add(vh->lserv_wsi->w_read.event_watcher, NULL);
}
vh = vh->vhost_next;
}
/* Register the signal watcher unless the user says not to */
if (!context->use_ev_sigint)
return 0;
context->pt[tsi].w_sigint.event_watcher = evsignal_new(loop, SIGINT,
context->lws_event_sigint_cb, &context->pt[tsi]);
event_add(context->pt[tsi].w_sigint.event_watcher, NULL);
return 0;
}
void
lws_libevent_destroyloop(struct lws_context *context, int tsi)
{
if (!lws_check_opt(context->options, LWS_SERVER_OPTION_LIBEVENT))
return;
struct lws_context_per_thread *pt = &context->pt[tsi];
struct lws_vhost *vh = context->vhost_list;
struct lws_context_per_thread *pt = &context->pt[tsi];
if (!pt->io_loop_event_base)
return;
if (!lws_check_opt(context->options, LWS_SERVER_OPTION_LIBEVENT))
return;
/*
* Free all events with the listening sockets
*/
struct lws_vhost *vh = context->vhost_list;
while (vh)
{
if (vh->lserv_wsi)
{
event_free(vh->lserv_wsi->w_read.event_watcher);
vh->lserv_wsi->w_read.event_watcher = NULL;
}
vh = vh->vhost_next;
}
if (!pt->io_loop_event_base)
return;
if (context->use_ev_sigint)
event_free(pt->w_sigint.event_watcher);
if (!pt->ev_loop_foreign)
event_base_free(pt->io_loop_event_base);
/*
* Free all events with the listening sockets
*/
while (vh) {
if (vh->lserv_wsi) {
event_free(vh->lserv_wsi->w_read.event_watcher);
vh->lserv_wsi->w_read.event_watcher = NULL;
}
vh = vh->vhost_next;
}
if (context->use_ev_sigint)
event_free(pt->w_sigint.event_watcher);
if (!pt->ev_loop_foreign)
event_base_free(pt->io_loop_event_base);
}
LWS_VISIBLE void
lws_libevent_accept(struct lws *new_wsi, lws_sock_file_fd_type desc)
{
struct lws_context *context = lws_get_context(new_wsi);
if (!LWS_LIBEVENT_ENABLED(context))
return;
struct lws_context *context = lws_get_context(new_wsi);
struct lws_context_per_thread *pt;
int fd;
new_wsi->w_read.context = context;
new_wsi->w_write.context = context;
if (!LWS_LIBEVENT_ENABLED(context))
return;
// Initialize the event
struct lws_context_per_thread *pt = &context->pt[(int)new_wsi->tsi];
int fd;
if (new_wsi->mode == LWSCM_RAW_FILEDESC)
fd = desc.filefd;
else
fd = desc.sockfd;
new_wsi->w_read.event_watcher = event_new(pt->io_loop_event_base, fd,
(EV_READ | EV_PERSIST), lws_event_cb, &new_wsi->w_read);
new_wsi->w_write.event_watcher = event_new(pt->io_loop_event_base, fd,
(EV_WRITE | EV_PERSIST), lws_event_cb, &new_wsi->w_write);
new_wsi->w_read.context = context;
new_wsi->w_write.context = context;
// Initialize the event
pt = &context->pt[(int)new_wsi->tsi];
if (new_wsi->mode == LWSCM_RAW_FILEDESC)
fd = desc.filefd;
else
fd = desc.sockfd;
new_wsi->w_read.event_watcher = event_new(pt->io_loop_event_base, fd,
(EV_READ | EV_PERSIST), lws_event_cb, &new_wsi->w_read);
new_wsi->w_write.event_watcher = event_new(pt->io_loop_event_base, fd,
(EV_WRITE | EV_PERSIST), lws_event_cb, &new_wsi->w_write);
}
LWS_VISIBLE void
lws_libevent_io(struct lws *wsi, int flags)
{
struct lws_context *context = lws_get_context(wsi);
struct lws_context *context = lws_get_context(wsi);
struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
if (!LWS_LIBEVENT_ENABLED(context))
return;
if (!LWS_LIBEVENT_ENABLED(context))
return;
struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
if (!pt->io_loop_event_base || context->being_destroyed)
return;
if (!pt->io_loop_event_base || context->being_destroyed)
return;
assert((flags & (LWS_EV_START | LWS_EV_STOP)) &&
(flags & (LWS_EV_READ | LWS_EV_WRITE)));
assert((flags & (LWS_EV_START | LWS_EV_STOP)) &&
(flags & (LWS_EV_READ | LWS_EV_WRITE)));
if (flags & LWS_EV_START)
{
if (flags & LWS_EV_WRITE)
{
event_add(wsi->w_write.event_watcher, NULL);
}
if (flags & LWS_EV_READ)
{
event_add(wsi->w_read.event_watcher, NULL);
}
}
else
{
if (flags & LWS_EV_WRITE)
{
event_del(wsi->w_write.event_watcher);
}
if (flags & LWS_EV_READ)
{
event_del(wsi->w_read.event_watcher);
}
}
if (flags & LWS_EV_START) {
if (flags & LWS_EV_WRITE)
event_add(wsi->w_write.event_watcher, NULL);
if (flags & LWS_EV_READ)
event_add(wsi->w_read.event_watcher, NULL);
} else {
if (flags & LWS_EV_WRITE)
event_del(wsi->w_write.event_watcher);
if (flags & LWS_EV_READ)
event_del(wsi->w_read.event_watcher);
}
}
LWS_VISIBLE int
lws_libevent_init_fd_table(struct lws_context *context)
{
if (!LWS_LIBEVENT_ENABLED(context))
return 0;
int n;
int n;
for (n = 0; n < context->count_threads; n++)
{
context->pt[n].w_sigint.context = context;
}
if (!LWS_LIBEVENT_ENABLED(context))
return 0;
return 1;
for (n = 0; n < context->count_threads; n++)
context->pt[n].w_sigint.context = context;
return 1;
}
LWS_VISIBLE void
lws_libevent_run(const struct lws_context *context, int tsi)
{
// Run/Dispatch the event_base loop
if (context->pt[tsi].io_loop_event_base && LWS_LIBEVENT_ENABLED(context))
event_base_dispatch(context->pt[tsi].io_loop_event_base);
/* Run / Dispatch the event_base loop */
if (context->pt[tsi].io_loop_event_base &&
LWS_LIBEVENT_ENABLED(context))
event_base_dispatch(context->pt[tsi].io_loop_event_base);
}

View file

@ -1,7 +1,7 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010-2016 Andy Green <andy@warmcat.com>
* Copyright (C) 2010-2017 Andy Green <andy@warmcat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -40,8 +40,6 @@ lws_uv_idle(uv_idle_t *handle
struct lws_context_per_thread *pt = lws_container_of(handle,
struct lws_context_per_thread, uv_idle);
// lwsl_debug("%s\n", __func__);
/*
* is there anybody with pending stuff that needs service forcing?
*/
@ -51,14 +49,11 @@ lws_uv_idle(uv_idle_t *handle
/* still somebody left who wants forced service? */
if (!lws_service_adjust_timeout(pt->context, 1, pt->tid))
/* yes... come back again later */
// lwsl_debug("%s: done again\n", __func__);
return;
}
/* there is nobody who needs service forcing, shut down idle */
uv_idle_stop(handle);
//lwsl_debug("%s: done stop\n", __func__);
}
static void
@ -79,10 +74,12 @@ lws_io_cb(uv_poll_t *watcher, int status, int revents)
eventfd.revents = 0;
if (status < 0) {
/* at this point status will be an UV error, like UV_EBADF,
we treat all errors as LWS_POLLHUP */
/* you might want to return; instead of servicing the fd in some cases */
/*
* At this point status will be an UV error, like UV_EBADF,
* we treat all errors as LWS_POLLHUP
*
* You might want to return; instead of servicing the fd in
* some cases */
if (status == UV_EAGAIN)
return;
@ -223,7 +220,8 @@ lws_uv_initloop(struct lws_context *context, uv_loop_t *loop, int tsi)
uv_signal_init(loop, &pt->signals[n]);
pt->signals[n].data = pt->context;
uv_signal_start(&pt->signals[n],
context->lws_uv_sigint_cb, sigs[n]);
context->lws_uv_sigint_cb,
sigs[n]);
}
}
} else
@ -253,7 +251,6 @@ lws_uv_initloop(struct lws_context *context, uv_loop_t *loop, int tsi)
static void lws_uv_close_cb(uv_handle_t *handle)
{
//lwsl_err("%s: handle %p\n", __func__, handle);
}
static void lws_uv_walk_cb(uv_handle_t *handle, void *arg)
@ -272,7 +269,6 @@ void
lws_libuv_destroyloop(struct lws_context *context, int tsi)
{
struct lws_context_per_thread *pt = &context->pt[tsi];
// struct lws_context *ctx;
int m, budget = 100, ns;
if (!lws_check_opt(context->options, LWS_SERVER_OPTION_LIBUV))
@ -281,13 +277,12 @@ lws_libuv_destroyloop(struct lws_context *context, int tsi)
if (!pt->io_loop_uv)
return;
lwsl_notice("%s: closing signals + timers context %p\n", __func__, context);
if (context->use_ev_sigint) {
uv_signal_stop(&pt->w_sigint.uv_watcher);
ns = ARRAY_SIZE(sigs);
if (lws_check_opt(context->options, LWS_SERVER_OPTION_UV_NO_SIGSEGV_SIGFPE_SPIN))
if (lws_check_opt(context->options,
LWS_SERVER_OPTION_UV_NO_SIGSEGV_SIGFPE_SPIN))
ns = 2;
for (m = 0; m < ns; m++) {
@ -308,12 +303,8 @@ lws_libuv_destroyloop(struct lws_context *context, int tsi)
while (budget-- && uv_run(pt->io_loop_uv, UV_RUN_NOWAIT))
;
lwsl_notice("%s: closing all loop handles context %p\n", __func__, context);
uv_stop(pt->io_loop_uv);
uv_walk(pt->io_loop_uv, lws_uv_walk_cb, NULL);
while (uv_run(pt->io_loop_uv, UV_RUN_NOWAIT))
;
#if UV_VERSION_MAJOR > 0
@ -333,8 +324,6 @@ lws_libuv_accept(struct lws *wsi, lws_sock_file_fd_type desc)
if (!LWS_LIBUV_ENABLED(context))
return;
lwsl_debug("%s: new wsi %p\n", __func__, wsi);
wsi->w_read.context = context;
if (wsi->mode == LWSCM_RAW_FILEDESC)
uv_poll_init(pt->io_loop_uv, &wsi->w_read.uv_watcher,
@ -361,8 +350,6 @@ lws_libuv_io(struct lws *wsi, int flags)
if (!LWS_LIBUV_ENABLED(context))
return;
// lwsl_notice("%s: wsi: %p, flags:0x%x\n", __func__, wsi, flags);
// w->context is set after the loop is initialized
if (!pt->io_loop_uv || !w->context) {
@ -432,12 +419,9 @@ lws_libuv_kill(const struct lws_context *context)
{
int n;
lwsl_notice("%s\n", __func__);
for (n = 0; n < context->count_threads; n++)
if (context->pt[n].io_loop_uv &&
LWS_LIBUV_ENABLED(context) )//&&
//!context->pt[n].ev_loop_foreign)
LWS_LIBUV_ENABLED(context))
uv_stop(context->pt[n].io_loop_uv);
}
@ -447,7 +431,6 @@ lws_libuv_kill(const struct lws_context *context)
* wsi, and set a flag; when all the wsi closures are finalized then we
* actually stop the libuv event loops.
*/
LWS_VISIBLE void
lws_libuv_stop(struct lws_context *context)
{
@ -514,8 +497,6 @@ lws_libuv_closewsi(uv_handle_t* handle)
context->deprecation_cb();
}
//lwsl_notice("%s: ctx %p: wsi left %d\n", __func__, context, context->count_wsi_allocated);
if (context->requested_kill && context->count_wsi_allocated == 0)
lws_libuv_kill(context);
}
@ -601,7 +582,8 @@ lws_plat_plugins_init(struct lws_context *context, const char * const *d)
lwsl_notice(" %s\n", dent.name);
lws_snprintf(path, sizeof(path) - 1, "%s/%s", *d, dent.name);
lws_snprintf(path, sizeof(path) - 1, "%s/%s", *d,
dent.name);
if (uv_dlopen(path, &lib)) {
uv_dlerror(&lib);
lwsl_err("Error loading DSO: %s\n", lib.errmsg);
@ -631,7 +613,7 @@ lws_plat_plugins_init(struct lws_context *context, const char * const *d)
lcaps.api_magic = LWS_PLUGIN_API_MAGIC;
m = initfunc(context, &lcaps);
if (m) {
lwsl_err("Initializing %s failed %d\n", dent.name, m);
lwsl_err("Init %s failed %d\n", dent.name, m);
goto skip;
}
@ -669,9 +651,9 @@ lws_plat_plugins_destroy(struct lws_context *context)
struct lws_plugin *plugin = context->plugin_list, *p;
lws_plugin_destroy_func func;
char path[256];
int pofs = 0;
void *v;
int m;
int pofs = 0;
#if defined(__MINGW32__) || !defined(WIN32)
pofs = 3;
@ -680,16 +662,16 @@ lws_plat_plugins_destroy(struct lws_context *context)
if (!plugin)
return 0;
// lwsl_notice("%s\n", __func__);
while (plugin) {
p = plugin;
#if !defined(WIN32) && !defined(__MINGW32__)
m = lws_snprintf(path, sizeof(path) - 1, "destroy_%s", plugin->name + pofs);
m = lws_snprintf(path, sizeof(path) - 1, "destroy_%s",
plugin->name + pofs);
path[m - 3] = '\0';
#else
m = lws_snprintf(path, sizeof(path) - 1, "destroy_%s", plugin->name + pofs);
m = lws_snprintf(path, sizeof(path) - 1, "destroy_%s",
plugin->name + pofs);
path[m - 4] = '\0';
#endif

View file

@ -1,7 +1,7 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010-2016 Andy Green <andy@warmcat.com>
* Copyright (C) 2010-2017 Andy Green <andy@warmcat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -73,9 +73,10 @@ lws_free_wsi(struct lws *wsi)
pt = &wsi->context->pt[(int)wsi->tsi];
/* Protocol user data may be allocated either internally by lws
* or by specified the user.
* We should only free what we allocated. */
/*
* Protocol user data may be allocated either internally by lws
* or by specified the user. We should only free what we allocated.
*/
if (wsi->protocol && wsi->protocol->per_session_data_size &&
wsi->user_space && !wsi->user_space_externally_allocated)
lws_free(wsi->user_space);
@ -192,8 +193,8 @@ lws_remove_child_from_any_parent(struct lws *wsi)
pwsi = &wsi->parent->child_list;
while (*pwsi) {
if (*pwsi == wsi) {
lwsl_info("%s: detach %p from parent %p\n",
__func__, wsi, wsi->parent);
lwsl_info("%s: detach %p from parent %p\n", __func__,
wsi, wsi->parent);
if (wsi->parent->protocol)
wsi->parent->protocol->callback(wsi,
@ -251,8 +252,8 @@ lws_bind_protocol(struct lws *wsi, const struct lws_protocols *p)
vp++;
}
if (!hit)
lwsl_err("%s: protocol %p is not in vhost %s protocols list\n",
__func__, p, wsi->vhost->name);
lwsl_err("%s: %p is not in vhost '%s' protocols list\n",
__func__, p, wsi->vhost->name);
}
if (wsi->protocol->callback(wsi, LWS_CALLBACK_HTTP_BIND_PROTOCOL,
@ -326,11 +327,7 @@ lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason)
if (wsi->child_list) {
wsi2 = wsi->child_list;
while (wsi2) {
//lwsl_notice("%s: closing %p: close child %p\n",
// __func__, wsi, wsi2);
wsi1 = wsi2->sibling_list;
//lwsl_notice("%s: closing %p: next sibling %p\n",
// __func__, wsi2, wsi1);
wsi2->parent = NULL;
/* stop it doing shutdown processing */
wsi2->socket_is_permanently_unusable = 1;
@ -362,7 +359,6 @@ lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason)
}
wsi->socket_is_permanently_unusable = 1;
lwsl_debug("------ %s: detected cgi fdhandler wsi %p\n", __func__, wsi);
goto just_kill_connection;
}
@ -421,11 +417,11 @@ lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason)
lws_callback_on_writable(wsi);
return;
}
lwsl_info("wsi %p completed LWSS_FLUSHING_STORED_SEND_BEFORE_CLOSE\n", wsi);
lwsl_info("%p: end FLUSHING_STORED_SEND_BEFORE_CLOSE\n", wsi);
goto just_kill_connection;
default:
if (wsi->trunc_len) {
lwsl_info("wsi %p entering LWSS_FLUSHING_STORED_SEND_BEFORE_CLOSE\n", wsi);
lwsl_info("%p: start FLUSHING_STORED_SEND_BEFORE_CLOSE\n", wsi);
wsi->state = LWSS_FLUSHING_STORED_SEND_BEFORE_CLOSE;
lws_set_timeout(wsi, PENDING_FLUSH_STORED_SEND_BEFORE_CLOSE, 5);
return;
@ -448,7 +444,7 @@ lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason)
}
if (wsi->mode & LWSCM_FLAG_IMPLIES_CALLBACK_CLOSED_CLIENT_HTTP) {
wsi->vhost->protocols[0].callback(wsi, LWS_CALLBACK_CLOSED_CLIENT_HTTP,
wsi->user_space, NULL, 0);
wsi->user_space, NULL, 0);
wsi->told_user_closed = 1;
}
@ -457,8 +453,7 @@ lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason)
* parent and just his ch1 aspect is closing?
*/
if (lws_ext_cb_active(wsi,
LWS_EXT_CB_CHECK_OK_TO_REALLY_CLOSE, NULL, 0) > 0) {
if (lws_ext_cb_active(wsi, LWS_EXT_CB_CHECK_OK_TO_REALLY_CLOSE, NULL, 0) > 0) {
lwsl_ext("extension vetoed close\n");
return;
}
@ -467,7 +462,6 @@ lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason)
* flush any tx pending from extensions, since we may send close packet
* if there are problems with send, just nuke the connection
*/
do {
ret = 0;
eff_buf.token = NULL;
@ -543,22 +537,6 @@ just_kill_connection:
lws_remove_child_from_any_parent(wsi);
#if 0
/* manage the vhost same protocol list entry */
if (wsi->same_vh_protocol_prev) { // we are on the vh list
// make guy who pointed to us, point to what our next was pointing to
*wsi->same_vh_protocol_prev = wsi->same_vh_protocol_next;
// if we had a next guy...
if (wsi->same_vh_protocol_next)
// have him point back to our prev
wsi->same_vh_protocol_next->same_vh_protocol_prev =
wsi->same_vh_protocol_prev;
}
#endif
#if LWS_POSIX
/*
* Testing with ab shows that we have to stage the socket close when
@ -574,44 +552,58 @@ just_kill_connection:
reason != LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY &&
!wsi->socket_is_permanently_unusable) {
#ifdef LWS_OPENSSL_SUPPORT
if (lws_is_ssl(wsi) && wsi->ssl)
{
lwsl_info("%s: shutting down SSL connection: %p (ssl %p, sock %d, state %d)\n", __func__, wsi, wsi->ssl, (int)(long)wsi->desc.sockfd, wsi->state);
int shutdown_error;
if (lws_is_ssl(wsi) && wsi->ssl) {
n = SSL_shutdown(wsi->ssl);
if (n == 1) /* If finished the SSL shutdown, then do socket shutdown, else need to retry SSL shutdown */
n = shutdown(wsi->desc.sockfd, SHUT_WR);
else if (n == 0)
/*
* If finished the SSL shutdown, then do socket
* shutdown, else need to retry SSL shutdown
*/
switch (n) {
case 0:
lws_change_pollfd(wsi, LWS_POLLOUT, LWS_POLLIN);
else /* n < 0 */
{
int shutdown_error = SSL_get_error(wsi->ssl, n);
lwsl_debug("SSL_shutdown returned %d, SSL_get_error: %d\n", n, shutdown_error);
if (shutdown_error == SSL_ERROR_WANT_READ) {
break;
case 1:
n = shutdown(wsi->desc.sockfd, SHUT_WR);
break;
default:
shutdown_error = SSL_get_error(wsi->ssl, n);
lwsl_debug("SSL_shutdown %d, get_error: %d\n",
n, shutdown_error);
switch (shutdown_error) {
case SSL_ERROR_WANT_READ:
lws_change_pollfd(wsi, LWS_POLLOUT, LWS_POLLIN);
n = 0;
} else if (shutdown_error == SSL_ERROR_WANT_WRITE) {
break;
case SSL_ERROR_WANT_WRITE:
lws_change_pollfd(wsi, LWS_POLLOUT, LWS_POLLOUT);
n = 0;
} else { // actual error occurred, just close the connection
break;
default: /* real error, close */
n = shutdown(wsi->desc.sockfd, SHUT_WR);
break;
}
}
}
else
} else
#endif
{
lwsl_info("%s: shutting down connection: %p (sock %d, state %d)\n", __func__, wsi, (int)(long)wsi->desc.sockfd, wsi->state);
lwsl_info("%s: shuttdown conn: %p (sock %d, state %d)\n",
__func__, wsi, (int)(long)wsi->desc.sockfd,
wsi->state);
n = shutdown(wsi->desc.sockfd, SHUT_WR);
}
if (n)
lwsl_debug("closing: shutdown (state %d) ret %d\n", wsi->state, LWS_ERRNO);
lwsl_debug("closing: shutdown (state %d) ret %d\n",
wsi->state, LWS_ERRNO);
// This causes problems with disconnection when the events are half closing connection
// FD_READ | FD_CLOSE (33)
/*
* This causes problems on WINCE / ESP32 with disconnection
* when the events are half closing connection
*/
#if !defined(_WIN32_WCE) && !defined(LWS_WITH_ESP32)
/* libuv: no event available to guarantee completion */
if (!LWS_LIBUV_ENABLED(context)) {
lws_change_pollfd(wsi, LWS_POLLOUT, LWS_POLLIN);
wsi->state = LWSS_SHUTDOWN;
lws_set_timeout(wsi, PENDING_TIMEOUT_SHUTDOWN_FLUSH,
@ -623,8 +615,8 @@ just_kill_connection:
}
#endif
lwsl_info("%s: real just_kill_connection: %p (sockfd %d)\n", __func__,
wsi, wsi->desc.sockfd);
lwsl_debug("%s: real just_kill_connection: %p (sockfd %d)\n", __func__,
wsi, wsi->desc.sockfd);
#ifdef LWS_WITH_HTTP_PROXY
if (wsi->rw) {
@ -637,7 +629,6 @@ just_kill_connection:
* delete socket from the internal poll list if still present
*/
lws_ssl_remove_wsi_from_buffered_list(wsi);
lws_remove_from_timeout_list(wsi);
/* checking return redundant since we anyway close */
@ -698,7 +689,8 @@ just_kill_connection:
/* tell the user it's all over for this guy */
if (wsi->mode != LWSCM_RAW && wsi->protocol && wsi->protocol->callback &&
if (wsi->mode != LWSCM_RAW && wsi->protocol &&
wsi->protocol->callback &&
((wsi->state_pre_close == LWSS_ESTABLISHED) ||
(wsi->state_pre_close == LWSS_RETURNED_CLOSE_ALREADY) ||
(wsi->state_pre_close == LWSS_AWAITING_CLOSE_ACK) ||
@ -708,10 +700,11 @@ just_kill_connection:
(wsi->mode == LWSCM_WS_SERVING && wsi->state_pre_close == LWSS_HTTP))) {
if (wsi->user_space) {
lwsl_debug("%s: doing LWS_CALLBACK_HTTP_DROP_PROTOCOL for %p prot %s\n", __func__, wsi, wsi->protocol->name);
lwsl_debug("%s: %p: DROP_PROTOCOL %s\n", __func__, wsi,
wsi->protocol->name);
wsi->protocol->callback(wsi,
LWS_CALLBACK_HTTP_DROP_PROTOCOL,
wsi->user_space, NULL, 0);
LWS_CALLBACK_HTTP_DROP_PROTOCOL,
wsi->user_space, NULL, 0);
}
lwsl_debug("calling back CLOSED\n");
wsi->protocol->callback(wsi, LWS_CALLBACK_CLOSED,
@ -743,18 +736,21 @@ just_kill_connection:
lwsl_warn("ext destroy wsi failed\n");
async_close:
wsi->socket_is_permanently_unusable = 1;
#ifdef LWS_USE_LIBUV
if (!wsi->parent_carries_io)
if (LWS_LIBUV_ENABLED(context)) {
if (wsi->listener) {
lwsl_debug("%s: stopping listner libuv poll\n", __func__);
lwsl_debug("%s: stop listener poll\n", __func__);
uv_poll_stop(&wsi->w_read.uv_watcher);
}
lwsl_debug("%s: lws_libuv_closehandle: wsi %p\n", __func__, wsi);
/* libuv has to do his own close handle processing asynchronously */
lwsl_debug("%s: lws_libuv_closehandle: wsi %p\n",
__func__, wsi);
/*
* libuv has to do his own close handle processing
* asynchronously
*/
lws_libuv_closehandle(wsi);
return;
@ -771,7 +767,6 @@ lws_close_free_wsi_final(struct lws *wsi)
if (!lws_ssl_close(wsi) && lws_socket_is_valid(wsi->desc.sockfd)) {
#if LWS_POSIX
//lwsl_err("*** closing sockfd %d\n", wsi->desc.sockfd);
n = compatible_close(wsi->desc.sockfd);
if (n)
lwsl_debug("closing: close ret %d\n", LWS_ERRNO);
@ -785,7 +780,7 @@ lws_close_free_wsi_final(struct lws *wsi)
/* outermost destroy notification for wsi (user_space still intact) */
wsi->vhost->protocols[0].callback(wsi, LWS_CALLBACK_WSI_DESTROY,
wsi->user_space, NULL, 0);
wsi->user_space, NULL, 0);
#ifdef LWS_WITH_CGI
if (wsi->cgi) {
@ -824,7 +819,8 @@ lws_get_urlarg_by_name(struct lws *wsi, const char *name, char *buf, int len)
#if LWS_POSIX && !defined(LWS_WITH_ESP32)
LWS_VISIBLE int
interface_to_sa(struct lws_vhost *vh, const char *ifname, struct sockaddr_in *addr, size_t addrlen)
interface_to_sa(struct lws_vhost *vh, const char *ifname,
struct sockaddr_in *addr, size_t addrlen)
{
int ipv6 = 0;
#ifdef LWS_USE_IPV6
@ -852,7 +848,9 @@ lws_get_addresses(struct lws_vhost *vh, void *ads, char *name,
#ifdef LWS_USE_IPV6
if (LWS_IPV6_ENABLED(vh)) {
if (!lws_plat_inet_ntop(AF_INET6, &((struct sockaddr_in6 *)ads)->sin6_addr, rip, rip_len)) {
if (!lws_plat_inet_ntop(AF_INET6,
&((struct sockaddr_in6 *)ads)->sin6_addr,
rip, rip_len)) {
lwsl_err("inet_ntop: %s", strerror(LWS_ERRNO));
return -1;
}
@ -862,8 +860,7 @@ lws_get_addresses(struct lws_vhost *vh, void *ads, char *name,
memmove(rip, rip + 7, strlen(rip) - 6);
getnameinfo((struct sockaddr *)ads,
sizeof(struct sockaddr_in6), name,
name_len, NULL, 0, 0);
sizeof(struct sockaddr_in6), name, name_len, NULL, 0, 0);
return 0;
} else
@ -889,7 +886,8 @@ lws_get_addresses(struct lws_vhost *vh, void *ads, char *name,
while (addr4.sin_family == AF_UNSPEC && res) {
switch (res->ai_family) {
case AF_INET:
addr4.sin_addr = ((struct sockaddr_in *)res->ai_addr)->sin_addr;
addr4.sin_addr =
((struct sockaddr_in *)res->ai_addr)->sin_addr;
addr4.sin_family = AF_INET;
break;
}
@ -1155,9 +1153,9 @@ LWS_VISIBLE lws_fileofs_t
lws_vfs_file_seek_set(lws_fop_fd_t fop_fd, lws_fileofs_t offset)
{
lws_fileofs_t ofs;
lwsl_debug("%s: seeking to %ld, len %ld\n", __func__, (long)offset, (long)fop_fd->len);
ofs = fop_fd->fops->LWS_FOP_SEEK_CUR(fop_fd, offset - fop_fd->pos);
lwsl_debug("%s: result %ld, fop_fd pos %ld\n", __func__, (long)ofs, (long)fop_fd->pos);
return ofs;
}
@ -1165,7 +1163,8 @@ lws_vfs_file_seek_set(lws_fop_fd_t fop_fd, lws_fileofs_t offset)
LWS_VISIBLE lws_fileofs_t
lws_vfs_file_seek_end(lws_fop_fd_t fop_fd, lws_fileofs_t offset)
{
return fop_fd->fops->LWS_FOP_SEEK_CUR(fop_fd, fop_fd->len + fop_fd->pos + offset);
return fop_fd->fops->LWS_FOP_SEEK_CUR(fop_fd, fop_fd->len +
fop_fd->pos + offset);
}
@ -1222,8 +1221,9 @@ lws_vfs_file_open(const struct lws_plat_file_ops *fops, const char *vfs_path,
lws_fop_flags_t *flags)
{
const char *vpath = "";
const struct lws_plat_file_ops *selected = lws_vfs_select_fops(
fops, vfs_path, &vpath);
const struct lws_plat_file_ops *selected;
selected = lws_vfs_select_fops(fops, vfs_path, &vpath);
return selected->LWS_FOP_OPEN(fops, vfs_path, vpath, flags);
}
@ -1500,7 +1500,8 @@ lws_is_final_fragment(struct lws *wsi)
lwsl_info("%s: final %d, rx pk length %ld, draining %ld\n", __func__,
wsi->u.ws.final, (long)wsi->u.ws.rx_packet_length,
(long)wsi->u.ws.rx_draining_ext);
return wsi->u.ws.final && !wsi->u.ws.rx_packet_length && !wsi->u.ws.rx_draining_ext;
return wsi->u.ws.final && !wsi->u.ws.rx_packet_length &&
!wsi->u.ws.rx_draining_ext;
}
LWS_VISIBLE int
@ -1518,7 +1519,8 @@ lws_get_reserved_bits(struct lws *wsi)
int
lws_ensure_user_space(struct lws *wsi)
{
lwsl_info("%s: %p protocol %p\n", __func__, wsi, wsi->protocol);
lwsl_debug("%s: %p protocol %p\n", __func__, wsi, wsi->protocol);
if (!wsi->protocol)
return 1;
@ -1527,13 +1529,13 @@ lws_ensure_user_space(struct lws *wsi)
if (wsi->protocol->per_session_data_size && !wsi->user_space) {
wsi->user_space = lws_zalloc(wsi->protocol->per_session_data_size);
if (wsi->user_space == NULL) {
lwsl_err("Out of memory for conn user space\n");
lwsl_err("%s: OOM\n", __func__);
return 1;
}
} else
lwsl_info("%s: %p protocol pss %lu, user_space=%p\n",
__func__, wsi, (long)wsi->protocol->per_session_data_size,
wsi->user_space);
lwsl_debug("%s: %p protocol pss %lu, user_space=%p\n", __func__,
wsi, (long)wsi->protocol->per_session_data_size,
wsi->user_space);
return 0;
}
@ -1829,10 +1831,8 @@ _lws_rx_flow_control(struct lws *wsi)
}
/* there is no pending change */
if (!(wsi->rxflow_change_to & LWS_RXFLOW_PENDING_CHANGE)) {
// lwsl_debug("%s: no pending change\n", __func__);
if (!(wsi->rxflow_change_to & LWS_RXFLOW_PENDING_CHANGE))
return 0;
}
/* stuff is still buffered, not ready to really accept new input */
if (wsi->rxflow_buffer) {
@ -2043,7 +2043,7 @@ lws_socket_bind(struct lws_vhost *vhost, lws_sockfd_type sockfd, int port,
if (iface) {
if (interface_to_sa(vhost, iface,
(struct sockaddr_in *)v, n) < 0) {
lwsl_err("Unable to find interface %s\n", iface);
lwsl_err("Unable to find if %s\n", iface);
return -1;
}
serv_addr6.sin6_scope_id = lws_get_addr_scope(iface);
@ -2170,19 +2170,17 @@ lws_get_addr_scope(const char *ipaddr)
}
}
if ((ret == NO_ERROR) && (addrs))
{
if ((ret == NO_ERROR) && (addrs)) {
adapter = addrs;
while ((adapter) && (!found))
{
while (adapter && !found) {
addr = adapter->FirstUnicastAddress;
while ((addr) && (!found))
{
if (addr->Address.lpSockaddr->sa_family == AF_INET6)
{
sockaddr = (struct sockaddr_in6 *) (addr->Address.lpSockaddr);
while (addr && !found) {
if (addr->Address.lpSockaddr->sa_family == AF_INET6) {
sockaddr = (struct sockaddr_in6 *)
(addr->Address.lpSockaddr);
lws_plat_inet_ntop(sockaddr->sin6_family, &sockaddr->sin6_addr,
lws_plat_inet_ntop(sockaddr->sin6_family,
&sockaddr->sin6_addr,
ip, sizeof(ip));
if (!strcmp(ip, ipaddr)) {
@ -2513,8 +2511,9 @@ lws_cgi(struct lws *wsi, const char * const *exec_array, int script_uri_path_len
cgi->stdwsi[n]->cgi_channel = n;
cgi->stdwsi[n]->vhost = wsi->vhost;
lwsl_debug("%s: cgi %p: pipe fd %d -> fd %d / %d\n", __func__, cgi->stdwsi[n], n,
cgi->pipe_fds[n][!!(n == 0)], cgi->pipe_fds[n][!(n == 0)]);
lwsl_debug("%s: cgi %p: pipe fd %d -> fd %d / %d\n", __func__,
cgi->stdwsi[n], n, cgi->pipe_fds[n][!!(n == 0)],
cgi->pipe_fds[n][!(n == 0)]);
/* read side is 0, stdin we want the write side, others read */
cgi->stdwsi[n]->desc.sockfd = cgi->pipe_fds[n][!!(n == 0)];
@ -2661,13 +2660,13 @@ lws_cgi(struct lws *wsi, const char * const *exec_array, int script_uri_path_len
if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE)) {
env_array[n++] = p;
p += lws_snprintf(p, end - p, "CONTENT_TYPE=%s",
lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE));
lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE));
p++;
}
if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH)) {
env_array[n++] = p;
p += lws_snprintf(p, end - p, "CONTENT_LENGTH=%s",
lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH));
lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH));
p++;
}
}
@ -2717,7 +2716,9 @@ lws_cgi(struct lws *wsi, const char * const *exec_array, int script_uri_path_len
prctl(PR_SET_PDEATHSIG, SIGTERM);
#endif
if (script_uri_path_len >= 0)
setpgrp(); /* stops on-daemonized main processess getting SIGINT from TTY */
/* stops non-daemonized main processess getting SIGINT
* from TTY */
setpgrp();
if (cgi->pid) {
/* we are the parent process */
@ -2816,16 +2817,16 @@ lws_cgi_write_split_stdout_headers(struct lws *wsi)
while (wsi->hdr_state != LHCS_PAYLOAD) {
/*
* we have to separate header / finalize and
* payload chunks, since they need to be
* handled separately
* We have to separate header / finalize and payload chunks,
* since they need to be handled separately
*/
switch (wsi->hdr_state) {
case LHCS_RESPONSE:
lwsl_info("LHCS_RESPONSE: issuing response %d\n",
wsi->cgi->response_code);
if (lws_add_http_header_status(wsi, wsi->cgi->response_code, &p, end))
if (lws_add_http_header_status(wsi, wsi->cgi->response_code,
&p, end))
return 1;
if (!wsi->cgi->explicitly_chunked &&
!wsi->cgi->content_length &&
@ -2920,7 +2921,8 @@ lws_cgi_write_split_stdout_headers(struct lws *wsi)
}
}
if (n) {
lwsl_debug("-- 0x%02X %c %d %d\n", (unsigned char)c, c, wsi->cgi->match[1], wsi->hdr_state);
lwsl_debug("-- 0x%02X %c %d %d\n", (unsigned char)c, c,
wsi->cgi->match[1], wsi->hdr_state);
if (!c)
return -1;
switch (wsi->hdr_state) {
@ -3042,7 +3044,8 @@ lws_cgi_write_split_stdout_headers(struct lws *wsi)
if (n > 0) {
if (m) {
char chdr[LWS_HTTP_CHUNK_HDR_SIZE];
m = lws_snprintf(chdr, LWS_HTTP_CHUNK_HDR_SIZE - 3, "%X\x0d\x0a", n);
m = lws_snprintf(chdr, LWS_HTTP_CHUNK_HDR_SIZE - 3,
"%X\x0d\x0a", n);
memmove(start + m, start, n);
memcpy(start, chdr, m);
memcpy(start + m + n, "\x0d\x0a", 2);
@ -3057,7 +3060,7 @@ lws_cgi_write_split_stdout_headers(struct lws *wsi)
wsi->cgi->content_length_seen += m;
} else {
if (wsi->cgi_stdout_zero_length) {
lwsl_debug("%s: failed to read anything: stdout is POLLHUP'd\n", __func__);
lwsl_debug("%s: stdout is POLLHUP'd\n", __func__);
return 1;
}
wsi->cgi_stdout_zero_length = 1;
@ -3085,8 +3088,8 @@ lws_cgi_kill(struct lws *wsi)
}
/* kill the process group */
n = kill(-wsi->cgi->pid, SIGTERM);
lwsl_debug("%s: SIGTERM child PID %d says %d (errno %d)\n", __func__,
wsi->cgi->pid, n, errno);
lwsl_debug("%s: SIGTERM child PID %d says %d (errno %d)\n",
__func__, wsi->cgi->pid, n, errno);
if (n < 0) {
/*
* hum seen errno=3 when process is listed in ps,
@ -3185,7 +3188,8 @@ lws_cgi_kill_terminated(struct lws_context_per_thread *pt)
if (!cgi->content_length) {
/*
* well, if he sends chunked... give him 2s after the
* well, if he sends chunked...
* give him 2s after the
* cgi terminated to send buffered
*/
cgi->chunked_grace++;
@ -3208,8 +3212,6 @@ lws_cgi_kill_terminated(struct lws_context_per_thread *pt)
}
}
/* disable this to confirm timeout cgi cleanup flow */
#if 1
pcgi = &pt->cgi_list;
/* check all the subprocesses on the cgi list */
@ -3239,14 +3241,16 @@ lws_cgi_kill_terminated(struct lws_context_per_thread *pt)
if (cgi->content_length)
lwsl_debug("%s: wsi %p: expected content length seen: %lld\n",
__func__, cgi->wsi, (unsigned long long)cgi->content_length_seen);
__func__, cgi->wsi,
(unsigned long long)cgi->content_length_seen);
/* reap it */
if (waitpid(cgi->pid, &status, WNOHANG) > 0) {
if (!cgi->content_length) {
/*
* well, if he sends chunked... give him 2s after the
* well, if he sends chunked...
* give him 2s after the
* cgi terminated to send buffered
*/
cgi->chunked_grace++;
@ -3255,6 +3259,7 @@ lws_cgi_kill_terminated(struct lws_context_per_thread *pt)
finish_him:
lwsl_debug("%s: found PID %d on cgi list\n",
__func__, cgi->pid);
/* defeat kill() */
cgi->pid = 0;
lws_cgi_kill(cgi->wsi);
@ -3262,12 +3267,6 @@ finish_him:
break;
}
}
#endif
/* general anti zombie defence */
// n = waitpid(-1, &status, WNOHANG);
//if (n > 0)
// lwsl_notice("%s: anti-zombie wait says %d\n", __func__, n);
return 0;
}
@ -3919,7 +3918,6 @@ lws_ring_insert(struct lws_ring *ring, const void *src, size_t max_count)
* n is legal to insert, but as an optimization we can cut the
* insert into one or two memcpys, depending on if it wraps
*/
if (ring->head + n > ring->buflen) {
/*
@ -3945,7 +3943,8 @@ lws_ring_insert(struct lws_ring *ring, const void *src, size_t max_count)
}
LWS_VISIBLE LWS_EXTERN size_t
lws_ring_consume(struct lws_ring *ring, uint32_t *tail, void *dest, size_t max_count)
lws_ring_consume(struct lws_ring *ring, uint32_t *tail, void *dest,
size_t max_count)
{
uint8_t *odest = dest;
void *orig_tail = tail;

View file

@ -125,9 +125,11 @@ _lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi)
n = esp_get_free_heap_size();
if (n != context->last_free_heap) {
if (n > context->last_free_heap)
lwsl_notice(" heap :%d (+%d)\n", n, n - context->last_free_heap);
lwsl_notice(" heap :%d (+%d)\n", n,
n - context->last_free_heap);
else
lwsl_notice(" heap :%d (-%d)\n", n, context->last_free_heap - n);
lwsl_notice(" heap :%d (-%d)\n", n,
context->last_free_heap - n);
context->last_free_heap = n;
}
}
@ -295,8 +297,6 @@ lws_plat_set_socket_options(struct lws_vhost *vhost, int fd)
/* Disable Nagle */
optval = 1;
// if (setsockopt(fd, SOL_TCP, TCP_NODELAY, (const void *)&optval, optlen) < 0)
// return 1;
if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &optval, optlen) < 0)
return 1;
@ -315,10 +315,6 @@ lws_plat_drop_app_privileges(struct lws_context_creation_info *info)
LWS_VISIBLE int
lws_plat_context_early_init(void)
{
//signal(SIGPIPE, SIG_IGN);
// signal(SIGABRT, sigabrt_handler);
return 0;
}

View file

@ -1,3 +1,24 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010-2017 Andy Green <andy@warmcat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation:
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#include "private-libwebsockets.h"
#include <pwd.h>
@ -8,14 +29,10 @@
#endif
#include <dirent.h>
/*
* included from libwebsockets.c for unix builds
*/
unsigned long long time_in_microseconds(void)
{
struct timeval tv;
gettimeofday(&tv, NULL);
return ((unsigned long long)tv.tv_sec * 1000000LL) + tv.tv_usec;
}
@ -497,7 +514,6 @@ static void
sigabrt_handler(int x)
{
printf("%s\n", __func__);
//*(char *)0 = 0;
}
#endif
@ -508,8 +524,6 @@ lws_plat_context_early_init(void)
signal(SIGPIPE, SIG_IGN);
#endif
// signal(SIGABRT, sigabrt_handler);
return 0;
}
@ -802,7 +816,7 @@ lws_plat_init(struct lws_context *context,
if (!lws_libev_init_fd_table(context) &&
!lws_libuv_init_fd_table(context) &&
!lws_libevent_init_fd_table(context)) {
/* otherwise libev handled it instead */
/* otherwise libev/uv/event handled it instead */
while (n--) {
if (pipe(pt->dummy_pipe_fds)) {

View file

@ -1,7 +1,7 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010-2015 Andy Green <andy@warmcat.com>
* Copyright (C) 2010-2017 Andy Green <andy@warmcat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -159,8 +159,6 @@ int lws_issue_raw(struct lws *wsi, unsigned char *buf, size_t len)
n = lws_ssl_capable_write(wsi, buf, n);
lws_latency(context, wsi, "send lws_issue_raw", n, n == len);
//lwsl_notice("lws_ssl_capable_write: %d\n", n);
switch (n) {
case LWS_SSL_CAPABLE_ERROR:
/* we're going to close, let close know sends aren't possible */
@ -244,8 +242,8 @@ LWS_VISIBLE int lws_write(struct lws *wsi, unsigned char *buf, size_t len,
unsigned char is_masked_bit = 0;
unsigned char *dropmask = NULL;
struct lws_tokens eff_buf;
int pre = 0, n;
size_t orig_len = len;
int pre = 0, n;
if (wsi->parent_carries_io) {
struct lws_write_passthru pas;
@ -284,7 +282,6 @@ LWS_VISIBLE int lws_write(struct lws *wsi, unsigned char *buf, size_t len,
/* remove us from the list */
struct lws **w = &pt->tx_draining_ext_list;
// lwsl_notice("%s: TX EXT DRAINING: Remove from list\n", __func__);
wsi->u.ws.tx_draining_ext = 0;
/* remove us from context draining ext list */
while (*w) {
@ -407,8 +404,6 @@ LWS_VISIBLE int lws_write(struct lws *wsi, unsigned char *buf, size_t len,
buf = (unsigned char *)eff_buf.token;
len = eff_buf.token_len;
lwsl_debug("%p / %d\n", buf, (int)len);
if (!buf) {
lwsl_err("null buf (%d)\n", (int)len);
return -1;
@ -611,8 +606,6 @@ LWS_VISIBLE int lws_serve_http_file_fragment(struct lws *wsi)
#endif
int n, m;
// lwsl_notice("%s (trunc len %d)\n", __func__, wsi->trunc_len);
while (wsi->http2_substream || !lws_send_pipe_choked(wsi)) {
if (wsi->trunc_len) {
@ -689,8 +682,6 @@ LWS_VISIBLE int lws_serve_http_file_fragment(struct lws *wsi)
if (lws_vfs_file_read(wsi->u.http.fop_fd, &amount, p, poss) < 0)
goto file_had_it; /* caller will close */
//lwsl_notice("amount %ld\n", amount);
if (wsi->sending_chunked)
n = (int)amount;
@ -852,7 +843,8 @@ lws_ssl_capable_write_no_ssl(struct lws *wsi, unsigned char *buf, int len)
// !!!
#endif
lwsl_debug("ERROR writing len %d to skt fd %d err %d / errno %d\n", len, wsi->desc.sockfd, n, LWS_ERRNO);
lwsl_debug("ERROR writing len %d to skt fd %d err %d / errno %d\n",
len, wsi->desc.sockfd, n, LWS_ERRNO);
return LWS_SSL_CAPABLE_ERROR;
}
#endif

View file

@ -1,7 +1,7 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010-2013 Andy Green <andy@warmcat.com>
* Copyright (C) 2010-2017 Andy Green <andy@warmcat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -109,11 +109,11 @@ lws_header_table_reset(struct lws *wsi, int autoservice)
lws_free_set_NULL(wsi->u.hdr.preamble_rx);
if (autoservice) {
lwsl_notice("%s: calling service on readbuf ah\n", __func__);
lwsl_debug("%s: service on readbuf ah\n", __func__);
pt = &wsi->context->pt[(int)wsi->tsi];
/* unlike a normal connect, we have the headers already
/*
* Unlike a normal connect, we have the headers already
* (or the first part of them anyway)
*/
pfd = &pt->fds[wsi->position_in_fds_table];
@ -153,9 +153,6 @@ __lws_remove_from_ah_waiting_list(struct lws *wsi)
struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
struct lws **pwsi =&pt->ah_wait_list;
//if (wsi->u.hdr.ah)
// return 0;
while (*pwsi) {
if (*pwsi == wsi) {
lwsl_info("%s: wsi %p\n", __func__, wsi);
@ -426,7 +423,7 @@ int lws_header_table_detach(struct lws *wsi, int autoservice)
assert(!!pt->ah_wait_list_length == !!(lws_intptr_t)pt->ah_wait_list);
bail:
lwsl_info("%s: wsi %p: ah %p (tsi=%d, count = %d)\n", __func__,
(void *)wsi, (void *)ah, pt->tid, pt->ah_count_in_use);
(void *)wsi, (void *)ah, pt->tid, pt->ah_count_in_use);
lws_pt_unlock(pt);
@ -527,7 +524,8 @@ LWS_VISIBLE int lws_hdr_copy(struct lws *wsi, char *dst, int len,
return 0;
do {
strcpy(dst, &wsi->u.hdr.ah->data[wsi->u.hdr.ah->frags[n].offset]);
strcpy(dst,
&wsi->u.hdr.ah->data[wsi->u.hdr.ah->frags[n].offset]);
dst += wsi->u.hdr.ah->frags[n].len;
n = wsi->u.hdr.ah->frags[n].nfrag;
} while (n);
@ -549,7 +547,8 @@ char *lws_hdr_simple_ptr(struct lws *wsi, enum lws_token_indexes h)
int LWS_WARN_UNUSED_RESULT
lws_pos_in_bounds(struct lws *wsi)
{
if (wsi->u.hdr.ah->pos < (unsigned int)wsi->context->max_http_header_data)
if (wsi->u.hdr.ah->pos <
(unsigned int)wsi->context->max_http_header_data)
return 0;
if (wsi->u.hdr.ah->pos == wsi->context->max_http_header_data) {
@ -559,9 +558,8 @@ lws_pos_in_bounds(struct lws *wsi)
/*
* with these tests everywhere, it should never be able to exceed
* the limit, only meet the limit
* the limit, only meet it
*/
lwsl_err("%s: pos %d, limit %d\n", __func__, wsi->u.hdr.ah->pos,
wsi->context->max_http_header_data);
assert(0);
@ -1567,7 +1565,8 @@ drain_extension:
goto already_done;
n = lws_ext_cb_active(wsi, LWS_EXT_CB_PAYLOAD_RX, &eff_buf, 0);
/* eff_buf may be pointing somewhere completely different now,
/*
* eff_buf may be pointing somewhere completely different now,
* it's the output
*/
wsi->u.ws.first_fragment = 0;
@ -1582,10 +1581,10 @@ drain_extension:
if (rx_draining_ext && eff_buf.token_len == 0)
goto already_done;
if (n && eff_buf.token_len) {
if (n && eff_buf.token_len)
/* extension had more... main loop will come back */
lws_add_wsi_to_draining_ext_list(wsi);
} else
else
lws_remove_wsi_from_draining_ext_list(wsi);
if (eff_buf.token_len > 0 ||

View file

@ -1,7 +1,7 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010-2015 Andy Green <andy@warmcat.com>
* Copyright (C) 2010-2017 Andy Green <andy@warmcat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -63,9 +63,6 @@ _lws_change_pollfd(struct lws *wsi, int _and, int _or, struct lws_pollargs *pa)
pa->prev_events = pfd->events;
pa->events = pfd->events = (pfd->events & ~_and) | _or;
//lwsl_notice("%s: wsi %p, posin %d. from %d -> %d\n", __func__, wsi, wsi->position_in_fds_table, pa->prev_events, pa->events);
if (wsi->http2_substream)
return 0;
@ -194,13 +191,11 @@ insert_wsi_socket_into_fds(struct lws_context *context, struct lws *wsi)
#endif
wsi->position_in_fds_table = pt->fds_count;
// lwsl_notice("%s: %p: setting posinfds %d\n", __func__, wsi, wsi->position_in_fds_table);
pt->fds[wsi->position_in_fds_table].fd = wsi->desc.sockfd;
#if LWS_POSIX
pt->fds[wsi->position_in_fds_table].events = LWS_POLLIN;
#else
pt->fds[wsi->position_in_fds_table].events = 0; // LWS_POLLIN;
pt->fds[wsi->position_in_fds_table].events = 0;
#endif
pa.events = pt->fds[pt->fds_count].events;
@ -243,7 +238,8 @@ remove_wsi_socket_from_fds(struct lws *wsi)
#if !defined(_WIN32) && !defined(LWS_WITH_ESP8266)
if (wsi->desc.sockfd > context->max_fds) {
lwsl_err("fd %d too high (%d)\n", wsi->desc.sockfd, context->max_fds);
lwsl_err("fd %d too high (%d)\n", wsi->desc.sockfd,
context->max_fds);
return 1;
}
#endif
@ -258,8 +254,10 @@ remove_wsi_socket_from_fds(struct lws *wsi)
m = wsi->position_in_fds_table;
#if !defined(LWS_WITH_ESP8266)
lws_libev_io(wsi, LWS_EV_STOP | LWS_EV_READ | LWS_EV_WRITE | LWS_EV_PREPARE_DELETION);
lws_libuv_io(wsi, LWS_EV_STOP | LWS_EV_READ | LWS_EV_WRITE | LWS_EV_PREPARE_DELETION);
lws_libev_io(wsi, LWS_EV_STOP | LWS_EV_READ | LWS_EV_WRITE |
LWS_EV_PREPARE_DELETION);
lws_libuv_io(wsi, LWS_EV_STOP | LWS_EV_READ | LWS_EV_WRITE |
LWS_EV_PREPARE_DELETION);
lws_pt_lock(pt);
@ -277,7 +275,8 @@ remove_wsi_socket_from_fds(struct lws *wsi)
/* end guy's "position in fds table" is now the deletion guy's old one */
end_wsi = wsi_from_fd(context, v);
if (!end_wsi) {
lwsl_err("no wsi found for sock fd %d at pos %d, pt->fds_count=%d\n", (int)pt->fds[m].fd, m, pt->fds_count);
lwsl_err("no wsi found for sock fd %d at pos %d, pt->fds_count=%d\n",
(int)pt->fds[m].fd, m, pt->fds_count);
assert(0);
} else
end_wsi->position_in_fds_table = m;
@ -301,7 +300,7 @@ remove_wsi_socket_from_fds(struct lws *wsi)
lws_pt_unlock(pt);
if (wsi->vhost->protocols[0].callback(wsi, LWS_CALLBACK_UNLOCK_POLL,
wsi->user_space, (void *) &pa, 1))
wsi->user_space, (void *) &pa, 1))
ret = -1;
#endif
return ret;
@ -323,7 +322,7 @@ lws_change_pollfd(struct lws *wsi, int _and, int _or)
return 1;
if (wsi->vhost->protocols[0].callback(wsi, LWS_CALLBACK_LOCK_POLL,
wsi->user_space, (void *) &pa, 0))
wsi->user_space, (void *) &pa, 0))
return -1;
pt = &context->pt[(int)wsi->tsi];
@ -360,7 +359,8 @@ lws_callback_on_writable(struct lws *wsi)
#if defined(LWS_WITH_STATS)
if (!wsi->active_writable_req_us) {
wsi->active_writable_req_us = time_in_microseconds();
lws_stats_atomic_bump(wsi->context, pt, LWSSTATS_C_WRITEABLE_CB_EFF_REQ, 1);
lws_stats_atomic_bump(wsi->context, pt,
LWSSTATS_C_WRITEABLE_CB_EFF_REQ, 1);
}
#endif
n = lws_callback_on_writable(wsi->parent);
@ -450,20 +450,14 @@ network_sock:
void
lws_same_vh_protocol_insert(struct lws *wsi, int n)
{
//lwsl_err("%s: pre insert vhost start wsi %p, that wsi prev == %p\n",
// __func__,
// wsi->vhost->same_vh_protocol_list[n],
// wsi->same_vh_protocol_prev);
if (wsi->same_vh_protocol_prev || wsi->same_vh_protocol_next) {
lws_same_vh_protocol_remove(wsi);
lwsl_notice("Attempted to attach wsi twice to same vh prot\n");
}
wsi->same_vh_protocol_prev = /* guy who points to us */
&wsi->vhost->same_vh_protocol_list[n];
wsi->same_vh_protocol_next = /* old first guy is our next */
wsi->vhost->same_vh_protocol_list[n];
wsi->same_vh_protocol_prev = &wsi->vhost->same_vh_protocol_list[n];
/* old first guy is our next */
wsi->same_vh_protocol_next = wsi->vhost->same_vh_protocol_list[n];
/* we become the new first guy */
wsi->vhost->same_vh_protocol_list[n] = wsi;
@ -514,7 +508,6 @@ lws_callback_on_writable_all_protocol_vhost(const struct lws_vhost *vhost,
if (protocol < vhost->protocols ||
protocol >= (vhost->protocols + vhost->count_protocols)) {
lwsl_err("%s: protocol %p is not from vhost %p (%p - %p)\n",
__func__, protocol, vhost->protocols, vhost,
(vhost->protocols + vhost->count_protocols));
@ -523,19 +516,13 @@ lws_callback_on_writable_all_protocol_vhost(const struct lws_vhost *vhost,
}
wsi = vhost->same_vh_protocol_list[protocol - vhost->protocols];
//lwsl_notice("%s: protocol %p, start wsi %p\n", __func__, protocol, wsi);
while (wsi) {
//lwsl_notice("%s: protocol %p, this wsi %p (wsi->protocol=%p)\n",
// __func__, protocol, wsi, wsi->protocol);
assert(wsi->protocol == protocol);
assert(*wsi->same_vh_protocol_prev == wsi);
if (wsi->same_vh_protocol_next) {
// lwsl_err("my next says %p\n", wsi->same_vh_protocol_next);
// lwsl_err("my next's prev says %p\n",
// wsi->same_vh_protocol_next->same_vh_protocol_prev);
assert(wsi->same_vh_protocol_next->same_vh_protocol_prev == &wsi->same_vh_protocol_next);
}
//lwsl_notice(" apv: %p\n", wsi);
if (wsi->same_vh_protocol_next)
assert(wsi->same_vh_protocol_next->same_vh_protocol_prev ==
&wsi->same_vh_protocol_next);
lws_callback_on_writable(wsi);
wsi = wsi->same_vh_protocol_next;
}

View file

@ -121,7 +121,10 @@ lws_ranges_next(struct lws_range_parsing *rp)
if (c == ',')
rp->pos++;
/* by the end of this, start and end are always valid if the range still is */
/*
* By the end of this, start and end are
* always valid if the range still is
*/
if (!rp->start_valid) { /* eg, -500 */
if (rp->end > rp->extent)

View file

@ -1,7 +1,7 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010-2016 Andy Green <andy@warmcat.com>
* Copyright (C) 2010-2017 Andy Green <andy@warmcat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -262,7 +262,6 @@ lws_select_vhost(struct lws_context *context, int port, const char *servername)
* never reach here. SSL will still fail it if the cert doesn't allow
* *.x.com.
*/
vhost = context->vhost_list;
while (vhost) {
m = strlen(vhost->name);
@ -455,7 +454,6 @@ lws_http_serve(struct lws *wsi, char *uri, const char *origin,
wsi->u.http.fop_fd->mod_time = (uint32_t)st.st_mtime;
fflags |= LWS_FOP_FLAG_MOD_TIME_VALID;
lwsl_debug(" %s mode %d\n", path, S_IFMT & st.st_mode);
#if !defined(WIN32) && LWS_POSIX && !defined(LWS_WITH_ESP32)
if ((S_IFMT & st.st_mode) == S_IFLNK) {
len = readlink(path, sym, sizeof(sym) - 1);
@ -1016,9 +1014,7 @@ lws_http_action(struct lws *wsi)
(hit->origin_protocol == LWSMPRO_REDIR_HTTP ||
hit->origin_protocol == LWSMPRO_REDIR_HTTPS)) &&
(hit->origin_protocol != LWSMPRO_CGI &&
hit->origin_protocol != LWSMPRO_CALLBACK //&&
//hit->protocol == NULL
)) {
hit->origin_protocol != LWSMPRO_CALLBACK)) {
unsigned char *start = pt->serv_buf + LWS_PRE,
*p = start, *end = p + 512;
@ -1081,8 +1077,6 @@ lws_http_action(struct lws *wsi)
goto transaction_result_n;
}
// lwsl_notice(plain);
if (!lws_find_string_in_file(hit->basic_auth_login_file, plain, m)) {
lwsl_err("basic auth lookup failed\n");
return lws_unauthorised_basic_auth(wsi);
@ -1310,10 +1304,10 @@ deal_body:
bail_nuke_ah:
/* we're closing, losing some rx is OK */
lws_header_table_force_to_detachable_state(wsi);
// lwsl_notice("%s: drop1\n", __func__);
lws_header_table_detach(wsi, 1);
return 1;
#if LWS_POSIX
transaction_result_n:
lws_return_http_status(wsi, n, NULL);
@ -1639,9 +1633,9 @@ upgrade_ws:
while (*p && !hit) {
n = 0;
non_space_char_found = 0;
while (n < sizeof(protocol_name) - 1 && *p &&
*p != ',') {
// ignore leading spaces
while (n < sizeof(protocol_name) - 1 &&
*p && *p != ',') {
/* ignore leading spaces */
if (!non_space_char_found && *p == ' ') {
n++;
continue;
@ -1767,8 +1761,6 @@ upgrade_ws:
/* !!! drop ah unreservedly after ESTABLISHED */
if (!wsi->more_rx_waiting) {
lws_header_table_force_to_detachable_state(wsi);
//lwsl_notice("%p: dropping ah EST\n", wsi);
lws_header_table_detach(wsi, 1);
}
@ -1781,7 +1773,6 @@ bail_nuke_ah:
/* drop the header info */
/* we're closing, losing some rx is OK */
lws_header_table_force_to_detachable_state(wsi);
//lwsl_notice("%s: drop2\n", __func__);
lws_header_table_detach(wsi, 1);
return 1;
@ -2500,8 +2491,6 @@ lws_server_socket_service(struct lws_context *context, struct lws *wsi,
socklen_t clilen;
#endif
int n, len;
// lwsl_notice("%s: mode %d\n", __func__, wsi->mode);
switch (wsi->mode) {
@ -2555,8 +2544,6 @@ lws_server_socket_service(struct lws_context *context, struct lws *wsi,
wsi->state == LWSS_HTTP_ISSUING_FILE ||
wsi->state == LWSS_HTTP_HEADERS)) {
if (!wsi->u.hdr.ah) {
//lwsl_err("wsi %p: missing ah\n", wsi);
/* no autoservice beacuse we will do it next */
if (lws_header_table_attach(wsi, 0)) {
lwsl_info("wsi %p: failed to acquire ah\n", wsi);
@ -2565,22 +2552,14 @@ lws_server_socket_service(struct lws_context *context, struct lws *wsi,
}
ah = wsi->u.hdr.ah;
//lwsl_notice("%s: %p: rxpos:%d rxlen:%d\n", __func__, wsi,
// ah->rxpos, ah->rxlen);
/* if nothing in ah rx buffer, get some fresh rx */
if (ah->rxpos == ah->rxlen) {
ah->rxlen = lws_ssl_capable_read(wsi, ah->rx,
sizeof(ah->rx));
ah->rxpos = 0;
//lwsl_notice("%s: wsi %p, ah->rxlen = %d\r\n",
// __func__, wsi, ah->rxlen);
switch (ah->rxlen) {
case 0:
lwsl_info("%s: read 0 len\n", __func__);
/* lwsl_info(" state=%d\n", wsi->state); */
// if (!wsi->hdr_parsing_completed)
// lws_header_table_detach(wsi);
/* fallthru */
case LWS_SSL_CAPABLE_ERROR:
goto fail;
@ -2615,7 +2594,10 @@ lws_server_socket_service(struct lws_context *context, struct lws *wsi,
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);
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 &&
@ -2635,9 +2617,7 @@ lws_server_socket_service(struct lws_context *context, struct lws *wsi,
switch (len) {
case 0:
lwsl_info("%s: read 0 len\n", __func__);
/* lwsl_info(" state=%d\n", wsi->state); */
// if (!wsi->hdr_parsing_completed)
// lws_header_table_detach(wsi);
/* fallthru */
case LWS_SSL_CAPABLE_ERROR:
goto fail;
@ -2792,7 +2772,6 @@ try_pollout:
if (accept_fd < 0) {
if (LWS_ERRNO == LWS_EAGAIN ||
LWS_ERRNO == LWS_EWOULDBLOCK) {
// lwsl_err("accept asks to try again\n");
break;
}
lwsl_err("ERROR on accept: %s\n", strerror(LWS_ERRNO));
@ -3089,7 +3068,6 @@ lws_interpret_incoming_packet(struct lws *wsi, unsigned char **buf, size_t len)
}
if (wsi->u.ws.rx_draining_ext) {
// lwsl_notice("draining with 0\n");
m = lws_rx_sm(wsi, 0);
if (m < 0)
return -1;
@ -3401,10 +3379,6 @@ retry_as_first:
/* form-data; name="file"; filename="t.txt" */
if (*in == '\x0d') {
// lwsl_notice("disp: '%s', '%s', '%s'\n",
// s->content_disp, s->name,
// s->content_disp_filename);
if (s->content_disp_filename[0])
if (s->output(s->data, s->name,
&s->out, s->pos, LWS_UFS_OPEN))

View file

@ -1,7 +1,7 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010-2015 Andy Green <andy@warmcat.com>
* Copyright (C) 2010-2017 Andy Green <andy@warmcat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -30,10 +30,13 @@ lws_calllback_as_writeable(struct lws *wsi)
lws_stats_atomic_bump(wsi->context, pt, LWSSTATS_C_WRITEABLE_CB, 1);
#if defined(LWS_WITH_STATS)
if (wsi->active_writable_req_us) {
uint64_t ul = time_in_microseconds() - wsi->active_writable_req_us;
uint64_t ul = time_in_microseconds() -
wsi->active_writable_req_us;
lws_stats_atomic_bump(wsi->context, pt, LWSSTATS_MS_WRITABLE_DELAY, ul);
lws_stats_atomic_max(wsi->context, pt, LWSSTATS_MS_WORST_WRITABLE_DELAY, ul);
lws_stats_atomic_bump(wsi->context, pt,
LWSSTATS_MS_WRITABLE_DELAY, ul);
lws_stats_atomic_max(wsi->context, pt,
LWSSTATS_MS_WORST_WRITABLE_DELAY, ul);
wsi->active_writable_req_us = 0;
}
#endif
@ -74,8 +77,6 @@ lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd)
#endif
int ret, m, n;
// lwsl_err("%s: %p\n", __func__, wsi);
wsi->leave_pollout_active = 0;
wsi->handling_pollout = 1;
/*
@ -110,9 +111,9 @@ lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd)
if (wsi->mode == LWSCM_WSCL_ISSUE_HTTP_BODY)
goto user_service;
#ifdef LWS_USE_HTTP2
/* Priority 2: protocol packets
/*
* Priority 2: protocol packets
*/
if (wsi->pps) {
lwsl_info("servicing pps %d\n", wsi->pps);
@ -254,6 +255,7 @@ lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd)
ret = 1;
if (wsi->mode == LWSCM_RAW || wsi->mode == LWSCM_RAW_FILEDESC)
ret = 0;
while (ret == 1) {
/* default to nobody has more to spill */
@ -264,9 +266,8 @@ lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd)
/* give every extension a chance to spill */
m = lws_ext_cb_active(wsi,
LWS_EXT_CB_PACKET_TX_PRESEND,
&eff_buf, 0);
m = lws_ext_cb_active(wsi, LWS_EXT_CB_PACKET_TX_PRESEND,
&eff_buf, 0);
if (m < 0) {
lwsl_err("ext reports fatal error\n");
goto bail_die;
@ -439,10 +440,8 @@ bail_die:
int
lws_service_timeout_check(struct lws *wsi, unsigned int sec)
{
//#if LWS_POSIX
struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
int n = 0;
//#endif
(void)n;
@ -461,19 +460,24 @@ lws_service_timeout_check(struct lws *wsi, unsigned int sec)
* connection
*/
if ((time_t)sec > wsi->pending_timeout_limit) {
//#if LWS_POSIX
if (wsi->desc.sockfd != LWS_SOCK_INVALID && wsi->position_in_fds_table >= 0)
if (wsi->desc.sockfd != LWS_SOCK_INVALID &&
wsi->position_in_fds_table >= 0)
n = pt->fds[wsi->position_in_fds_table].events;
lws_stats_atomic_bump(wsi->context, pt, LWSSTATS_C_TIMEOUTS, 1);
/* no need to log normal idle keepalive timeout */
if (wsi->pending_timeout != PENDING_TIMEOUT_HTTP_KEEPALIVE_IDLE)
lwsl_info("wsi %p: TIMEDOUT WAITING on %d (did hdr %d, ah %p, wl %d, pfd events %d) %llu vs %llu\n",
(void *)wsi, wsi->pending_timeout,
wsi->hdr_parsing_completed, wsi->u.hdr.ah,
pt->ah_wait_list_length, n, (unsigned long long)sec, (unsigned long long)wsi->pending_timeout_limit);
//#endif
lwsl_info("wsi %p: TIMEDOUT WAITING on %d "
"(did hdr %d, ah %p, wl %d, pfd "
"events %d) %llu vs %llu\n",
(void *)wsi, wsi->pending_timeout,
wsi->hdr_parsing_completed, wsi->u.hdr.ah,
pt->ah_wait_list_length, n,
(unsigned long long)sec,
(unsigned long long)wsi->pending_timeout_limit);
/*
* Since he failed a timeout, he already had a chance to do
* something and was unable to... that includes situations like
@ -485,7 +489,8 @@ lws_service_timeout_check(struct lws *wsi, unsigned int sec)
if (wsi->mode == LWSCM_WSCL_WAITING_SSL)
wsi->vhost->protocols[0].callback(wsi,
LWS_CALLBACK_CLIENT_CONNECTION_ERROR,
wsi->user_space, (void *)"Timed out waiting SSL", 21);
wsi->user_space,
(void *)"Timed out waiting SSL", 21);
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
@ -507,8 +512,10 @@ int lws_rxflow_cache(struct lws *wsi, unsigned char *buf, int n, int len)
/* a new rxflow, buffer it and warn caller */
lwsl_info("new rxflow input buffer len %d\n", len - n);
wsi->rxflow_buffer = lws_malloc(len - n);
if (!wsi->rxflow_buffer)
return -1;
wsi->rxflow_len = len - n;
wsi->rxflow_pos = 0;
memcpy(wsi->rxflow_buffer, buf + n, len - n);
@ -548,7 +555,7 @@ lws_service_adjust_timeout(struct lws_context *context, int timeout_ms, int tsi)
if (pt->ah_pool[n].rxpos != pt->ah_pool[n].rxlen) {
/* any ah with pending rx must be attached to someone */
if (!pt->ah_pool[n].wsi) {
lwsl_err("%s: assert: no wsi attached to ah\n", __func__);
lwsl_err("%s: ah with no wsi\n", __func__);
assert(0);
}
return 0;
@ -919,11 +926,12 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, int t
continue;
}
if (lws_hdr_copy(wsi, buf, sizeof buf, m) > 0) {
if (lws_hdr_copy(wsi, buf,
sizeof buf, m) > 0) {
buf[sizeof(buf) - 1] = '\0';
lwsl_notice(" %s = %s\n",
(const char *)c, buf);
(const char *)c, buf);
}
m++;
} while (1);
@ -1031,7 +1039,6 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, int t
#endif
// lwsl_debug("fd=%d, revents=%d, mode=%d, state=%d\n", pollfd->fd, pollfd->revents, (int)wsi->mode, (int)wsi->state);
if ((!(pollfd->revents & pollfd->events & LWS_POLLIN)) &&
(pollfd->revents & LWS_POLLHUP)) {
lwsl_debug("pollhup\n");
@ -1039,7 +1046,6 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, int t
goto close_and_handled;
}
#ifdef LWS_OPENSSL_SUPPORT
if ((wsi->state == LWSS_SHUTDOWN) && lws_is_ssl(wsi) && wsi->ssl)
{
@ -1059,7 +1065,8 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, int t
else /* n < 0 */
{
int shutdown_error = SSL_get_error(wsi->ssl, n);
lwsl_debug("SSL_shutdown returned %d, SSL_get_error: %d\n", n, shutdown_error);
lwsl_debug("SSL_shutdown ret %d, SSL_get_error: %d\n",
n, shutdown_error);
if (shutdown_error == SSL_ERROR_WANT_READ) {
lws_change_pollfd(wsi, LWS_POLLOUT, LWS_POLLIN);
n = 0;
@ -1306,7 +1313,7 @@ drain:
wsi->protocol->callback,
wsi, LWS_CALLBACK_RECEIVE_CLIENT_HTTP,
wsi->user_space, NULL, 0)) {
lwsl_notice("LWS_CALLBACK_RECEIVE_CLIENT_HTTP closed it\n");
lwsl_info("RECEIVE_CLIENT_HTTP closed it\n");
goto close_and_handled;
}
@ -1345,7 +1352,6 @@ drain:
* around again it will pick up from where it
* left off.
*/
// lwsl_notice("doing lws_read from pt->serv_buf %p %p for len %d\n", pt->serv_buf, eff_buf.token, (int)eff_buf.token_len);
n = lws_read(wsi, (unsigned char *)eff_buf.token,
eff_buf.token_len);
@ -1418,8 +1424,9 @@ drain:
args.stdwsi = &wsi->parent->cgi->stdwsi[0];
args.hdr_state = wsi->hdr_state;
lwsl_debug("CGI LWS_STDOUT waiting wsi %p mode %d state %d\n",
wsi->parent, wsi->parent->mode, wsi->parent->state);
lwsl_debug("CGI LWS_STDOUT %p mode %d state %d\n",
wsi->parent, wsi->parent->mode,
wsi->parent->state);
if (user_callback_handle_rxflow(
wsi->parent->protocol->callback,

View file

@ -1,7 +1,7 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010-2016 Andy Green <andy@warmcat.com>
* Copyright (C) 2010-2017 Andy Green <andy@warmcat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -36,7 +36,6 @@ static int
OpenSSL_client_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)
{
#if defined(LWS_USE_MBEDTLS)
// long gvr = ssl_pm_get_verify_result(
lwsl_notice("%s\n", __func__);
return 0;
@ -75,7 +74,9 @@ OpenSSL_client_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)
ssl = X509_STORE_CTX_get_ex_data(x509_ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
wsi = SSL_get_ex_data(ssl, openssl_websocket_private_data_index);
n = lws_get_context_protocol(wsi->context, 0).callback(wsi, LWS_CALLBACK_OPENSSL_PERFORM_SERVER_CERT_VERIFICATION, x509_ctx, ssl, preverify_ok);
n = lws_get_context_protocol(wsi->context, 0).callback(wsi,
LWS_CALLBACK_OPENSSL_PERFORM_SERVER_CERT_VERIFICATION,
x509_ctx, ssl, preverify_ok);
/* keep old behaviour if something wrong with server certs */
/* if ssl error is overruled in callback and cert is ok,

View file

@ -1,7 +1,7 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010-2016 Andy Green <andy@warmcat.com>
* Copyright (C) 2010-2017 Andy Green <andy@warmcat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -462,7 +462,6 @@ lws_context_init_server_ssl(struct lws_context_creation_info *info,
* SSL is happy and has a cert it's content with
* If we're supporting HTTP2, initialize that
*/
lws_context_init_http2_ssl(vhost);
}

View file

@ -785,8 +785,8 @@ lws_server_socket_service_ssl(struct lws *wsi, lws_sockfd_type accept_fd)
if (wsi->vhost->allow_non_ssl_on_ssl_port) {
n = recv(wsi->desc.sockfd, (char *)pt->serv_buf, context->pt_serv_buf_size,
MSG_PEEK);
n = recv(wsi->desc.sockfd, (char *)pt->serv_buf,
context->pt_serv_buf_size, MSG_PEEK);
/*
* optionally allow non-SSL connect on SSL listening socket
@ -876,16 +876,20 @@ go_again:
break;
}
lws_stats_atomic_bump(wsi->context, pt, LWSSTATS_C_SSL_CONNECTIONS_FAILED, 1);
lws_stats_atomic_bump(wsi->context, pt,
LWSSTATS_C_SSL_CONNECTIONS_FAILED, 1);
lwsl_info("SSL_accept failed socket %u: %s\n", wsi->desc.sockfd,
lws_ssl_get_error_string(m, n, buf, sizeof(buf)));
lws_ssl_elaborate_error();
goto fail;
accepted:
lws_stats_atomic_bump(wsi->context, pt, LWSSTATS_C_SSL_CONNECTIONS_ACCEPTED, 1);
lws_stats_atomic_bump(wsi->context, pt,
LWSSTATS_C_SSL_CONNECTIONS_ACCEPTED, 1);
#if defined(LWS_WITH_STATS)
lws_stats_atomic_bump(wsi->context, pt, LWSSTATS_MS_SSL_CONNECTIONS_ACCEPTED_DELAY, time_in_microseconds() - wsi->accept_start_us);
lws_stats_atomic_bump(wsi->context, pt,
LWSSTATS_MS_SSL_CONNECTIONS_ACCEPTED_DELAY,
time_in_microseconds() - wsi->accept_start_us);
wsi->accept_start_us = time_in_microseconds();
#endif