diff --git a/lib/context.c b/lib/context.c index 37219cdb..9bed5901 100644 --- a/lib/context.c +++ b/lib/context.c @@ -256,6 +256,13 @@ lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason, wsi->reason_bf &= ~1; break; } + + if (wsi->reason_bf & 4) { + n = lws_write(wsi, (unsigned char *)"0\x0d\x0a\x0d\x0a", 5, LWS_WRITE_HTTP); + if (n < 0) + return -1; + break; + } #endif #if defined(LWS_WITH_HTTP_PROXY) if (wsi->reason_bf & 2) { @@ -375,6 +382,11 @@ lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason, break; case LWS_CALLBACK_CGI_TERMINATED: + if (!wsi->cgi->explicitly_chunked && !wsi->cgi->content_length) { + /* send terminating chunk */ + wsi->reason_bf |= 4; + lws_callback_on_writable(wsi); + } return -1; case LWS_CALLBACK_CGI_STDIN_DATA: /* POST body for stdin */ diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c index 3c0a0e74..57c7afc1 100755 --- a/lib/libwebsockets.c +++ b/lib/libwebsockets.c @@ -2793,6 +2793,11 @@ lws_cgi_write_split_stdout_headers(struct lws *wsi) wsi->cgi->response_code); if (lws_add_http_header_status(wsi, wsi->cgi->response_code, &p, end)) return 1; + if (!wsi->cgi->explicitly_chunked && + !wsi->cgi->content_length && + lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_TRANSFER_ENCODING, + (unsigned char *)"chunked", 7, &p, end)) + return 1; if (lws_add_http_header_by_token(wsi, WSI_TOKEN_CONNECTION, (unsigned char *)"close", 5, &p, end)) return 1; @@ -2990,14 +2995,24 @@ lws_cgi_write_split_stdout_headers(struct lws *wsi) /* payload processing */ + m = !wsi->cgi->explicitly_chunked && !wsi->cgi->content_length; + n = read(lws_get_socket_fd(wsi->cgi->stdwsi[LWS_STDOUT]), - start, sizeof(buf) - LWS_PRE); + start, sizeof(buf) - LWS_PRE - (m ? LWS_HTTP_CHUNK_HDR_SIZE : 0)); if (n < 0 && errno != EAGAIN) { lwsl_debug("%s: stdout read says %d\n", __func__, n); return -1; } 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); + memmove(start + m, start, n); + memcpy(start, chdr, m); + memcpy(start + m + n, "\x0d\x0a", 2); + n += m + 2; + } m = lws_write(wsi, (unsigned char *)start, n, LWS_WRITE_HTTP); //lwsl_notice("write %d\n", m); if (m < 0) { diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h index 1fd06b10..5b5b25df 100644 --- a/lib/private-libwebsockets.h +++ b/lib/private-libwebsockets.h @@ -1490,6 +1490,8 @@ struct _lws_websocket_related { #ifdef LWS_WITH_CGI +#define LWS_HTTP_CHUNK_HDR_SIZE 16 + enum { SIGNIFICANT_HDR_CONTENT_LENGTH, SIGNIFICANT_HDR_LOCATION,