1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

LRS_DOING_TRANSACTION

This commit is contained in:
Andy Green 2018-05-04 12:05:56 +08:00
parent de064fd65a
commit c99a99e9b4
6 changed files with 61 additions and 25 deletions

View file

@ -308,9 +308,9 @@ lws_h1_server_socket_service(struct lws *wsi, struct lws_pollfd *pollfd)
lwsi_state(wsi) == LRS_ISSUING_FILE ||
lwsi_state(wsi) == LRS_HEADERS ||
lwsi_state(wsi) == LRS_BODY)) {
if (!wsi->http.ah &&
lws_header_table_attach(wsi, 0)) {
lwsl_info("wsi %p: ah get fail\n", wsi);
if (!wsi->http.ah && lws_header_table_attach(wsi, 0)) {
lwsl_info("%s: wsi %p: ah not available\n", __func__, wsi);
goto try_pollout;
}
@ -319,6 +319,9 @@ lws_h1_server_socket_service(struct lws *wsi, struct lws_pollfd *pollfd)
* regardless of our buflist state, we need to get it,
* and either use it, or append to the buflist and use
* buflist head material.
*
* We will not notice a connection close until the buflist is
* exhausted and we tried to do a read of some kind.
*/
buffered = lws_buflist_aware_read(pt, wsi, &ebuf);
@ -327,8 +330,20 @@ lws_h1_server_socket_service(struct lws *wsi, struct lws_pollfd *pollfd)
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;
//goto fail;
#if !defined(LWS_WITHOUT_EXTENSIONS)
/*
* autobahn requires us to win the race between close
* and draining the extensions
*/
if (wsi->ws &&
(wsi->ws->rx_draining_ext || wsi->ws->tx_draining_ext))
goto try_pollout;
#endif
/*
* normally, we respond to close with logically closing
* our side immediately
*/
goto fail;
case LWS_SSL_CAPABLE_ERROR:
goto fail;
@ -469,7 +484,8 @@ try_pollout:
fail:
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "server socket svc fail");
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS,
"server socket svc fail");
return LWS_HPI_RET_WSI_ALREADY_DIED;
}

View file

@ -81,6 +81,8 @@ _lws_header_table_reset(struct allocated_headers *ah)
ah->nfrag = 0;
ah->pos = 0;
ah->http_response = 0;
ah->parser_state = WSI_TOKEN_NAME_PART;
ah->lextable_pos = 0;
}
// doesn't scrub the ah rxbuffer by default, parent must do if needed
@ -99,9 +101,6 @@ __lws_header_table_reset(struct lws *wsi, int autoservice)
_lws_header_table_reset(ah);
ah->parser_state = WSI_TOKEN_NAME_PART;
ah->lextable_pos = 0;
/* since we will restart the ah, our new headers are not completed */
wsi->hdr_parsing_completed = 0;
@ -353,7 +352,7 @@ int __lws_header_table_detach(struct lws *wsi, int autoservice)
if (!wsi) /* everybody waiting already has too many ah... */
goto nobody_usable_waiting;
lwsl_info("%s: last eligible wsi in wait list %p\n", __func__, wsi);
lwsl_info("%s: transferring ah to last eligible wsi in wait list %p (wsistate 0x%x)\n", __func__, wsi, wsi->wsistate);
wsi->http.ah = ah;
ah->wsi = wsi; /* new owner */

View file

