diff --git a/include/libwebsockets/lws-timeout-timer.h b/include/libwebsockets/lws-timeout-timer.h index a02ba3485..839b68349 100644 --- a/include/libwebsockets/lws-timeout-timer.h +++ b/include/libwebsockets/lws-timeout-timer.h @@ -113,6 +113,10 @@ lws_set_timeout(struct lws *wsi, enum pending_timeout reason, int secs); void lws_set_timeout_us(struct lws *wsi, enum pending_timeout reason, lws_usec_t us); +/* helper for clearer LWS_TO_KILL_ASYNC / LWS_TO_KILL_SYNC usage */ +#define lws_wsi_close(w, to_kill) lws_set_timeout(wsi, 1, to_kill) + + #define LWS_SET_TIMER_USEC_CANCEL ((lws_usec_t)-1ll) #define LWS_USEC_PER_SEC ((lws_usec_t)1000000) diff --git a/lib/core-net/close.c b/lib/core-net/close.c index c078aa0f0..16128036b 100644 --- a/lib/core-net/close.c +++ b/lib/core-net/close.c @@ -322,8 +322,13 @@ __lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason, /* we are not a network connection, but a handler for CGI io */ if (wsi->parent && wsi->parent->http.cgi) { - if (wsi->parent->child_list == wsi && !wsi->sibling_list) - lws_cgi_remove_and_kill(wsi->parent); + /* + * We need to keep the logical cgi around so we can + * drain it + */ + +// if (wsi->parent->child_list == wsi && !wsi->sibling_list) +// lws_cgi_remove_and_kill(wsi->parent); /* end the binding between us and master */ if (wsi->parent->http.cgi && wsi->parent->http.cgi->lsp) diff --git a/lib/core-net/dummy-callback.c b/lib/core-net/dummy-callback.c index e093f9993..449758327 100644 --- a/lib/core-net/dummy-callback.c +++ b/lib/core-net/dummy-callback.c @@ -326,7 +326,7 @@ lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason, lwsl_debug("AUX_BF__CGI forcing close\n"); return -1; } - if (!n && wsi->http.cgi && + if (!n && wsi->http.cgi && wsi->http.cgi->lsp && wsi->http.cgi->lsp->stdwsi[LWS_STDOUT]) lws_rx_flow_control( wsi->http.cgi->lsp->stdwsi[LWS_STDOUT], 1); @@ -649,8 +649,9 @@ lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason, /* TBD stdin rx flow control */ break; case LWS_STDOUT: - /* quench POLLIN on STDOUT until MASTER got writeable */ - lws_rx_flow_control(args->stdwsi[LWS_STDOUT], 0); + if (args->stdwsi[LWS_STDOUT]) + /* quench POLLIN on STDOUT until MASTER got writeable */ + lws_rx_flow_control(args->stdwsi[LWS_STDOUT], 0); wsi->reason_bf |= LWS_CB_REASON_AUX_BF__CGI; /* when writing to MASTER would not block */ lws_callback_on_writable(wsi); @@ -785,33 +786,35 @@ lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason, lwsl_notice("LWS_CALLBACK_CGI_STDIN_DATA: " "sent %d only %d went", n, args->len); + lwsl_notice("%s: proxied %d bytes\n", __func__, n); + if (wsi->http.cgi->post_in_expected && args->stdwsi[LWS_STDIN] && args->stdwsi[LWS_STDIN]->desc.filefd > 0) { wsi->http.cgi->post_in_expected -= n; if (!wsi->http.cgi->post_in_expected) { struct lws *siwsi = args->stdwsi[LWS_STDIN]; - lwsl_debug("%s: expected POST in end: " + /* + * The situation here is that we finished + * proxying the incoming body from the net to + * the STDIN stdwsi... and we want to close it + * so it can understand we are done (necessary + * if no content-length)... + */ + + lwsl_notice("%s: expected POST in end: " "closing stdin wsi %p, fd %d\n", __func__, siwsi, siwsi->desc.sockfd); - __remove_wsi_socket_from_fds(siwsi); - lwsi_set_state(siwsi, LRS_DEAD_SOCKET); - siwsi->socket_is_permanently_unusable = 1; -// lws_remove_child_from_any_parent(siwsi); - if (wsi->context->event_loop_ops-> - close_handle_manually) { + /* + * We don't want the child / parent relationship + * to be handled in close, since we want the + * rest of the cgi and children to stay up + */ - wsi->context->event_loop_ops-> - close_handle_manually(siwsi); - siwsi->told_event_loop_closed = 1; - } else { - compatible_close(siwsi->desc.sockfd); - __lws_free_wsi(siwsi); - } - wsi->http.cgi->lsp->pipe_fds[LWS_STDIN][1] = -1; - -// args->stdwsi[LWS_STDIN] = NULL; + lws_remove_child_from_any_parent(siwsi); + lws_wsi_close(siwsi, LWS_TO_KILL_ASYNC); + wsi->http.cgi->lsp->stdwsi[LWS_STDIN] = NULL; } } diff --git a/minimal-examples/http-server/minimal-http-server-cgi/my-cgi-script.sh b/minimal-examples/http-server/minimal-http-server-cgi/my-cgi-script.sh index 7437999b6..e705f84e8 100755 --- a/minimal-examples/http-server/minimal-http-server-cgi/my-cgi-script.sh +++ b/minimal-examples/http-server/minimal-http-server-cgi/my-cgi-script.sh @@ -14,7 +14,7 @@ if [ "$REQUEST_METHOD" = "POST" ] ; then >&2 echo "lwstest script stderr: doing read" echo "CONTENT_LENGTH=$CONTENT_LENGTH" read -n $CONTENT_LENGTH line - >&2 echo "lwstest script stderr: done read" + >&2 echo "lwstest script stderr: done read $line" echo "read=\"$line\"" else