/*
 * Stream filters related variables and functions.
 *
 * Copyright (C) 2015 Qualys Inc., Christopher Faulet <cfaulet@qualys.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 *
 */

#include <haproxy/api.h>
#include <haproxy/cfgparse.h>
#include <haproxy/compression.h>
#include <haproxy/dynbuf.h>
#include <haproxy/filters.h>
#include <haproxy/http.h>
#include <haproxy/http_ana-t.h>
#include <haproxy/http_htx.h>
#include <haproxy/htx.h>
#include <haproxy/list.h>
#include <haproxy/proxy.h>
#include <haproxy/sample.h>
#include <haproxy/stream.h>
#include <haproxy/tools.h>

#define COMP_STATE_PROCESSING 0x01

const char *http_comp_flt_id = "compression filter";

struct flt_ops comp_ops;

struct comp_state {
	/*
	 * For both comp_ctx and comp_algo, COMP_DIR_REQ is the index
	 * for requests, and COMP_DIR_RES for responses
	 */
	struct comp_ctx  *comp_ctx[2];   /* compression context */
	struct comp_algo *comp_algo[2];  /* compression algorithm if not NULL */
	unsigned int      flags;      /* COMP_STATE_* */
};

/* Pools used to allocate comp_state structs */
DECLARE_STATIC_POOL(pool_head_comp_state, "comp_state", sizeof(struct comp_state));

static THREAD_LOCAL struct buffer tmpbuf;
static THREAD_LOCAL struct buffer zbuf;

static int select_compression_request_header(struct comp_state *st,
					     struct stream *s,
					     struct http_msg *msg);
static int select_compression_response_header(struct comp_state *st,
					      struct stream *s,
					      struct http_msg *msg);
static int set_compression_header(struct comp_state *st,
			          struct stream *s,
				  struct http_msg *msg);

static int htx_compression_buffer_init(struct htx *htx, struct buffer *out);
static int htx_compression_buffer_add_data(struct comp_state *st, const char *data, size_t len,
					    struct buffer *out, int dir);
static int htx_compression_buffer_end(struct comp_state *st, struct buffer *out, int end, int dir);

/***********************************************************************/
static int
comp_flt_init(struct proxy *px, struct flt_conf *fconf)
{
	fconf->flags |= FLT_CFG_FL_HTX;
	return 0;
}

static int
comp_flt_init_per_thread(struct proxy *px, struct flt_conf *fconf)
{
	if (b_alloc(&tmpbuf) == NULL)
		return -1;
	if (b_alloc(&zbuf) == NULL)
		return -1;
	return 0;
}

static void
comp_flt_deinit_per_thread(struct proxy *px, struct flt_conf *fconf)
{
	if (tmpbuf.size)
		b_free(&tmpbuf);
	if (zbuf.size)
		b_free(&zbuf);
}

static int
comp_strm_init(struct stream *s, struct filter *filter)
{
	struct comp_state *st;

	st = pool_alloc(pool_head_comp_state);
	if (st == NULL)
		return -1;

	st->comp_algo[COMP_DIR_REQ] = NULL;
	st->comp_algo[COMP_DIR_RES] = NULL;
	st->comp_ctx[COMP_DIR_REQ]  = NULL;
	st->comp_ctx[COMP_DIR_RES] = NULL;
	st->flags     = 0;
	filter->ctx   = st;

	/* Register post-analyzer on AN_RES_WAIT_HTTP because we need to
	 * analyze response headers before http-response rules execution
	 * to be sure we can use res.comp and res.comp_algo sample
	 * fetches */
	filter->post_analyzers |= AN_RES_WAIT_HTTP;
	return 1;
}

static void
comp_strm_deinit(struct stream *s, struct filter *filter)
{
	struct comp_state *st = filter->ctx;

	if (!st)
		return;

	/* release any possible compression context */
	if (st->comp_algo[COMP_DIR_REQ])
		st->comp_algo[COMP_DIR_REQ]->end(&st->comp_ctx[COMP_DIR_REQ]);
	if (st->comp_algo[COMP_DIR_RES])
		st->comp_algo[COMP_DIR_RES]->end(&st->comp_ctx[COMP_DIR_RES]);
	pool_free(pool_head_comp_state, st);
	filter->ctx = NULL;
}

