# HG changeset patch # User Matwey V. Kornilov <matwey.korni...@gmail.com> # Date 1492936703 -10800 # Sun Apr 23 11:38:23 2017 +0300 # Branch fsize # Node ID 0d6c509169a32624cce431f2469b10b4f961510e # Parent 5116cfea1e9a84be678af10e0ff1f1fce9b00cfb SSI: implemented "fsize" SSI command.
diff -r 5116cfea1e9a -r 0d6c509169a3 src/http/modules/ngx_http_ssi_filter_module.c --- a/src/http/modules/ngx_http_ssi_filter_module.c Thu Apr 20 18:26:38 2017 +0300 +++ b/src/http/modules/ngx_http_ssi_filter_module.c Sun Apr 23 11:38:23 2017 +0300 @@ -89,6 +89,10 @@ ngx_int_t rc); static ngx_int_t ngx_http_ssi_set_variable(ngx_http_request_t *r, void *data, ngx_int_t rc); +static ngx_int_t ngx_http_ssi_fsize(ngx_http_request_t *r, + ngx_http_ssi_ctx_t *ctx, ngx_str_t **params); +static ngx_int_t ngx_http_ssi_fsize_output(ngx_http_request_t *r, void *data, + ngx_int_t rc); static ngx_int_t ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, ngx_str_t **params); static ngx_int_t ngx_http_ssi_config(ngx_http_request_t *r, @@ -223,12 +227,16 @@ #define NGX_HTTP_SSI_INCLUDE_SET 3 #define NGX_HTTP_SSI_INCLUDE_STUB 4 +#define NGX_HTTP_SSI_FSIZE_VIRTUAL 0 +#define NGX_HTTP_SSI_FSIZE_FILE 1 + #define NGX_HTTP_SSI_ECHO_VAR 0 #define NGX_HTTP_SSI_ECHO_DEFAULT 1 #define NGX_HTTP_SSI_ECHO_ENCODING 2 #define NGX_HTTP_SSI_CONFIG_ERRMSG 0 #define NGX_HTTP_SSI_CONFIG_TIMEFMT 1 +#define NGX_HTTP_SSI_CONFIG_SIZEFMT 2 #define NGX_HTTP_SSI_SET_VAR 0 #define NGX_HTTP_SSI_SET_VALUE 1 @@ -248,6 +256,13 @@ }; +static ngx_http_ssi_param_t ngx_http_ssi_fsize_params[] = { + { ngx_string("virtual"), NGX_HTTP_SSI_FSIZE_VIRTUAL, 0, 0 }, + { ngx_string("file"), NGX_HTTP_SSI_FSIZE_FILE, 0, 0 }, + { ngx_null_string, 0, 0, 0 } +}; + + static ngx_http_ssi_param_t ngx_http_ssi_echo_params[] = { { ngx_string("var"), NGX_HTTP_SSI_ECHO_VAR, 1, 0 }, { ngx_string("default"), NGX_HTTP_SSI_ECHO_DEFAULT, 0, 0 }, @@ -259,6 +274,7 @@ static ngx_http_ssi_param_t ngx_http_ssi_config_params[] = { { ngx_string("errmsg"), NGX_HTTP_SSI_CONFIG_ERRMSG, 0, 0 }, { ngx_string("timefmt"), NGX_HTTP_SSI_CONFIG_TIMEFMT, 0, 0 }, + { ngx_string("sizefmt"), NGX_HTTP_SSI_CONFIG_SIZEFMT, 0, 0 }, { ngx_null_string, 0, 0, 0 } }; @@ -290,6 +306,8 @@ static ngx_http_ssi_command_t ngx_http_ssi_commands[] = { { ngx_string("include"), ngx_http_ssi_include, ngx_http_ssi_include_params, 0, 0, 1 }, + { ngx_string("fsize"), ngx_http_ssi_fsize, + ngx_http_ssi_fsize_params, 0, 0, 1 }, { ngx_string("echo"), ngx_http_ssi_echo, ngx_http_ssi_echo_params, 0, 0, 0 }, { ngx_string("config"), ngx_http_ssi_config, @@ -2241,6 +2259,149 @@ static ngx_int_t +ngx_http_ssi_fsize(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, + ngx_str_t **params) +{ + ngx_int_t rc; + ngx_str_t *uri, *file, args; + ngx_uint_t flags; + ngx_http_request_t *sr; + ngx_http_post_subrequest_t *psr; + + uri = params[NGX_HTTP_SSI_FSIZE_VIRTUAL]; + file = params[NGX_HTTP_SSI_FSIZE_FILE]; + + if (uri && file) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "fsize may be either virtual=\"%V\" or file=\"%V\"", + uri, file); + return NGX_HTTP_SSI_ERROR; + } + + if (uri == NULL && file == NULL) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "no parameter in \"fsize\" SSI command"); + return NGX_HTTP_SSI_ERROR; + } + + if (uri == NULL) { + uri = file; + } + + rc = ngx_http_ssi_evaluate_string(r, ctx, uri, NGX_HTTP_SSI_ADD_PREFIX); + + if (rc != NGX_OK) { + return rc; + } + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "ssi fsize: \"%V\"", uri); + + ngx_str_null(&args); + flags = NGX_HTTP_LOG_UNSAFE; + + if (ngx_http_parse_unsafe_uri(r, uri, &args, &flags) != NGX_OK) { + return NGX_HTTP_SSI_ERROR; + } + + psr = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t)); + if (psr == NULL) { + return NGX_ERROR; + } + + psr->handler = ngx_http_ssi_fsize_output; + psr->data = ctx; + + if (ngx_http_subrequest(r, uri, &args, &sr, psr, flags) != NGX_OK) { + return NGX_HTTP_SSI_ERROR; + } + + sr->header_only = 1; + + return NGX_OK; +} + + +static ngx_int_t +ngx_http_ssi_fsize_output(ngx_http_request_t *r, void *data, ngx_int_t rc) +{ + off_t length; + u_char scale; + unsigned exact_size; + ngx_buf_t *b; + ngx_int_t size; + ngx_chain_t *out; + ngx_http_ssi_ctx_t *ctx; + + ctx = data; + exact_size = ctx->exact_size; + + if (r->request_output) { + return rc; + } + + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "ssi fsize output: \"%V?%V\"", &r->uri, &r->args); + + b = ngx_create_temp_buf(r->pool, NGX_OFF_T_LEN + 2); + if (b == NULL) { + return NGX_ERROR; + } + + length = r->headers_out.content_length_n; + + if (!exact_size && length > 1024 * 1024 * 1024 - 1) { + size = (ngx_int_t) (length / (1024 * 1024 * 1024)); + if ((length % (1024 * 1024 * 1024)) + > (1024 * 1024 * 1024 / 2 - 1)) + { + size++; + } + scale = 'G'; + + } else if (!exact_size && length > 1024 * 1024 - 1) { + size = (ngx_int_t) (length / (1024 * 1024)); + if ((length % (1024 * 1024)) > (1024 * 1024 / 2 - 1)) { + size++; + } + scale = 'M'; + + } else if (!exact_size && length > 9999) { + size = (ngx_int_t) (length / 1024); + if (length % 1024 > 511) { + size++; + } + scale = 'K'; + + } else { + size = (ngx_int_t) length; + scale = '\0'; + } + + if (length < 0) { + b->pos = ctx->errmsg.data; + b->last = ctx->errmsg.data + ctx->errmsg.len; + + } else if (scale) { + b->last = ngx_sprintf(b->last, "%6i%c", size, scale); + + } else { + b->last = ngx_sprintf(b->last, " %6i", size); + } + + out = ngx_alloc_chain_link(r->pool); + if (out == NULL) { + return NGX_ERROR; + } + + out->buf = b; + out->next = NULL; + + return ngx_http_output_filter(r, out); +} + + +static ngx_int_t ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, ngx_str_t **params) { @@ -2400,6 +2561,27 @@ ctx->errmsg = *value; } + value = params[NGX_HTTP_SSI_CONFIG_SIZEFMT]; + + if (value) { + if (value->len == 5 + && ngx_strncasecmp(value->data, (u_char *) "bytes", 5) == 0) + { + ctx->exact_size = 1; + + } else if (value->len == 6 + && ngx_strncasecmp(value->data, (u_char *) "abbrev", 6) == 0) + { + ctx->exact_size = 0; + + } else { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "unknown size format \"%V\" " + "in \"config\" SSI command", value); + return NGX_HTTP_SSI_ERROR; + } + } + return NGX_OK; } diff -r 5116cfea1e9a -r 0d6c509169a3 src/http/modules/ngx_http_ssi_filter_module.h --- a/src/http/modules/ngx_http_ssi_filter_module.h Thu Apr 20 18:26:38 2017 +0300 +++ b/src/http/modules/ngx_http_ssi_filter_module.h Sun Apr 23 11:38:23 2017 +0300 @@ -76,6 +76,7 @@ unsigned block:1; unsigned output:1; unsigned output_chosen:1; + unsigned exact_size:1; ngx_http_request_t *wait; void *value_buf; _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel