mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
cgi: fix for https git server
This commit is contained in:
parent
d44fe7a280
commit
d2bdb60a17
11 changed files with 378 additions and 21 deletions
|
@ -119,4 +119,4 @@
|
|||
/* Define if the inline keyword doesn't exist. */
|
||||
#cmakedefine inline ${inline}
|
||||
|
||||
|
||||
#cmakedefine LWS_WITH_ZLIB
|
||||
|
|
|
@ -14,6 +14,156 @@
|
|||
"ABIView": "Off",
|
||||
"ABIDiff": "Off"
|
||||
},
|
||||
{
|
||||
"Number": "3.0.0",
|
||||
"Installed": "installed/libwebsockets/3.0.0",
|
||||
"Source": "src/libwebsockets/3.0.0/libwebsockets-3.0.0.tar.gz",
|
||||
"Changelog": "changelog",
|
||||
"HeadersDiff": "On",
|
||||
"PkgDiff": "Off",
|
||||
"ABIView": "Off",
|
||||
"ABIDiff": "Off"
|
||||
},
|
||||
{
|
||||
"Number": "2.4.2",
|
||||
"Installed": "installed/libwebsockets/2.4.2",
|
||||
"Source": "src/libwebsockets/2.4.2/libwebsockets-2.4.2.tar.gz",
|
||||
"Changelog": "changelog",
|
||||
"HeadersDiff": "On",
|
||||
"PkgDiff": "Off",
|
||||
"ABIView": "Off",
|
||||
"ABIDiff": "Off"
|
||||
},
|
||||
{
|
||||
"Number": "2.4.1",
|
||||
"Installed": "installed/libwebsockets/2.4.1",
|
||||
"Source": "src/libwebsockets/2.4.1/libwebsockets-2.4.1.tar.gz",
|
||||
"Changelog": "changelog",
|
||||
"HeadersDiff": "On",
|
||||
"PkgDiff": "Off",
|
||||
"ABIView": "Off",
|
||||
"ABIDiff": "Off"
|
||||
},
|
||||
{
|
||||
"Number": "2.4.0",
|
||||
"Installed": "installed/libwebsockets/2.4.0",
|
||||
"Source": "src/libwebsockets/2.4.0/libwebsockets-2.4.0.tar.gz",
|
||||
"Changelog": "changelog",
|
||||
"HeadersDiff": "On",
|
||||
"PkgDiff": "Off",
|
||||
"ABIView": "Off",
|
||||
"ABIDiff": "Off"
|
||||
},
|
||||
{
|
||||
"Number": "2.3.0",
|
||||
"Installed": "installed/libwebsockets/2.3.0",
|
||||
"Source": "src/libwebsockets/2.3.0/libwebsockets-2.3.0.tar.gz",
|
||||
"Changelog": "changelog",
|
||||
"HeadersDiff": "On",
|
||||
"PkgDiff": "Off",
|
||||
"ABIView": "Off",
|
||||
"ABIDiff": "Off"
|
||||
},
|
||||
{
|
||||
"Number": "2.2.2",
|
||||
"Installed": "installed/libwebsockets/2.2.2",
|
||||
"Source": "src/libwebsockets/2.2.2/libwebsockets-2.2.2.tar.gz",
|
||||
"Changelog": "changelog",
|
||||
"HeadersDiff": "On",
|
||||
"PkgDiff": "Off",
|
||||
"ABIView": "Off",
|
||||
"ABIDiff": "Off"
|
||||
},
|
||||
{
|
||||
"Number": "2.2.1",
|
||||
"Installed": "installed/libwebsockets/2.2.1",
|
||||
"Source": "src/libwebsockets/2.2.1/libwebsockets-2.2.1.tar.gz",
|
||||
"Changelog": "changelog",
|
||||
"HeadersDiff": "On",
|
||||
"PkgDiff": "Off",
|
||||
"ABIView": "Off",
|
||||
"ABIDiff": "Off"
|
||||
},
|
||||
{
|
||||
"Number": "2.2.0",
|
||||
"Installed": "installed/libwebsockets/2.2.0",
|
||||
"Source": "src/libwebsockets/2.2.0/libwebsockets-2.2.0.tar.gz",
|
||||
"Changelog": "changelog",
|
||||
"HeadersDiff": "On",
|
||||
"PkgDiff": "Off",
|
||||
"ABIView": "Off",
|
||||
"ABIDiff": "Off"
|
||||
},
|
||||
{
|
||||
"Number": "2.1.1",
|
||||
"Installed": "installed/libwebsockets/2.1.1",
|
||||
"Source": "src/libwebsockets/2.1.1/libwebsockets-2.1.1.tar.gz",
|
||||
"Changelog": "changelog",
|
||||
"HeadersDiff": "On",
|
||||
"PkgDiff": "Off",
|
||||
"ABIView": "Off",
|
||||
"ABIDiff": "Off"
|
||||
},
|
||||
{
|
||||
"Number": "2.1.0",
|
||||
"Installed": "installed/libwebsockets/2.1.0",
|
||||
"Source": "src/libwebsockets/2.1.0/libwebsockets-2.1.0.tar.gz",
|
||||
"Changelog": "changelog",
|
||||
"HeadersDiff": "On",
|
||||
"PkgDiff": "Off",
|
||||
"ABIView": "Off",
|
||||
"ABIDiff": "Off"
|
||||
},
|
||||
{
|
||||
"Number": "1.7.9",
|
||||
"Installed": "installed/libwebsockets/1.7.9",
|
||||
"Source": "src/libwebsockets/1.7.9/libwebsockets-1.7.9.tar.gz",
|
||||
"Changelog": "changelog",
|
||||
"HeadersDiff": "On",
|
||||
"PkgDiff": "Off",
|
||||
"ABIView": "Off",
|
||||
"ABIDiff": "Off"
|
||||
},
|
||||
{
|
||||
"Number": "1.7.8",
|
||||
"Installed": "installed/libwebsockets/1.7.8",
|
||||
"Source": "src/libwebsockets/1.7.8/libwebsockets-1.7.8.tar.gz",
|
||||
"Changelog": "changelog",
|
||||
"HeadersDiff": "On",
|
||||
"PkgDiff": "Off",
|
||||
"ABIView": "Off",
|
||||
"ABIDiff": "Off"
|
||||
},
|
||||
{
|
||||
"Number": "1.7.7",
|
||||
"Installed": "installed/libwebsockets/1.7.7",
|
||||
"Source": "src/libwebsockets/1.7.7/libwebsockets-1.7.7.tar.gz",
|
||||
"Changelog": "changelog",
|
||||
"HeadersDiff": "On",
|
||||
"PkgDiff": "Off",
|
||||
"ABIView": "Off",
|
||||
"ABIDiff": "Off"
|
||||
},
|
||||
{
|
||||
"Number": "1.7.6",
|
||||
"Installed": "installed/libwebsockets/1.7.6",
|
||||
"Source": "src/libwebsockets/1.7.6/libwebsockets-1.7.6.tar.gz",
|
||||
"Changelog": "changelog",
|
||||
"HeadersDiff": "On",
|
||||
"PkgDiff": "Off",
|
||||
"ABIView": "Off",
|
||||
"ABIDiff": "Off"
|
||||
},
|
||||
{
|
||||
"Number": "1.7.5",
|
||||
"Installed": "installed/libwebsockets/1.7.5",
|
||||
"Source": "src/libwebsockets/1.7.5/libwebsockets-1.7.5.tar.gz",
|
||||
"Changelog": "changelog",
|
||||
"HeadersDiff": "On",
|
||||
"PkgDiff": "Off",
|
||||
"ABIView": "Off",
|
||||
"ABIDiff": "Off"
|
||||
},
|
||||
{
|
||||
"Number": "1.7.4",
|
||||
"Installed": "installed/libwebsockets/1.7.4",
|
||||
|
|
|
@ -346,7 +346,7 @@ lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason,
|
|||
struct lws_cgi_args *args;
|
||||
#endif
|
||||
#if defined(LWS_WITH_CGI) || defined(LWS_WITH_HTTP_PROXY)
|
||||
char buf[512];
|
||||
char buf[128];
|
||||
int n;
|
||||
#endif
|
||||
|
||||
|
@ -387,6 +387,9 @@ lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason,
|
|||
~LWS_CB_REASON_AUX_BF__CGI_HEADERS;
|
||||
else
|
||||
wsi->reason_bf &= ~LWS_CB_REASON_AUX_BF__CGI;
|
||||
|
||||
if (wsi->http.cgi && wsi->http.cgi->cgi_transaction_over)
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -537,16 +540,125 @@ lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason,
|
|||
case LWS_CALLBACK_CGI_STDIN_DATA: /* POST body for stdin */
|
||||
args = (struct lws_cgi_args *)in;
|
||||
args->data[args->len] = '\0';
|
||||
if (!args->stdwsi[LWS_STDIN])
|
||||
return -1;
|
||||
n = lws_get_socket_fd(args->stdwsi[LWS_STDIN]);
|
||||
if (n < 0)
|
||||
return -1;
|
||||
|
||||
#if defined(LWS_WITH_ZLIB)
|
||||
if (wsi->http.cgi->gzip_inflate) {
|
||||
/* gzip handling */
|
||||
|
||||
if (!wsi->http.cgi->gzip_init) {
|
||||
lwsl_err("inflating gzip\n");
|
||||
|
||||
memset(&wsi->http.cgi->inflate, 0, sizeof(wsi->http.cgi->inflate));
|
||||
|
||||
if (inflateInit2(&wsi->http.cgi->inflate, 16 + 15) != Z_OK) {
|
||||
lwsl_err("%s: iniflateInit failed\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
wsi->http.cgi->gzip_init = 1;
|
||||
}
|
||||
|
||||
wsi->http.cgi->inflate.next_in = args->data;
|
||||
wsi->http.cgi->inflate.avail_in = args->len;
|
||||
|
||||
do {
|
||||
|
||||
wsi->http.cgi->inflate.next_out = wsi->http.cgi->inflate_buf;
|
||||
wsi->http.cgi->inflate.avail_out = sizeof(wsi->http.cgi->inflate_buf);
|
||||
|
||||
n = inflate(&wsi->http.cgi->inflate, Z_SYNC_FLUSH);
|
||||
lwsl_err("inflate: %d\n", n);
|
||||
switch (n) {
|
||||
case Z_NEED_DICT:
|
||||
case Z_STREAM_ERROR:
|
||||
case Z_DATA_ERROR:
|
||||
case Z_MEM_ERROR:
|
||||
inflateEnd(&wsi->http.cgi->inflate);
|
||||
wsi->http.cgi->gzip_init = 0;
|
||||
lwsl_err("zlib error inflate %d\n", n);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (wsi->http.cgi->inflate.avail_out != sizeof(wsi->http.cgi->inflate_buf)) {
|
||||
int written;
|
||||
|
||||
// lwsl_hexdump_notice(wsi->http.cgi->inflate_buf,
|
||||
// sizeof(wsi->http.cgi->inflate_buf) - wsi->http.cgi->inflate.avail_out);
|
||||
|
||||
written = write(args->stdwsi[LWS_STDIN]->desc.filefd, wsi->http.cgi->inflate_buf,
|
||||
sizeof(wsi->http.cgi->inflate_buf) - wsi->http.cgi->inflate.avail_out);
|
||||
|
||||
if (written != (int)(sizeof(wsi->http.cgi->inflate_buf) - wsi->http.cgi->inflate.avail_out)) {
|
||||
lwsl_notice("LWS_CALLBACK_CGI_STDIN_DATA: "
|
||||
"sent %d only %d went", n, args->len);
|
||||
}
|
||||
lwsl_err("send inflated on fd %d says %d\n", args->stdwsi[LWS_STDIN]->desc.filefd, written);
|
||||
|
||||
if (n == Z_STREAM_END) {
|
||||
lwsl_err("gzip inflate end\n");
|
||||
inflateEnd(&wsi->http.cgi->inflate);
|
||||
wsi->http.cgi->gzip_init = 0;
|
||||
|
||||
//compatible_close(args->stdwsi[LWS_STDIN]->desc.filefd);
|
||||
//args->stdwsi[LWS_STDIN]->desc.filefd = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
} else
|
||||
break;
|
||||
|
||||
if (wsi->http.cgi->inflate.avail_out)
|
||||
break;
|
||||
|
||||
} while (1);
|
||||
|
||||
return args->len;
|
||||
}
|
||||
#endif /* WITH_ZLIB */
|
||||
|
||||
n = write(n, args->data, args->len);
|
||||
// lwsl_hexdump_notice(args->data, args->len);
|
||||
if (n < args->len)
|
||||
lwsl_notice("LWS_CALLBACK_CGI_STDIN_DATA: "
|
||||
"sent %d only %d went", n, args->len);
|
||||
|
||||
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: "
|
||||
"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) {
|
||||
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->pipe_fds[LWS_STDIN][1] = -1;
|
||||
|
||||
args->stdwsi[LWS_STDIN] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
#endif
|
||||
#endif
|
||||
#endif /* WITH_CGI */
|
||||
#endif /* ROLE_ H1 / H2 */
|
||||
case LWS_CALLBACK_SSL_INFO:
|
||||
si = in;
|
||||
|
||||
|
|
|
@ -434,7 +434,7 @@ lws_timed_callback_vh_protocol(struct lws_vhost *vh, const struct lws_protocols
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
lws_remove_child_from_any_parent(struct lws *wsi)
|
||||
{
|
||||
struct lws **pwsi;
|
||||
|
@ -856,6 +856,7 @@ __lws_close_free_wsi_final(struct lws *wsi)
|
|||
int n;
|
||||
|
||||
if (lws_socket_is_valid(wsi->desc.sockfd) && !lws_ssl_close(wsi)) {
|
||||
lwsl_debug("%s: wsi %p: fd %d\n", __func__, wsi, wsi->desc.sockfd);
|
||||
n = compatible_close(wsi->desc.sockfd);
|
||||
if (n)
|
||||
lwsl_debug("closing: close ret %d\n", LWS_ERRNO);
|
||||
|
|
|
@ -1756,6 +1756,8 @@ lws_context_destroy2(struct lws_context *context);
|
|||
int
|
||||
lws_role_call_client_bind(struct lws *wsi,
|
||||
const struct lws_client_connect_info *i);
|
||||
void
|
||||
lws_remove_child_from_any_parent(struct lws *wsi);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
|
|
|
@ -315,7 +315,7 @@ static void
|
|||
lws_libuv_closewsi_m(uv_handle_t* handle)
|
||||
{
|
||||
lws_sockfd_type sockfd = (lws_sockfd_type)(lws_intptr_t)handle->data;
|
||||
|
||||
lwsl_debug("%s: sockfd %d\n", __func__, sockfd);
|
||||
compatible_close(sockfd);
|
||||
}
|
||||
|
||||
|
|
|
@ -195,6 +195,13 @@ lws_cgi(struct lws *wsi, const char * const *exec_array, int script_uri_path_len
|
|||
|
||||
sum += lws_snprintf(sum, sumend - sum, "%s ", exec_array[0]);
|
||||
|
||||
if (0) {
|
||||
char *pct = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_CONTENT_ENCODING);
|
||||
|
||||
if (pct && !strcmp(pct, "gzip"))
|
||||
wsi->http.cgi->gzip_inflate = 1;
|
||||
}
|
||||
|
||||
/* prepare his CGI env */
|
||||
|
||||
n = 0;
|
||||
|
@ -327,10 +334,31 @@ lws_cgi(struct lws *wsi, const char * const *exec_array, int script_uri_path_len
|
|||
if (script_uri_path_len >= 0 &&
|
||||
lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_USER_AGENT)) {
|
||||
env_array[n++] = p;
|
||||
p += lws_snprintf(p, end - p, "USER_AGENT=%s",
|
||||
p += lws_snprintf(p, end - p, "HTTP_USER_AGENT=%s",
|
||||
lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_USER_AGENT));
|
||||
p++;
|
||||
}
|
||||
if (script_uri_path_len >= 0 &&
|
||||
lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_CONTENT_ENCODING)) {
|
||||
env_array[n++] = p;
|
||||
p += lws_snprintf(p, end - p, "HTTP_CONTENT_ENCODING=%s",
|
||||
lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_CONTENT_ENCODING));
|
||||
p++;
|
||||
}
|
||||
if (script_uri_path_len >= 0 &&
|
||||
lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_ACCEPT)) {
|
||||
env_array[n++] = p;
|
||||
p += lws_snprintf(p, end - p, "HTTP_ACCEPT=%s",
|
||||
lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_ACCEPT));
|
||||
p++;
|
||||
}
|
||||
if (script_uri_path_len >= 0 &&
|
||||
lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_ACCEPT_ENCODING)) {
|
||||
env_array[n++] = p;
|
||||
p += lws_snprintf(p, end - p, "HTTP_ACCEPT_ENCODING=%s",
|
||||
lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_ACCEPT_ENCODING));
|
||||
p++;
|
||||
}
|
||||
if (script_uri_path_len >= 0 &&
|
||||
uritok == WSI_TOKEN_POST_URI) {
|
||||
if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE)) {
|
||||
|
@ -339,14 +367,21 @@ lws_cgi(struct lws *wsi, const char * const *exec_array, int script_uri_path_len
|
|||
lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE));
|
||||
p++;
|
||||
}
|
||||
if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH)) {
|
||||
if (!wsi->http.cgi->gzip_inflate &&
|
||||
lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH)) {
|
||||
env_array[n++] = p;
|
||||
p += lws_snprintf(p, end - p, "CONTENT_LENGTH=%s",
|
||||
lws_hdr_simple_ptr(wsi,
|
||||
WSI_TOKEN_HTTP_CONTENT_LENGTH));
|
||||
p++;
|
||||
}
|
||||
|
||||
if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH))
|
||||
wsi->http.cgi->post_in_expected =
|
||||
atoll(lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH));
|
||||
}
|
||||
|
||||
|
||||
env_array[n++] = "PATH=/bin:/usr/bin:/usr/local/bin:/var/www/cgi-bin";
|
||||
|
||||
env_array[n++] = p;
|
||||
|
@ -356,6 +391,10 @@ lws_cgi(struct lws *wsi, const char * const *exec_array, int script_uri_path_len
|
|||
env_array[n++] = p;
|
||||
p += lws_snprintf(p, end - p, "%s=%s", mp_cgienv->name,
|
||||
mp_cgienv->value);
|
||||
if (!strcmp(mp_cgienv->name, "GIT_PROJECT_ROOT")) {
|
||||
wsi->http.cgi->implied_chunked = 1;
|
||||
wsi->http.cgi->explicitly_chunked = 1;
|
||||
}
|
||||
lwsl_info(" Applying mount-specific cgi env '%s'\n",
|
||||
env_array[n - 1]);
|
||||
p++;
|
||||
|
@ -367,7 +406,7 @@ lws_cgi(struct lws *wsi, const char * const *exec_array, int script_uri_path_len
|
|||
|
||||
#if 0
|
||||
for (m = 0; m < n; m++)
|
||||
lwsl_info(" %s\n", env_array[m]);
|
||||
lwsl_notice(" %s\n", env_array[m]);
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -399,9 +438,10 @@ lws_cgi(struct lws *wsi, const char * const *exec_array, int script_uri_path_len
|
|||
if (cgi->pid) {
|
||||
/* we are the parent process */
|
||||
wsi->context->count_cgi_spawned++;
|
||||
lwsl_debug("%s: cgi %p spawned PID %d\n", __func__,
|
||||
lwsl_info("%s: cgi %p spawned PID %d\n", __func__,
|
||||
cgi, cgi->pid);
|
||||
|
||||
/* close: stdin:r, stdout:w, stderr:w */
|
||||
for (n = 0; n < 3; n++)
|
||||
close(cgi->pipe_fds[n][!(n == 0)]);
|
||||
|
||||
|
@ -430,7 +470,8 @@ lws_cgi(struct lws *wsi, const char * const *exec_array, int script_uri_path_len
|
|||
lwsl_err("%s: stdin dup2 failed\n", __func__);
|
||||
goto bail3;
|
||||
}
|
||||
close(cgi->pipe_fds[n][!(n == 0)]);
|
||||
close(cgi->pipe_fds[n][0]);
|
||||
close(cgi->pipe_fds[n][1]);
|
||||
}
|
||||
|
||||
#if !defined(LWS_HAVE_VFORK) || !defined(LWS_HAVE_EXECVPE)
|
||||
|
@ -454,14 +495,14 @@ bail3:
|
|||
__remove_wsi_socket_from_fds(wsi->http.cgi->stdwsi[n]);
|
||||
bail2:
|
||||
for (n = 0; n < 3; n++)
|
||||
if (wsi->http.cgi->stdwsi[n])
|
||||
if (wsi->http.cgi->stdwsi[n] > 0)
|
||||
__lws_free_wsi(cgi->stdwsi[n]);
|
||||
|
||||
bail1:
|
||||
for (n = 0; n < 3; n++) {
|
||||
if (cgi->pipe_fds[n][0])
|
||||
if (cgi->pipe_fds[n][0] > 0)
|
||||
close(cgi->pipe_fds[n][0]);
|
||||
if (cgi->pipe_fds[n][1])
|
||||
if (cgi->pipe_fds[n][1] > 0)
|
||||
close(cgi->pipe_fds[n][1]);
|
||||
}
|
||||
|
||||
|
@ -479,6 +520,7 @@ static const char * const significant_hdr[SIGNIFICANT_HDR_COUNT] = {
|
|||
"location: ",
|
||||
"status: ",
|
||||
"transfer-encoding: chunked",
|
||||
"content-encoding: gzip",
|
||||
};
|
||||
|
||||
enum header_recode {
|
||||
|
@ -620,6 +662,9 @@ post_hpack_recode:
|
|||
return -1;
|
||||
}
|
||||
|
||||
// lwsl_hexdump_notice(wsi->http.cgi->headers_pos,
|
||||
// wsi->http.cgi->headers_end - wsi->http.cgi->headers_pos);
|
||||
|
||||
wsi->hdr_state = LHCS_DUMP_HEADERS;
|
||||
wsi->reason_bf |= LWS_CB_REASON_AUX_BF__CGI_HEADERS;
|
||||
lws_callback_on_writable(wsi);
|
||||
|
@ -764,7 +809,7 @@ post_hpack_recode:
|
|||
!significant_hdr[SIGNIFICANT_HDR_TRANSFER_ENCODING]
|
||||
[wsi->http.cgi->match[
|
||||
SIGNIFICANT_HDR_TRANSFER_ENCODING]]) {
|
||||
lwsl_debug("cgi produced chunked\n");
|
||||
lwsl_info("cgi produced chunked\n");
|
||||
wsi->http.cgi->explicitly_chunked = 1;
|
||||
}
|
||||
|
||||
|
@ -775,7 +820,6 @@ post_hpack_recode:
|
|||
lwsl_debug("CGI: Location hdr seen\n");
|
||||
wsi->http.cgi->response_code = 302;
|
||||
}
|
||||
|
||||
break;
|
||||
case LCHS_LF1:
|
||||
*wsi->http.cgi->headers_pos++ = c;
|
||||
|
@ -836,10 +880,25 @@ agin:
|
|||
|
||||
/* payload processing */
|
||||
|
||||
m = !wsi->http.cgi->explicitly_chunked && !wsi->http.cgi->content_length;
|
||||
m = !wsi->http.cgi->implied_chunked && !wsi->http2_substream && !wsi->http.cgi->explicitly_chunked && !wsi->http.cgi->content_length;
|
||||
n = lws_get_socket_fd(wsi->http.cgi->stdwsi[LWS_STDOUT]);
|
||||
if (n < 0)
|
||||
return -1;
|
||||
if (m) {
|
||||
uint8_t term[LWS_PRE + 6];
|
||||
|
||||
lwsl_info("%s: zero chunk\n", __func__);
|
||||
|
||||
memcpy(term + LWS_PRE, (uint8_t *)"0\x0d\x0a\x0d\x0a", 5);
|
||||
|
||||
if (lws_write(wsi, term + LWS_PRE, 5, LWS_WRITE_HTTP_FINAL) != 5)
|
||||
return -1;
|
||||
|
||||
wsi->http.cgi->cgi_transaction_over = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = read(n, start, sizeof(buf) - LWS_PRE -
|
||||
(m ? LWS_HTTP_CHUNK_HDR_SIZE : 0));
|
||||
|
||||
|
@ -848,6 +907,7 @@ agin:
|
|||
return -1;
|
||||
}
|
||||
if (n > 0) {
|
||||
|
||||
if (!wsi->http2_substream && m) {
|
||||
char chdr[LWS_HTTP_CHUNK_HDR_SIZE];
|
||||
m = lws_snprintf(chdr, LWS_HTTP_CHUNK_HDR_SIZE - 3,
|
||||
|
@ -860,6 +920,7 @@ agin:
|
|||
cmd = LWS_WRITE_HTTP;
|
||||
if (wsi->http.cgi->content_length_seen + n == wsi->http.cgi->content_length)
|
||||
cmd = LWS_WRITE_HTTP_FINAL;
|
||||
|
||||
m = lws_write(wsi, (unsigned char *)start, n, cmd);
|
||||
//lwsl_notice("write %d\n", m);
|
||||
if (m < 0) {
|
||||
|
|
|
@ -75,6 +75,22 @@ rops_periodic_checks_cgi(struct lws_context *context, int tsi, time_t now)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
rops_destroy_role_cgi(struct lws *wsi)
|
||||
{
|
||||
#if defined(LWS_WITH_ZLIB)
|
||||
if (!wsi->http.cgi)
|
||||
return 0;
|
||||
if (!wsi->http.cgi->gzip_init)
|
||||
return 0;
|
||||
|
||||
inflateEnd(&wsi->http.cgi->inflate);
|
||||
wsi->http.cgi->gzip_init = 0;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct lws_role_ops role_ops_cgi = {
|
||||
/* role name */ "cgi",
|
||||
/* alpn id */ NULL,
|
||||
|
@ -95,7 +111,7 @@ struct lws_role_ops role_ops_cgi = {
|
|||
/* close_via_role_protocol */ NULL,
|
||||
/* close_role */ NULL,
|
||||
/* close_kill_connection */ NULL,
|
||||
/* destroy_role */ NULL,
|
||||
/* destroy_role */ rops_destroy_role_cgi,
|
||||
/* adoption_bind */ NULL,
|
||||
/* client_bind */ NULL,
|
||||
/* writeable cb clnt, srv */ { 0, 0 },
|
||||
|
|
|
@ -21,6 +21,10 @@
|
|||
* This is included from core/private.h if LWS_ROLE_WS
|
||||
*/
|
||||
|
||||
#if defined(LWS_WITH_ZLIB)
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
|
||||
extern struct lws_role_ops role_ops_cgi;
|
||||
|
||||
#define lwsi_role_cgi(wsi) (wsi->role_ops == &role_ops_cgi)
|
||||
|
@ -28,10 +32,11 @@ extern struct lws_role_ops role_ops_cgi;
|
|||
#define LWS_HTTP_CHUNK_HDR_SIZE 16
|
||||
|
||||
enum {
|
||||
SIGNIFICANT_HDR_CONTENT_LENGTH,
|
||||
SIGNIFICANT_HDR_CONTENT_LENGTH, /* numeric */
|
||||
SIGNIFICANT_HDR_LOCATION,
|
||||
SIGNIFICANT_HDR_STATUS,
|
||||
SIGNIFICANT_HDR_STATUS, /* numeric */
|
||||
SIGNIFICANT_HDR_TRANSFER_ENCODING,
|
||||
SIGNIFICANT_HDR_CONTENT_ENCODING_GZIP,
|
||||
|
||||
SIGNIFICANT_HDR_COUNT
|
||||
};
|
||||
|
@ -51,7 +56,12 @@ struct lws_cgi {
|
|||
unsigned char *headers_end;
|
||||
|
||||
char summary[128];
|
||||
#if defined(LWS_WITH_ZLIB)
|
||||
z_stream inflate;
|
||||
uint8_t inflate_buf[1024];
|
||||
#endif
|
||||
|
||||
lws_filepos_t post_in_expected;
|
||||
lws_filepos_t content_length;
|
||||
lws_filepos_t content_length_seen;
|
||||
|
||||
|
@ -64,6 +74,10 @@ struct lws_cgi {
|
|||
|
||||
unsigned char being_closed:1;
|
||||
unsigned char explicitly_chunked:1;
|
||||
unsigned char cgi_transaction_over:1;
|
||||
unsigned char implied_chunked:1;
|
||||
unsigned char gzip_inflate:1;
|
||||
unsigned char gzip_init:1;
|
||||
|
||||
unsigned char chunked_grace;
|
||||
};
|
||||
|
|
|
@ -1652,7 +1652,7 @@ lws_http_transaction_completed(struct lws *wsi)
|
|||
return 1;
|
||||
|
||||
if (wsi->http.connection_type != HTTP_CONNECTION_KEEP_ALIVE) {
|
||||
lwsl_notice("%s: %p: close connection\n", __func__, wsi);
|
||||
lwsl_info("%s: %p: close connection\n", __func__, wsi);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ minimal-http-server-form-post-file|Process a multipart POST form with file trans
|
|||
minimal-http-server-form-post|Process a POST form (no file transfer)
|
||||
minimal-http-server-mimetypes|Shows how to add support for additional mimetypes at runtime
|
||||
minimal-http-server-multivhost|Same as minimal-http-server but three different vhosts
|
||||
minimal-http-server-proxy|Reverse Proxy
|
||||
minimal-http-server-smp|Multiple service threads
|
||||
minimal-http-server-sse-ring|Server Side Events with ringbuffer and threaded event sources
|
||||
minimal-http-server-sse|Simple Server Side Events
|
||||
|
|
Loading…
Add table
Reference in a new issue