static void
comp_prepare_compress_request(struct comp_state *st, struct stream *s, struct http_msg *msg)
{
	struct htx *htx = htxbuf(&msg->chn->buf);
	struct http_txn *txn = s->txn;
	struct http_hdr_ctx ctx;
	struct comp_type *comp_type;

	ctx.blk = NULL;
	/* Already compressed, don't bother */
	if (http_find_header(htx, ist("Content-Encoding"), &ctx, 1))
		return;
	/* HTTP < 1.1 should not be compressed */
	if (!(msg->flags & HTTP_MSGF_VER_11) || !(txn->req.flags & HTTP_MSGF_VER_11))
		return;
	comp_type = NULL;

	/*
	 * We don't want to compress content-types not listed in the "compression type" directive if any. If no content-type was found but configuration
	 * requires one, we don't compress either. Backend has the priority.
	 */
	ctx.blk = NULL;
	if (http_find_header(htx, ist("Content-Type"), &ctx, 1)) {
		if ((s->be->comp && (comp_type = s->be->comp->types_req)) ||
		    (strm_fe(s)->comp && (comp_type = strm_fe(s)->comp->types_req))) {
			for (; comp_type; comp_type = comp_type->next) {
				if (ctx.value.len >= comp_type->name_len &&
				    strncasecmp(ctx.value.ptr, comp_type->name, comp_type->name_len) == 0)
					/* this Content-Type should be compressed */
					break;
			}
			/* this Content-Type should not be compressed */
			if (comp_type == NULL)
				goto fail;
		}
	}
	else { /* no content-type header */
		if ((s->be->comp && s->be->comp->types_req) ||
		    (strm_fe(s)->comp && strm_fe(s)->comp->types_req))
			goto fail; /* a content-type was required */
	}

	/* limit compression rate */
	if (global.comp_rate_lim > 0)
		if (read_freq_ctr(&global.comp_bps_in) > global.comp_rate_lim)
			goto fail;

	/* limit cpu usage */
	if (th_ctx->idle_pct < compress_min_idle)
		goto fail;

	if (txn->meth == HTTP_METH_HEAD)
		return;
	if (s->be->comp->algo_req != NULL)
		st->comp_algo[COMP_DIR_REQ] = s->be->comp->algo_req;
	else if (strm_fe(s)->comp->algo_req != NULL)
		st->comp_algo[COMP_DIR_REQ] = strm_fe(s)->comp->algo_req;


	/* limit compression rate */
	if (global.comp_rate_lim > 0)
		if (read_freq_ctr(&global.comp_bps_in) > global.comp_rate_lim)
			goto fail;

	/* limit cpu usage */
	if (th_ctx->idle_pct < compress_min_idle)
		goto fail;

	/* initialize compression */
	if (st->comp_algo[COMP_DIR_REQ]->init(&st->comp_ctx[COMP_DIR_REQ], global.tune.comp_maxlevel) < 0)
		goto fail;

	return;
fail:
	st->comp_algo[COMP_DIR_REQ] = NULL;
}

static int
comp_http_headers(struct stream *s, struct filter *filter, struct http_msg *msg)
{
	struct comp_state *st = filter->ctx;
	int comp_flags = 0;

	if (!strm_fe(s)->comp && !s->be->comp)
		goto end;
	if (strm_fe(s)->comp)
		comp_flags |= strm_fe(s)->comp->flags;
	if (s->be->comp)
		comp_flags |= s->be->comp->flags;

	if (!(msg->chn->flags & CF_ISRESP)) {
		if (comp_flags & COMP_FL_DIR_REQ) {
			    comp_prepare_compress_request(st, s, msg);
			    if (st->comp_algo[COMP_DIR_REQ]) {
				    if (!set_compression_header(st, s, msg))
					    goto end;
				    register_data_filter(s, msg->chn, filter);
				    st->flags |= COMP_STATE_PROCESSING;
			    }
		}
		if (comp_flags & COMP_FL_DIR_RES)
			select_compression_request_header(st, s, msg);
	} else if (comp_flags & COMP_FL_DIR_RES) {
		/* Response headers have already been checked in
		 * comp_http_post_analyze callback. */
		if (st->comp_algo[COMP_DIR_RES]) {
			if (!set_compression_header(st, s, msg))
				goto end;
			register_data_filter(s, msg->chn, filter);
			st->flags |= COMP_STATE_PROCESSING;
		}
	}

  end:
	return 1;
}

static int
comp_http_post_analyze(struct stream *s, struct filter *filter,
		       struct channel *chn, unsigned an_bit)
{
	struct http_txn   *txn = s->txn;
	struct http_msg   *msg = &txn->rsp;
	struct comp_state *st  = filter->ctx;

	if (an_bit != AN_RES_WAIT_HTTP)
		goto end;

	if (!strm_fe(s)->comp && !s->be->comp)
		goto end;

	select_compression_response_header(st, s, msg);

