Skip to content

Commit

Permalink
[mod_ssi] produce content in subrequest hook
Browse files Browse the repository at this point in the history
(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:
  lighttpd#73
  • Loading branch information
gstrauss committed Dec 6, 2016
1 parent ac9822f commit 83ec97a
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 17 deletions.
63 changes: 52 additions & 11 deletions src/mod_ssi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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 */
Expand All @@ -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 ... -->
Expand Down Expand Up @@ -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 ... -->
Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -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;

Expand All @@ -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;
Expand All @@ -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"));
Expand Down Expand Up @@ -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;
}

Expand All @@ -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;

Expand Down
19 changes: 15 additions & 4 deletions src/mod_ssi.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,31 @@ typedef struct {
PLUGIN_DATA;

buffer *timefmt;
int sizefmt;

buffer *stat_fn;

array *ssi_vars;
array *ssi_cgi_env;

int if_level, if_is_false_level, if_is_false, if_is_false_endif;

plugin_config **config_storage;

plugin_config conf;
} plugin_data;

int ssi_eval_expr(server *srv, connection *con, plugin_data *p, const char *expr);
typedef struct {
buffer *timefmt;
int sizefmt;

buffer *stat_fn;

array *ssi_vars;
array *ssi_cgi_env;

int if_level, if_is_false_level, if_is_false, if_is_false_endif;

plugin_config conf;
} handler_ctx;

int ssi_eval_expr(server *srv, connection *con, handler_ctx *p, const char *expr);

#endif
4 changes: 2 additions & 2 deletions src/mod_ssi_expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 83ec97a

Please sign in to comment.