mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
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:
parent
5b23b8c99f
commit
afc9c0ac26
3 changed files with 30 additions and 1 deletions
|
@ -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 */
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Reference in a new issue