[PATCH] SSI: Implement #fsize SSI command
Matwey V. Kornilov
matwey.kornilov at gmail.com
Wed Feb 1 11:56:14 UTC 2017
30.01.2017 17:26, Maxim Dounin пишет:
> Hello!
>
> On Sat, Jan 28, 2017 at 02:08:29PM +0300, Matwey V. Kornilov wrote:
>
>> # HG changeset patch
>> # User Matwey V. Kornilov <matwey.kornilov at gmail.com>
>> # Date 1485600652 -10800
>> # Sat Jan 28 13:50:52 2017 +0300
>> # Branch fsize
>> # Node ID f3bb0258beb24b975b94966a94d45e9a9f5c3c39
>> # Parent 640f035293959b2d4b0ba5939d954bc517f57f77
>> SSI: Implement #fsize SSI command
>
> Thanks, looks interesting, though certainly it needs more work.
> Some comments below.
Hello,
Thank you for valuable comments.
I probably missed something about header_only, it was tricky to
understand how it was really supposed to be used. Probably I need other
(or introduce new dedicated) way to achieve the same result.
Frankly speaking, I don't like idea with waited subrequest because there
could be many #fsize-s at the same page and simultaneous #fsize
processing would be desired here due to lower page rendering time.
>
> [...]
>
>> +static ngx_int_t ngx_http_ssi_fsize(ngx_http_request_t *r,
>> + ngx_http_ssi_ctx_t *ctx, ngx_str_t **params)
>
> Style:
> The function type should be on a line by itself preceding the
> function. That is, function name should start on its own line:
>
> static ngx_int_t
> ngx_http_ssi_fsize(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
> ngx_str_t **params)
>
> [...]
>
>> + 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)
>> +{
>> + ngx_chain_t *out;
>> + ngx_buf_t *b;
>> + u_char *p;
>> + size_t len, i;
>> + ngx_http_ssi_ctx_t *ctx;
>> + unsigned sizefmt_bytes;
>> +
>> + ctx = data;
>> + sizefmt_bytes = (ctx ? ctx->sizefmt_bytes : 0);
>
> Just a side note:
> It is not clear how ctx can be NULL here.
>
>> +
>> + p = ngx_pnalloc(r->pool, NGX_OFF_T_LEN + 1);
>> + if (p == NULL) {
>> + return NGX_ERROR;
>> + }
>> +
>> + len = ngx_sprintf(p, "%O", r->headers_out.content_length_n) - p;
>
> Note that r->headers_out.content_length_n may be -1 here. Either
> because it is not known at all (this can happen for proxied
> requests), or because it was cleared/modified by a filter
> expecting to change the response. In either case "-1" is probably
> not a correct value to print here.
>
> It might also be a good idea to find out how to prevent filters
> from clearing the length and/or how to save it earlier.
>
>> +
>> + if (!sizefmt_bytes) {
>> + i = len / 3;
>> + len = len % 3;
>> +
>> + p[len] = ngx_http_ssi_si_prefix[i];
>> + len++;
>> + }
>> +
>> + b = ngx_calloc_buf(r->pool);
>> + if (b == NULL) {
>> + return NGX_ERROR;
>> + }
>> +
>> + b->memory = 1;
>> + b->pos = p;
>> + b->last = p + len;
>
> Just a side note:
> Using ngx_create_temp_buf() might be more appropriate here.
>
>> +
>> + 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);
>
> Not sure if it's ok to declare a subrequest as a header_only one,
> and then output a body for it. I suspect it may break in
> unexpected places.
>
> Alternative approach would be to wait for the subrequest and then
> output the result in the main request context, much like it is
> done for "include set".
>
>> @@ -2400,6 +2529,22 @@
>> 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->sizefmt_bytes = 1;
>
> Style:
> The "{" should be on its own line. And the cast needs more
> spaces,
>
> if (value->len == 5
> && ngx_strncasecmp(value->data, (u_char *) "bytes", 5) == 0)
> {
> ctx->sizefmt_bytes = 1;
>
More information about the nginx-devel
mailing list