[mod_ssi] produce content in subrequest hook
(prerequisite for future mod_ssi enhancements) This commit also addresses the concern that mod_geoip would (previously) need to be listed in modules prior to mod_ssi. x-ref: https://github.com/lighttpd/lighttpd1.4/pull/73
This commit is contained in:
parent
ac9822f468
commit
83ec97a054
|
@ -40,6 +40,21 @@
|
|||
|
||||
#include "etag.h"
|
||||
|
||||
static handler_ctx * handler_ctx_init(plugin_data *p) {
|
||||
handler_ctx *hctx = calloc(1, sizeof(*hctx));
|
||||
force_assert(hctx);
|
||||
hctx->timefmt = p->timefmt;
|
||||
hctx->stat_fn = p->stat_fn;
|
||||
hctx->ssi_vars = p->ssi_vars;
|
||||
hctx->ssi_cgi_env = p->ssi_cgi_env;
|
||||
memcpy(&hctx->conf, &p->conf, sizeof(plugin_config));
|
||||
return hctx;
|
||||
}
|
||||
|
||||
static void handler_ctx_free(handler_ctx *hctx) {
|
||||
free(hctx);
|
||||
}
|
||||
|
||||
/* The newest modified time of included files for include statement */
|
||||
static volatile time_t include_file_last_mtime = 0;
|
||||
|
||||
|
@ -150,7 +165,7 @@ static int ssi_env_add(void *venv, const char *key, size_t klen, const char *val
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int build_ssi_cgi_vars(server *srv, connection *con, plugin_data *p) {
|
||||
static int build_ssi_cgi_vars(server *srv, connection *con, handler_ctx *p) {
|
||||
http_cgi_opts opts = { 0, 0, NULL, NULL };
|
||||
/* temporarily remove Authorization from request headers
|
||||
* so that Authorization does not end up in SSI environment */
|
||||
|
@ -175,7 +190,7 @@ static int build_ssi_cgi_vars(server *srv, connection *con, plugin_data *p) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, const char **l, size_t n, struct stat *st) {
|
||||
static int process_ssi_stmt(server *srv, connection *con, handler_ctx *p, const char **l, size_t n, struct stat *st) {
|
||||
|
||||
/**
|
||||
* <!--#element attribute=value attribute=value ... -->
|
||||
|
@ -1008,7 +1023,7 @@ static int mod_ssi_parse_ssi_stmt_offlen(int o[10], const char * const s, const
|
|||
return -1;
|
||||
}
|
||||
|
||||
static void mod_ssi_parse_ssi_stmt(server *srv, connection *con, plugin_data *p, char *s, int len, struct stat *st) {
|
||||
static void mod_ssi_parse_ssi_stmt(server *srv, connection *con, handler_ctx *p, char *s, int len, struct stat *st) {
|
||||
|
||||
/**
|
||||
* <!--#element attribute=value attribute=value ... -->
|
||||
|
@ -1079,7 +1094,7 @@ static int mod_ssi_stmt_len(const char *s, const int len) {
|
|||
return 0; /* incomplete directive "<!--#...-->" */
|
||||
}
|
||||
|
||||
static void mod_ssi_read_fd(server *srv, connection *con, plugin_data *p, int fd, struct stat *st) {
|
||||
static void mod_ssi_read_fd(server *srv, connection *con, handler_ctx *p, int fd, struct stat *st) {
|
||||
ssize_t rd;
|
||||
size_t offset, pretag;
|
||||
char buf[8192];
|
||||
|
@ -1164,7 +1179,7 @@ static void mod_ssi_read_fd(server *srv, connection *con, plugin_data *p, int fd
|
|||
# define FIFO_NONBLOCK 0
|
||||
#endif
|
||||
|
||||
static int mod_ssi_handle_request(server *srv, connection *con, plugin_data *p) {
|
||||
static int mod_ssi_handle_request(server *srv, connection *con, handler_ctx *p) {
|
||||
int fd;
|
||||
struct stat st;
|
||||
|
||||
|
@ -1173,9 +1188,7 @@ static int mod_ssi_handle_request(server *srv, connection *con, plugin_data *p)
|
|||
array_reset(p->ssi_vars);
|
||||
array_reset(p->ssi_cgi_env);
|
||||
buffer_copy_string_len(p->timefmt, CONST_STR_LEN("%a, %d %b %Y %H:%M:%S %Z"));
|
||||
p->sizefmt = 0;
|
||||
build_ssi_cgi_vars(srv, con, p);
|
||||
p->if_is_false = 0;
|
||||
|
||||
/* Reset the modified time of included files */
|
||||
include_file_last_mtime = 0;
|
||||
|
@ -1197,7 +1210,6 @@ static int mod_ssi_handle_request(server *srv, connection *con, plugin_data *p)
|
|||
close(fd);
|
||||
con->file_started = 1;
|
||||
con->file_finished = 1;
|
||||
con->mode = p->id;
|
||||
|
||||
if (buffer_string_is_empty(p->conf.content_type)) {
|
||||
response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/html"));
|
||||
|
@ -1291,19 +1303,46 @@ URIHANDLER_FUNC(mod_ssi_physical_path) {
|
|||
if (buffer_is_empty(ds->value)) continue;
|
||||
|
||||
if (buffer_is_equal_right_len(con->physical.path, ds->value, buffer_string_length(ds->value))) {
|
||||
con->plugin_ctx[p->id] = handler_ctx_init(p);
|
||||
con->mode = p->id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return HANDLER_GO_ON;
|
||||
}
|
||||
|
||||
SUBREQUEST_FUNC(mod_ssi_handle_subrequest) {
|
||||
plugin_data *p = p_d;
|
||||
handler_ctx *hctx = con->plugin_ctx[p->id];
|
||||
if (NULL == hctx) return HANDLER_GO_ON;
|
||||
if (con->mode != p->id) return HANDLER_GO_ON; /* not my job */
|
||||
/*
|
||||
* NOTE: if mod_ssi modified to use fdevents, HANDLER_WAIT_FOR_EVENT,
|
||||
* instead of blocking to completion, then hctx->timefmt, hctx->ssi_vars,
|
||||
* and hctx->ssi_cgi_env should be allocated and cleaned up per request.
|
||||
*/
|
||||
|
||||
/* handle ssi-request */
|
||||
|
||||
if (mod_ssi_handle_request(srv, con, p)) {
|
||||
if (mod_ssi_handle_request(srv, con, hctx)) {
|
||||
/* on error */
|
||||
con->http_status = 500;
|
||||
con->mode = DIRECT;
|
||||
}
|
||||
|
||||
return HANDLER_FINISHED;
|
||||
}
|
||||
}
|
||||
|
||||
static handler_t mod_ssi_connection_reset(server *srv, connection *con, void *p_d) {
|
||||
plugin_data *p = p_d;
|
||||
handler_ctx *hctx = con->plugin_ctx[p->id];
|
||||
if (hctx) {
|
||||
handler_ctx_free(hctx);
|
||||
con->plugin_ctx[p->id] = NULL;
|
||||
}
|
||||
|
||||
/* not found */
|
||||
UNUSED(srv);
|
||||
return HANDLER_GO_ON;
|
||||
}
|
||||
|
||||
|
@ -1316,6 +1355,8 @@ int mod_ssi_plugin_init(plugin *p) {
|
|||
|
||||
p->init = mod_ssi_init;
|
||||
p->handle_subrequest_start = mod_ssi_physical_path;
|
||||
p->handle_subrequest = mod_ssi_handle_subrequest;
|
||||
p->connection_reset = mod_ssi_connection_reset;
|
||||
p->set_defaults = mod_ssi_set_defaults;
|
||||
p->cleanup = mod_ssi_free;
|
||||
|
||||
|
|
|
@ -20,6 +20,19 @@ typedef struct {
|
|||
typedef struct {
|
||||
PLUGIN_DATA;
|
||||
|
||||
buffer *timefmt;
|
||||
|
||||
buffer *stat_fn;
|
||||
|
||||
array *ssi_vars;
|
||||
array *ssi_cgi_env;
|
||||
|
||||
plugin_config **config_storage;
|
||||
|
||||
plugin_config conf;
|
||||
} plugin_data;
|
||||
|
||||
typedef struct {
|
||||
buffer *timefmt;
|
||||
int sizefmt;
|
||||
|
||||
|
@ -30,11 +43,9 @@ typedef struct {
|
|||
|
||||
int if_level, if_is_false_level, if_is_false, if_is_false_endif;
|
||||
|
||||
plugin_config **config_storage;
|
||||
|
||||
plugin_config conf;
|
||||
} plugin_data;
|
||||
} handler_ctx;
|
||||
|
||||
int ssi_eval_expr(server *srv, connection *con, plugin_data *p, const char *expr);
|
||||
int ssi_eval_expr(server *srv, connection *con, handler_ctx *p, const char *expr);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -43,7 +43,7 @@ int ssi_val_tobool(ssi_val_t *B) {
|
|||
}
|
||||
}
|
||||
|
||||
static int ssi_expr_tokenizer(server *srv, connection *con, plugin_data *p,
|
||||
static int ssi_expr_tokenizer(server *srv, connection *con, handler_ctx *p,
|
||||
ssi_tokenizer_t *t, int *token_id, buffer *token) {
|
||||
int tid = 0;
|
||||
size_t i;
|
||||
|
@ -272,7 +272,7 @@ static int ssi_expr_tokenizer(server *srv, connection *con, plugin_data *p,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ssi_eval_expr(server *srv, connection *con, plugin_data *p, const char *expr) {
|
||||
int ssi_eval_expr(server *srv, connection *con, handler_ctx *p, const char *expr) {
|
||||
ssi_tokenizer_t t;
|
||||
void *pParser;
|
||||
int token_id;
|
||||
|
|
Loading…
Reference in New Issue