  end:
	return 1;
}

static int
comp_http_payload(struct stream *s, struct filter *filter, struct http_msg *msg,
		  unsigned int offset, unsigned int len)
{
	struct comp_state *st = filter->ctx;
	struct htx *htx = htxbuf(&msg->chn->buf);
	struct htx_ret htxret = htx_find_offset(htx, offset);
	struct htx_blk *blk, *next;
	int ret, consumed = 0, to_forward = 0, last = 0;
	int dir;

	if (msg->chn->flags & CF_ISRESP)
		dir = COMP_DIR_RES;
	else
		dir = COMP_DIR_REQ;

	blk = htxret.blk;
	offset = htxret.ret;
	for (next = NULL; blk && len; blk = next) {
		enum htx_blk_type type = htx_get_blk_type(blk);
		uint32_t sz = htx_get_blksz(blk);
		struct ist v;

		next = htx_get_next_blk(htx, blk);
		while (next && htx_get_blk_type(next) == HTX_BLK_UNUSED)
			next = htx_get_next_blk(htx, next);

		if (!(st->flags & COMP_STATE_PROCESSING))
			goto consume;

		if (htx_compression_buffer_init(htx, &trash) < 0) {
			msg->chn->flags |= CF_WAKE_WRITE;
			goto end;
		}

		switch (type) {
			case HTX_BLK_DATA:
				/* it is the last data block */
				last = ((!next && (htx->flags & HTX_FL_EOM)) || (next && htx_get_blk_type(next) != HTX_BLK_DATA));
				v = htx_get_blk_value(htx, blk);
				v = istadv(v, offset);
				if (v.len > len) {
					last = 0;
					v.len = len;
				}

				ret = htx_compression_buffer_add_data(st, v.ptr, v.len, &trash, dir);
				if (ret < 0 || htx_compression_buffer_end(st, &trash, last, dir) < 0)
					goto error;
				BUG_ON(v.len != ret);

				if (ret == sz && !b_data(&trash))
					next = htx_remove_blk(htx, blk);
				else {
					blk = htx_replace_blk_value(htx, blk, v, ist2(b_head(&trash), b_data(&trash)));
					next = htx_get_next_blk(htx, blk);
				}

				len -= ret;
				consumed += ret;
				to_forward += b_data(&trash);
				if (last)
					st->flags &= ~COMP_STATE_PROCESSING;
				break;

			case HTX_BLK_TLR:
			case HTX_BLK_EOT:
				if (htx_compression_buffer_end(st, &trash, 1, dir) < 0)
					goto error;
				if (b_data(&trash)) {
					struct htx_blk *last = htx_add_last_data(htx, ist2(b_head(&trash), b_data(&trash)));
					if (!last)
						goto error;
					blk = htx_get_next_blk(htx, last);
					if (!blk)
						goto error;
					next = htx_get_next_blk(htx, blk);
					to_forward += b_data(&trash);
				}
				st->flags &= ~COMP_STATE_PROCESSING;
				__fallthrough;

			default:
			  consume:
				sz -= offset;
				if (sz > len)
					sz = len;
				consumed += sz;
				to_forward += sz;
				len -= sz;
				break;
		}

		offset = 0;
	}

  end:
	if (to_forward != consumed)
		flt_update_offsets(filter, msg->chn, to_forward - consumed);

	if (st->comp_ctx[dir] && st->comp_ctx[dir]->cur_lvl > 0) {
		update_freq_ctr(&global.comp_bps_in, consumed);
		_HA_ATOMIC_ADD(&strm_fe(s)->fe_counters.comp_in[dir], consumed);
		_HA_ATOMIC_ADD(&s->be->be_counters.comp_in[dir], consumed);
		update_freq_ctr(&global.comp_bps_out, to_forward);
		_HA_ATOMIC_ADD(&strm_fe(s)->fe_counters.comp_out[dir], to_forward);
		_HA_ATOMIC_ADD(&s->be->be_counters.comp_out[dir], to_forward);
	} else {
		_HA_ATOMIC_ADD(&strm_fe(s)->fe_counters.comp_byp[dir], consumed);
		_HA_ATOMIC_ADD(&s->be->be_counters.comp_byp[dir], consumed);
	}
	return to_forward;

  error:
	return -1;
}


static int
comp_http_end(struct stream *s, struct filter *filter,
	      struct http_msg *msg)
{
	struct comp_state *st = filter->ctx;

	if (!(msg->chn->flags & CF_ISRESP) || !st || !st->comp_algo[COMP_DIR_RES])
		goto end;

