diff options
Diffstat (limited to 'src/http/modules')
-rw-r--r-- | src/http/modules/ngx_http_access_module.c | 4 | ||||
-rw-r--r-- | src/http/modules/ngx_http_fastcgi_module.c | 54 | ||||
-rw-r--r-- | src/http/modules/ngx_http_geo_module.c | 57 | ||||
-rw-r--r-- | src/http/modules/ngx_http_gzip_filter_module.c | 61 | ||||
-rw-r--r-- | src/http/modules/ngx_http_headers_filter_module.c | 121 | ||||
-rw-r--r-- | src/http/modules/ngx_http_index_module.c | 5 | ||||
-rw-r--r-- | src/http/modules/ngx_http_log_module.c | 304 | ||||
-rw-r--r-- | src/http/modules/ngx_http_log_module.h | 23 | ||||
-rw-r--r-- | src/http/modules/ngx_http_proxy_module.c | 153 | ||||
-rw-r--r-- | src/http/modules/ngx_http_realip_module.c | 275 | ||||
-rw-r--r-- | src/http/modules/ngx_http_rewrite_module.c | 58 | ||||
-rw-r--r-- | src/http/modules/ngx_http_ssi_filter_module.c | 126 | ||||
-rw-r--r-- | src/http/modules/ngx_http_ssl_module.c | 14 | ||||
-rw-r--r-- | src/http/modules/ngx_http_ssl_module.h | 10 | ||||
-rw-r--r-- | src/http/modules/ngx_http_static_module.c | 2 | ||||
-rw-r--r-- | src/http/modules/ngx_http_userid_filter_module.c | 79 |
16 files changed, 960 insertions, 386 deletions
diff --git a/src/http/modules/ngx_http_access_module.c b/src/http/modules/ngx_http_access_module.c index b02e8cfd1..0e3430385 100644 --- a/src/http/modules/ngx_http_access_module.c +++ b/src/http/modules/ngx_http_access_module.c @@ -14,7 +14,7 @@ typedef struct { in_addr_t mask; in_addr_t addr; - unsigned deny; + ngx_uint_t deny; /* unsigned deny:1; */ } ngx_http_access_rule_t; @@ -106,7 +106,7 @@ ngx_http_access_handler(ngx_http_request_t *r) for (i = 0; i < alcf->rules->nelts; i++) { ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "%08XD %08XD %08XD", + "access: %08XD %08XD %08XD", sin->sin_addr.s_addr, rule[i].mask, rule[i].addr); if ((sin->sin_addr.s_addr & rule[i].mask) == rule[i].addr) { diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c index d58c7c664..160aacbc3 100644 --- a/src/http/modules/ngx_http_fastcgi_module.c +++ b/src/http/modules/ngx_http_fastcgi_module.c @@ -17,6 +17,7 @@ typedef struct { ngx_str_t index; + ngx_array_t *flushes; ngx_array_t *params_len; ngx_array_t *params; ngx_array_t *params_source; @@ -111,9 +112,8 @@ static ngx_int_t ngx_http_fastcgi_add_variables(ngx_conf_t *cf); static void *ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf); static char *ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child); -static ngx_http_variable_value_t * - ngx_http_fastcgi_script_name_variable(ngx_http_request_t *r, - uintptr_t data); +static ngx_int_t ngx_http_fastcgi_script_name_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); static char *ngx_http_fastcgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); @@ -410,6 +410,9 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r) if (flcf->params_len) { ngx_memzero(&le, sizeof(ngx_http_script_engine_t)); + ngx_http_script_flush_no_cachable_variables(r, flcf->flushes); + le.flushed = 1; + le.ip = flcf->params_len->elts; le.request = r; @@ -507,6 +510,7 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r) e.ip = flcf->params->elts; e.pos = b->last; e.request = r; + e.flushed = 1; le.ip = flcf->params_len->elts; @@ -597,8 +601,8 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r) *b->last++ = ch; } - b->last = ngx_cpymem(b->last, header[i].value.data, - header[i].value.len); + b->last = ngx_copy(b->last, header[i].value.data, + header[i].value.len); } } @@ -1634,9 +1638,10 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) } if (conf->params_source == NULL) { - conf->params_source = prev->params_source; + conf->flushes = prev->flushes; conf->params_len = prev->params_len; conf->params = prev->params; + conf->params_source = prev->params_source; if (conf->params_source == NULL) { return NGX_CONF_OK; @@ -1647,7 +1652,7 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) if (conf->params_len == NULL) { return NGX_CONF_ERROR; } - + conf->params = ngx_array_create(cf->pool, 512, 1); if (conf->params == NULL) { return NGX_CONF_ERROR; @@ -1729,6 +1734,7 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) sc.cf = cf; sc.source = &src[i].value; + sc.flushes = &conf->flushes; sc.lengths = &conf->params_len; sc.values = &conf->params; @@ -1764,38 +1770,36 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) } -static ngx_http_variable_value_t * -ngx_http_fastcgi_script_name_variable(ngx_http_request_t *r, uintptr_t data) +static ngx_int_t +ngx_http_fastcgi_script_name_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) { u_char *p; - ngx_http_variable_value_t *vv; ngx_http_fastcgi_loc_conf_t *flcf; - vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); - if (vv == NULL) { - return NULL; - } - - vv->value = 0; + v->valid = 1; + v->no_cachable = 0; + v->not_found = 0; flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module); if (r->uri.data[r->uri.len - 1] != '/') { - vv->text = r->uri; - return vv; + v->len = r->uri.len; + v->data = r->uri.data; + return NGX_OK; } - vv->text.len = r->uri.len + flcf->index.len; + v->len = r->uri.len + flcf->index.len; - vv->text.data = ngx_palloc(r->pool, vv->text.len); - if (vv->text.data == NULL) { - return NULL; + v->data = ngx_palloc(r->pool, v->len); + if (v->data == NULL) { + return NGX_ERROR; } - p = ngx_cpymem(vv->text.data, r->uri.data, r->uri.len); + p = ngx_copy(v->data, r->uri.data, r->uri.len); ngx_memcpy(p, flcf->index.data, flcf->index.len); - return vv; + return NGX_OK; } @@ -1860,7 +1864,7 @@ ngx_http_fastcgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) clcf->handler = ngx_http_fastcgi_handler; - lcf->upstream.location = &clcf->name; + lcf->upstream.location = clcf->name; if (clcf->name.data[clcf->name.len - 1] == '/') { clcf->auto_redirect = 1; diff --git a/src/http/modules/ngx_http_geo_module.c b/src/http/modules/ngx_http_geo_module.c index 6d94a069e..a3638e4bf 100644 --- a/src/http/modules/ngx_http_geo_module.c +++ b/src/http/modules/ngx_http_geo_module.c @@ -65,31 +65,34 @@ ngx_module_t ngx_http_geo_module = { static ngx_http_variable_value_t ngx_http_geo_null_value = - { 0, ngx_string("0") }; + ngx_http_variable(""); /* AF_INET only */ -static ngx_http_variable_value_t * -ngx_http_geo_variable(ngx_http_request_t *r, uintptr_t data) +static ngx_int_t +ngx_http_geo_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, + uintptr_t data) { ngx_radix_tree_t *tree = (ngx_radix_tree_t *) data; struct sockaddr_in *sin; - ngx_http_variable_value_t *var; + ngx_http_variable_value_t *vv; sin = (struct sockaddr_in *) r->connection->sockaddr; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http geo started"); - var = (ngx_http_variable_value_t *) + vv = (ngx_http_variable_value_t *) ngx_radix32tree_find(tree, ntohl(sin->sin_addr.s_addr)); + *v = *vv; + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http geo: %V %V", &r->connection->addr_text, &var->text); + "http geo: %V %V", &r->connection->addr_text, v); - return var; + return NGX_OK; } @@ -182,7 +185,7 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) static char * ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) { - ngx_int_t rc, n; + ngx_int_t rc; ngx_str_t *value, file; ngx_uint_t i; ngx_inet_cidr_t cidrin; @@ -226,30 +229,18 @@ ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) cidrin.mask = ntohl(cidrin.mask); } - n = ngx_atoi(value[1].data, value[1].len); - var = NULL; v = geo->values.elts; - if (n == NGX_ERROR) { - for (i = 0; i < geo->values.nelts; i++) { - if (v[i]->text.len != value[1].len) { - continue; - } - - if (ngx_strncmp(value[1].data, v[i]->text.data, value[1].len) == 0) - { - var = v[i]; - break; - } + for (i = 0; i < geo->values.nelts; i++) { + if ((size_t) v[i]->len != value[1].len) { + continue; } - } else { - for (i = 0; i < geo->values.nelts; i++) { - if (v[i]->value == (ngx_uint_t) n) { - var = v[i]; - break; - } + if (ngx_strncmp(value[1].data, v[i]->data, value[1].len) == 0) + { + var = v[i]; + break; } } @@ -259,13 +250,15 @@ ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) return NGX_CONF_ERROR; } - var->text.len = value[1].len; - var->text.data = ngx_pstrdup(geo->pool, &value[1]); - if (var->text.data == NULL) { + var->len = value[1].len; + var->data = ngx_pstrdup(geo->pool, &value[1]); + if (var->data == NULL) { return NGX_CONF_ERROR; } - var->value = (n == NGX_ERROR) ? 0 : n; + var->valid = 1; + var->no_cachable = 0; + var->not_found = 0; v = ngx_array_push(&geo->values); if (v == NULL) { @@ -294,7 +287,7 @@ ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) ngx_conf_log_error(NGX_LOG_WARN, cf, 0, "duplicate parameter \"%V\", value: \"%V\", " "old value: \"%V\"", - &value[0], &var->text, &old->text); + &value[0], var, old); rc = ngx_radix32tree_delete(geo->tree, cidrin.addr, cidrin.mask); diff --git a/src/http/modules/ngx_http_gzip_filter_module.c b/src/http/modules/ngx_http_gzip_filter_module.c index 923dd1724..adf7005c2 100644 --- a/src/http/modules/ngx_http_gzip_filter_module.c +++ b/src/http/modules/ngx_http_gzip_filter_module.c @@ -79,7 +79,9 @@ static void ngx_http_gzip_error(ngx_http_gzip_ctx_t *ctx); static u_char *ngx_http_gzip_log_ratio(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op); -static ngx_int_t ngx_http_gzip_add_log_formats(ngx_conf_t *cf); +static ngx_int_t ngx_http_gzip_add_variables(ngx_conf_t *cf); +static ngx_int_t ngx_http_gzip_ratio_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_gzip_filter_init(ngx_cycle_t *cycle); static void *ngx_http_gzip_create_conf(ngx_conf_t *cf); @@ -199,7 +201,7 @@ static ngx_command_t ngx_http_gzip_filter_commands[] = { static ngx_http_module_t ngx_http_gzip_filter_module_ctx = { - ngx_http_gzip_add_log_formats, /* preconfiguration */ + ngx_http_gzip_add_variables, /* preconfiguration */ NULL, /* postconfiguration */ NULL, /* create main configuration */ @@ -256,6 +258,7 @@ struct gztrailer { #endif +static ngx_str_t ngx_http_gzip_ratio = ngx_string("gzip_ratio"); static ngx_str_t ngx_http_gzip_no_cache = ngx_string("no-cache"); static ngx_str_t ngx_http_gzip_no_store = ngx_string("no-store"); static ngx_str_t ngx_http_gzip_private = ngx_string("private"); @@ -956,10 +959,18 @@ ngx_http_gzip_error(ngx_http_gzip_ctx_t *ctx) static ngx_int_t -ngx_http_gzip_add_log_formats(ngx_conf_t *cf) +ngx_http_gzip_add_variables(ngx_conf_t *cf) { + ngx_http_variable_t *var; ngx_http_log_op_name_t *op; + var = ngx_http_add_variable(cf, &ngx_http_gzip_ratio, 0); + if (var == NULL) { + return NGX_ERROR; + } + + var->handler = ngx_http_gzip_ratio_variable; + for (op = ngx_http_gzip_log_fmt_ops; op->name.len; op++) { /* void */ } op->run = NULL; @@ -976,6 +987,50 @@ ngx_http_gzip_add_log_formats(ngx_conf_t *cf) static ngx_int_t +ngx_http_gzip_ratio_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + ngx_uint_t zint, zfrac; + ngx_http_gzip_ctx_t *ctx; + + v->valid = 1; + v->no_cachable = 0; + v->not_found = 0; + + ctx = ngx_http_get_module_ctx(r, ngx_http_gzip_filter_module); + + if (ctx == NULL || ctx->zout == 0) { + v->not_found = 1; + return NGX_OK; + } + + v->data = ngx_palloc(r->pool, NGX_INT32_LEN + 3); + if (v->data == NULL) { + return NGX_ERROR; + } + + zint = (ngx_uint_t) (ctx->zin / ctx->zout); + zfrac = (ngx_uint_t) ((ctx->zin * 100 / ctx->zout) % 100); + + if ((ctx->zin * 1000 / ctx->zout) % 10 > 4) { + + /* the rounding, e.g., 2.125 to 2.13 */ + + zfrac++; + + if (zfrac > 99) { + zint++; + zfrac = 0; + } + } + + v->len = ngx_sprintf(v->data, "%ui.%02ui", zint, zfrac) - v->data; + + return NGX_OK; +} + + +static ngx_int_t ngx_http_gzip_filter_init(ngx_cycle_t *cycle) { ngx_http_next_header_filter = ngx_http_top_header_filter; diff --git a/src/http/modules/ngx_http_headers_filter_module.c b/src/http/modules/ngx_http_headers_filter_module.c index 0855990a5..da9061be8 100644 --- a/src/http/modules/ngx_http_headers_filter_module.c +++ b/src/http/modules/ngx_http_headers_filter_module.c @@ -10,7 +10,9 @@ typedef struct { - time_t expires; + time_t expires; + ngx_str_t cache_control; + ngx_array_t *headers; } ngx_http_headers_conf_t; @@ -22,20 +24,31 @@ typedef struct { static ngx_int_t ngx_http_headers_filter_init(ngx_cycle_t *cycle); static void *ngx_http_headers_create_conf(ngx_conf_t *cf); static char *ngx_http_headers_merge_conf(ngx_conf_t *cf, - void *parent, void *child); + void *parent, void *child); static char *ngx_http_headers_expires(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static char *ngx_http_headers_add(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); static ngx_command_t ngx_http_headers_filter_commands[] = { { ngx_string("expires"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF + |NGX_CONF_TAKE1, ngx_http_headers_expires, NGX_HTTP_LOC_CONF_OFFSET, 0, NULL}, + { ngx_string("add_header"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF + |NGX_CONF_TAKE2, + ngx_http_headers_add, + NGX_HTTP_LOC_CONF_OFFSET, + 0, + NULL}, + ngx_null_command }; @@ -79,7 +92,7 @@ ngx_http_headers_filter(ngx_http_request_t *r) { size_t len; ngx_uint_t i; - ngx_table_elt_t *expires, *cc, **ccp; + ngx_table_elt_t *expires, *cc, **ccp, *h, *out; ngx_http_headers_conf_t *conf; if ((r->headers_out.status != NGX_HTTP_OK @@ -117,7 +130,8 @@ ngx_http_headers_filter(ngx_http_request_t *r) if (ccp == NULL) { if (ngx_array_init(&r->headers_out.cache_control, r->pool, - 1, sizeof(ngx_table_elt_t *)) != NGX_OK) + 1, sizeof(ngx_table_elt_t *)) + != NGX_OK) { return NGX_ERROR; } @@ -188,6 +202,50 @@ ngx_http_headers_filter(ngx_http_request_t *r) } } + if (conf->cache_control.len) { + + ccp = r->headers_out.cache_control.elts; + + if (ccp == NULL) { + + if (ngx_array_init(&r->headers_out.cache_control, r->pool, + 1, sizeof(ngx_table_elt_t *)) + != NGX_OK) + { + return NGX_ERROR; + } + } + + ccp = ngx_array_push(&r->headers_out.cache_control); + if (ccp == NULL) { + return NGX_ERROR; + } + + cc = ngx_list_push(&r->headers_out.headers); + if (cc == NULL) { + return NGX_ERROR; + } + + cc->hash = 1; + cc->key.len = sizeof("Cache-Control") - 1; + cc->key.data = (u_char *) "Cache-Control"; + cc->value = conf->cache_control; + + *ccp = cc; + } + + if (conf->headers) { + h = conf->headers->elts; + for (i = 0; i < conf->headers->nelts; i++) { + out = ngx_list_push(&r->headers_out.headers); + if (out == NULL) { + return NGX_ERROR; + } + + *out = h[i]; + } + } + return ngx_http_next_header_filter(r); } @@ -207,11 +265,19 @@ ngx_http_headers_create_conf(ngx_conf_t *cf) { ngx_http_headers_conf_t *conf; - conf = ngx_palloc(cf->pool, sizeof(ngx_http_headers_conf_t)); + conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_headers_conf_t)); if (conf == NULL) { return NGX_CONF_ERROR; } + /* + * set by ngx_pcalloc(): + * + * conf->cache_control.len = 0; + * conf->cache_control.data = NULL; + * conf->headers = NULL; + */ + conf->expires = NGX_HTTP_EXPIRES_UNSET; return conf; @@ -229,6 +295,14 @@ ngx_http_headers_merge_conf(ngx_conf_t *cf, void *parent, void *child) NGX_HTTP_EXPIRES_OFF : prev->expires; } + if (conf->cache_control.data == NULL) { + conf->cache_control = prev->cache_control; + } + + if (conf->headers == NULL) { + conf->headers = prev->headers; + } + return NGX_CONF_OK; } @@ -287,3 +361,38 @@ ngx_http_headers_expires(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) return NGX_CONF_OK; } + + +static char * +ngx_http_headers_add(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + ngx_http_headers_conf_t *hcf = conf; + + ngx_str_t *value; + ngx_table_elt_t *h; + + value = cf->args->elts; + + if (ngx_strcasecmp(value[1].data, "cache-control") == 0) { + hcf->cache_control = value[2]; + return NGX_CONF_OK; + } + + if (hcf->headers == NULL) { + hcf->headers = ngx_array_create(cf->pool, 1, sizeof(ngx_table_elt_t)); + if (hcf->headers == NULL) { + return NGX_CONF_ERROR; + } + } + + h = ngx_array_push(hcf->headers); + if (h == NULL) { + return NGX_CONF_ERROR; + } + + h->hash = 1; + h->key = value[1]; + h->value = value[2]; + + return NGX_CONF_OK; +} diff --git a/src/http/modules/ngx_http_index_module.c b/src/http/modules/ngx_http_index_module.c index b7daa6d41..4847cb700 100644 --- a/src/http/modules/ngx_http_index_module.c +++ b/src/http/modules/ngx_http_index_module.c @@ -180,6 +180,7 @@ ngx_http_index_handler(ngx_http_request_t *r) e.ip = index[i].lengths->elts; e.request = r; + e.flushed = 1; /* 1 byte for terminating '\0' */ @@ -298,7 +299,7 @@ ngx_http_index_handler(ngx_http_request_t *r) return NGX_HTTP_INTERNAL_SERVER_ERROR; } - last = ngx_cpymem(uri.data, r->uri.data, r->uri.len); + last = ngx_copy(uri.data, r->uri.data, r->uri.len); ngx_memcpy(last, ctx->index.data, ctx->index.len - 1); } @@ -476,7 +477,7 @@ ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ilcf->max_index_len = index->name.len; } - /* include the terminating '\0' to the length to use ngx_memcpy() */ + /* include the terminating '\0' to the length to use ngx_copy() */ index->name.len++; continue; diff --git a/src/http/modules/ngx_http_log_module.c b/src/http/modules/ngx_http_log_module.c index f4993b5a9..e83207042 100644 --- a/src/http/modules/ngx_http_log_module.c +++ b/src/http/modules/ngx_http_log_module.c @@ -10,6 +10,35 @@ #include <nginx.h> + +typedef struct { + ngx_str_t name; + ngx_array_t *ops; /* array of ngx_http_log_op_t */ +} ngx_http_log_fmt_t; + +typedef struct { + ngx_array_t formats; /* array of ngx_http_log_fmt_t */ + ngx_uint_t combined_used; /* unsigned combined_used:1 */ +} ngx_http_log_main_conf_t; + +typedef struct { + ngx_open_file_t *file; + ngx_array_t *ops; /* array of ngx_http_log_op_t */ +} ngx_http_log_t; + +typedef struct { + ngx_array_t *logs; /* array of ngx_http_log_t */ + ngx_uint_t off; /* unsigned off:1 */ +} ngx_http_log_loc_conf_t; + + +typedef struct { + ngx_str_t name; + size_t len; + ngx_http_log_op_run_pt run; +} ngx_http_log_var_t; + + static u_char *ngx_http_log_addr(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op); static u_char *ngx_http_log_connection(ngx_http_request_t *r, u_char *buf, @@ -24,10 +53,10 @@ static u_char *ngx_http_log_request_time(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op); static u_char *ngx_http_log_status(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op); -static u_char *ngx_http_log_length(ngx_http_request_t *r, u_char *buf, - ngx_http_log_op_t *op); -static u_char *ngx_http_log_apache_length(ngx_http_request_t *r, u_char *buf, +static u_char *ngx_http_log_bytes_sent(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op); +static u_char *ngx_http_log_apache_bytes_sent(ngx_http_request_t *r, + u_char *buf, ngx_http_log_op_t *op); static u_char *ngx_http_log_request_length(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op); @@ -83,7 +112,9 @@ static char *ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static char *ngx_http_log_set_format(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); -static ngx_int_t ngx_http_log_init(ngx_cycle_t *cycle); +static char *ngx_http_log_compile_format(ngx_conf_t *cf, + ngx_array_t *ops, ngx_array_t *args, ngx_uint_t s); +static ngx_int_t ngx_http_log_init(ngx_conf_t *cf); static ngx_command_t ngx_http_log_commands[] = { @@ -108,7 +139,7 @@ static ngx_command_t ngx_http_log_commands[] = { ngx_http_module_t ngx_http_log_module_ctx = { ngx_http_log_set_formats, /* preconfiguration */ - NULL, /* postconfiguration */ + ngx_http_log_init, /* postconfiguration */ ngx_http_log_create_main_conf, /* create main configuration */ NULL, /* init main configuration */ @@ -127,7 +158,7 @@ ngx_module_t ngx_http_log_module = { ngx_http_log_commands, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ - ngx_http_log_init, /* init module */ + NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ @@ -137,21 +168,34 @@ ngx_module_t ngx_http_log_module = { }; -static ngx_str_t http_access_log = ngx_string(NGX_HTTP_LOG_PATH); +static ngx_str_t http_access_log = ngx_string(NGX_HTTP_LOG_PATH); -static ngx_str_t ngx_http_combined_fmt = -#if 0 - ngx_string("$remote_addr - $remote_user [%time] " - "\"$request\" %status %apache_length " +static ngx_str_t ngx_http_combined_fmt = + ngx_string("$remote_addr - $remote_user [$time_gmt] " + "\"$request\" $status $apache_bytes_sent " "\"$http_referer\" \"$http_user_agent\""); -#endif - ngx_string("%addr - - [%time] " - "\"%request\" %status %apache_length " - "\"%{referer}i\" \"%{user-agent}i\""); -ngx_http_log_op_name_t ngx_http_log_fmt_ops[] = { +static ngx_http_log_var_t ngx_http_log_vars[] = { + { ngx_string("connection"), NGX_ATOMIC_T_LEN, ngx_http_log_connection }, + { ngx_string("pipe"), 1, ngx_http_log_pipe }, + { ngx_string("time_gmt"), sizeof("28/Sep/1970:12:00:00 +0600") - 1, + ngx_http_log_time }, + { ngx_string("msec"), NGX_TIME_T_LEN + 4, ngx_http_log_msec }, + { ngx_string("request_time"), NGX_TIME_T_LEN, ngx_http_log_request_time }, + { ngx_string("status"), 3, ngx_http_log_status }, + { ngx_string("bytes_sent"), NGX_OFF_T_LEN, ngx_http_log_bytes_sent }, + { ngx_string("apache_bytes_sent"), NGX_OFF_T_LEN, + ngx_http_log_apache_bytes_sent }, + { ngx_string("request_length"), NGX_SIZE_T_LEN, + ngx_http_log_request_length }, + + { ngx_null_string, 0, NULL } +}; + + +ngx_http_log_op_name_t ngx_http_log_fmt_ops[] = { { ngx_string("addr"), INET_ADDRSTRLEN - 1, NULL, NULL, ngx_http_log_addr }, { ngx_string("conn"), NGX_ATOMIC_T_LEN, NULL, NULL, ngx_http_log_connection }, @@ -162,9 +206,10 @@ ngx_http_log_op_name_t ngx_http_log_fmt_ops[] = { { ngx_string("request_time"), NGX_TIME_T_LEN, NULL, NULL, ngx_http_log_request_time }, { ngx_string("status"), 3, NULL, NULL, ngx_http_log_status }, - { ngx_string("length"), NGX_OFF_T_LEN, NULL, NULL, ngx_http_log_length }, + { ngx_string("length"), NGX_OFF_T_LEN, + NULL, NULL, ngx_http_log_bytes_sent }, { ngx_string("apache_length"), NGX_OFF_T_LEN, - NULL, NULL, ngx_http_log_apache_length }, + NULL, NULL, ngx_http_log_apache_bytes_sent }, { ngx_string("request_length"), NGX_SIZE_T_LEN, NULL, NULL, ngx_http_log_request_length }, @@ -376,14 +421,15 @@ ngx_http_log_status(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op) static u_char * -ngx_http_log_length(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op) +ngx_http_log_bytes_sent(ngx_http_request_t *r, u_char *buf, + ngx_http_log_op_t *op) { return ngx_sprintf(buf, "%O", r->connection->sent); } static u_char * -ngx_http_log_apache_length(ngx_http_request_t *r, u_char *buf, +ngx_http_log_apache_bytes_sent(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op) { off_t length; @@ -792,14 +838,11 @@ ngx_http_log_variable_getlen(ngx_http_request_t *r, uintptr_t data) value = ngx_http_get_indexed_variable(r, data); - if (value == NULL - || value == NGX_HTTP_VAR_NOT_FOUND - || value->text.len == 0) - { + if (value == NULL || value->not_found) { return 1; } - return value->text.len; + return value->len; } @@ -810,15 +853,12 @@ ngx_http_log_variable(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op) value = ngx_http_get_indexed_variable(r, op->data); - if (value == NULL - || value == NGX_HTTP_VAR_NOT_FOUND - || value->text.len == 0) - { + if (value == NULL || value->not_found) { *buf = '-'; return buf + 1; } - return ngx_cpymem(buf, value->text.data, value->text.len); + return ngx_cpymem(buf, value->data, value->len); } @@ -839,8 +879,7 @@ ngx_http_log_create_main_conf(ngx_conf_t *cf) { ngx_http_log_main_conf_t *conf; - char *rc; - ngx_str_t *value; + ngx_http_log_fmt_t *fmt; conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_log_main_conf_t)); if (conf == NULL) { @@ -848,38 +887,21 @@ ngx_http_log_create_main_conf(ngx_conf_t *cf) } if (ngx_array_init(&conf->formats, cf->pool, 4, sizeof(ngx_http_log_fmt_t)) - == NGX_ERROR) + != NGX_OK) { return NGX_CONF_ERROR; } - cf->args->nelts = 0; - - value = ngx_array_push(cf->args); - if (value == NULL) { - return NGX_CONF_ERROR; - } - - value->len = 0; - value->data = NULL; - - value = ngx_array_push(cf->args); - if (value == NULL) { - return NGX_CONF_ERROR; - } - - value->len = sizeof("combined") - 1; - value->data = (u_char *) "combined"; - - value = ngx_array_push(cf->args); - if (value == NULL) { + fmt = ngx_array_push(&conf->formats); + if (fmt == NULL) { return NGX_CONF_ERROR; } - *value = ngx_http_combined_fmt; + fmt->name.len = sizeof("combined") - 1; + fmt->name.data = (u_char *) "combined"; - rc = ngx_http_log_set_format(cf, NULL, conf); - if (rc != NGX_CONF_OK) { + fmt->ops = ngx_array_create(cf->pool, 16, sizeof(ngx_http_log_op_t)); + if (fmt->ops == NULL) { return NGX_CONF_ERROR; } @@ -947,6 +969,7 @@ ngx_http_log_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) /* the default "combined" format */ log->ops = fmt[0].ops; + lmcf->combined_used = 1; } } @@ -997,6 +1020,7 @@ ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) } else { name.len = sizeof("combined") - 1; name.data = (u_char *) "combined"; + lmcf->combined_used = 1; } fmt = lmcf->formats.elts; @@ -1058,20 +1082,16 @@ ngx_http_log_set_format(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_log_main_conf_t *lmcf = conf; - u_char *data, *p, *fname, ch; - size_t i, len, fname_len; - ngx_str_t *value, var, arg, *a; - ngx_uint_t s, f, bracket; - ngx_http_log_op_t *op; - ngx_http_log_fmt_t *fmt; - ngx_http_log_op_name_t *name; + ngx_str_t *value; + ngx_uint_t i; + ngx_http_log_fmt_t *fmt; value = cf->args->elts; fmt = lmcf->formats.elts; - for (f = 0; f < lmcf->formats.nelts; f++) { - if (fmt[f].name.len == value[1].len - && ngx_strcmp(fmt->name.data, value[1].data) == 0) + for (i = 0; i < lmcf->formats.nelts; i++) { + if (fmt[i].name.len == value[1].len + && ngx_strcmp(fmt[i].name.data, value[1].data) == 0) { return "duplicate \"log_format\" name"; } @@ -1084,20 +1104,38 @@ ngx_http_log_set_format(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) fmt->name = value[1]; - fmt->ops = ngx_array_create(cf->pool, 20, sizeof(ngx_http_log_op_t)); + fmt->ops = ngx_array_create(cf->pool, 16, sizeof(ngx_http_log_op_t)); if (fmt->ops == NULL) { return NGX_CONF_ERROR; } - arg.data = NULL; + return ngx_http_log_compile_format(cf, fmt->ops, cf->args, 2); +} + + +static char * +ngx_http_log_compile_format(ngx_conf_t *cf, ngx_array_t *ops, + ngx_array_t *args, ngx_uint_t s) +{ + u_char *data, *p, *fname, *arg_data, ch; + size_t i, len, fname_len, arg_len; + ngx_str_t *value, var, *a; + ngx_uint_t bracket; + ngx_http_log_op_t *op; + ngx_http_log_var_t *v; + ngx_http_log_op_name_t *name; + static ngx_uint_t warn; - for (s = 2; s < cf->args->nelts; s++) { + value = args->elts; + arg_data = NULL; + + for ( /* void */ ; s < args->nelts; s++) { i = 0; while (i < value[s].len) { - op = ngx_array_push(fmt->ops); + op = ngx_array_push(ops); if (op == NULL) { return NGX_CONF_ERROR; } @@ -1114,22 +1152,29 @@ ngx_http_log_set_format(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) if (value[s].data[i] == '{') { i++; - arg.data = &value[s].data[i]; + arg_data = &value[s].data[i]; while (i < value[s].len && value[s].data[i] != '}') { i++; } - arg.len = &value[s].data[i] - arg.data; + arg_len = &value[s].data[i] - arg_data; - if (i == value[s].len || arg.len == 0) { + if (i == value[s].len || arg_len == 0) { goto invalid; } i++; } else { - arg.len = 0; + arg_len = 0; + } + + if (warn == 0) { + ngx_conf_log_error(NGX_LOG_WARN, cf, 0, + "the parameters in the \"%%name\" form are deprecated, " + "use the \"$variable\" instead"); + warn = 1; } fname = &value[s].data[i]; @@ -1156,7 +1201,7 @@ ngx_http_log_set_format(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) && ngx_strncmp(name->name.data, fname, fname_len) == 0) { if (name->compile == NULL) { - if (arg.len) { + if (arg_len) { fname[fname_len] = '\0'; ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"%s\" must not have argument", @@ -1172,7 +1217,7 @@ ngx_http_log_set_format(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) break; } - if (arg.len == 0) { + if (arg_len == 0) { fname[fname_len] = '\0'; ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"%s\" requires argument", @@ -1185,7 +1230,9 @@ ngx_http_log_set_format(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) return NGX_CONF_ERROR; } - *a = arg; + a->len = arg_len; + a->data = arg_data; + if (name->compile(cf, op, a) == NGX_ERROR) { return NGX_CONF_ERROR; } @@ -1198,6 +1245,8 @@ ngx_http_log_set_format(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) goto invalid; } + continue; + } else if (value[s].data[i] == '$') { if (++i == value[s].len) { @@ -1249,47 +1298,64 @@ ngx_http_log_set_format(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) goto invalid; } + for (v = ngx_http_log_vars; v->name.len; v++) { + + if (v->name.len == var.len + && ngx_strncmp(v->name.data, var.data, var.len) == 0) + { + op->len = v->len; + op->getlen = NULL; + op->run = v->run; + op->data = 0; + + goto found; + } + } + if (ngx_http_log_variable_compile(cf, op, &var) != NGX_OK) { return NGX_CONF_ERROR; } - } else { - i++; + found: - while (i < value[s].len - && value[s].data[i] != '$' - && value[s].data[i] != '%') - { - i++; - } + continue; + } - len = &value[s].data[i] - data; + i++; - if (len) { + while (i < value[s].len + && value[s].data[i] != '$' + && value[s].data[i] != '%') + { + i++; + } - op->len = len; - op->getlen = NULL; + len = &value[s].data[i] - data; - if (len <= sizeof(uintptr_t)) { - op->run = ngx_http_log_copy_short; - op->data = 0; + if (len) { - while (len--) { - op->data <<= 8; - op->data |= data[len]; - } + op->len = len; + op->getlen = NULL; - } else { - op->run = ngx_http_log_copy_long; + if (len <= sizeof(uintptr_t)) { + op->run = ngx_http_log_copy_short; + op->data = 0; - p = ngx_palloc(cf->pool, len); - if (p == NULL) { - return NGX_CONF_ERROR; - } + while (len--) { + op->data <<= 8; + op->data |= data[len]; + } - ngx_memcpy(p, data, len); - op->data = (uintptr_t) p; + } else { + op->run = ngx_http_log_copy_long; + + p = ngx_palloc(cf->pool, len); + if (p == NULL) { + return NGX_CONF_ERROR; } + + ngx_memcpy(p, data, len); + op->data = (uintptr_t) p; } } } @@ -1306,11 +1372,37 @@ invalid: static ngx_int_t -ngx_http_log_init(ngx_cycle_t *cycle) +ngx_http_log_init(ngx_conf_t *cf) { + ngx_str_t *value; + ngx_array_t a; + ngx_http_log_fmt_t *fmt; + ngx_http_log_main_conf_t *lmcf; ngx_http_core_main_conf_t *cmcf; - cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module); + lmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_log_module); + + if (lmcf->combined_used) { + if (ngx_array_init(&a, cf->pool, 1, sizeof(ngx_str_t)) != NGX_OK) { + return NGX_ERROR; + } + + value = ngx_array_push(&a); + if (value == NULL) { + return NGX_ERROR; + } + + *value = ngx_http_combined_fmt; + fmt = lmcf->formats.elts; + + if (ngx_http_log_compile_format(cf, fmt->ops, &a, 0) + != NGX_CONF_OK) + { + return NGX_ERROR; + } + } + + cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); cmcf->log_handler = ngx_http_log_handler; diff --git a/src/http/modules/ngx_http_log_module.h b/src/http/modules/ngx_http_log_module.h index c414bc4ac..01cfb5418 100644 --- a/src/http/modules/ngx_http_log_module.h +++ b/src/http/modules/ngx_http_log_module.h @@ -35,12 +35,6 @@ struct ngx_http_log_op_s { typedef struct { ngx_str_t name; - ngx_array_t *ops; /* array of ngx_http_log_op_t */ -} ngx_http_log_fmt_t; - - -typedef struct { - ngx_str_t name; size_t len; ngx_http_log_op_compile_pt compile; ngx_http_log_op_getlen_pt getlen; @@ -48,23 +42,6 @@ typedef struct { } ngx_http_log_op_name_t; -typedef struct { - ngx_array_t formats; /* array of ngx_http_log_fmt_t */ -} ngx_http_log_main_conf_t; - - -typedef struct { - ngx_open_file_t *file; - ngx_array_t *ops; /* array of ngx_http_log_op_t */ -} ngx_http_log_t; - - -typedef struct { - ngx_array_t *logs; /* array of ngx_http_log_t */ - ngx_uint_t off; /* unsigned off:1 */ -} ngx_http_log_loc_conf_t; - - extern ngx_http_log_op_name_t ngx_http_log_fmt_ops[]; diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c index 8c4231a53..26f08315e 100644 --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -37,6 +37,7 @@ typedef struct { ngx_peers_t *peers; + ngx_array_t *flushes; ngx_array_t *headers_set_len; ngx_array_t *headers_set; ngx_hash_t *headers_set_hash; @@ -75,13 +76,13 @@ static void ngx_http_proxy_abort_request(ngx_http_request_t *r); static void ngx_http_proxy_finalize_request(ngx_http_request_t *r, ngx_int_t rc); -static ngx_http_variable_value_t * - ngx_http_proxy_host_variable(ngx_http_request_t *r, uintptr_t data); -static ngx_http_variable_value_t * - ngx_http_proxy_port_variable(ngx_http_request_t *r, uintptr_t data); -static ngx_http_variable_value_t * +static ngx_int_t ngx_http_proxy_host_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_proxy_port_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_proxy_add_x_forwarded_for_variable(ngx_http_request_t *r, - uintptr_t data); + ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_proxy_rewrite_redirect(ngx_http_request_t *r, ngx_table_elt_t *h, size_t prefix); @@ -431,7 +432,7 @@ ngx_http_proxy_create_request(ngx_http_request_t *r) escape = 0; - loc_len = r->valid_location ? u->conf->location->len : 0; + loc_len = r->valid_location ? u->conf->location.len : 0; if (u->conf->uri.len == 0 && r->valid_unparsed_uri) { len += r->unparsed_uri.len; @@ -447,8 +448,11 @@ ngx_http_proxy_create_request(ngx_http_request_t *r) ngx_memzero(&e, sizeof(ngx_http_script_engine_t)); + ngx_http_script_flush_no_cachable_variables(r, plcf->flushes); + le.ip = plcf->headers_set_len->elts; le.request = r; + le.flushed = 1; while (*(uintptr_t *) le.ip) { while (*(uintptr_t *) le.ip) { @@ -506,16 +510,16 @@ ngx_http_proxy_create_request(ngx_http_request_t *r) /* the request line */ - b->last = ngx_cpymem(b->last, method.data, method.len); + b->last = ngx_copy(b->last, method.data, method.len); u->uri.data = b->last; if (u->conf->uri.len == 0 && r->valid_unparsed_uri) { - b->last = ngx_cpymem(b->last, r->unparsed_uri.data, - r->unparsed_uri.len); + b->last = ngx_copy(b->last, r->unparsed_uri.data, r->unparsed_uri.len); + } else { if (r->valid_location) { - b->last = ngx_cpymem(b->last, u->conf->uri.data, u->conf->uri.len); + b->last = ngx_copy(b->last, u->conf->uri.data, u->conf->uri.len); } if (escape) { @@ -524,13 +528,13 @@ ngx_http_proxy_create_request(ngx_http_request_t *r) b->last += r->uri.len - loc_len + escape; } else { - b->last = ngx_cpymem(b->last, r->uri.data + loc_len, - r->uri.len - loc_len); + b->last = ngx_copy(b->last, r->uri.data + loc_len, + r->uri.len - loc_len); } if (r->args.len > 0) { *b->last++ = '?'; - b->last = ngx_cpymem(b->last, r->args.data, r->args.len); + b->last = ngx_copy(b->last, r->args.data, r->args.len); } } @@ -543,6 +547,7 @@ ngx_http_proxy_create_request(ngx_http_request_t *r) e.ip = plcf->headers_set->elts; e.pos = b->last; e.request = r; + e.flushed = 1; le.ip = plcf->headers_set_len->elts; @@ -600,13 +605,12 @@ ngx_http_proxy_create_request(ngx_http_request_t *r) continue; } - b->last = ngx_cpymem(b->last, header[i].key.data, - header[i].key.len); + b->last = ngx_copy(b->last, header[i].key.data, header[i].key.len); *b->last++ = ':'; *b->last++ = ' '; - b->last = ngx_cpymem(b->last, header[i].value.data, - header[i].value.len); + b->last = ngx_copy(b->last, header[i].value.data, + header[i].value.len); *b->last++ = CR; *b->last++ = LF; @@ -735,6 +739,7 @@ ngx_http_proxy_process_status_line(ngx_http_request_t *r) if (u->headers_in.status_line.data == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } + ngx_memcpy(u->headers_in.status_line.data, p->status_start, u->headers_in.status_line.len); @@ -1054,83 +1059,77 @@ ngx_http_proxy_finalize_request(ngx_http_request_t *r, ngx_int_t rc) } -static ngx_http_variable_value_t * -ngx_http_proxy_host_variable(ngx_http_request_t *r, uintptr_t data) +static ngx_int_t +ngx_http_proxy_host_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) { - ngx_http_variable_value_t *vv; ngx_http_proxy_loc_conf_t *plcf; - vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); - if (vv == NULL) { - return NULL; - } - plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module); - vv->value = 0; - vv->text = plcf->host_header; + v->len = plcf->host_header.len; + v->valid = 1; + v->no_cachable = 0; + v->not_found = 0; + v->data = plcf->host_header.data; - return vv; + return NGX_OK; } -static ngx_http_variable_value_t * -ngx_http_proxy_port_variable(ngx_http_request_t *r, uintptr_t data) +static ngx_int_t +ngx_http_proxy_port_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) { - ngx_http_variable_value_t *vv; ngx_http_proxy_loc_conf_t *plcf; - vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); - if (vv == NULL) { - return NULL; - } - plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module); - vv->value = 0; - vv->text = plcf->port_text; + v->len = plcf->port_text.len; + v->valid = 1; + v->no_cachable = 0; + v->not_found = 0; + v->data = plcf->port_text.data; - return vv; + return NGX_OK; } -static ngx_http_variable_value_t * +static ngx_int_t ngx_http_proxy_add_x_forwarded_for_variable(ngx_http_request_t *r, - uintptr_t data) + + ngx_http_variable_value_t *v, uintptr_t data) { - u_char *p; - ngx_http_variable_value_t *vv; + u_char *p; - vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); - if (vv == NULL) { - return NULL; - } - - vv->value = 0; + v->valid = 1; + v->no_cachable = 0; + v->not_found = 0; if (r->headers_in.x_forwarded_for == NULL) { - vv->text = r->connection->addr_text; - return vv; + v->len = r->connection->addr_text.len; + v->data = r->connection->addr_text.data; + return NGX_OK; } - vv->text.len = r->headers_in.x_forwarded_for->value.len - + sizeof(", ") - 1 + r->connection->addr_text.len; + v->len = r->headers_in.x_forwarded_for->value.len + + sizeof(", ") - 1 + r->connection->addr_text.len; - p = ngx_palloc(r->pool, vv->text.len); + p = ngx_palloc(r->pool, v->len); if (p == NULL) { - return NULL; + return NGX_ERROR; } - vv->text.data = p; + v->data = p; - p = ngx_cpymem(p, r->headers_in.x_forwarded_for->value.data, - r->headers_in.x_forwarded_for->value.len); + p = ngx_copy(p, r->headers_in.x_forwarded_for->value.data, + r->headers_in.x_forwarded_for->value.len); *p++ = ','; *p++ = ' '; ngx_memcpy(p, r->connection->addr_text.data, r->connection->addr_text.len); - return vv; + return NGX_OK; } @@ -1186,11 +1185,9 @@ ngx_http_proxy_rewrite_redirect_text(ngx_http_request_t *r, ngx_table_elt_t *h, p = data; - if (prefix) { - p = ngx_cpymem(p, h->value.data, prefix); - } + p = ngx_copy(p, h->value.data, prefix); - p = ngx_cpymem(p, pr->replacement.text.data, pr->replacement.text.len); + p = ngx_copy(p, pr->replacement.text.data, pr->replacement.text.len); ngx_memcpy(p, h->value.data + prefix + pr->redirect.len, h->value.len - pr->redirect.len - prefix); @@ -1235,9 +1232,7 @@ ngx_http_proxy_rewrite_redirect_vars(ngx_http_request_t *r, ngx_table_elt_t *h, p = data; - if (prefix) { - p = ngx_cpymem(p, h->value.data, prefix); - } + p = ngx_copy(p, h->value.data, prefix); e.ip = pr->replacement.vars.values; e.pos = p; @@ -1530,7 +1525,7 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) pr->handler = ngx_http_proxy_rewrite_redirect_text; pr->redirect = conf->upstream.url; - pr->replacement.text = *conf->upstream.location; + pr->replacement.text = conf->upstream.location; } } @@ -1540,10 +1535,11 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) } if (conf->headers_source == NULL) { - conf->headers_source = prev->headers_source; + conf->flushes = prev->flushes; conf->headers_set_len = prev->headers_set_len; conf->headers_set = prev->headers_set; conf->headers_set_hash = prev->headers_set_hash; + conf->headers_source = prev->headers_source; } if (conf->headers_set_hash) { @@ -1680,6 +1676,7 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) sc.cf = cf; sc.source = &src[i].value; + sc.flushes = &conf->flushes; sc.lengths = &conf->headers_set_len; sc.values = &conf->headers_set; @@ -1843,15 +1840,19 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) clcf->handler = ngx_http_proxy_handler; - plcf->upstream.location = &clcf->name; + plcf->upstream.location = clcf->name; #if (NGX_PCRE) - if (clcf->regex && plcf->upstream.uri.len) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"proxy_pass\" may not have URI part in " - "location given by regular expression"); - return NGX_CONF_ERROR; + if (clcf->regex) { + if (plcf->upstream.uri.len) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "\"proxy_pass\" may not have URI part in " + "location given by regular expression"); + return NGX_CONF_ERROR; + } + + plcf->upstream.location.len = 0; } #endif @@ -1911,7 +1912,7 @@ ngx_http_proxy_redirect(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) pr->handler = ngx_http_proxy_rewrite_redirect_text; pr->redirect = plcf->upstream.url; - pr->replacement.text = *plcf->upstream.location; + pr->replacement.text = plcf->upstream.location; return NGX_CONF_OK; } diff --git a/src/http/modules/ngx_http_realip_module.c b/src/http/modules/ngx_http_realip_module.c new file mode 100644 index 000000000..8732423fd --- /dev/null +++ b/src/http/modules/ngx_http_realip_module.c @@ -0,0 +1,275 @@ + +/* + * Copyright (C) Igor Sysoev + */ + + +#include <ngx_config.h> +#include <ngx_core.h> +#include <ngx_http.h> + + +/* AF_INET only */ + +typedef struct { + in_addr_t mask; + in_addr_t addr; +} ngx_http_realip_from_t; + + +typedef struct { + ngx_array_t *from; /* array of ngx_http_realip_from_t */ + + ngx_uint_t xfwd; +} ngx_http_realip_loc_conf_t; + + +static ngx_int_t ngx_http_realip_handler(ngx_http_request_t *r); +static char *ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); +static void *ngx_http_realip_create_loc_conf(ngx_conf_t *cf); +static char *ngx_http_realip_merge_loc_conf(ngx_conf_t *cf, + void *parent, void *child); +static ngx_int_t ngx_http_realip_init(ngx_cycle_t *cycle); + + +static ngx_conf_enum_t ngx_http_realip_header[] = { + { ngx_string("X-Forwarded-For"), 1 }, + { ngx_string("X-Real-IP"), 0 }, + { ngx_null_string, 0 } +}; + + +static ngx_command_t ngx_http_realip_commands[] = { + + { ngx_string("set_real_ip_from"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_http_realip_from, + NGX_HTTP_LOC_CONF_OFFSET, + 0, + NULL }, + + { ngx_string("real_ip_header"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_enum_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_realip_loc_conf_t, xfwd), + &ngx_http_realip_header }, + + ngx_null_command +}; + + + +ngx_http_module_t ngx_http_realip_module_ctx = { + NULL, /* preconfiguration */ + NULL, /* postconfiguration */ + + NULL, /* create main configuration */ + NULL, /* init main configuration */ + + NULL, /* create server configuration */ + NULL, /* merge server configuration */ + + ngx_http_realip_create_loc_conf, /* create location configuration */ + ngx_http_realip_merge_loc_conf /* merge location configuration */ +}; + + +ngx_module_t ngx_http_realip_module = { + NGX_MODULE_V1, + &ngx_http_realip_module_ctx, /* module context */ + ngx_http_realip_commands, /* module directives */ + NGX_HTTP_MODULE, /* module type */ + NULL, /* init master */ + ngx_http_realip_init, /* init module */ + NULL, /* init process */ + NULL, /* init thread */ + NULL, /* exit thread */ + NULL, /* exit process */ + NULL, /* exit master */ + NGX_MODULE_V1_PADDING +}; + + +static ngx_int_t +ngx_http_realip_handler(ngx_http_request_t *r) +{ + u_char *ip, *p; + size_t len; + ngx_uint_t i; + struct sockaddr_in *sin; + ngx_http_realip_from_t *from; + ngx_http_realip_loc_conf_t *rlcf; + + if (r->realip_set) { + return NGX_OK; + } + + rlcf = ngx_http_get_module_loc_conf(r, ngx_http_realip_module); + + if (rlcf->from == NULL) { + return NGX_OK; + } + + if (rlcf->xfwd == 0) { + if (r->headers_in.x_real_ip == NULL) { + return NGX_OK; + } + + len = r->headers_in.x_real_ip->value.len; + ip = r->headers_in.x_real_ip->value.data; + + } else { + if (r->headers_in.x_forwarded_for == NULL) { + return NGX_OK; + } + + len = r->headers_in.x_forwarded_for->value.len; + ip = r->headers_in.x_forwarded_for->value.data; + + for (p = ip + len; p > ip; p--) { + if (*p == ' ' || *p == ',') { + p++; + len -= p - ip; + ip = p; + break; + } + } + } + + /* AF_INET only */ + + sin = (struct sockaddr_in *) r->connection->sockaddr; + + from = rlcf->from->elts; + for (i = 0; i < rlcf->from->nelts; i++) { + + ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "realip: %08XD %08XD %08XD", + sin->sin_addr.s_addr, from[i].mask, from[i].addr); + + if ((sin->sin_addr.s_addr & from[i].mask) == from[i].addr) { + + r->connection->addr_text.len = len; + r->connection->addr_text.data = ip; + + sin->sin_addr.s_addr = inet_addr((char *) ip); + + r->realip_set = 1; + + return NGX_OK; + } + } + + return NGX_OK; +} + + +static char * +ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + ngx_http_realip_loc_conf_t *rlcf = conf; + + ngx_str_t *value; + ngx_inet_cidr_t in_cidr; + ngx_http_realip_from_t *from; + + if (rlcf->from == NULL) { + rlcf->from = ngx_array_create(cf->pool, 2, + sizeof(ngx_http_realip_from_t)); + if (rlcf->from == NULL) { + return NGX_CONF_ERROR; + } + } + + from = ngx_array_push(rlcf->from); + if (from == NULL) { + return NGX_CONF_ERROR; + } + + value = cf->args->elts; + + from->addr = inet_addr((char *) value[1].data); + + if (from->addr != INADDR_NONE) { + from->mask = 0xffffffff; + + return NGX_CONF_OK; + } + + if (ngx_ptocidr(&value[1], &in_cidr) == NGX_ERROR) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", + &value[1]); + return NGX_CONF_ERROR; + } + + from->mask = in_cidr.mask; + from->addr = in_cidr.addr; + + return NGX_CONF_OK; +} + + +static void * +ngx_http_realip_create_loc_conf(ngx_conf_t *cf) +{ + ngx_http_realip_loc_conf_t *conf; + + conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_realip_loc_conf_t)); + if (conf == NULL) { + return NGX_CONF_ERROR; + } + + /* + * set by ngx_pcalloc(): + * + * conf->from = NULL; + */ + + conf->xfwd = NGX_CONF_UNSET_UINT; + + return conf; +} + + +static char * +ngx_http_realip_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) +{ + ngx_http_realip_loc_conf_t *prev = parent; + ngx_http_realip_loc_conf_t *conf = child; + + if (conf->from == NULL) { + conf->from = prev->from; + } + + ngx_conf_merge_unsigned_value(conf->xfwd, prev->xfwd, 0); + + return NGX_CONF_OK; +} + + +static ngx_int_t +ngx_http_realip_init(ngx_cycle_t *cycle) +{ + ngx_http_handler_pt *h; + ngx_http_core_main_conf_t *cmcf; + + cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module); + + h = ngx_array_push(&cmcf->phases[NGX_HTTP_POST_READ_PHASE].handlers); + if (h == NULL) { + return NGX_ERROR; + } + + *h = ngx_http_realip_handler; + + h = ngx_array_push(&cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers); + if (h == NULL) { + return NGX_ERROR; + } + + *h = ngx_http_realip_handler; + + return NGX_OK; +} diff --git a/src/http/modules/ngx_http_rewrite_module.c b/src/http/modules/ngx_http_rewrite_module.c index c575d4343..6e64f6a99 100644 --- a/src/http/modules/ngx_http_rewrite_module.c +++ b/src/http/modules/ngx_http_rewrite_module.c @@ -142,7 +142,7 @@ ngx_module_t ngx_http_rewrite_module = { static ngx_http_variable_value_t ngx_http_rewrite_null_value = - { 0, ngx_string("") }; + ngx_http_variable(""); static ngx_int_t @@ -214,9 +214,8 @@ ngx_http_rewrite_invalid_referer_code(ngx_http_script_engine_t *e) e->ip += sizeof(uintptr_t); if (cf->referers == NULL) { - e->sp->value = 0; - e->sp->text.len = 0; - e->sp->text.data = (u_char *) ""; + e->sp->data = (u_char *) ""; + e->sp->len = 0; e->sp++; return; @@ -224,17 +223,15 @@ ngx_http_rewrite_invalid_referer_code(ngx_http_script_engine_t *e) if (r->headers_in.referer == NULL) { if (cf->no_referer) { - e->sp->value = 0; - e->sp->text.len = 0; - e->sp->text.data = (u_char *) ""; + e->sp->data = (u_char *) ""; + e->sp->len = 0; e->sp++; return; } else { - e->sp->value = 1; - e->sp->text.len = 1; - e->sp->text.data = (u_char *) "1"; + e->sp->data = (u_char *) "1"; + e->sp->len = 1; e->sp++; return; @@ -248,17 +245,15 @@ ngx_http_rewrite_invalid_referer_code(ngx_http_script_engine_t *e) || (ngx_strncasecmp(ref, "http://", 7) != 0)) { if (cf->blocked_referer) { - e->sp->value = 0; - e->sp->text.len = 0; - e->sp->text.data = (u_char *) "0"; + e->sp->data = (u_char *) ""; + e->sp->len = 0; e->sp++; return; } else { - e->sp->value = 1; - e->sp->text.len = 1; - e->sp->text.data = (u_char *) "1"; + e->sp->data = (u_char *) "1"; + e->sp->len = 1; e->sp++; return; @@ -288,9 +283,8 @@ ngx_http_rewrite_invalid_referer_code(ngx_http_script_engine_t *e) if (ngx_strncmp(&ref[n], refs[i].name.data, refs[i].name.len) == 0) { - e->sp->value = 0; - e->sp->text.len = 0; - e->sp->text.data = (u_char *) ""; + e->sp->data = (u_char *) ""; + e->sp->len = 0; e->sp++; return; @@ -300,9 +294,8 @@ ngx_http_rewrite_invalid_referer_code(ngx_http_script_engine_t *e) } else { if (ngx_strncasecmp(refs[i].name.data, ref, refs[i].name.len) == 0) { - e->sp->value = 0; - e->sp->text.len = 0; - e->sp->text.data = (u_char *) ""; + e->sp->data = (u_char *) ""; + e->sp->len = 0; e->sp++; return; @@ -310,15 +303,15 @@ ngx_http_rewrite_invalid_referer_code(ngx_http_script_engine_t *e) } } - e->sp->value = 1; - e->sp->text.len = 1; - e->sp->text.data = (u_char *) "1"; + e->sp->data = (u_char *) "1"; + e->sp->len = 1; e->sp++; } -static ngx_http_variable_value_t * -ngx_http_rewrite_var(ngx_http_request_t *r, uintptr_t data) +static ngx_int_t +ngx_http_rewrite_var(ngx_http_request_t *r, ngx_http_variable_value_t *v, + uintptr_t data) { ngx_http_variable_t *var; ngx_http_core_main_conf_t *cmcf; @@ -336,7 +329,9 @@ ngx_http_rewrite_var(ngx_http_request_t *r, uintptr_t data) ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, "using uninitialized \"%V\" variable", &var[data].name); - return &ngx_http_rewrite_null_value; + *v = ngx_http_rewrite_null_value; + + return NGX_OK; } @@ -411,6 +406,13 @@ ngx_http_rewrite_init(ngx_cycle_t *cycle) cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module); + h = ngx_array_push(&cmcf->phases[NGX_HTTP_SERVER_REWRITE_PHASE].handlers); + if (h == NULL) { + return NGX_ERROR; + } + + *h = ngx_http_rewrite_handler; + h = ngx_array_push(&cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers); if (h == NULL) { return NGX_ERROR; diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c index 80de6910c..86700ecf3 100644 --- a/src/http/modules/ngx_http_ssi_filter_module.c +++ b/src/http/modules/ngx_http_ssi_filter_module.c @@ -144,8 +144,8 @@ static ngx_int_t ngx_http_ssi_else(ngx_http_request_t *r, static ngx_int_t ngx_http_ssi_endif(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, ngx_str_t **params); -static ngx_http_variable_value_t * - ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r, uintptr_t gmt); +static ngx_int_t ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t gmt); static char *ngx_http_ssi_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); @@ -562,6 +562,8 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in) } + b = NULL; + if (rc == NGX_OK) { for (cmd = ngx_http_ssi_commands; cmd->handler; cmd++) { @@ -1200,10 +1202,12 @@ ngx_http_ssi_parse(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx) } if (ch == '"' && state == ssi_double_quoted_value_state) { + ctx->param->value.data[ctx->param->value.len - 1] = ch; break; } if (ch == '\'' && state == ssi_quoted_value_state) { + ctx->param->value.data[ctx->param->value.len - 1] = ch; break; } @@ -1378,9 +1382,9 @@ static ngx_int_t ngx_http_ssi_evaluate_string(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, ngx_str_t *text, ngx_uint_t flags) { - u_char ch, *p, **value, *data; - size_t *size, len, prefix; - ngx_str_t var, part, *val; + u_char ch, *p, **value, *data, *part_data; + size_t *size, len, prefix, part_len; + ngx_str_t var, *val; ngx_uint_t i, j, n, bracket; ngx_array_t lengths, values; ngx_http_variable_value_t *vv; @@ -1408,7 +1412,7 @@ ngx_http_ssi_evaluate_string(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, return NGX_ERROR; } - p = ngx_cpymem(data, r->uri.data, prefix); + p = ngx_copy(data, r->uri.data, prefix); ngx_memcpy(p, text->data, text->len); text->len = len; @@ -1498,20 +1502,22 @@ ngx_http_ssi_evaluate_string(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, return NGX_ERROR; } - if (vv == NGX_HTTP_VAR_NOT_FOUND) { + if (vv->not_found) { continue; } - part = vv->text; + part_data = vv->data; + part_len = vv->len; } else { - part = *val; + part_data = val->data; + part_len = val->len; } } else { - part.data = &text->data[i]; + part_data = &text->data[i]; - for (p = part.data; i < text->len; i++) { + for (p = part_data; i < text->len; i++) { ch = text->data[i]; if (ch == '$') { @@ -1527,24 +1533,24 @@ ngx_http_ssi_evaluate_string(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, *p++ = ch; } - part.len = p - part.data; + part_len = p - part_data; } - len += part.len; + len += part_len; size = ngx_array_push(&lengths); if (size == NULL) { return NGX_ERROR; } - *size = part.len; + *size = part_len; value = ngx_array_push(&values); if (value == NULL) { return NGX_ERROR; } - *value = part.data; + *value = part_data; } prefix = 0; @@ -1577,12 +1583,10 @@ ngx_http_ssi_evaluate_string(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, text->len = len; text->data = p; - if (prefix) { - p = ngx_cpymem(p, r->uri.data, prefix); - } + p = ngx_copy(p, r->uri.data, prefix); for (i = 0; i < values.nelts; i++) { - p = ngx_cpymem(p, value[i], size[i]); + p = ngx_copy(p, value[i], size[i]); } return NGX_OK; @@ -1601,7 +1605,7 @@ ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, ngx_str_t **params) { ngx_str_t *uri, *file, args; - ngx_uint_t i; + ngx_uint_t flags; uri = params[NGX_HTTP_SSI_INCLUDE_VIRTUAL]; file = params[NGX_HTTP_SSI_INCLUDE_FILE]; @@ -1631,20 +1635,16 @@ ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, args.len = 0; args.data = NULL; + flags = 0; - if (params[NGX_HTTP_SSI_INCLUDE_VIRTUAL]) { - for (i = 0; i < uri->len; i++) { - if (uri->data[i] == '?') { - args.len = uri->len - i - 1; - args.data = &uri->data[i + 1]; - uri->len -= args.len + 1; + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "ssi include: \"%V\"", uri); - break; - } - } + if (ngx_http_parse_unsafe_uri(r, uri, &args, &flags) != NGX_OK) { + return NGX_HTTP_SSI_ERROR; } - if (ngx_http_subrequest(r, uri, &args) != NGX_OK) { + if (ngx_http_subrequest(r, uri, &args, flags) != NGX_OK) { return NGX_HTTP_SSI_ERROR; } @@ -1658,7 +1658,7 @@ ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, { ngx_uint_t i; ngx_buf_t *b; - ngx_str_t *var, *value; + ngx_str_t *var, *value, text; ngx_chain_t *cl; ngx_http_variable_value_t *vv; @@ -1677,8 +1677,10 @@ ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, return NGX_HTTP_SSI_ERROR; } - if (vv != NGX_HTTP_VAR_NOT_FOUND) { - value = &vv->text; + if (!vv->not_found) { + text.data = vv->data; + text.len = vv->len; + value = &text; } } @@ -1817,7 +1819,8 @@ ngx_http_ssi_if(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, if ((*p >= 'a' && *p <= 'z') || (*p >= '0' && *p <= '9') - || *p == '$' || *p == '{' || *p == '}' || *p == '_') + || *p == '$' || *p == '{' || *p == '}' || *p == '_' + || *p == '"' || *p == '\'') { continue; } @@ -1971,19 +1974,18 @@ ngx_http_ssi_endif(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, } -static ngx_http_variable_value_t * -ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r, uintptr_t gmt) +static ngx_int_t +ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t gmt) { - ngx_http_ssi_ctx_t *ctx; - ngx_http_variable_value_t *vv; - ngx_time_t *tp; - struct tm tm; - char buf[NGX_HTTP_SSI_DATE_LEN]; + ngx_http_ssi_ctx_t *ctx; + ngx_time_t *tp; + struct tm tm; + char buf[NGX_HTTP_SSI_DATE_LEN]; - vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); - if (vv == NULL) { - return NULL; - } + v->valid = 1; + v->no_cachable = 0; + v->not_found = 0; tp = ngx_timeofday(); @@ -1992,16 +1994,14 @@ ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r, uintptr_t gmt) if (ctx->timefmt.len == sizeof("%s") - 1 && ctx->timefmt.data[0] == '%' && ctx->timefmt.data[1] == 's') { - vv->value = tp->sec + (gmt ? 0 : tp->gmtoff); - - vv->text.data = ngx_palloc(r->pool, NGX_TIME_T_LEN); - if (vv->text.data == NULL) { - return NULL; + v->data = ngx_palloc(r->pool, NGX_TIME_T_LEN); + if (v->data == NULL) { + return NGX_ERROR; } - vv->text.len = ngx_sprintf(vv->text.data, "%T", vv->value) - - vv->text.data; - return vv; + v->len = ngx_sprintf(v->data, "%T", tp->sec + (gmt ? 0 : tp->gmtoff)) + - v->data; + return NGX_OK; } if (gmt) { @@ -2010,22 +2010,20 @@ ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r, uintptr_t gmt) ngx_libc_localtime(tp->sec, &tm); } - vv->value = tp->sec + (gmt ? 0 : tp->gmtoff); - - vv->text.len = strftime(buf, NGX_HTTP_SSI_DATE_LEN, - (char *) ctx->timefmt.data, &tm); - if (vv->text.len == 0) { - return NULL; + v->len = strftime(buf, NGX_HTTP_SSI_DATE_LEN, + (char *) ctx->timefmt.data, &tm); + if (v->len == 0) { + return NGX_ERROR; } - vv->text.data = ngx_palloc(r->pool, vv->text.len); - if (vv->text.data == NULL) { - return NULL; + v->data = ngx_palloc(r->pool, v->len); + if (v->data == NULL) { + return NGX_ERROR; } - ngx_memcpy(vv->text.data, buf, vv->text.len); + ngx_memcpy(v->data, buf, v->len); - return vv; + return NGX_OK; } diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c index 09bf63dcf..d75b9e60d 100644 --- a/src/http/modules/ngx_http_ssl_module.c +++ b/src/http/modules/ngx_http_ssl_module.c @@ -8,6 +8,7 @@ #include <ngx_core.h> #include <ngx_http.h> + #define NGX_DEFLAUT_CERTIFICATE "cert.pem" #define NGX_DEFLAUT_CERTIFICATE_KEY "cert.pem" #define NGX_DEFLAUT_CIPHERS "ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP" @@ -84,6 +85,13 @@ static ngx_command_t ngx_http_ssl_commands[] = { ngx_http_ssl_nosupported, 0, 0, ngx_http_ssl_openssl097 }, #endif + { ngx_string("ssl_session_timeout"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, + ngx_conf_set_sec_slot, + NGX_HTTP_SRV_CONF_OFFSET, + offsetof(ngx_http_ssl_srv_conf_t, session_timeout), + NULL }, + ngx_null_command }; @@ -146,6 +154,7 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t *cf) */ scf->enable = NGX_CONF_UNSET; + scf->session_timeout = NGX_CONF_UNSET; scf->prefer_server_ciphers = NGX_CONF_UNSET; return scf; @@ -166,6 +175,9 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) return NGX_CONF_OK; } + ngx_conf_merge_value(conf->session_timeout, + prev->session_timeout, 300); + ngx_conf_merge_value(conf->prefer_server_ciphers, prev->prefer_server_ciphers, 0); @@ -229,6 +241,8 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) SSL_CTX_set_session_id_context(conf->ssl.ctx, ngx_http_session_id_ctx, sizeof(ngx_http_session_id_ctx) - 1); + SSL_CTX_set_timeout(conf->ssl.ctx, conf->session_timeout); + return NGX_CONF_OK; } diff --git a/src/http/modules/ngx_http_ssl_module.h b/src/http/modules/ngx_http_ssl_module.h index a705635ff..4207cdfdb 100644 --- a/src/http/modules/ngx_http_ssl_module.h +++ b/src/http/modules/ngx_http_ssl_module.h @@ -22,6 +22,8 @@ typedef struct { ngx_uint_t protocols; + time_t session_timeout; + ngx_str_t certificate; ngx_str_t certificate_key; @@ -29,14 +31,6 @@ typedef struct { } ngx_http_ssl_srv_conf_t; -ngx_int_t ngx_http_ssl_read(ngx_http_request_t *r, u_char *buf, size_t size); -ngx_int_t ngx_http_ssl_shutdown(ngx_http_request_t *r); -ngx_chain_t *ngx_http_ssl_write(ngx_connection_t *c, ngx_chain_t *in, - off_t limit); - -void ngx_http_ssl_close_connection(SSL *ssl, ngx_log_t *log); - - extern ngx_module_t ngx_http_ssl_module; diff --git a/src/http/modules/ngx_http_static_module.c b/src/http/modules/ngx_http_static_module.c index 0e995f526..ab7ac9c6f 100644 --- a/src/http/modules/ngx_http_static_module.c +++ b/src/http/modules/ngx_http_static_module.c @@ -195,7 +195,7 @@ ngx_http_static_handler(ngx_http_request_t *r) return NGX_HTTP_INTERNAL_SERVER_ERROR; } - last = ngx_cpymem(location, r->uri.data, r->uri.len); + last = ngx_copy(location, r->uri.data, r->uri.len); } *last = '/'; diff --git a/src/http/modules/ngx_http_userid_filter_module.c b/src/http/modules/ngx_http_userid_filter_module.c index 221d33bf3..94a709b60 100644 --- a/src/http/modules/ngx_http_userid_filter_module.c +++ b/src/http/modules/ngx_http_userid_filter_module.c @@ -55,7 +55,10 @@ static size_t ngx_http_userid_log_uid_set_getlen(ngx_http_request_t *r, static u_char *ngx_http_userid_log_uid_set(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op); -static ngx_int_t ngx_http_userid_add_log_formats(ngx_conf_t *cf); +static ngx_int_t ngx_http_userid_add_variables(ngx_conf_t *cf); +static ngx_int_t ngx_http_userid_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); + static ngx_int_t ngx_http_userid_init(ngx_cycle_t *cycle); static void *ngx_http_userid_create_conf(ngx_conf_t *cf); static char *ngx_http_userid_merge_conf(ngx_conf_t *cf, void *parent, @@ -158,7 +161,7 @@ static ngx_command_t ngx_http_userid_commands[] = { ngx_http_module_t ngx_http_userid_filter_module_ctx = { - ngx_http_userid_add_log_formats, /* preconfiguration */ + ngx_http_userid_add_variables, /* preconfiguration */ NULL, /* postconfiguration */ NULL, /* create main configuration */ @@ -199,6 +202,10 @@ static ngx_http_log_op_name_t ngx_http_userid_log_fmt_ops[] = { }; +static ngx_str_t ngx_http_userid_got = ngx_string("uid_got"); +static ngx_str_t ngx_http_userid_set = ngx_string("uid_set"); + + static ngx_int_t ngx_http_userid_filter(ngx_http_request_t *r) { @@ -387,7 +394,7 @@ ngx_http_userid_set_uid(ngx_http_request_t *r, ngx_http_userid_ctx_t *ctx, return NGX_ERROR; } - p = ngx_cpymem(cookie, conf->name.data, conf->name.len); + p = ngx_copy(cookie, conf->name.data, conf->name.len); *p++ = '='; if (ctx->uid_got[3] == 0) { @@ -417,11 +424,9 @@ ngx_http_userid_set_uid(ngx_http_request_t *r, ngx_http_userid_ctx_t *ctx, p = ngx_http_cookie_time(p, ngx_time() + conf->expires); } - if (conf->domain.len) { - p = ngx_cpymem(p, conf->domain.data, conf->domain.len); - } + p = ngx_copy(p, conf->domain.data, conf->domain.len); - p = ngx_cpymem(p, conf->path.data, conf->path.len); + p = ngx_copy(p, conf->path.data, conf->path.len); set_cookie = ngx_list_push(&r->headers_out.headers); if (set_cookie == NULL) { @@ -489,7 +494,7 @@ ngx_http_userid_log_uid_got(ngx_http_request_t *r, u_char *buf, conf = ngx_http_get_module_loc_conf(r, ngx_http_userid_filter_module); - buf = ngx_cpymem(buf, conf->name.data, conf->name.len); + buf = ngx_copy(buf, conf->name.data, conf->name.len); *buf++ = '='; @@ -533,7 +538,7 @@ ngx_http_userid_log_uid_set(ngx_http_request_t *r, u_char *buf, conf = ngx_http_get_module_loc_conf(r, ngx_http_userid_filter_module); - buf = ngx_cpymem(buf, conf->name.data, conf->name.len); + buf = ngx_copy(buf, conf->name.data, conf->name.len); *buf++ = '='; @@ -544,10 +549,28 @@ ngx_http_userid_log_uid_set(ngx_http_request_t *r, u_char *buf, static ngx_int_t -ngx_http_userid_add_log_formats(ngx_conf_t *cf) +ngx_http_userid_add_variables(ngx_conf_t *cf) { + ngx_http_variable_t *var; ngx_http_log_op_name_t *op; + var = ngx_http_add_variable(cf, &ngx_http_userid_got, 0); + if (var == NULL) { + return NGX_ERROR; + } + + var->handler = ngx_http_userid_variable; + var->data = offsetof(ngx_http_userid_ctx_t, uid_got); + + var = ngx_http_add_variable(cf, &ngx_http_userid_set, 0); + if (var == NULL) { + return NGX_ERROR; + } + + var->handler = ngx_http_userid_variable; + var->data = offsetof(ngx_http_userid_ctx_t, uid_set); + + for (op = ngx_http_userid_log_fmt_ops; op->name.len; op++) { /* void */ } op->run = NULL; @@ -564,6 +587,42 @@ ngx_http_userid_add_log_formats(ngx_conf_t *cf) static ngx_int_t +ngx_http_userid_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, + uintptr_t data) +{ + uint32_t *uid; + ngx_http_userid_ctx_t *ctx; + ngx_http_userid_conf_t *conf; + + v->valid = 1; + v->no_cachable = 0; + v->not_found = 0; + + ctx = ngx_http_get_module_ctx(r, ngx_http_userid_filter_module); + + uid = (uint32_t *) ((char *) ctx + data); + + if (ctx == NULL || uid[3] == 0) { + v->not_found = 1; + return NGX_OK; + } + + conf = ngx_http_get_module_loc_conf(r, ngx_http_userid_filter_module); + + v->len = conf->name.len + sizeof("=00001111222233334444555566667777") - 1; + v->data = ngx_palloc(r->pool, v->len); + if (v->data == NULL) { + return NGX_ERROR; + } + + ngx_sprintf(v->data, "%V=%08XD%08XD%08XD%08XD", + &conf->name, uid[0], uid[1], uid[2], uid[3]); + + return NGX_OK; +} + + +static ngx_int_t ngx_http_userid_init(ngx_cycle_t *cycle) { ngx_http_next_header_filter = ngx_http_top_header_filter; |