Project

General

Profile

Feature #2313 ยป cgi_x-send-file.patch

Max_nl, 2011-05-08 19:03

View differences:

src/mod_cgi.c 2011-05-08 18:46:08.745960442 +0200
typedef struct {
array *cgi;
unsigned short execute_x_only;
unsigned short allow_xsendfile;
} plugin_config;
typedef struct {
......
pid_t pid;
int fd;
int fde_ndx; /* index into the fd-event buffer */
int send_content_body;
connection *remote_conn; /* dumb pointer */
plugin_data *plugin_data; /* dumb pointer */
......
hctx->response = buffer_init();
hctx->response_header = buffer_init();
hctx->send_content_body = 1;
return hctx;
}
......
config_values_t cv[] = {
{ "cgi.assign", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
{ "cgi.execute-x-only", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
{ "cgi.allow-x-send-file", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 2 */
{ NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET}
};
......
assert(s);
s->cgi = array_init();
s->execute_x_only = 0;
s->execute_x_only = 0;
s->allow_xsendfile = 0;
cv[0].destination = s->cgi;
cv[1].destination = &(s->execute_x_only);
cv[2].destination = &(s->allow_xsendfile);
p->config_storage[i] = s;
......
return 0;
}
static int cgi_response_parse(server *srv, connection *con, plugin_data *p, buffer *in) {
static int cgi_response_parse(server *srv, connection *con, plugin_data *p, buffer *in, handler_ctx *hctx) {
char *ns;
const char *s;
int line = 0;
......
con->response.keep_alive = (0 == strcasecmp(value, "Keep-Alive")) ? 1 : 0;
con->parsed_response |= HTTP_CONNECTION;
}
// falthrough
case 20:
if (p->conf.allow_xsendfile && hctx->send_content_body
&& (0 == strncasecmp(key, "X-LIGHTTPD-send-file", key_len) || 0 == strncasecmp(key, "X-Sendfile", key_len)) )
{
stat_cache_entry *sce;
if (HANDLER_ERROR != stat_cache_get_entry(srv, con, ds->value, &sce)) {
data_string *dcls;
if (NULL == (dcls = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
dcls = data_response_init();
}
/* found */
http_chunk_append_file(srv, con, ds->value, 0, sce->st.st_size);
hctx->send_content_body = 0; /* ignore the content */
joblist_append(srv, con);
buffer_copy_string_len(dcls->key, "Content-Length", sizeof("Content-Length")-1);
buffer_copy_off_t(dcls->value, sce->st.st_size);
dcls = (data_string*) array_replace(con->response.headers, (data_unset *)dcls);
if (dcls) dcls->free((data_unset*)dcls);
con->parsed_response |= HTTP_CONTENT_LENGTH;
con->response.content_length = sce->st.st_size;
} else {
log_error_write(srv, __FILE__, __LINE__, "sb",
"send-file error: couldn't get stat_cache entry for:",
ds->value);
con->http_status = 502;
hctx->send_content_body = 0;
con->file_started = 1;
break;
}
}
break;
case 14:
if (0 == strncasecmp(key, "Content-Length", key_len)) {
......
con->file_finished = 1;
/* send final chunk */
http_chunk_append_mem(srv, con, NULL, 0);
joblist_append(srv, con);
if ( hctx->send_content_body )
{
http_chunk_append_mem(srv, con, NULL, 0);
joblist_append(srv, con);
}
return FDEVENT_HANDLED_FINISHED;
}
......
hctx->response_header->used = i + 1; /* the string + \0 */
/* parse the response header */
cgi_response_parse(srv, con, p, hctx->response_header);
cgi_response_parse(srv, con, p, hctx->response_header, hctx);
/* enable chunked-transfer-encoding */
if (con->request.http_version == HTTP_VERSION_1_1 &&
......
con->response.transfer_encoding = HTTP_TRANSFER_ENCODING_CHUNKED;
}
if (blen > 0) {
if (blen > 0 && hctx->send_content_body) {
http_chunk_append_mem(srv, con, bstart, blen + 1);
joblist_append(srv, con);
}
......
con->file_started = 1;
}
} else {
} else if (hctx->send_content_body) {
http_chunk_append_mem(srv, con, hctx->response->ptr, hctx->response->used);
joblist_append(srv, con);
}
......
PATCH(cgi);
PATCH(execute_x_only);
PATCH(allow_xsendfile);
/* skip the first, the global context */
for (i = 1; i < srv->config_context->used; i++) {
......
PATCH(cgi);
} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("cgi.execute-x-only"))) {
PATCH(execute_x_only);
} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("cgi.allow-x-send-file"))) {
PATCH(allow_xsendfile);
}
}
}
    (1-1/1)