	if (strm_fe(s)->mode == PR_MODE_HTTP)
		_HA_ATOMIC_INC(&strm_fe(s)->fe_counters.p.http.comp_rsp);
	if ((s->flags & SF_BE_ASSIGNED) && (s->be->mode == PR_MODE_HTTP))
		_HA_ATOMIC_INC(&s->be->be_counters.p.http.comp_rsp);
 end:
	return 1;
}

/***********************************************************************/
static int
set_compression_header(struct comp_state *st, struct stream *s, struct http_msg *msg)
{
	struct htx *htx = htxbuf(&msg->chn->buf);
	struct htx_sl *sl;
	struct http_hdr_ctx ctx;
	struct comp_algo *comp_algo;
	int comp_index;

	if (msg->chn->flags & CF_ISRESP)
		comp_index = COMP_DIR_RES;
	else
		comp_index = COMP_DIR_REQ;

	sl = http_get_stline(htx);
	if (!sl)
		goto error;

	comp_algo = st->comp_algo[comp_index];

	/* add "Transfer-Encoding: chunked" header */
	if (!(msg->flags & HTTP_MSGF_TE_CHNK)) {
		if (!http_add_header(htx, ist("Transfer-Encoding"), ist("chunked")))
			goto error;
		msg->flags |= HTTP_MSGF_TE_CHNK;
		sl->flags |= (HTX_SL_F_XFER_ENC|HTX_SL_F_CHNK);
	}

	/* remove Content-Length header */
	if (msg->flags & HTTP_MSGF_CNT_LEN) {
		ctx.blk = NULL;
		while (http_find_header(htx, ist("Content-Length"), &ctx, 1))
			http_remove_header(htx, &ctx);
		msg->flags &= ~HTTP_MSGF_CNT_LEN;
		sl->flags &= ~HTX_SL_F_CLEN;
	}

	/* convert "ETag" header to a weak ETag */
	ctx.blk = NULL;
	if (http_find_header(htx, ist("ETag"), &ctx, 1)) {
		if (ctx.value.ptr[0] == '"') {
			/* This a strong ETag. Convert it to a weak one. */
			struct ist v = ist2(trash.area, 0);
			if (istcat(&v, ist("W/"), trash.size) == -1 || istcat(&v, ctx.value, trash.size) == -1)
				goto error;

			if (!http_replace_header_value(htx, &ctx, v))
				goto error;
		}
	}

	if (!http_add_header(htx, ist("Vary"), ist("Accept-Encoding")))
		goto error;

	/*
	 * Add Content-Encoding header when it's not identity encoding.
	 * RFC 2616 : Identity encoding: This content-coding is used only in the
	 * Accept-Encoding header, and SHOULD NOT be used in the Content-Encoding
	 * header.
	 */
	if (comp_algo->cfg_name_len != 8 || memcmp(comp_algo->cfg_name, "identity", 8) != 0) {
		struct ist v = ist2(comp_algo->ua_name, comp_algo->ua_name_len);

		if (!http_add_header(htx, ist("Content-Encoding"), v))
			goto error;
	}

	return 1;

  error:
	st->comp_algo[comp_index]->end(&st->comp_ctx[comp_index]);
	st->comp_algo[comp_index] = NULL;
	return 0;
}

/*
 * Selects a compression algorithm depending on the client request.
 */