@ -330,8 +330,8 @@ lws_select_vhost(struct lws_context *context, int port, const char *servername)
vhost = context->vhost_list;
while (vhost) {
if (port == vhost->listen_port) {
lwsl_info("vhost match to %s based on port %d\n",
vhost->name, port);
lwsl_info("%s: vhost match to %s based on port %d\n",
__func__, vhost->name, port);
return vhost;
}
vhost = vhost->vhost_next;
@ -991,6 +991,8 @@ lws_http_action(struct lws *wsi)
if (lws_bind_protocol(wsi, &wsi->vhost->protocols[0]))
return 1;
lwsi_set_state(wsi, LRS_DOING_TRANSACTION);
n = wsi->protocol->callback(wsi, LWS_CALLBACK_HTTP,
wsi->user_space, uri_ptr, uri_len);
@ -1547,7 +1549,7 @@ raw_transition:
/* no upgrade ack... he remained as HTTP */
lwsl_info("No upgrade\n");
lwsl_info("%s: %p: No upgrade\n", __func__, wsi);
lwsi_set_state(wsi, LRS_ESTABLISHED);
wsi->http.fop_fd = NULL;
@ -1742,7 +1744,8 @@ lws_http_transaction_completed(struct lws *wsi)
* until we can verify POLLOUT. The part of this that confirms POLLOUT
* with no partials is in lws_server_socket_service() below.
*/
lwsl_debug("%s: setting DEF_ACT from 0x%x\n", __func__, wsi->wsistate);
lwsl_debug("%s: %p: setting DEF_ACT from 0x%x\n", __func__,
wsi, wsi->wsistate);
lwsi_set_state(wsi, LRS_DEFERRING_ACTION);
wsi->http.tx_content_length = 0;
wsi->http.tx_content_remain = 0;
@ -1770,7 +1773,8 @@ lws_http_transaction_completed(struct lws *wsi)
if (wsi->http.ah) {
// lws_buflist_describe(&wsi->buflist, wsi);
if (!lws_buflist_next_segment_len(&wsi->buflist, NULL)) {
lwsl_debug("%s: nothing in buflist so detaching ah\n", __func__);
lwsl_info("%s: %p: nothing in buflist so detaching ah\n",
__func__, wsi);
lws_header_table_detach(wsi, 1);
#ifdef LWS_WITH_TLS
/*
@ -1789,8 +1793,8 @@ lws_http_transaction_completed(struct lws *wsi)
}
#endif
} else {
lwsl_debug("%s: resetting and keeping ah as pipeline\n",
__func__);
lwsl_info("%s: %p: resetting and keeping ah as pipeline\n",
__func__, wsi);
lws_header_table_reset(wsi, 0);
/*
* If we kept the ah, we should restrict the amount

View file

@ -122,18 +122,27 @@ enum lwsi_state {
LRS_HEADERS = 21,
LRS_BODY = 22,
LRS_ESTABLISHED = LWSIFS_POCB | 23,
/* we are established, but we have embarked on serving a single
* transaction. Other transaction input may be pending, but we will
* not service it while we are busy dealing with the current
* transaction.
*
* When we complete the current transaction, we would reset our state
* back to ESTABLISHED and start to process the next transaction.
*/
LRS_DOING_TRANSACTION = LWSIFS_POCB | 24,
/* Phase 6: finishing */
LRS_WAITING_TO_SEND_CLOSE = LWSIFS_POCB | 24,
LRS_RETURNED_CLOSE = LWSIFS_POCB | 25,
LRS_AWAITING_CLOSE_ACK = LWSIFS_POCB | 26,
LRS_FLUSHING_BEFORE_CLOSE = LWSIFS_POCB | 27,
LRS_SHUTDOWN = 28,
LRS_WAITING_TO_SEND_CLOSE = LWSIFS_POCB | 25,
LRS_RETURNED_CLOSE = LWSIFS_POCB | 26,
LRS_AWAITING_CLOSE_ACK = LWSIFS_POCB | 27,
LRS_FLUSHING_BEFORE_CLOSE = LWSIFS_POCB | 28,
LRS_SHUTDOWN = 29,
/* Phase 7: dead */
LRS_DEAD_SOCKET = 29,
LRS_DEAD_SOCKET = 30,
LRS_MASK = 0xffff
};

View file

@ -177,6 +177,10 @@ int main(int argc, const char **argv)
info.protocols = protocols;
info.mounts = &mount;
/* for testing ah queue, not useful in real world */
if (lws_cmdline_option(argc, argv, "--ah1"))
info.max_http_header_pool = 1;
context = lws_create_context(&info);
if (!context) {
lwsl_err("lws init failed\n");

View file

@ -31,6 +31,7 @@ static struct lws *raw_wsi, *stdin_wsi;
static uint8_t buf[LWS_PRE + 4096];
static int waiting, interrupted;
static struct lws_context *context;
static int us_wait_after_input_close = LWS_USEC_PER_SEC / 10;
static int
callback_raw_test(struct lws *wsi, enum lws_callback_reasons reason,
@ -50,7 +51,7 @@ callback_raw_test(struct lws *wsi, enum lws_callback_reasons reason,
/* stdin close, wait 1s then close the raw skt */
stdin_wsi = NULL; /* invalid now we close */
if (raw_wsi)
lws_set_timer_usecs(raw_wsi, LWS_USEC_PER_SEC / 10);
lws_set_timer_usecs(raw_wsi, us_wait_after_input_close);
else {
interrupted = 1;
lws_cancel_service(context);
@ -153,7 +154,7 @@ int main(int argc, const char **argv)
logs = atoi(p);
lws_set_log_level(logs, NULL);
lwsl_user("LWS minimal raw netcat [--server ip] [--port port]\n");
lwsl_user("LWS minimal raw netcat [--server ip] [--port port] [-w ms]\n");
memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */
info.options = LWS_SERVER_OPTION_EXPLICIT_VHOSTS;
@ -193,6 +194,9 @@ int main(int argc, const char **argv)
if ((p = lws_cmdline_option(argc, argv, "--server")))
server = p;
if ((p = lws_cmdline_option(argc, argv, "-w")))
us_wait_after_input_close = 1000 * atoi(p);
n = getaddrinfo(server, port, &h, &r);
if (n) {
lwsl_err("%s: problem resolving %s: %s\n", __func__,