nginx-0.0.3-2004-04-26-00:13:21 import
diff --git a/src/http/modules/ngx_http_gzip_filter.c b/src/http/modules/ngx_http_gzip_filter.c
index 89598fb..f5cdb49 100644
--- a/src/http/modules/ngx_http_gzip_filter.c
+++ b/src/http/modules/ngx_http_gzip_filter.c
@@ -51,7 +51,9 @@
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 @@
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 @@
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 @@
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 @@
"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 @@
ngx_http_gzip_error(ctx));
*ctx->last_out = cl;
ctx->last_out = &cl->next;
+ ctx->pass = 1;
break;
}
@@ -665,6 +679,7 @@
ctx->zstream.avail_out = 0;
ctx->done = 1;
+ ctx->pass = 1;
break;
}
@@ -674,13 +689,22 @@
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 @@
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 0000000..560b5b1
--- /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 8a645e0..7d36b13 100644
--- a/src/http/modules/ngx_http_rewrite_handler.c
+++ b/src/http/modules/ngx_http_rewrite_handler.c
@@ -26,6 +26,7 @@
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 @@
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 @@
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 @@
rule->msize = 0;
rule->size = 0;
+ rule->status = 0;
+ rule->last = 0;
value = cf->args->elts;
@@ -264,6 +273,19 @@
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))) {
diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h
index 3e0385b..d7b4d12 100644
--- a/src/http/ngx_http.h
+++ b/src/http/ngx_http.h
@@ -96,8 +96,6 @@
extern ngx_module_t ngx_http_module;
-extern int ngx_max_module;
-
extern ngx_uint_t ngx_http_total_requests;
extern uint64_t ngx_http_total_sent;
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 3128a76..b7eb951 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -1493,14 +1493,14 @@
return NGX_CONF_ERROR;
}
- err->code = ngx_atoi(value[i].data, value[i].len);
- if (err->code == NGX_ERROR) {
+ err->status = ngx_atoi(value[i].data, value[i].len);
+ if (err->status == NGX_ERROR) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid value \"%s\"", value[i].data);
return NGX_CONF_ERROR;
}
- if (err->code < 400 || err->code > 599) {
+ if (err->status < 400 || err->status > 599) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"value \"%s\" must be between 400 and 599",
value[i].data);
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index 661fcaf..40cf40f 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -105,8 +105,8 @@
typedef struct {
- int code;
- int overwrite;
+ ngx_int_t status;
+ ngx_int_t overwrite;
ngx_str_t uri;
} ngx_http_err_page_t;
diff --git a/src/http/ngx_http_output_filter.c b/src/http/ngx_http_output_filter.c
index 9b87174..7c8986f 100644
--- a/src/http/ngx_http_output_filter.c
+++ b/src/http/ngx_http_output_filter.c
@@ -52,8 +52,9 @@
-int ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *in)
+ngx_int_t ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *in)
{
+ ngx_int_t rc;
ngx_output_chain_ctx_t *ctx;
ngx_http_output_filter_conf_t *conf;
@@ -81,7 +82,16 @@
}
- return ngx_output_chain(ctx, in);
+ rc = ngx_output_chain(ctx, in);
+
+ if (rc == NGX_ERROR) {
+
+ /* NGX_ERROR could be returned by any filter */
+
+ r->connection->write->error = 1;
+ }
+
+ return rc;
}
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index 1697eef..1e03621 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -991,7 +991,7 @@
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
if (!ngx_terminate
- && !ngx_quit
+ && !ngx_exiting
&& r->keepalive != 0
&& clcf->keepalive_timeout > 0)
{
@@ -1582,6 +1582,19 @@
}
}
+ if (r->request_body
+ && r->request_body->temp_file
+ && r->request_body->temp_file->file.fd != NGX_INVALID_FILE)
+ {
+ if (ngx_close_file(r->request_body->temp_file->file.fd)
+ == NGX_FILE_ERROR)
+ {
+ ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
+ ngx_close_file_n " deleted file \"%s\" failed",
+ r->request_body->temp_file->file.name.data);
+ }
+ }
+
/* ctx->url was allocated from r->pool */
ctx = log->data;
ctx->url = NULL;
diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c
index 4eb8899..ba87969 100644
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -213,7 +213,7 @@
if (r->err_ctx == NULL && clcf->error_pages) {
err_page = clcf->error_pages->elts;
for (i = 0; i < clcf->error_pages->nelts; i++) {
- if (err_page[i].code == error) {
+ if (err_page[i].status == error) {
if (err_page[i].overwrite) {
r->err_status = err_page[i].overwrite;
} else {