static int
select_compression_request_header(struct comp_state *st, struct stream *s, struct http_msg *msg)
{
	struct htx *htx = htxbuf(&msg->chn->buf);
	struct http_hdr_ctx ctx;
	struct comp_algo *comp_algo = NULL;
	struct comp_algo *comp_algo_back = NULL;

	/* Disable compression for older user agents announcing themselves as "Mozilla/4"
	 * unless they are known good (MSIE 6 with XP SP2, or MSIE 7 and later).
	 * See http://zoompf.com/2012/02/lose-the-wait-http-compression for more details.
	 */
	ctx.blk = NULL;
	if (http_find_header(htx, ist("User-Agent"), &ctx, 1) &&
	    ctx.value.len >= 9 &&
	    memcmp(ctx.value.ptr, "Mozilla/4", 9) == 0 &&
	    (ctx.value.len < 31 ||
	     memcmp(ctx.value.ptr + 25, "MSIE ", 5) != 0 ||
	     *(ctx.value.ptr + 30) < '6' ||
	     (*(ctx.value.ptr + 30) == '6' &&
	      (ctx.value.len < 54 || memcmp(ctx.value.ptr + 51, "SV1", 3) != 0)))) {
		st->comp_algo[COMP_DIR_RES] = NULL;
		return 0;
	}

	/* search for the algo in the backend in priority or the frontend */
	if ((s->be->comp && (comp_algo_back = s->be->comp->algos_res)) ||
	    (strm_fe(s)->comp && (comp_algo_back = strm_fe(s)->comp->algos_res))) {
		int best_q = 0;

		ctx.blk = NULL;
		while (http_find_header(htx, ist("Accept-Encoding"), &ctx, 0)) {
			const char *qval;
			int q;
			int toklen;

			/* try to isolate the token from the optional q-value */
			toklen = 0;
			while (toklen < ctx.value.len && HTTP_IS_TOKEN(*(ctx.value.ptr + toklen)))
				toklen++;

			qval = ctx.value.ptr + toklen;
			while (1) {
				while (qval < istend(ctx.value) && HTTP_IS_LWS(*qval))
					qval++;

				if (qval >= istend(ctx.value) || *qval != ';') {
					qval = NULL;
					break;
				}
				qval++;

				while (qval < istend(ctx.value) && HTTP_IS_LWS(*qval))
					qval++;

				if (qval >= istend(ctx.value)) {
					qval = NULL;
					break;
				}
				if (strncmp(qval, "q=", MIN(istend(ctx.value) - qval, 2)) == 0)
					break;

				while (qval < istend(ctx.value) && *qval != ';')
					qval++;
			}

			/* here we have qval pointing to the first "q=" attribute or NULL if not found */
			q = qval ? http_parse_qvalue(qval + 2, NULL) : 1000;

			if (q <= best_q)
				continue;

			for (comp_algo = comp_algo_back; comp_algo; comp_algo = comp_algo->next) {
				if (*(ctx.value.ptr) == '*' ||
				    word_match(ctx.value.ptr, toklen, comp_algo->ua_name, comp_algo->ua_name_len)) {
					st->comp_algo[COMP_DIR_RES] = comp_algo;
					best_q = q;
					break;
				}
			}
		}
	}

	/* remove all occurrences of the header when "compression offload" is set */
	if (st->comp_algo[COMP_DIR_RES]) {
		if ((s->be->comp && (s->be->comp->flags & COMP_FL_OFFLOAD)) ||
		    (strm_fe(s)->comp && (strm_fe(s)->comp->flags & COMP_FL_OFFLOAD))) {
			http_remove_header(htx, &ctx);
			ctx.blk = NULL;
			while (http_find_header(htx, ist("Accept-Encoding"), &ctx, 1))
				http_remove_header(htx, &ctx);
		}
		return 1;
	}

	/* identity is implicit does not require headers */
	if ((s->be->comp && (comp_algo_back = s->be->comp->algos_res)) ||
	    (strm_fe(s)->comp && (comp_algo_back = strm_fe(s)->comp->algos_res))) {
		for (comp_algo = comp_algo_back; comp_algo; comp_algo = comp_algo->next) {
			if (comp_algo->cfg_name_len == 8 && memcmp(comp_algo->cfg_name, "identity", 8) == 0) {
				st->comp_algo[COMP_DIR_RES] = comp_algo;
				return 1;
			}
		}
	}

	st->comp_algo[COMP_DIR_RES] = NULL;
	return 0;
}

/*
 * Selects a compression algorithm depending of the server response.
 */
