aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/ngx_alloc.c86
-rw-r--r--src/core/ngx_alloc.h9
-rw-r--r--src/core/ngx_conf_file.c71
-rw-r--r--src/core/ngx_conf_file.h37
-rw-r--r--src/core/ngx_file.c2
-rw-r--r--src/http/modules/ngx_http_gzip_filter.c273
-rw-r--r--src/http/modules/proxy/ngx_http_proxy_handler.c1
-rw-r--r--src/os/win32/ngx_types.h1
8 files changed, 372 insertions, 108 deletions
diff --git a/src/core/ngx_alloc.c b/src/core/ngx_alloc.c
index 02c9342ac..32aa25c7e 100644
--- a/src/core/ngx_alloc.c
+++ b/src/core/ngx_alloc.c
@@ -20,6 +20,7 @@ void *ngx_alloc(size_t size, ngx_log_t *log)
return p;
}
+
void *ngx_calloc(size_t size, ngx_log_t *log)
{
void *p;
@@ -32,6 +33,7 @@ void *ngx_calloc(size_t size, ngx_log_t *log)
return p;
}
+
ngx_pool_t *ngx_create_pool(size_t size, ngx_log_t *log)
{
ngx_pool_t *p;
@@ -47,6 +49,7 @@ ngx_pool_t *ngx_create_pool(size_t size, ngx_log_t *log)
return p;
}
+
void ngx_destroy_pool(ngx_pool_t *pool)
{
ngx_pool_t *p, *n;
@@ -56,7 +59,9 @@ void ngx_destroy_pool(ngx_pool_t *pool)
#if (NGX_DEBUG_ALLOC)
ngx_log_debug(pool->log, "free: %08x" _ l->alloc);
#endif
- free(l->alloc);
+ if (l->alloc) {
+ free(l->alloc);
+ }
}
/*
@@ -85,6 +90,7 @@ void ngx_destroy_pool(ngx_pool_t *pool)
pool = NULL;
}
+
void *ngx_palloc(ngx_pool_t *pool, size_t size)
{
char *m;
@@ -107,53 +113,71 @@ void *ngx_palloc(ngx_pool_t *pool, size_t size)
}
}
- /* alloc new pool block */
+ /* alloc a new pool block */
+
ngx_test_null(n, ngx_create_pool(p->end - (char *) p, p->log), NULL);
p->next = n;
m = n->last;
n->last += size;
+
return m;
+ }
- /* alloc large block */
- } else {
- large = NULL;
- last = NULL;
-
- if (pool->large) {
- for (last = pool->large; /* void */; last = last->next) {
- if (last->alloc == NULL) {
- large = last;
- last = NULL;
- break;
- }
-
- if (last->next == NULL) {
- break;
- }
+ /* alloc a large block */
+
+ large = NULL;
+ last = NULL;
+
+ if (pool->large) {
+ for (last = pool->large; /* void */; last = last->next) {
+ if (last->alloc == NULL) {
+ large = last;
+ last = NULL;
+ break;
}
- }
- if (large == NULL) {
- ngx_test_null(large, ngx_palloc(pool, sizeof(ngx_pool_large_t)),
- NULL);
- large->next = NULL;
+ if (last->next == NULL) {
+ break;
+ }
}
+ }
- ngx_test_null(p, ngx_alloc(size, pool->log), NULL);
+ if (large == NULL) {
+ ngx_test_null(large, ngx_palloc(pool, sizeof(ngx_pool_large_t)), NULL);
+ large->next = NULL;
+ }
- if (pool->large == NULL) {
- pool->large = large;
+ ngx_test_null(p, ngx_alloc(size, pool->log), NULL);
- } else if (last) {
- last->next = large;
- }
+ if (pool->large == NULL) {
+ pool->large = large;
+
+ } else if (last) {
+ last->next = large;
+ }
+
+ large->alloc = p;
- large->alloc = p;
+ return p;
+}
- return p;
+
+void ngx_pfree(ngx_pool_t *pool, void *p)
+{
+ ngx_pool_large_t *l;
+
+ for (l = pool->large; l; l = l->next) {
+ if (p == l->alloc) {
+#if (NGX_DEBUG_ALLOC)
+ ngx_log_debug(pool->log, "free: %08x" _ l->alloc);
+#endif
+ free(l->alloc);
+ l->alloc = NULL;
+ }
}
}
+
void *ngx_pcalloc(ngx_pool_t *pool, size_t size)
{
void *p;
diff --git a/src/core/ngx_alloc.h b/src/core/ngx_alloc.h
index b63f4bdc1..946361182 100644
--- a/src/core/ngx_alloc.h
+++ b/src/core/ngx_alloc.h
@@ -6,9 +6,10 @@
#include <ngx_core.h>
-/* NGX_MAX_ALLOC_FROM_POOL should be (PAGE_SIZE - 1), i.e. 4095 on x86.
- On FreeBSD 5.x it allows to use zero copy send.
- On Windows NT it decreases number of locked pages in kernel.
+/*
+ * NGX_MAX_ALLOC_FROM_POOL should be (PAGE_SIZE - 1), i.e. 4095 on x86.
+ * On FreeBSD 5.x it allows to use zero copy send.
+ * On Windows NT it decreases number of locked pages in kernel.
*/
#define NGX_MAX_ALLOC_FROM_POOL 4095
@@ -44,6 +45,8 @@ void ngx_destroy_pool(ngx_pool_t *pool);
void *ngx_palloc(ngx_pool_t *pool, size_t size);
void *ngx_pcalloc(ngx_pool_t *pool, size_t size);
+void ngx_pfree(ngx_pool_t *pool, void *p);
+
#define ngx_free free
diff --git a/src/core/ngx_conf_file.c b/src/core/ngx_conf_file.c
index 70da2dcbe..a5a907ae1 100644
--- a/src/core/ngx_conf_file.c
+++ b/src/core/ngx_conf_file.c
@@ -546,6 +546,7 @@ char *ngx_conf_set_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
int flag;
ngx_str_t *value;
+
if (*(int *) (p + cmd->offset) != NGX_CONF_UNSET) {
return "is duplicate";
}
@@ -596,23 +597,25 @@ char *ngx_conf_set_num_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
char *p = conf;
- int num, len;
+ int *np;
ngx_str_t *value;
- if (*(int *) (p + cmd->offset) != NGX_CONF_UNSET) {
+
+ np = (int *) (p + cmd->offset);
+
+ if (*np != NGX_CONF_UNSET) {
return "is duplicate";
}
value = (ngx_str_t *) cf->args->elts;
-
- len = value[1].len;
-
- num = ngx_atoi(value[1].data, len);
- if (num == NGX_ERROR) {
+ *np = ngx_atoi(value[1].data, value[1].len);
+ if (*np == NGX_ERROR) {
return "invalid number";
}
- *(int *) (p + cmd->offset) = num;
+ if (cmd->bounds) {
+ return cmd->bounds->check(cf, cmd->bounds, np);
+ }
return NGX_CONF_OK;
}
@@ -622,11 +625,14 @@ char *ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
char *p = conf;
- int size, len, scale;
+ int size, len, scale, *np;
char last;
ngx_str_t *value;
- if (*(int *) (p + cmd->offset) != NGX_CONF_UNSET) {
+
+ np = (int *) (p + cmd->offset);
+
+ if (*np != NGX_CONF_UNSET) {
return "is duplicate";
}
@@ -658,8 +664,11 @@ char *ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
size *= scale;
+ *np = size;
- *(int *) (p + cmd->offset) = size;
+ if (cmd->bounds) {
+ return cmd->bounds->check(cf, cmd->bounds, np);
+ }
return NGX_CONF_OK;
}
@@ -669,12 +678,15 @@ char *ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
char *p = conf;
- int size, total, len, scale;
+ int size, total, len, scale, *np;
u_int max, i;
char last, *start;
ngx_str_t *value;
- if (*(int *) (p + cmd->offset) != NGX_CONF_UNSET) {
+
+ np = (int *) (p + cmd->offset);
+
+ if (*np != NGX_CONF_UNSET) {
return "is duplicate";
}
@@ -756,7 +768,11 @@ char *ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
start = &value[1].data[i + 1];
}
- *(int *) (p + cmd->offset) = total;
+ *np = total;
+
+ if (cmd->bounds) {
+ return cmd->bounds->check(cf, cmd->bounds, np);
+ }
return NGX_CONF_OK;
}
@@ -766,12 +782,15 @@ char *ngx_conf_set_sec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
char *p = conf;
- int size, total, len, scale;
+ int size, total, len, scale, *np;
u_int max, i;
char last, *start;
ngx_str_t *value;
- if (*(int *) (p + cmd->offset) != NGX_CONF_UNSET) {
+
+ np = (int *) (p + cmd->offset);
+
+ if (*np != NGX_CONF_UNSET) {
return "is duplicate";
}
@@ -865,7 +884,11 @@ char *ngx_conf_set_sec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
start = &value[1].data[i + 1];
}
- *(int *) (p + cmd->offset) = total;
+ *np = total;
+
+ if (cmd->bounds) {
+ return cmd->bounds->check(cf, cmd->bounds, np);
+ }
return NGX_CONF_OK;
}
@@ -929,3 +952,17 @@ char *ngx_conf_unsupported(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
return "unsupported on this platform";
}
+
+
+char *ngx_conf_check_num_bounds(ngx_conf_t *cf, ngx_conf_bounds_t *bounds,
+ void *conf)
+{
+ int *num = conf;
+
+ if (*num >= bounds->type.num.low && *num <= bounds->type.num.high) {
+ return NGX_CONF_OK;
+
+ }
+
+ return "invalid value";
+}
diff --git a/src/core/ngx_conf_file.h b/src/core/ngx_conf_file.h
index 66ca2a912..e09cc65e9 100644
--- a/src/core/ngx_conf_file.h
+++ b/src/core/ngx_conf_file.h
@@ -52,17 +52,37 @@
#define NGX_CONF_MODULE 0x464E4F43 /* "CONF" */
+typedef struct ngx_conf_bounds_s ngx_conf_bounds_t;
+
+struct ngx_conf_bounds_s {
+ char *(*check)(ngx_conf_t *cf, ngx_conf_bounds_t *bounds, void *conf);
+
+ union {
+ struct {
+ int low;
+ int high;
+ } num;
+
+ struct num {
+ int low_num;
+ int high_num;
+ int low_size;
+ int high_size;
+ } bufs;
+ } type;
+};
+
struct ngx_command_s {
- ngx_str_t name;
- int type;
- char *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
- int conf;
- int offset;
- void *bounds;
+ ngx_str_t name;
+ int type;
+ char *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
+ int conf;
+ int offset;
+ ngx_conf_bounds_t *bounds;
};
-#define ngx_null_command {ngx_null_string, 0, NULL, 0, 0, NULL}
+#define ngx_null_command { ngx_null_string, 0, NULL, 0, 0, NULL }
struct ngx_open_file_s {
@@ -221,6 +241,9 @@ char *ngx_conf_set_bufs_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_core_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
+char *ngx_conf_check_num_bounds(ngx_conf_t *cf, ngx_conf_bounds_t *bounds,
+ void *conf);
+
extern ngx_module_t *ngx_modules[];
extern ngx_cycle_t *ngx_cycle;
diff --git a/src/core/ngx_file.c b/src/core/ngx_file.c
index 538adff1d..2383e5c52 100644
--- a/src/core/ngx_file.c
+++ b/src/core/ngx_file.c
@@ -203,5 +203,5 @@ char *ngx_conf_set_path_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
path->level[i++] = 0;
}
- return NULL;
+ return NGX_CONF_OK;
}
diff --git a/src/http/modules/ngx_http_gzip_filter.c b/src/http/modules/ngx_http_gzip_filter.c
index 6cdc56a05..6a89ca0da 100644
--- a/src/http/modules/ngx_http_gzip_filter.c
+++ b/src/http/modules/ngx_http_gzip_filter.c
@@ -7,38 +7,55 @@
typedef struct {
- int enable;
- ngx_bufs_t bufs;
- int no_buffer;
+ int enable;
+ ngx_bufs_t bufs;
+ int level;
+ int wbits;
+ int memlevel;
+ int no_buffer;
} ngx_http_gzip_conf_t;
typedef struct {
- ngx_chain_t *in;
- ngx_chain_t *free;
- ngx_chain_t *busy;
- ngx_chain_t *out;
- ngx_chain_t **last_out;
- ngx_hunk_t *in_hunk;
- ngx_hunk_t *out_hunk;
- int hunks;
-
- off_t length;
- void *alloc;
-
- unsigned flush:4;
- unsigned redo:1;
-
- u_int crc32;
- z_stream zstream;
+ ngx_chain_t *in;
+ ngx_chain_t *free;
+ ngx_chain_t *busy;
+ ngx_chain_t *out;
+ ngx_chain_t **last_out;
+ ngx_hunk_t *in_hunk;
+ ngx_hunk_t *out_hunk;
+ int hunks;
+
+ off_t length;
+
+ void *preallocated;
+ char *free_mem;
+ int allocated;
+
+ unsigned flush:4;
+ unsigned redo:1;
+
+ u_int crc32;
+ z_stream zstream;
+ ngx_http_request_t *request;
} ngx_http_gzip_ctx_t;
+static void *ngx_http_gzip_filter_alloc(void *opaque, u_int items,
+ u_int size);
+static void ngx_http_gzip_filter_free(void *opaque, void *address);
+
ngx_inline static int ngx_http_gzip_error(ngx_http_gzip_ctx_t *ctx);
static int ngx_http_gzip_filter_init(ngx_cycle_t *cycle);
static void *ngx_http_gzip_create_conf(ngx_conf_t *cf);
static char *ngx_http_gzip_merge_conf(ngx_conf_t *cf,
void *parent, void *child);
+static char *ngx_http_gzip_set_window(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
+static char *ngx_http_gzip_set_hash(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
+
+static ngx_conf_bounds_t ngx_http_gzip_comp_level_bounds;
static ngx_command_t ngx_http_gzip_filter_commands[] = {
@@ -57,6 +74,27 @@ static ngx_command_t ngx_http_gzip_filter_commands[] = {
offsetof(ngx_http_gzip_conf_t, bufs),
NULL},
+ {ngx_string("gzip_comp_level"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_num_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_gzip_conf_t, level),
+ &ngx_http_gzip_comp_level_bounds},
+
+ {ngx_string("gzip_window"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_http_gzip_set_window,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_gzip_conf_t, wbits),
+ NULL},
+
+ {ngx_string("gzip_hash"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_http_gzip_set_hash,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_gzip_conf_t, memlevel),
+ NULL},
+
{ngx_string("gzip_no_buffer"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
@@ -90,9 +128,12 @@ ngx_module_t ngx_http_gzip_filter_module = {
};
-static char gzheader[10] = { 0x1f,
- (char) 0x8b, /* suppress MSVC warning */
- Z_DEFLATED, 0, 0, 0, 0, 0, 0, 3 };
+static ngx_conf_bounds_t ngx_http_gzip_comp_level_bounds = {
+ ngx_conf_check_num_bounds, { { 1, 9 } }
+};
+
+
+static u_char gzheader[10] = { 0x1f, 0x8b, Z_DEFLATED, 0, 0, 0, 0, 0, 0, 3 };
#if (HAVE_LITTLE_ENDIAN)
@@ -104,8 +145,8 @@ struct gztrailer {
#else /* HAVE_BIG_ENDIAN */
struct gztrailer {
- unsigned char crc32[4];
- unsigned char zlen[4];
+ u_char crc32[4];
+ u_char zlen[4];
};
#endif
@@ -146,6 +187,7 @@ static int ngx_http_gzip_header_filter(ngx_http_request_t *r)
ngx_http_create_ctx(r, ctx, ngx_http_gzip_filter_module,
sizeof(ngx_http_gzip_ctx_t), NGX_ERROR);
+ ctx->request = r;
ngx_test_null(r->headers_out.content_encoding,
ngx_push_table(r->headers_out.headers),
@@ -167,7 +209,7 @@ static int ngx_http_gzip_header_filter(ngx_http_request_t *r)
static int ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
{
- int rc, wbits, mem_level, zin, zout, last;
+ int rc, wbits, memlevel, zin, zout, last;
struct gztrailer *trailer;
ngx_hunk_t *h;
ngx_chain_t *cl;
@@ -182,9 +224,9 @@ static int ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
conf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_filter_module);
- if (ctx->alloc == NULL) {
- wbits = MAX_WBITS;
- mem_level = MAX_MEM_LEVEL - 1;
+ if (ctx->preallocated == NULL) {
+ wbits = conf->wbits;
+ memlevel = conf->memlevel;
if (ctx->length > 0) {
@@ -192,18 +234,34 @@ static int ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
while (ctx->length < ((1 << (wbits - 1)) - 262)) {
wbits--;
- mem_level--;
+ memlevel--;
}
}
-#if 0
- ngx_test_null(ctx->alloc, ngx_alloc(200K, r->log), NGX_ERROR);
-#else
- ctx->alloc = (void *) -1;
-#endif
+ /*
+ * We preallocate a memory for zlib in one hunk (200K-400K), this
+ * dicreases number of malloc() and free() calls and probably
+ * syscalls.
+ * Besides we free() this memory as soon as the gzipping will complete
+ * and do not wait while a whole response will be sent to a client.
+ *
+ * 8K is for zlib deflate_state (~6K).
+ *
+ * TODO: 64-bit, round to PAGE_SIZE
+ */
- rc = deflateInit2(&ctx->zstream, /**/ 1, Z_DEFLATED,
- -wbits, mem_level, Z_DEFAULT_STRATEGY);
+ ctx->allocated = 8192 + (1 << (wbits + 2)) + (1 << (memlevel + 9));
+
+ ngx_test_null(ctx->preallocated, ngx_palloc(r->pool, ctx->allocated),
+ NGX_ERROR);
+ ctx->free_mem = ctx->preallocated;
+
+ ctx->zstream.zalloc = ngx_http_gzip_filter_alloc;
+ ctx->zstream.zfree = ngx_http_gzip_filter_free;
+ ctx->zstream.opaque = ctx;
+
+ rc = deflateInit2(&ctx->zstream, conf->level, Z_DEFLATED,
+ -wbits, memlevel, Z_DEFAULT_STRATEGY);
if (rc != Z_OK) {
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
@@ -214,7 +272,7 @@ static int ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
ngx_test_null(h, ngx_calloc_hunk(r->pool), ngx_http_gzip_error(ctx));
h->type = NGX_HUNK_IN_MEMORY|NGX_HUNK_MEMORY;
- h->pos = gzheader;
+ h->pos = (char *) gzheader;
h->last = h->pos + 10;
ngx_alloc_link_and_set_hunk(cl, h, r->pool, ngx_http_gzip_error(ctx));
@@ -250,7 +308,7 @@ static int ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
ctx->in_hunk = ctx->in->hunk;
ctx->in = ctx->in->next;
- ctx->zstream.next_in = (unsigned char *) ctx->in_hunk->pos;
+ ctx->zstream.next_in = (u_char *) ctx->in_hunk->pos;
ctx->zstream.avail_in = ctx->in_hunk->last - ctx->in_hunk->pos;
if (ctx->in_hunk->type & NGX_HUNK_LAST) {
@@ -292,7 +350,7 @@ static int ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
break;
}
- ctx->zstream.next_out = (unsigned char *) ctx->out_hunk->pos;
+ ctx->zstream.next_out = (u_char *) ctx->out_hunk->pos;
ctx->zstream.avail_out = conf->bufs.size;
}
@@ -337,6 +395,7 @@ ngx_log_debug(r->connection->log, "DEFLATE(): %08x %08x %d %d %d" _
break;
} else if (ctx->flush == Z_FINISH) {
+
/* rc == Z_STREAM_END */
zin = ctx->zstream.total_in;
@@ -349,6 +408,8 @@ ngx_log_debug(r->connection->log, "DEFLATE(): %08x %08x %d %d %d" _
return ngx_http_gzip_error(ctx);
}
+ ngx_pfree(r->pool, ctx->preallocated);
+
ctx->flush = Z_NO_FLUSH;
ngx_alloc_link_and_set_hunk(cl, ctx->out_hunk, r->pool,
@@ -385,9 +446,7 @@ ngx_log_debug(r->connection->log, "DEFLATE(): %08x %08x %d %d %d" _
ctx->zstream.avail_in = 0;
ctx->zstream.avail_out = 0;
-#if 0
- ngx_free(ctx->alloc);
-#endif
+
ngx_http_delete_ctx(r, ngx_http_gzip_filter_module);
break;
@@ -420,13 +479,61 @@ ngx_log_debug(r->connection->log, "DEFLATE(): %08x %08x %d %d %d" _
}
-ngx_inline static int ngx_http_gzip_error(ngx_http_gzip_ctx_t *ctx)
+static void *ngx_http_gzip_filter_alloc(void *opaque, u_int items, u_int size)
{
+ ngx_http_gzip_ctx_t *ctx = opaque;
+
+ int alloc;
+ void *p;
+
+
+ alloc = items * size;
+ if (alloc % 512 != 0) {
+
+ /* we allocate 8K for zlib deflate_state (~6K) */
+ /* TODO: PAGE_SIZE */
+
+ alloc = (alloc + 4095) & ~4095;
+ }
+
+ if (alloc <= ctx->allocated) {
+ p = ctx->free_mem;
+ ctx->free_mem += alloc;
+ ctx->allocated -= alloc;
+
#if 0
- ngx_free(ctx->alloc);
-#else
- deflateEnd(&ctx->zstream);
+ ngx_log_debug(ctx->request->connection->log, "ALLOC: %d:%d:%d:%08X" _
+ items _ size _ alloc _ p);
+#endif
+
+ return p;
+ }
+
+ ngx_log_error(NGX_LOG_ALERT, ctx->request->connection->log, 0,
+ "gzip filter failed to use preallocated memory: %d of %d",
+ items * size, ctx->allocated);
+
+ p = ngx_palloc(ctx->request->pool, items * size);
+
+ return p;
+}
+
+
+static void ngx_http_gzip_filter_free(void *opaque, void *address)
+{
+ ngx_http_gzip_ctx_t *ctx = opaque;
+
+#if 0
+ ngx_log_debug(ctx->request->connection->log, "FREE: %08X" _ address);
#endif
+}
+
+
+ngx_inline static int ngx_http_gzip_error(ngx_http_gzip_ctx_t *ctx)
+{
+ deflateEnd(&ctx->zstream);
+
+ ngx_pfree(ctx->request->pool, ctx->preallocated);
ctx->zstream.avail_in = 0;
ctx->zstream.avail_out = 0;
@@ -456,8 +563,11 @@ static void *ngx_http_gzip_create_conf(ngx_conf_t *cf)
NGX_CONF_ERROR);
conf->enable = NGX_CONF_UNSET;
-/* conf->bufs.num = 0; */
+ /* conf->bufs.num = 0; */
conf->no_buffer = NGX_CONF_UNSET;
+ conf->level = NGX_CONF_UNSET;
+ conf->wbits = NGX_CONF_UNSET;
+ conf->memlevel = NGX_CONF_UNSET;
return conf;
}
@@ -472,7 +582,74 @@ static char *ngx_http_gzip_merge_conf(ngx_conf_t *cf,
ngx_conf_merge_value(conf->enable, prev->enable, 0);
ngx_conf_merge_bufs_value(conf->bufs, prev->bufs, 4,
/* STUB: PAGE_SIZE */ 4096);
+ ngx_conf_merge_value(conf->level, prev->level, 1);
+ ngx_conf_merge_value(conf->wbits, prev->wbits, MAX_WBITS);
+ ngx_conf_merge_value(conf->memlevel, prev->memlevel, MAX_MEM_LEVEL - 1);
ngx_conf_merge_value(conf->no_buffer, prev->no_buffer, 0);
return NGX_CONF_OK;
}
+
+
+static char *ngx_http_gzip_set_window(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf)
+{
+ ngx_http_gzip_conf_t *lcf = conf;
+
+ int wbits, wsize;
+ char *rv;
+
+
+ rv = ngx_conf_set_size_slot(cf, cmd, conf);
+ if (rv) {
+ return rv;
+ }
+
+ngx_conf_log_error(NGX_LOG_INFO, cf, 0, "WBITS: %d", lcf->wbits);
+
+ wbits = 15;
+ for (wsize = 32 * 1024; wsize > 256; wsize >>= 1) {
+
+ if (wsize == lcf->wbits) {
+ lcf->wbits = wbits;
+ngx_conf_log_error(NGX_LOG_INFO, cf, 0, "WBITS: %d", lcf->wbits);
+ return NULL;
+ }
+
+ wbits--;
+ }
+
+ return "must be 512, 1k, 2k, 4k, 8k, 16k, or 32k";
+}
+
+
+static char *ngx_http_gzip_set_hash(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf)
+{
+ ngx_http_gzip_conf_t *lcf = conf;
+
+ int memlevel, hsize;
+ char *rv;
+
+
+ rv = ngx_conf_set_size_slot(cf, cmd, conf);
+ if (rv) {
+ return rv;
+ }
+
+ngx_conf_log_error(NGX_LOG_INFO, cf, 0, "MEMLEVEL: %d", lcf->memlevel);
+
+ memlevel = 9;
+ for (hsize = 128 * 1024; hsize > 256; hsize >>= 1) {
+
+ if (hsize == lcf->memlevel) {
+ lcf->memlevel = memlevel;
+ngx_conf_log_error(NGX_LOG_INFO, cf, 0, "MEMLEVEL: %d", lcf->memlevel);
+ return NULL;
+ }
+
+ memlevel--;
+ }
+
+ return "must be 512, 1k, 2k, 4k, 8k, 16k, 32k, 64k, or 128k";
+}
diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.c b/src/http/modules/proxy/ngx_http_proxy_handler.c
index dda8e9b2c..888c912f8 100644
--- a/src/http/modules/proxy/ngx_http_proxy_handler.c
+++ b/src/http/modules/proxy/ngx_http_proxy_handler.c
@@ -1200,7 +1200,6 @@ static size_t ngx_http_proxy_log_error(void *data, char *buf, size_t len)
static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
{
- int i;
ngx_http_proxy_loc_conf_t *conf;
ngx_test_null(conf,
diff --git a/src/os/win32/ngx_types.h b/src/os/win32/ngx_types.h
index c009b5aa9..59ee72173 100644
--- a/src/os/win32/ngx_types.h
+++ b/src/os/win32/ngx_types.h
@@ -7,6 +7,7 @@
typedef unsigned __int32 u_int32_t;
+typedef __int64 int64_t;
typedef int ssize_t;
typedef long time_t;