summaryrefslogtreecommitdiffhomepage
path: root/src/http/modules
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2004-04-25 20:13:21 +0000
committerIgor Sysoev <igor@sysoev.ru>2004-04-25 20:13:21 +0000
commit3f4685f3ded30199ec0c61f98b016f5880330422 (patch)
tree9b633e6681f3b02123700dea850ba0083eb4d6cb /src/http/modules
parenta040f00167fa64e0bd5ea85f3c0551358e0ee544 (diff)
downloadnginx-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.c32
-rw-r--r--src/http/modules/ngx_http_headers_filter.c237
-rw-r--r--src/http/modules/ngx_http_rewrite_handler.c26
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))) {