Mercurial > hg > nginx-ranges
comparison src/http/modules/ngx_http_ssi_filter_module.c @ 635:e67b227c8dbb default tip
Merge with current.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 25 Apr 2011 04:07:55 +0400 |
parents | b4dcae568a2a |
children |
comparison
equal
deleted
inserted
replaced
578:f3a9e57d2e17 | 635:e67b227c8dbb |
---|---|
12 | 12 |
13 #define NGX_HTTP_SSI_DATE_LEN 2048 | 13 #define NGX_HTTP_SSI_DATE_LEN 2048 |
14 | 14 |
15 #define NGX_HTTP_SSI_ADD_PREFIX 1 | 15 #define NGX_HTTP_SSI_ADD_PREFIX 1 |
16 #define NGX_HTTP_SSI_ADD_ZERO 2 | 16 #define NGX_HTTP_SSI_ADD_ZERO 2 |
17 #define NGX_HTTP_SSI_EXPR_TEST 4 | |
18 | 17 |
19 | 18 |
20 typedef struct { | 19 typedef struct { |
21 ngx_flag_t enable; | 20 ngx_flag_t enable; |
22 ngx_flag_t silent_errors; | 21 ngx_flag_t silent_errors; |
69 } ngx_http_ssi_state_e; | 68 } ngx_http_ssi_state_e; |
70 | 69 |
71 | 70 |
72 static ngx_int_t ngx_http_ssi_output(ngx_http_request_t *r, | 71 static ngx_int_t ngx_http_ssi_output(ngx_http_request_t *r, |
73 ngx_http_ssi_ctx_t *ctx); | 72 ngx_http_ssi_ctx_t *ctx); |
73 static void ngx_http_ssi_buffered(ngx_http_request_t *r, | |
74 ngx_http_ssi_ctx_t *ctx); | |
74 static ngx_int_t ngx_http_ssi_parse(ngx_http_request_t *r, | 75 static ngx_int_t ngx_http_ssi_parse(ngx_http_request_t *r, |
75 ngx_http_ssi_ctx_t *ctx); | 76 ngx_http_ssi_ctx_t *ctx); |
76 static ngx_str_t *ngx_http_ssi_get_variable(ngx_http_request_t *r, | 77 static ngx_str_t *ngx_http_ssi_get_variable(ngx_http_request_t *r, |
77 ngx_str_t *name, ngx_uint_t key); | 78 ngx_str_t *name, ngx_uint_t key); |
78 static ngx_int_t ngx_http_ssi_evaluate_string(ngx_http_request_t *r, | 79 static ngx_int_t ngx_http_ssi_evaluate_string(ngx_http_request_t *r, |
345 ctx->params.elts = ctx->params_array; | 346 ctx->params.elts = ctx->params_array; |
346 ctx->params.size = sizeof(ngx_table_elt_t); | 347 ctx->params.size = sizeof(ngx_table_elt_t); |
347 ctx->params.nalloc = NGX_HTTP_SSI_PARAMS_N; | 348 ctx->params.nalloc = NGX_HTTP_SSI_PARAMS_N; |
348 ctx->params.pool = r->pool; | 349 ctx->params.pool = r->pool; |
349 | 350 |
350 ctx->timefmt.len = sizeof("%A, %d-%b-%Y %H:%M:%S %Z") - 1; | 351 ngx_str_set(&ctx->timefmt, "%A, %d-%b-%Y %H:%M:%S %Z"); |
351 ctx->timefmt.data = (u_char *) "%A, %d-%b-%Y %H:%M:%S %Z"; | 352 ngx_str_set(&ctx->errmsg, |
352 | 353 "[an error occurred while processing the directive]"); |
353 ctx->errmsg.len = | |
354 sizeof("[an error occurred while processing the directive]") - 1; | |
355 ctx->errmsg.data = (u_char *) | |
356 "[an error occurred while processing the directive]"; | |
357 | 354 |
358 r->filter_need_in_memory = 1; | 355 r->filter_need_in_memory = 1; |
359 | 356 |
360 if (r == r->main) { | 357 if (r == r->main) { |
361 ngx_http_clear_content_length(r); | 358 ngx_http_clear_content_length(r); |
434 | 431 |
435 slcf = ngx_http_get_module_loc_conf(r, ngx_http_ssi_filter_module); | 432 slcf = ngx_http_get_module_loc_conf(r, ngx_http_ssi_filter_module); |
436 | 433 |
437 while (ctx->in || ctx->buf) { | 434 while (ctx->in || ctx->buf) { |
438 | 435 |
439 if (ctx->buf == NULL ){ | 436 if (ctx->buf == NULL) { |
440 ctx->buf = ctx->in->buf; | 437 ctx->buf = ctx->in->buf; |
441 ctx->in = ctx->in->next; | 438 ctx->in = ctx->in->next; |
442 ctx->pos = ctx->buf->pos; | 439 ctx->pos = ctx->buf->pos; |
443 } | 440 } |
444 | 441 |
796 if (rc == NGX_OK) { | 793 if (rc == NGX_OK) { |
797 continue; | 794 continue; |
798 } | 795 } |
799 | 796 |
800 if (rc == NGX_DONE || rc == NGX_AGAIN || rc == NGX_ERROR) { | 797 if (rc == NGX_DONE || rc == NGX_AGAIN || rc == NGX_ERROR) { |
798 ngx_http_ssi_buffered(r, ctx); | |
801 return rc; | 799 return rc; |
802 } | 800 } |
803 } | 801 } |
804 | 802 |
805 | 803 |
948 cl->next = ctx->free; | 946 cl->next = ctx->free; |
949 ctx->free = cl; | 947 ctx->free = cl; |
950 } | 948 } |
951 } | 949 } |
952 | 950 |
951 ngx_http_ssi_buffered(r, ctx); | |
952 | |
953 return rc; | |
954 } | |
955 | |
956 | |
957 static void | |
958 ngx_http_ssi_buffered(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx) | |
959 { | |
953 if (ctx->in || ctx->buf) { | 960 if (ctx->in || ctx->buf) { |
954 r->buffered |= NGX_HTTP_SSI_BUFFERED; | 961 r->buffered |= NGX_HTTP_SSI_BUFFERED; |
955 | 962 |
956 } else { | 963 } else { |
957 r->buffered &= ~NGX_HTTP_SSI_BUFFERED; | 964 r->buffered &= ~NGX_HTTP_SSI_BUFFERED; |
958 } | 965 } |
959 | |
960 return rc; | |
961 } | 966 } |
962 | 967 |
963 | 968 |
964 static ngx_int_t | 969 static ngx_int_t |
965 ngx_http_ssi_parse(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx) | 970 ngx_http_ssi_parse(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx) |
1699 key = ngx_hash_strlow(var.data, var.data, var.len); | 1704 key = ngx_hash_strlow(var.data, var.data, var.len); |
1700 | 1705 |
1701 val = ngx_http_ssi_get_variable(r, &var, key); | 1706 val = ngx_http_ssi_get_variable(r, &var, key); |
1702 | 1707 |
1703 if (val == NULL) { | 1708 if (val == NULL) { |
1704 vv = ngx_http_get_variable(r, &var, key, | 1709 vv = ngx_http_get_variable(r, &var, key); |
1705 flags & NGX_HTTP_SSI_EXPR_TEST); | |
1706 if (vv == NULL) { | 1710 if (vv == NULL) { |
1707 return NGX_ERROR; | 1711 return NGX_ERROR; |
1708 } | 1712 } |
1709 | 1713 |
1710 if (vv->not_found) { | 1714 if (vv->not_found) { |
1896 | 1900 |
1897 ngx_unescape_uri(&dst, &src, uri->len, NGX_UNESCAPE_URI); | 1901 ngx_unescape_uri(&dst, &src, uri->len, NGX_UNESCAPE_URI); |
1898 | 1902 |
1899 len = (uri->data + uri->len) - src; | 1903 len = (uri->data + uri->len) - src; |
1900 if (len) { | 1904 if (len) { |
1901 dst = ngx_copy(dst, src, len); | 1905 dst = ngx_movemem(dst, src, len); |
1902 } | 1906 } |
1903 | 1907 |
1904 uri->len = dst - uri->data; | 1908 uri->len = dst - uri->data; |
1905 | 1909 |
1906 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 1910 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
1907 "ssi include: \"%V\"", uri); | 1911 "ssi include: \"%V\"", uri); |
1908 | 1912 |
1909 args.len = 0; | 1913 ngx_str_null(&args); |
1910 args.data = NULL; | |
1911 flags = NGX_HTTP_LOG_UNSAFE; | 1914 flags = NGX_HTTP_LOG_UNSAFE; |
1912 | 1915 |
1913 if (ngx_http_parse_unsafe_uri(r, uri, &args, &flags) != NGX_OK) { | 1916 if (ngx_http_parse_unsafe_uri(r, uri, &args, &flags) != NGX_OK) { |
1914 return NGX_HTTP_SSI_ERROR; | 1917 return NGX_HTTP_SSI_ERROR; |
1915 } | 1918 } |
2108 key = ngx_hash_strlow(var->data, var->data, var->len); | 2111 key = ngx_hash_strlow(var->data, var->data, var->len); |
2109 | 2112 |
2110 value = ngx_http_ssi_get_variable(r, var, key); | 2113 value = ngx_http_ssi_get_variable(r, var, key); |
2111 | 2114 |
2112 if (value == NULL) { | 2115 if (value == NULL) { |
2113 vv = ngx_http_get_variable(r, var, key, 1); | 2116 vv = ngx_http_get_variable(r, var, key); |
2114 | 2117 |
2115 if (vv == NULL) { | 2118 if (vv == NULL) { |
2116 return NGX_HTTP_SSI_ERROR; | 2119 return NGX_HTTP_SSI_ERROR; |
2117 } | 2120 } |
2118 | 2121 |
2159 "unknown encoding \"%V\" in the \"echo\" command", | 2162 "unknown encoding \"%V\" in the \"echo\" command", |
2160 enc); | 2163 enc); |
2161 } | 2164 } |
2162 } | 2165 } |
2163 | 2166 |
2167 p = value->data; | |
2168 | |
2164 switch (ctx->encoding) { | 2169 switch (ctx->encoding) { |
2165 | |
2166 case NGX_HTTP_SSI_NO_ENCODING: | |
2167 break; | |
2168 | 2170 |
2169 case NGX_HTTP_SSI_URL_ENCODING: | 2171 case NGX_HTTP_SSI_URL_ENCODING: |
2170 len = 2 * ngx_escape_uri(NULL, value->data, value->len, | 2172 len = 2 * ngx_escape_uri(NULL, value->data, value->len, |
2171 NGX_ESCAPE_HTML); | 2173 NGX_ESCAPE_HTML); |
2172 | 2174 |
2175 if (p == NULL) { | 2177 if (p == NULL) { |
2176 return NGX_HTTP_SSI_ERROR; | 2178 return NGX_HTTP_SSI_ERROR; |
2177 } | 2179 } |
2178 | 2180 |
2179 (void) ngx_escape_uri(p, value->data, value->len, NGX_ESCAPE_HTML); | 2181 (void) ngx_escape_uri(p, value->data, value->len, NGX_ESCAPE_HTML); |
2180 | 2182 } |
2181 value->len += len; | 2183 |
2182 value->data = p; | 2184 len += value->len; |
2183 } | |
2184 | |
2185 break; | 2185 break; |
2186 | 2186 |
2187 case NGX_HTTP_SSI_ENTITY_ENCODING: | 2187 case NGX_HTTP_SSI_ENTITY_ENCODING: |
2188 len = ngx_escape_html(NULL, value->data, value->len); | 2188 len = ngx_escape_html(NULL, value->data, value->len); |
2189 | 2189 |
2192 if (p == NULL) { | 2192 if (p == NULL) { |
2193 return NGX_HTTP_SSI_ERROR; | 2193 return NGX_HTTP_SSI_ERROR; |
2194 } | 2194 } |
2195 | 2195 |
2196 (void) ngx_escape_html(p, value->data, value->len); | 2196 (void) ngx_escape_html(p, value->data, value->len); |
2197 | 2197 } |
2198 value->len += len; | 2198 |
2199 value->data = p; | 2199 len += value->len; |
2200 } | 2200 break; |
2201 | 2201 |
2202 default: /* NGX_HTTP_SSI_NO_ENCODING */ | |
2203 len = value->len; | |
2202 break; | 2204 break; |
2203 } | 2205 } |
2204 | 2206 |
2205 b = ngx_calloc_buf(r->pool); | 2207 b = ngx_calloc_buf(r->pool); |
2206 if (b == NULL) { | 2208 if (b == NULL) { |
2211 if (cl == NULL) { | 2213 if (cl == NULL) { |
2212 return NGX_HTTP_SSI_ERROR; | 2214 return NGX_HTTP_SSI_ERROR; |
2213 } | 2215 } |
2214 | 2216 |
2215 b->memory = 1; | 2217 b->memory = 1; |
2216 b->pos = value->data; | 2218 b->pos = p; |
2217 b->last = value->data + value->len; | 2219 b->last = p + len; |
2218 | 2220 |
2219 cl->buf = b; | 2221 cl->buf = b; |
2220 cl->next = NULL; | 2222 cl->next = NULL; |
2221 *ctx->last_out = cl; | 2223 *ctx->last_out = cl; |
2222 ctx->last_out = &cl->next; | 2224 ctx->last_out = &cl->next; |
2360 | 2362 |
2361 while (p < last && *p == ' ') { | 2363 while (p < last && *p == ' ') { |
2362 p++; | 2364 p++; |
2363 } | 2365 } |
2364 | 2366 |
2365 flags = (p == last) ? NGX_HTTP_SSI_EXPR_TEST : 0; | 2367 flags = 0; |
2366 | 2368 |
2367 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 2369 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
2368 "left: \"%V\"", &left); | 2370 "left: \"%V\"", &left); |
2369 | 2371 |
2370 rc = ngx_http_ssi_evaluate_string(r, ctx, &left, flags); | 2372 rc = ngx_http_ssi_evaluate_string(r, ctx, &left, flags); |