static int
select_compression_response_header(struct comp_state *st, struct stream *s, struct http_msg *msg)
{
	struct htx *htx = htxbuf(&msg->chn->buf);
	struct http_txn *txn = s->txn;
	struct http_hdr_ctx ctx;
	struct comp_type *comp_type;

	/* no common compression algorithm was found in request header */
	if (st->comp_algo[COMP_DIR_RES] == NULL)
		goto fail;

	/* compression already in progress */
	if (msg->flags & HTTP_MSGF_COMPRESSING)
		goto fail;

	/* HTTP < 1.1 should not be compressed */
	if (!(msg->flags & HTTP_MSGF_VER_11) || !(txn->req.flags & HTTP_MSGF_VER_11))
		goto fail;

	if (txn->meth == HTTP_METH_HEAD)
		goto fail;

	/* compress 200,201,202,203 responses only */
	if ((txn->status != 200) &&
	    (txn->status != 201) &&
	    (txn->status != 202) &&
	    (txn->status != 203))
		goto fail;

	if (!(msg->flags & HTTP_MSGF_XFER_LEN) || msg->flags & HTTP_MSGF_BODYLESS)
		goto fail;

	/* content is already compressed */
	ctx.blk = NULL;
	if (http_find_header(htx, ist("Content-Encoding"), &ctx, 1))
		goto fail;

	/* no compression when Cache-Control: no-transform is present in the message */
	ctx.blk = NULL;
	while (http_find_header(htx, ist("Cache-Control"), &ctx, 0)) {
		if (word_match(ctx.value.ptr, ctx.value.len, "no-transform", 12))
			goto fail;
	}

	/* no compression when ETag is malformed */
	ctx.blk = NULL;
	if (http_find_header(htx, ist("ETag"), &ctx, 1)) {
		if (http_get_etag_type(ctx.value) == ETAG_INVALID)
			goto fail;
	}
	/* no compression when multiple ETags are present
	 * Note: Do not reset ctx.blk!
	 */
	if (http_find_header(htx, ist("ETag"), &ctx, 1))
		goto fail;

	comp_type = NULL;

	/* we don't want to compress multipart content-types, nor content-types that are
	 * not listed in the "compression type" directive if any. If no content-type was
	 * found but configuration requires one, we don't compress either. Backend has
	 * the priority.
	 */
	ctx.blk = NULL;
	if (http_find_header(htx, ist("Content-Type"), &ctx, 1)) {
		if (ctx.value.len >= 9 && strncasecmp("multipart", ctx.value.ptr, 9) == 0)
			goto fail;

		if ((s->be->comp && (comp_type = s->be->comp->types_res)) ||
		    (strm_fe(s)->comp && (comp_type = strm_fe(s)->comp->types_res))) {
			for (; comp_type; comp_type = comp_type->next) {
				if (ctx.value.len >= comp_type->name_len &&
				    strncasecmp(ctx.value.ptr, comp_type->name, comp_type->name_len) == 0)
					/* this Content-Type should be compressed */
					break;
			}
			/* this Content-Type should not be compressed */
			if (comp_type == NULL)
				goto fail;
		}
	}
	else { /* no content-type header */
		if ((s->be->comp && s->be->comp->types_res) ||
		    (strm_fe(s)->comp && strm_fe(s)->comp->types_res))
			goto fail; /* a content-type was required */
	}

	/* limit compression rate */
	if (global.comp_rate_lim > 0)
		if (read_freq_ctr(&global.comp_bps_in) > global.comp_rate_lim)
			goto fail;

	/* limit cpu usage */
	if (th_ctx->idle_pct < compress_min_idle)
		goto fail;

	/* initialize compression */
	if (st->comp_algo[COMP_DIR_RES]->init(&st->comp_ctx[COMP_DIR_RES], global.tune.comp_maxlevel) < 0)
		goto fail;
	msg->flags |= HTTP_MSGF_COMPRESSING;
	return 1;

  fail:
	st->comp_algo[COMP_DIR_RES] = NULL;
	return 0;
}

/***********************************************************************/
static int
htx_compression_buffer_init(struct htx *htx, struct buffer *out)
{
	/* output stream requires at least 10 bytes for the gzip header, plus
	 * at least 8 bytes for the gzip trailer (crc+len), plus a possible
	 * plus at most 5 bytes per 32kB block and 2 bytes to close the stream.
	 */
	if (htx_free_space(htx) < 20 + 5 * ((htx->data + 32767) >> 15))
		return -1;
	b_reset(out);
	return 0;
}

static int
htx_compression_buffer_add_data(struct comp_state *st, const char *data, size_t len,
				struct buffer *out, int dir)
{

	return st->comp_algo[dir]->add_data(st->comp_ctx[dir], data, len, out);
}

static int
htx_compression_buffer_end(struct comp_state *st, struct buffer *out, int end, int dir)
{

	if (end)
		return st->comp_algo[dir]->finish(st->comp_ctx[dir], out);
	else
		return st->comp_algo[dir]->flush(st->comp_ctx[dir], out);
}


/***********************************************************************/
struct flt_ops comp_ops = {
	.init              = comp_flt_init,
	.init_per_thread   = comp_flt_init_per_thread,
	.deinit_per_thread = comp_flt_deinit_per_thread,

	.attach = comp_strm_init,
	.detach = comp_strm_deinit,

	.channel_post_analyze  = comp_http_post_analyze,

	.http_headers          = comp_http_headers,
	.http_payload          = comp_http_payload,
	.http_end              = comp_http_end,
};

