[PATCH] - flastmod SSI command
Rastislav Stanik
nginx at rastos.org
Mon Oct 3 18:43:20 UTC 2016
On 09/21/2016 08:55 PM I've sent a patch
http://mailman.nginx.org/pipermail/nginx-devel/2016-September/008815.html
that adds support for "flastmod" SSI command. I got no feedback.
I'm not that familiar with local culture, so I hope I'm not too annoying
by sending this again:
# HG changeset patch
# User Rastislav Stanik <nginx at rastos.org>
# Date 1474145684 -7200
# Sat Sep 17 22:54:44 2016 +0200
# Node ID f12b9f072e00182c8e12f24a4b8fa323c0d28080
# Parent 52367732bcbc87430e8276424356aaec3c2b6a87
add handling of flastmod SSI directive
Add handling of SSI directive 'flastmod'. The directive
takes a single argument 'file' and is replaced with
modification time of the specified file. The filename
is accepted/rejected based on the same rules as for the
SSI directive 'include'.
The time string is constructed based on SSI directive config timefmt.
Failure to obtain the modification time is logged.
diff -r 52367732bcbc -r f12b9f072e00 src/http/modules/ngx_http_ssi_filter_module.c
--- a/src/http/modules/ngx_http_ssi_filter_module.c Fri Sep 16 15:13:24 2016 +0300
+++ b/src/http/modules/ngx_http_ssi_filter_module.c Sat Sep 17 22:54:44 2016 +0200
@@ -85,6 +85,8 @@
static ngx_int_t ngx_http_ssi_include(ngx_http_request_t *r,
ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
+static ngx_int_t ngx_http_ssi_flastmod(ngx_http_request_t *r,
+ ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
static ngx_int_t ngx_http_ssi_stub_output(ngx_http_request_t *r, void *data,
ngx_int_t rc);
static ngx_int_t ngx_http_ssi_set_variable(ngx_http_request_t *r, void *data,
@@ -223,6 +225,8 @@
#define NGX_HTTP_SSI_INCLUDE_SET 3
#define NGX_HTTP_SSI_INCLUDE_STUB 4
+#define NGX_HTTP_SSI_FLASTMOD_FILE 0
+
#define NGX_HTTP_SSI_ECHO_VAR 0
#define NGX_HTTP_SSI_ECHO_DEFAULT 1
#define NGX_HTTP_SSI_ECHO_ENCODING 2
@@ -247,6 +251,10 @@
{ ngx_null_string, 0, 0, 0 }
};
+static ngx_http_ssi_param_t ngx_http_ssi_flastmod_params[] = {
+ { ngx_string("file"), NGX_HTTP_SSI_FLASTMOD_FILE, 0, 0 }
+};
+
static ngx_http_ssi_param_t ngx_http_ssi_echo_params[] = {
{ ngx_string("var"), NGX_HTTP_SSI_ECHO_VAR, 1, 0 },
@@ -308,7 +316,8 @@
ngx_http_ssi_block_params, 0, 0, 0 },
{ ngx_string("endblock"), ngx_http_ssi_endblock,
ngx_http_ssi_no_params, 0, 1, 0 },
-
+ { ngx_string("flastmod"), ngx_http_ssi_flastmod,
+ ngx_http_ssi_flastmod_params, 0, 0, 0 },
{ ngx_null_string, NULL, NULL, 0, 0, 0 }
};
@@ -2197,6 +2206,97 @@
return NGX_OK;
}
+static ngx_int_t
+ngx_http_ssi_flastmod(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
+ ngx_str_t **params)
+{
+ ngx_str_t *file;
+ ngx_str_t current_path;
+ ngx_uint_t flags;
+ ngx_int_t rc;
+ ngx_str_t args;
+ size_t root;
+ struct stat st_buf;
+ u_char *endpos;
+ char *statpath;
+ struct tm mod_time;
+
+ file = params[NGX_HTTP_SSI_FLASTMOD_FILE];
+
+ if (file == NULL) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "no parameter in \"flastmod\" SSI command");
+ return NGX_HTTP_SSI_ERROR;
+ }
+
+ rc = ngx_http_ssi_evaluate_string(r, ctx, file, 0);
+
+ if (rc != NGX_OK) {
+ return rc;
+ }
+
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "ssi flastmod: \"%V\"", file);
+
+ ngx_str_null(&args);
+ flags = NGX_HTTP_LOG_UNSAFE;
+
+ if (ngx_http_parse_unsafe_uri(r, file, &args, &flags) != NGX_OK) {
+ return NGX_HTTP_SSI_ERROR;
+ }
+
+ root=0;
+ ngx_http_map_uri_to_path(r, ¤t_path, &root, 0);
+ // in worst case we will append the flastmod file at the end of the current pathname and add terminating zero
+ statpath=ngx_pcalloc(r->pool,current_path.len+file->len+1);
+ if (!statpath) {
+ return NGX_HTTP_SSI_ERROR;
+ }
+ // write the current pathname to 'statpath'
+ strncpy(statpath,current_path.data,current_path.len);
+ endpos=statpath+current_path.len;
+ // find the last slash
+ for (;endpos>current_path.data && !ngx_path_separator(*endpos);endpos--)
+ ;
+ // append the flastmod file after last slash
+ strncpy(endpos+1,file->data,file->len);
+ *(endpos+1+file->len)='\0'; // zero terminate the string so that we can pass it to stat(2)
+
+ if (0==stat(statpath,&st_buf)) {
+ if (gmtime_r(&st_buf.st_mtim.tv_sec,&mod_time)) {
+ char *result=NULL;
+ ngx_uint_t len=0;
+ ngx_buf_t *b=NULL;
+
+ result = ngx_pcalloc(r->pool, NGX_HTTP_SSI_MAX_FLASTMOD);
+ if (result) {
+ // convert the modification time to string:
+ len=strftime(result,NGX_HTTP_SSI_MAX_FLASTMOD,ctx->timefmt.data,&mod_time);
+ b = ngx_calloc_buf(r->pool);
+ if (b) {
+ ngx_chain_t *cl = ngx_alloc_chain_link(r->pool);
+ if (cl) {
+ // insert the time string into the http response:
+ b->memory = 1;
+ b->pos = result;
+ b->last = result + len;
+
+ cl->buf = b;
+ cl->next = NULL;
+ *ctx->last_out = cl;
+ ctx->last_out = &cl->next;
+ return NGX_OK;
+ }
+ }
+ }
+ }
+ }
+ else
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "could not stat() \"%s\" file. err=%d",statpath,ngx_errno);
+
+ return NGX_HTTP_SSI_ERROR;
+}
static ngx_int_t
ngx_http_ssi_stub_output(ngx_http_request_t *r, void *data, ngx_int_t rc)
diff -r 52367732bcbc -r f12b9f072e00 src/http/modules/ngx_http_ssi_filter_module.h
--- a/src/http/modules/ngx_http_ssi_filter_module.h Fri Sep 16 15:13:24 2016 +0300
+++ b/src/http/modules/ngx_http_ssi_filter_module.h Sat Sep 17 22:54:44 2016 +0200
@@ -30,6 +30,9 @@
#define NGX_HTTP_SSI_ENTITY_ENCODING 2
+#define NGX_HTTP_SSI_MAX_FLASTMOD 100
+
+
typedef struct {
ngx_hash_t hash;
ngx_hash_keys_arrays_t commands;
More information about the nginx-devel
mailing list