cgi: add support for manual chunking of CGI output

In cases when CGI output doesn't contain content-length nor it is
explicitly chunked, do manual chunking of CGI output.

Signed-off-by: Petar Paradzik <petar.paradzik@sartura.hr>
This commit is contained in:
Petar Paradzik 2017-08-26 12:00:24 +08:00 committed by Andy Green
parent 5b23b8c99f
commit afc9c0ac26
3 changed files with 30 additions and 1 deletions

View file

@ -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 */

View file

@ -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) {

View file

@ -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,