static int
parse_compression_options(char **args, int section, struct proxy *proxy,
			  const struct proxy *defpx, const char *file, int line,
			  char **err)
{
	struct comp    *comp;
	int ret = 0;

	if (proxy->comp == NULL) {
		comp = calloc(1, sizeof(*comp));
		/* Always default to compress responses */
		comp->flags = COMP_FL_DIR_RES;
		proxy->comp = comp;
	}
	else
		comp = proxy->comp;

	if (strcmp(args[1], "algo") == 0 || strcmp(args[1], "algo-res") == 0) {
		struct comp_ctx *ctx;
		int              cur_arg = 2;

		if (!*args[cur_arg]) {
			memprintf(err, "parsing [%s:%d] : '%s' expects <algorithm>.",
				  file, line, args[0]);
			ret = -1;
			goto end;
		}
		while (*(args[cur_arg])) {
			int retval = comp_append_algo(&comp->algos_res, args[cur_arg]);
			if (retval) {
				if (retval < 0)
					memprintf(err, "'%s' : '%s' is not a supported algorithm.",
						  args[0], args[cur_arg]);
				else
					memprintf(err, "'%s' : out of memory while parsing algo '%s'.",
						  args[0], args[cur_arg]);
				ret = -1;
				goto end;
			}

			if (proxy->comp->algos_res->init(&ctx, 9) == 0)
				proxy->comp->algos_res->end(&ctx);
			else {
				memprintf(err, "'%s' : Can't init '%s' algorithm.",
					  args[0], args[cur_arg]);
				ret = -1;
				goto end;
			}
			cur_arg++;
			continue;
		}
	}
	else if (strcmp(args[1], "algo-req") == 0) {
		struct comp_ctx *ctx;
		int retval = comp_append_algo(&comp->algo_req, args[2]);

		if (retval) {
			if (retval < 0)
				memprintf(err, "'%s' : '%s' is not a supported algorithm.",
				    args[0], args[2]);
			else
				memprintf(err, "'%s' : out of memory while parsing algo '%s'.",
				    args[0], args[2]);
			ret = -1;
			goto end;
		}

		if (proxy->comp->algo_req->init(&ctx, 9) == 0)
			proxy->comp->algo_req->end(&ctx);
		else {
			memprintf(err, "'%s' : Can't init '%s' algorithm.",
			    args[0], args[2]);
			ret = -1;
			goto end;
		}
	}
	else if (strcmp(args[1], "offload") == 0) {
		if (proxy->cap & PR_CAP_DEF) {
			memprintf(err, "'%s' : '%s' ignored in 'defaults' section.",
				  args[0], args[1]);
			ret = 1;
		}
		comp->flags |= COMP_FL_OFFLOAD;
	}
	else if (strcmp(args[1], "type") == 0 || strcmp(args[1], "type-res") == 0) {
		int cur_arg = 2;

		if (!*args[cur_arg]) {
			memprintf(err, "'%s' expects <type>.", args[0]);
			ret = -1;
			goto end;
		}
		while (*(args[cur_arg])) {
			if (comp_append_type(&comp->types_res, args[cur_arg])) {
				memprintf(err, "'%s': out of memory.", args[0]);
				ret = -1;
				goto end;
			}
			cur_arg++;
			continue;
		}
	}
	else if (strcmp(args[1], "type-req") == 0) {
		int cur_arg = 2;

		if (!*args[cur_arg]) {
			memprintf(err, "'%s' expects <type>.", args[0]);
			ret = -1;
			goto end;
		}
		while (*(args[cur_arg])) {
			if (comp_append_type(&comp->types_req, args[cur_arg])) {
				memprintf(err, "'%s': out of memory.", args[0]);
				ret = -1;
				goto end;
			}
			cur_arg++;
			continue;
		}
	}
	else if (strcmp(args[1], "direction") == 0) {
		if (!args[2]) {
			memprintf(err, "'%s' expects 'request', 'response', or 'both'.", args[0]);
			ret = -1;
			goto end;
		}
		if (strcmp(args[2], "request") == 0) {
			comp->flags &= ~COMP_FL_DIR_RES;
			comp->flags |= COMP_FL_DIR_REQ;
		} else if (strcmp(args[2], "response") == 0) {
			comp->flags &= COMP_FL_DIR_REQ;
			comp->flags |= COMP_FL_DIR_RES;
		} else if (strcmp(args[2], "both") == 0)
			comp->flags |= COMP_FL_DIR_REQ | COMP_FL_DIR_RES;
		else {
			memprintf(err, "'%s' expects 'request', 'response', or 'both'.", args[0]);
			ret = -1;
			goto end;
		}
	}
	else {
		memprintf(err, "'%s' expects 'algo', 'type' 'direction' or 'offload'",
			  args[0]);
		ret = -1;
		goto end;
	}

  end:
	return ret;
}

static int
parse_http_comp_flt(char **args, int *cur_arg, struct proxy *px,
                    struct flt_conf *fconf, char **err, void *private)
{
	struct flt_conf *fc, *back;

