int http_compression_buffer_add_data(struct session *s, struct buffer *in, struct buffer *out);
int http_compression_buffer_end(struct session *s, struct buffer **in, struct buffer **out, int end);
-int identity_init(struct comp_ctx *comp_ctx, int level);
+int identity_init(struct comp_ctx **comp_ctx, int level);
int identity_add_data(struct comp_ctx *comp_ctx, const char *in_data, int in_len, struct buffer *out);
int identity_flush(struct comp_ctx *comp_ctx, struct buffer *out, int flag);
int identity_reset(struct comp_ctx *comp_ctx);
-int identity_end(struct comp_ctx *comp_ctx);
+int identity_end(struct comp_ctx **comp_ctx);
#ifdef USE_ZLIB
-
-int deflate_init(struct comp_ctx *comp_ctx, int level);
+int deflate_init(struct comp_ctx **comp_ctx, int level);
int deflate_add_data(struct comp_ctx *comp_ctx, const char *in_data, int in_len, struct buffer *out);
int deflate_flush(struct comp_ctx *comp_ctx, struct buffer *out, int flag);
int deflate_reset(struct comp_ctx *comp_ctx);
-int deflate_end(struct comp_ctx *comp_ctx);
+int deflate_end(struct comp_ctx **comp_ctx);
-int gzip_init(struct comp_ctx *comp_ctx, int level);
+int gzip_init(struct comp_ctx **comp_ctx, int level);
#endif /* USE_ZLIB */
#endif /* _PROTO_COMP_H */
#ifdef USE_ZLIB
+static void *alloc_zlib(void *opaque, unsigned int items, unsigned int size);
+static void free_zlib(void *opaque, void *ptr);
+
/* zlib allocation */
static struct pool_head *zlib_pool_deflate_state = NULL;
static struct pool_head *zlib_pool_window = NULL;
static long long zlib_memory_available = -1;
-
#endif
+static struct pool_head *pool_comp_ctx = NULL;
+
const struct comp_algo comp_algos[] =
{
left = data_process_len - bi_contig_data(in);
if (left <= 0) {
- consumed_data += ret = s->comp_algo->add_data(&s->comp_ctx, bi_ptr(in), data_process_len, out);
+ consumed_data += ret = s->comp_algo->add_data(s->comp_ctx, bi_ptr(in), data_process_len, out);
if (ret < 0)
return -1;
} else {
- consumed_data += ret = s->comp_algo->add_data(&s->comp_ctx, bi_ptr(in), bi_contig_data(in), out);
+ consumed_data += ret = s->comp_algo->add_data(s->comp_ctx, bi_ptr(in), bi_contig_data(in), out);
if (ret < 0)
return -1;
- consumed_data += ret = s->comp_algo->add_data(&s->comp_ctx, in->data, left, out);
+ consumed_data += ret = s->comp_algo->add_data(s->comp_ctx, in->data, left, out);
if (ret < 0)
return -1;
}
/* flush data here */
if (end)
- ret = s->comp_algo->flush(&s->comp_ctx, ob, Z_FINISH); /* end of data */
+ ret = s->comp_algo->flush(s->comp_ctx, ob, Z_FINISH); /* end of data */
else
- ret = s->comp_algo->flush(&s->comp_ctx, ob, Z_SYNC_FLUSH); /* end of buffer */
+ ret = s->comp_algo->flush(s->comp_ctx, ob, Z_SYNC_FLUSH); /* end of buffer */
if (ret < 0)
return -1; /* flush failed */
}
to_forward = ob->i;
-
/* update input rate */
- if (s->comp_ctx.cur_lvl > 0)
+ if (s->comp_ctx && s->comp_ctx->cur_lvl > 0)
update_freq_ctr(&global.comp_bps_in, ib->o - ob->o);
/* copy the remaining data in the tmp buffer. */
*in = ob;
*out = ib;
- if (s->comp_ctx.cur_lvl > 0)
+ if (s->comp_ctx && s->comp_ctx->cur_lvl > 0)
update_freq_ctr(&global.comp_bps_out, to_forward);
/* forward the new chunk without remaining data */
return to_forward;
}
+/*
+ * Alloc the comp_ctx
+ */
+static inline int init_comp_ctx(struct comp_ctx **comp_ctx)
+{
+#ifdef USE_ZLIB
+ z_stream *strm;
+
+ if (global.maxzlibmem > 0 && zlib_memory_available < 0)
+ zlib_memory_available = global.maxzlibmem * 1024 * 1024; /* Megabytes to bytes */
+
+ if (global.maxzlibmem > 0 && zlib_memory_available < sizeof(struct comp_ctx))
+ return -1;
+#endif
+
+ if (unlikely(pool_comp_ctx == NULL))
+ pool_comp_ctx = create_pool("comp_ctx", sizeof(struct comp_ctx), MEM_F_SHARED);
+
+ *comp_ctx = pool_alloc2(pool_comp_ctx);
+ if (*comp_ctx == NULL)
+ return -1;
+#ifdef USE_ZLIB
+ zlib_memory_available -= sizeof(struct comp_ctx);
+
+ strm = &(*comp_ctx)->strm;
+ strm->zalloc = alloc_zlib;
+ strm->zfree = free_zlib;
+ strm->opaque = *comp_ctx;
+#endif
+ return 0;
+}
+
+/*
+ * Dealloc the comp_ctx
+ */
+static inline int deinit_comp_ctx(struct comp_ctx **comp_ctx)
+{
+ if (!*comp_ctx)
+ return 0;
+
+ pool_free2(pool_comp_ctx, *comp_ctx);
+ *comp_ctx = NULL;
+
+#ifdef USE_ZLIB
+ zlib_memory_available += sizeof(struct comp_ctx);
+#endif
+
+ return 0;
+}
+
/****************************
**** Identity algorithm ****
/*
* Init the identity algorithm
*/
-int identity_init(struct comp_ctx *comp_ctx, int level)
+int identity_init(struct comp_ctx **comp_ctx, int level)
{
return 0;
}
/*
* Deinit the algorithm
*/
-int identity_end(struct comp_ctx *comp_ctx)
+int identity_end(struct comp_ctx **comp_ctx)
{
return 0;
}
zlib_memory_available += pool->size;
}
-
/**************************
**** gzip algorithm ****
***************************/
-int gzip_init(struct comp_ctx *comp_ctx, int level)
+int gzip_init(struct comp_ctx **comp_ctx, int level)
{
- z_stream *strm = &comp_ctx->strm;
+ z_stream *strm;
- if (global.maxzlibmem > 0 && zlib_memory_available < 0)
- zlib_memory_available = global.maxzlibmem * 1024 * 1024; /* Megabytes to bytes */
+ if (init_comp_ctx(comp_ctx) < 0)
+ return -1;
- strm->zalloc = alloc_zlib;
- strm->zfree = free_zlib;
- strm->opaque = comp_ctx;
+ strm = &(*comp_ctx)->strm;
- if (deflateInit2(&comp_ctx->strm, level, Z_DEFLATED, global.tune.zlibwindowsize + 16, global.tune.zlibmemlevel, Z_DEFAULT_STRATEGY) != Z_OK)
+ if (deflateInit2(strm, level, Z_DEFLATED, global.tune.zlibwindowsize + 16, global.tune.zlibmemlevel, Z_DEFAULT_STRATEGY) != Z_OK) {
+ deinit_comp_ctx(comp_ctx);
return -1;
+ }
+
+ (*comp_ctx)->cur_lvl = level;
return 0;
}
**** Deflate algorithm ****
***************************/
-int deflate_init(struct comp_ctx *comp_ctx, int level)
+int deflate_init(struct comp_ctx **comp_ctx, int level)
{
- z_stream *strm = &comp_ctx->strm;
+ z_stream *strm;
- strm->zalloc = alloc_zlib;
- strm->zfree = free_zlib;
- strm->opaque = comp_ctx;
+ if (init_comp_ctx(comp_ctx) < 0)
+ return -1;
+
+ strm = &(*comp_ctx)->strm;
- if (deflateInit(&comp_ctx->strm, level) != Z_OK)
+ if (deflateInit(strm, level) != Z_OK) {
+ deinit_comp_ctx(comp_ctx);
return -1;
+ }
+
+ (*comp_ctx)->cur_lvl = level;
return 0;
}
return -1;
}
-int deflate_end(struct comp_ctx *comp_ctx)
+int deflate_end(struct comp_ctx **comp_ctx)
{
- z_stream *strm = &comp_ctx->strm;
+ z_stream *strm = &(*comp_ctx)->strm;
+ int ret;
- if (deflateEnd(strm) != Z_OK)
- return -1;
+ ret = deflateEnd(strm);
- return 0;
+ deinit_comp_ctx(comp_ctx);
+
+ return ret;
}
#endif /* USE_ZLIB */