Mercurial > hg > nginx-mail
comparison src/http/modules/ngx_http_ssi_filter_module.c @ 665:0b460e61bdcd default tip
Merge with nginx 1.0.0.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 25 Apr 2011 04:22:17 +0400 |
parents | b4dcae568a2a |
children |
comparison
equal
deleted
inserted
replaced
572:06419a2298a9 | 665:0b460e61bdcd |
---|---|
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; | 1914 flags = NGX_HTTP_LOG_UNSAFE; |
1911 flags = 0; | |
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 } |
1916 | 1919 |
2059 "ssi stub output: \"%V?%V\"", &r->uri, &r->args); | 2062 "ssi stub output: \"%V?%V\"", &r->uri, &r->args); |
2060 | 2063 |
2061 out = data; | 2064 out = data; |
2062 | 2065 |
2063 if (!r->header_sent) { | 2066 if (!r->header_sent) { |
2064 if (ngx_http_set_content_type(r) != NGX_OK) { | 2067 r->headers_out.content_type_len = |
2065 return NGX_ERROR; | 2068 r->parent->headers_out.content_type_len; |
2066 } | 2069 r->headers_out.content_type = r->parent->headers_out.content_type; |
2067 | 2070 |
2068 if (ngx_http_send_header(r) == NGX_ERROR) { | 2071 if (ngx_http_send_header(r) == NGX_ERROR) { |
2069 return NGX_ERROR; | 2072 return NGX_ERROR; |
2070 } | 2073 } |
2071 } | 2074 } |
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); |
2448 rc = ngx_strncmp(left.data, right.data, right.len); | 2450 rc = ngx_strncmp(left.data, right.data, right.len); |
2449 } | 2451 } |
2450 | 2452 |
2451 } else { | 2453 } else { |
2452 #if (NGX_PCRE) | 2454 #if (NGX_PCRE) |
2453 ngx_str_t err; | 2455 ngx_regex_compile_t rgc; |
2454 ngx_regex_t *regex; | 2456 u_char errstr[NGX_MAX_CONF_ERRSTR]; |
2455 u_char errstr[NGX_MAX_CONF_ERRSTR]; | |
2456 | |
2457 err.len = NGX_MAX_CONF_ERRSTR; | |
2458 err.data = errstr; | |
2459 | 2457 |
2460 right.data[right.len] = '\0'; | 2458 right.data[right.len] = '\0'; |
2461 | 2459 |
2462 regex = ngx_regex_compile(&right, 0, r->pool, &err); | 2460 ngx_memzero(&rgc, sizeof(ngx_regex_compile_t)); |
2463 | 2461 |
2464 if (regex == NULL) { | 2462 rgc.pattern = right; |
2465 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "%s", err.data); | 2463 rgc.pool = r->pool; |
2464 rgc.err.len = NGX_MAX_CONF_ERRSTR; | |
2465 rgc.err.data = errstr; | |
2466 | |
2467 if (ngx_regex_compile(&rgc) != NGX_OK) { | |
2468 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "%V", &rgc.err); | |
2466 return NGX_HTTP_SSI_ERROR; | 2469 return NGX_HTTP_SSI_ERROR; |
2467 } | 2470 } |
2468 | 2471 |
2469 rc = ngx_regex_exec(regex, &left, NULL, 0); | 2472 rc = ngx_regex_exec(rgc.regex, &left, NULL, 0); |
2470 | 2473 |
2471 if (rc != NGX_REGEX_NO_MATCHED && rc < 0) { | 2474 if (rc < NGX_REGEX_NO_MATCHED) { |
2472 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, | 2475 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, |
2473 ngx_regex_exec_n " failed: %d on \"%V\" using \"%V\"", | 2476 ngx_regex_exec_n " failed: %i on \"%V\" using \"%V\"", |
2474 rc, &left, &right); | 2477 rc, &left, &right); |
2475 return NGX_HTTP_SSI_ERROR; | 2478 return NGX_HTTP_SSI_ERROR; |
2476 } | 2479 } |
2477 #else | 2480 #else |
2478 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, | 2481 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, |
2612 v->data = ngx_pnalloc(r->pool, NGX_TIME_T_LEN); | 2615 v->data = ngx_pnalloc(r->pool, NGX_TIME_T_LEN); |
2613 if (v->data == NULL) { | 2616 if (v->data == NULL) { |
2614 return NGX_ERROR; | 2617 return NGX_ERROR; |
2615 } | 2618 } |
2616 | 2619 |
2617 v->len = ngx_sprintf(v->data, "%T", tp->sec + (gmt ? 0 : tp->gmtoff)) | 2620 v->len = ngx_sprintf(v->data, "%T", tp->sec) - v->data; |
2618 - v->data; | |
2619 | 2621 |
2620 return NGX_OK; | 2622 return NGX_OK; |
2621 } | 2623 } |
2622 | 2624 |
2623 if (gmt) { | 2625 if (gmt) { |
2770 prev->ignore_recycled_buffers, 0); | 2772 prev->ignore_recycled_buffers, 0); |
2771 | 2773 |
2772 ngx_conf_merge_size_value(conf->min_file_chunk, prev->min_file_chunk, 1024); | 2774 ngx_conf_merge_size_value(conf->min_file_chunk, prev->min_file_chunk, 1024); |
2773 ngx_conf_merge_size_value(conf->value_len, prev->value_len, 256); | 2775 ngx_conf_merge_size_value(conf->value_len, prev->value_len, 256); |
2774 | 2776 |
2775 if (ngx_http_merge_types(cf, conf->types_keys, &conf->types, | 2777 if (ngx_http_merge_types(cf, &conf->types_keys, &conf->types, |
2776 prev->types_keys, &prev->types, | 2778 &prev->types_keys, &prev->types, |
2777 ngx_http_html_default_types) | 2779 ngx_http_html_default_types) |
2778 != NGX_OK) | 2780 != NGX_OK) |
2779 { | 2781 { |
2780 return NGX_CONF_ERROR; | 2782 return NGX_CONF_ERROR; |
2781 } | 2783 } |