	list_for_each_entry_safe(fc, back, &px->filter_configs, list) {
		if (fc->id == http_comp_flt_id) {
			memprintf(err, "%s: Proxy supports only one compression filter\n", px->id);
			return -1;
		}
	}

	fconf->id   = http_comp_flt_id;
	fconf->conf = NULL;
	fconf->ops  = &comp_ops;
	(*cur_arg)++;

	return 0;
}


int
check_implicit_http_comp_flt(struct proxy *proxy)
{
	struct flt_conf *fconf;
	int explicit = 0;
	int comp = 0;
	int err = 0;

	if (proxy->comp == NULL)
		goto end;
	if (!LIST_ISEMPTY(&proxy->filter_configs)) {
		list_for_each_entry(fconf, &proxy->filter_configs, list) {
			if (fconf->id == http_comp_flt_id)
				comp = 1;
			else if (fconf->id == cache_store_flt_id) {
				if (comp) {
					ha_alert("config: %s '%s': unable to enable the compression filter "
						 "before any cache filter.\n",
						 proxy_type_str(proxy), proxy->id);
					err++;
					goto end;
				}
			}
			else if (fconf->id == fcgi_flt_id)
				continue;
			else
				explicit = 1;
		}
	}
	if (comp)
		goto end;
	else if (explicit) {
		ha_alert("config: %s '%s': require an explicit filter declaration to use "
			 "HTTP compression\n", proxy_type_str(proxy), proxy->id);
		err++;
		goto end;
	}

	/* Implicit declaration of the compression filter is always the last
	 * one */
	fconf = calloc(1, sizeof(*fconf));
	if (!fconf) {
		ha_alert("config: %s '%s': out of memory\n",
			 proxy_type_str(proxy), proxy->id);
		err++;
		goto end;
	}
	fconf->id   = http_comp_flt_id;
	fconf->conf = NULL;
	fconf->ops  = &comp_ops;
	LIST_APPEND(&proxy->filter_configs, &fconf->list);
 end:
	return err;
}

/*
 * boolean, returns true if compression is used (either gzip or deflate) in the
 * response.
 */
static int
smp_fetch_res_comp(const struct arg *args, struct sample *smp, const char *kw,
		   void *private)
{
	struct http_txn *txn = smp->strm ? smp->strm->txn : NULL;

	smp->data.type = SMP_T_BOOL;
	smp->data.u.sint = (txn && (txn->rsp.flags & HTTP_MSGF_COMPRESSING));
	return 1;
}

/*
 * string, returns algo
 */
static int
smp_fetch_res_comp_algo(const struct arg *args, struct sample *smp,
			const char *kw, void *private)
{
	struct http_txn   *txn = smp->strm ? smp->strm->txn : NULL;
	struct filter     *filter;
	struct comp_state *st;

	if (!txn || !(txn->rsp.flags & HTTP_MSGF_COMPRESSING))
		return 0;

	list_for_each_entry(filter, &strm_flt(smp->strm)->filters, list) {
		if (FLT_ID(filter) != http_comp_flt_id)
			continue;

		if (!(st = filter->ctx))
			break;

		smp->data.type = SMP_T_STR;
		smp->flags = SMP_F_CONST;
		smp->data.u.str.area = st->comp_algo[COMP_DIR_RES]->cfg_name;
		smp->data.u.str.data = st->comp_algo[COMP_DIR_RES]->cfg_name_len;
		return 1;
	}
	return 0;
}

/* Declare the config parser for "compression" keyword */
static struct cfg_kw_list cfg_kws = {ILH, {
		{ CFG_LISTEN, "compression", parse_compression_options },
		{ 0, NULL, NULL },
	}
};

INITCALL1(STG_REGISTER, cfg_register_keywords, &cfg_kws);

/* Declare the filter parser for "compression" keyword */
static struct flt_kw_list filter_kws = { "COMP", { }, {
		{ "compression", parse_http_comp_flt, NULL },
		{ NULL, NULL, NULL },
	}
};

INITCALL1(STG_REGISTER, flt_register_keywords, &filter_kws);

/* Note: must not be declared <const> as its list will be overwritten */
static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
		{ "res.comp",      smp_fetch_res_comp,      0, NULL, SMP_T_BOOL, SMP_USE_HRSHP },
		{ "res.comp_algo", smp_fetch_res_comp_algo, 0, NULL, SMP_T_STR, SMP_USE_HRSHP },
		{ /* END */ },
	}
};

INITCALL1(STG_REGISTER, sample_register_fetches, &sample_fetch_keywords);
