diff options
| author | Igor Sysoev <igor@sysoev.ru> | 2004-04-25 20:13:21 +0000 |
|---|---|---|
| committer | Igor Sysoev <igor@sysoev.ru> | 2004-04-25 20:13:21 +0000 |
| commit | 3f4685f3ded30199ec0c61f98b016f5880330422 (patch) | |
| tree | 9b633e6681f3b02123700dea850ba0083eb4d6cb /src/http/modules | |
| parent | a040f00167fa64e0bd5ea85f3c0551358e0ee544 (diff) | |
| download | nginx-3f4685f3ded30199ec0c61f98b016f5880330422.tar.gz nginx-3f4685f3ded30199ec0c61f98b016f5880330422.tar.bz2 | |
nginx-0.0.3-2004-04-26-00:13:21 import
Diffstat (limited to 'src/http/modules')
| -rw-r--r-- | src/http/modules/ngx_http_gzip_filter.c | 32 | ||||
| -rw-r--r-- | src/http/modules/ngx_http_headers_filter.c | 237 | ||||
| -rw-r--r-- | src/http/modules/ngx_http_rewrite_handler.c | 26 |
3 files changed, 290 insertions, 5 deletions
diff --git a/src/http/modules/ngx_http_gzip_filter.c b/src/http/modules/ngx_http_gzip_filter.c index 89598fbab..f5cdb493e 100644 --- a/src/http/modules/ngx_http_gzip_filter.c +++ b/src/http/modules/ngx_http_gzip_filter.c @@ -51,7 +51,9 @@ typedef struct { unsigned flush:4; unsigned redo:1; + unsigned pass:1; unsigned done:1; + unsigned blocked:1; size_t zin; size_t zout; @@ -493,8 +495,8 @@ static int ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in) if (ctx->zstream.avail_in == 0 && ctx->flush == Z_NO_FLUSH - && !ctx->redo) { - + && !ctx->redo) + { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "gzip in: " PTR_FMT, ctx->in); @@ -517,6 +519,7 @@ static int ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in) if (ctx->in_hunk->last < ctx->in_hunk->pos) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, "zstream.avail_in is huge"); + ctx->done = 1; return NGX_ERROR; } @@ -555,9 +558,11 @@ static int ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in) ctx->hunks++; } else { + ctx->blocked = 1; break; } + ctx->blocked = 0; ctx->zstream.next_out = ctx->out_hunk->pos; ctx->zstream.avail_out = conf->bufs.size; } @@ -585,8 +590,16 @@ static int ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in) "gzip in_hunk:" PTR_FMT " pos:" PTR_FMT, ctx->in_hunk, ctx->in_hunk->pos); + +#if 0 + if (!ctx->redo) { + ctx->in_hunk->pos = ctx->zstream.next_in; + ctx->out_hunk->last = ctx->zstream.next_out; + } +#else ctx->in_hunk->pos = ctx->zstream.next_in; ctx->out_hunk->last = ctx->zstream.next_out; +#endif if (ctx->zstream.avail_out == 0) { ngx_alloc_link_and_set_hunk(cl, ctx->out_hunk, r->pool, @@ -608,6 +621,7 @@ static int ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in) ngx_http_gzip_error(ctx)); *ctx->last_out = cl; ctx->last_out = &cl->next; + ctx->pass = 1; break; } @@ -665,6 +679,7 @@ static int ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in) ctx->zstream.avail_out = 0; ctx->done = 1; + ctx->pass = 1; break; } @@ -674,13 +689,22 @@ static int ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in) ngx_http_gzip_error(ctx)); *ctx->last_out = cl; ctx->last_out = &cl->next; + ctx->pass = 1; break; } } if (ctx->out) { - if (last == NGX_AGAIN) { + if (ctx->pass) { + ctx->pass = 0; + + } else if (last == NGX_AGAIN) { + return last; + } + + } else if (ctx->blocked) { + if (last != NGX_NONE) { return last; } @@ -804,6 +828,8 @@ ngx_inline static int ngx_http_gzip_error(ngx_http_gzip_ctx_t *ctx) ctx->zstream.avail_in = 0; ctx->zstream.avail_out = 0; + ctx->done = 1; + return NGX_ERROR; } diff --git a/src/http/modules/ngx_http_headers_filter.c b/src/http/modules/ngx_http_headers_filter.c new file mode 100644 index 000000000..560b5b1b1 --- /dev/null +++ b/src/http/modules/ngx_http_headers_filter.c @@ -0,0 +1,237 @@ + +#include <ngx_config.h> +#include <ngx_core.h> +#include <ngx_http.h> + + +typedef struct { + time_t expires; +} ngx_http_headers_conf_t; + + +#define NGX_HTTP_EXPIRES_UNSET -2147483647 +#define NGX_HTTP_EXPIRES_OFF -2147483646 +#define NGX_HTTP_EXPIRES_EPOCH -2147483645 + + +static int 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); +char *ngx_http_headers_expires(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_headers_expires, + NGX_HTTP_LOC_CONF_OFFSET, + 0, + NULL}, + + ngx_null_command +}; + + +static ngx_http_module_t ngx_http_headers_filter_module_ctx = { + NULL, /* pre conf */ + + NULL, /* create main configuration */ + NULL, /* init main configuration */ + + NULL, /* create server configuration */ + NULL, /* merge server configuration */ + + ngx_http_headers_create_conf, /* create location configuration */ + ngx_http_headers_merge_conf /* merge location configuration */ +}; + + +ngx_module_t ngx_http_headers_filter_module = { + NGX_MODULE, + &ngx_http_headers_filter_module_ctx, /* module context */ + ngx_http_headers_filter_commands, /* module directives */ + NGX_HTTP_MODULE, /* module type */ + ngx_http_headers_filter_init, /* init module */ + NULL /* init child */ +}; + + +static ngx_http_output_header_filter_pt ngx_http_next_header_filter; + + +static int ngx_http_headers_filter(ngx_http_request_t *r) +{ + size_t len; + ngx_table_elt_t *expires, *cc; + ngx_http_headers_conf_t *conf; + + if (r->headers_out.status != NGX_HTTP_OK) { + return ngx_http_next_header_filter(r); + } + + conf = ngx_http_get_module_loc_conf(r, ngx_http_headers_filter_module); + + if (conf->expires != NGX_HTTP_EXPIRES_OFF) { + + expires = ngx_http_add_header(&r->headers_out, ngx_http_headers_out); + if (expires == NULL) { + return NGX_ERROR; + } + + r->headers_out.expires = expires; + + cc = ngx_http_add_header(&r->headers_out, ngx_http_headers_out); + if (cc == NULL) { + return NGX_ERROR; + } + + r->headers_out.cache_control = cc; + + len = sizeof("Mon, 28 Sep 1970 06:00:00 GMT"); + + expires->key.len = sizeof("Expires") - 1; + expires->key.data = (u_char *) "Expires"; + expires->value.len = len - 1; + + cc->key.len = sizeof("Cache-Control") - 1; + cc->key.data = (u_char *) "Cache-Control"; + + if (conf->expires == NGX_HTTP_EXPIRES_EPOCH) { + expires->value.data = (u_char *) "Thu, 01 Jan 1970 00:00:01 GMT"; + + cc->value.len = sizeof("no-cache") - 1; + cc->value.data = (u_char *) "no-cache"; + + } else { + expires->value.data = ngx_palloc(r->pool, len); + if (expires->value.data == NULL) { + return NGX_ERROR; + } + + if (conf->expires == 0) { + ngx_memcpy(expires->value.data, ngx_cached_http_time.data, + ngx_cached_http_time.len + 1); + + cc->value.len = sizeof("max-age=0") - 1; + cc->value.data = (u_char *) "max-age=0"; + + } else { + ngx_http_time(expires->value.data, + ngx_cached_time + conf->expires); + + if (conf->expires < 0) { + cc->value.len = sizeof("no-cache") - 1; + cc->value.data = (u_char *) "no-cache"; + + } else { + cc->value.data = ngx_palloc(r->pool, NGX_TIME_T_LEN + 1); + if (cc->value.data == NULL) { + return NGX_ERROR; + } + + cc->value.len = ngx_snprintf((char *) cc->value.data, + sizeof("max-age=") + + NGX_TIME_T_LEN, + "max-age=" TIME_T_FMT, + conf->expires); + } + } + } + } + + return ngx_http_next_header_filter(r); +} + + +static int ngx_http_headers_filter_init(ngx_cycle_t *cycle) +{ + ngx_http_next_header_filter = ngx_http_top_header_filter; + ngx_http_top_header_filter = ngx_http_headers_filter; + + return NGX_OK; +} + + +static void *ngx_http_headers_create_conf(ngx_conf_t *cf) +{ + ngx_http_headers_conf_t *conf; + + if (!(conf = ngx_palloc(cf->pool, sizeof(ngx_http_headers_conf_t)))) { + return NGX_CONF_ERROR; + } + + conf->expires = NGX_HTTP_EXPIRES_UNSET; + + return conf; +} + + +static char *ngx_http_headers_merge_conf(ngx_conf_t *cf, + void *parent, void *child) +{ + ngx_http_headers_conf_t *prev = parent; + ngx_http_headers_conf_t *conf = child; + + if (conf->expires == NGX_HTTP_EXPIRES_UNSET) { + conf->expires = (prev->expires == NGX_HTTP_EXPIRES_UNSET) ? + NGX_HTTP_EXPIRES_OFF : prev->expires; + } + + return NGX_CONF_OK; +} + + +char *ngx_http_headers_expires(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + ngx_http_headers_conf_t *hcf = conf; + + ngx_uint_t minus; + ngx_str_t *value; + + if (hcf->expires != NGX_HTTP_EXPIRES_UNSET) { + return "is duplicate"; + } + + value = cf->args->elts; + + if (ngx_strcmp(value[1].data, "epoch") == 0) { + hcf->expires = NGX_HTTP_EXPIRES_EPOCH; + return NGX_CONF_OK; + } + + if (ngx_strcmp(value[1].data, "off") == 0) { + hcf->expires = NGX_HTTP_EXPIRES_OFF; + return NGX_CONF_OK; + } + + if (value[1].data[0] == '+') { + value[1].data++; + value[1].len--; + minus = 0; + + } else if (value[1].data[0] == '-') { + value[1].data++; + value[1].len--; + minus = 1; + + } else { + minus = 0; + } + + hcf->expires = ngx_parse_time(&value[1], 1); + if (hcf->expires == NGX_ERROR) { + return "invalid value"; + } + + if (hcf->expires == NGX_PARSE_LARGE_TIME) { + return "value must be less than 68 years"; + } + + if (minus) { + hcf->expires = - hcf->expires; + } + + return NGX_CONF_OK; +} diff --git a/src/http/modules/ngx_http_rewrite_handler.c b/src/http/modules/ngx_http_rewrite_handler.c index 8a645e082..7d36b131a 100644 --- a/src/http/modules/ngx_http_rewrite_handler.c +++ b/src/http/modules/ngx_http_rewrite_handler.c @@ -26,6 +26,7 @@ typedef struct { ngx_str_t re_name; ngx_str_t s_name; + ngx_uint_t status; unsigned last:1; } ngx_http_rewrite_rule_t; @@ -123,7 +124,8 @@ static ngx_int_t ngx_http_rewrite_handler(ngx_http_request_t *r) if (rc == NGX_DECLINED) { if (scf->log) { ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, - "\"%s\" does not match", rule[i].re_name.data); + "\"%s\" does not match \"%s\"", + rule[i].re_name.data, r->uri.data); } continue; @@ -139,7 +141,12 @@ static ngx_int_t ngx_http_rewrite_handler(ngx_http_request_t *r) if (scf->log) { ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, - "\"%s\" matches", rule[i].re_name.data); + "\"%s\" matches \"%s\"", + rule[i].re_name.data, r->uri.data); + } + + if (rule[i].status) { + return rule[i].status; } uri.len = rule[i].size; @@ -247,6 +254,8 @@ static char *ngx_http_rewrite_rule(ngx_conf_t *cf, ngx_command_t *cmd, rule->msize = 0; rule->size = 0; + rule->status = 0; + rule->last = 0; value = cf->args->elts; @@ -264,6 +273,19 @@ static char *ngx_http_rewrite_rule(ngx_conf_t *cf, ngx_command_t *cmd, rule->re_name = value[1]; rule->s_name = value[2]; + if (ngx_strcasecmp(value[2].data, "forbidden:") == 0) { + + if (cf->args->nelts == 3) { + rule->status = NGX_HTTP_FORBIDDEN; + rule->last = 1; + return NGX_CONF_OK; + } + + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid parameter \"%s\"", value[3].data); + return NGX_CONF_ERROR; + } + for (i = 0; i < value[2].len; /* void */) { if (!(op = ngx_push_array(&rule->ops))) { |
