
/*
 * Copyright (C) Igor Sysoev
 * Copyright (C) Nginx, Inc.
 * Copyright (C) Google Inc.
 */


#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>

#if (NGX_BAZEL)
#include <brotli/encode.h>
#else
#include <brotli/enc/encode.h>
#endif


typedef struct {
    ngx_flag_t            enable;

    ngx_hash_t            types;

    ngx_bufs_t            bufs;

    ngx_int_t             quality;
    size_t                win_bits;
    ssize_t               min_length;

    ngx_array_t          *types_keys;
} ngx_http_brotli_conf_t;


typedef struct {
    BrotliEncoderState   *encoder;

    size_t                brotli_ring;
    size_t                brotli_in;
    u_char               *brotli_out;
    u_char               *brotli_last;

    off_t                 content_length;

    size_t                bytes_in;
    size_t                bytes_out;

    ngx_chain_t          *in;
    ngx_chain_t          *free;
    ngx_chain_t          *busy;
    ngx_chain_t          *out;
    ngx_chain_t         **last_out;

    ngx_buf_t            *out_buf;
    ngx_int_t             bufs;

    unsigned              done:1;
    unsigned              sent:1;
    unsigned              last:1;
    unsigned              flush:1;
    unsigned              nomem:1;
} ngx_http_brotli_ctx_t;


static BrotliEncoderState *ngx_http_brotli_filter_create_encoder(
    ngx_http_request_t *r);
static ngx_int_t ngx_http_brotli_filter_add_data(ngx_http_request_t *r,
    ngx_http_brotli_ctx_t *ctx);
static ngx_int_t ngx_http_brotli_filter_process(ngx_http_request_t *r,
    ngx_http_brotli_ctx_t *ctx);
static ngx_int_t ngx_http_brotli_filter_output(ngx_http_request_t *r,
    ngx_http_brotli_ctx_t *ctx);
static ngx_int_t ngx_http_brotli_filter_get_buf(ngx_http_request_t *r,
    ngx_http_brotli_ctx_t *ctx);
static void *ngx_http_brotli_filter_alloc(void *opaque, size_t size);
static void ngx_http_brotli_filter_free(void *opaque, void *address);
static void ngx_http_brotli_filter_cleanup(void *data);

static ngx_int_t ngx_http_brotli_ok(ngx_http_request_t *r);
static ngx_int_t ngx_http_brotli_accept_encoding(ngx_str_t *ae);

static ngx_int_t ngx_http_brotli_add_variables(ngx_conf_t *cf);
static ngx_int_t ngx_http_brotli_ratio_variable(ngx_http_request_t *r,
    ngx_http_variable_value_t *v, uintptr_t data);

static void *ngx_http_brotli_create_conf(ngx_conf_t *cf);
static char *ngx_http_brotli_merge_conf(ngx_conf_t *cf,
    void *parent, void *child);
static ngx_int_t ngx_http_brotli_filter_init(ngx_conf_t *cf);

static char *ngx_http_brotli_window(ngx_conf_t *cf, void *post, void *data);


static ngx_conf_num_bounds_t  ngx_http_brotli_comp_level_bounds = {
    ngx_conf_check_num_bounds, 0, 11
};

static ngx_conf_post_handler_pt  ngx_http_brotli_window_p =
    ngx_http_brotli_window;


static ngx_command_t  ngx_http_brotli_filter_commands[] = {

    { ngx_string("brotli"),
      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
                        |NGX_CONF_FLAG,
      ngx_conf_set_flag_slot,
      NGX_HTTP_LOC_CONF_OFFSET,
      offsetof(ngx_http_brotli_conf_t, enable),
      NULL },

    { ngx_string("brotli_buffers"),
      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
      ngx_conf_set_bufs_slot,
      NGX_HTTP_LOC_CONF_OFFSET,
      offsetof(ngx_http_brotli_conf_t, bufs),
      NULL },

    { ngx_string("brotli_types"),
      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
      ngx_http_types_slot,
      NGX_HTTP_LOC_CONF_OFFSET,
      offsetof(ngx_http_brotli_conf_t, types_keys),
      &ngx_http_html_default_types[0] },

    { ngx_string("brotli_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_brotli_conf_t, quality),
      &ngx_http_brotli_comp_level_bounds },

    { ngx_string("brotli_window"),
      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
      ngx_conf_set_size_slot,
      NGX_HTTP_LOC_CONF_OFFSET,
      offsetof(ngx_http_brotli_conf_t, win_bits),
      &ngx_http_brotli_window_p },

    { ngx_string("brotli_min_length"),
      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
      ngx_conf_set_size_slot,
      NGX_HTTP_LOC_CONF_OFFSET,
      offsetof(ngx_http_brotli_conf_t, min_length),
      NULL },

      ngx_null_command
};


static ngx_http_module_t  ngx_http_brotli_filter_module_ctx = {
    ngx_http_brotli_add_variables,         /* preconfiguration */
    ngx_http_brotli_filter_init,           /* postconfiguration */

    NULL,                                  /* create main configuration */
    NULL,                                  /* init main configuration */

    NULL,                                  /* create server configuration */
    NULL,                                  /* merge server configuration */

    ngx_http_brotli_create_conf,           /* create location configuration */
    ngx_http_brotli_merge_conf             /* merge location configuration */
};


ngx_module_t  ngx_http_brotli_filter_module = {
    NGX_MODULE_V1,
    &ngx_http_brotli_filter_module_ctx,    /* module context */
    ngx_http_brotli_filter_commands,       /* module directives */
    NGX_HTTP_MODULE,                       /* module type */
    NULL,                                  /* init master */
    NULL,                                  /* init module */
    NULL,                                  /* init process */
    NULL,                                  /* init thread */
    NULL,                                  /* exit thread */
    NULL,                                  /* exit process */
    NULL,                                  /* exit master */
    NGX_MODULE_V1_PADDING
};


static ngx_str_t  ngx_http_brotli_ratio = ngx_string("brotli_ratio");

static ngx_http_output_header_filter_pt  ngx_http_next_header_filter;
static ngx_http_output_body_filter_pt    ngx_http_next_body_filter;


static ngx_int_t
ngx_http_brotli_header_filter(ngx_http_request_t *r)
{
    ngx_table_elt_t         *h;
    ngx_http_brotli_ctx_t   *ctx;
    ngx_http_brotli_conf_t  *conf;

    conf = ngx_http_get_module_loc_conf(r, ngx_http_brotli_filter_module);

    if (!conf->enable
        || (r->headers_out.status != NGX_HTTP_OK
            && r->headers_out.status != NGX_HTTP_FORBIDDEN
            && r->headers_out.status != NGX_HTTP_NOT_FOUND)
        || (r->headers_out.content_encoding
            && r->headers_out.content_encoding->value.len)
        || (r->headers_out.content_length_n != -1
            && r->headers_out.content_length_n < conf->min_length)
        || ngx_http_test_content_type(r, &conf->types) == NULL
        || r->header_only)
    {
        return ngx_http_next_header_filter(r);
    }

    r->gzip_vary = 1;

    if (ngx_http_brotli_ok(r) != NGX_OK) {
        return ngx_http_next_header_filter(r);
    }

    ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_brotli_ctx_t));
    if (ctx == NULL) {
        return NGX_ERROR;
    }

    ctx->last_out = &ctx->out;

    ctx->content_length = r->headers_out.content_length_n;

    ngx_http_set_ctx(r, ctx, ngx_http_brotli_filter_module);

    h = ngx_list_push(&r->headers_out.headers);
    if (h == NULL) {
        return NGX_ERROR;
    }

    h->hash = 1;
    ngx_str_set(&h->key, "Content-Encoding");
    ngx_str_set(&h->value, "br");
    r->headers_out.content_encoding = h;

    r->main_filter_need_in_memory = 1;

    ngx_http_clear_content_length(r);
    ngx_http_clear_accept_ranges(r);
    ngx_http_weak_etag(r);

    return ngx_http_next_header_filter(r);
}


static ngx_int_t
ngx_http_brotli_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
{
    int                     rc;
    ngx_uint_t              flush;
    ngx_chain_t            *cl;
    ngx_pool_cleanup_t     *cln;
    ngx_http_brotli_ctx_t  *ctx;

    ctx = ngx_http_get_module_ctx(r, ngx_http_brotli_filter_module);

    if (ctx == NULL || ctx->done || r->header_only) {
        return ngx_http_next_body_filter(r, in);
    }

    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "http brotli filter");

    if (ctx->encoder == NULL) {
        ctx->encoder = ngx_http_brotli_filter_create_encoder(r);
        if (ctx->encoder == NULL) {
            goto failed;
        }

        ctx->brotli_ring = BrotliEncoderInputBlockSize(ctx->encoder);

        cln = ngx_pool_cleanup_add(r->pool, 0);
        if (cln == NULL) {
            goto failed;
        }

        cln->handler = ngx_http_brotli_filter_cleanup;
        cln->data = ctx;
    }

    if (in) {
        if (ngx_chain_add_copy(r->pool, &ctx->in, in) != NGX_OK) {
            goto failed;
        }

        r->connection->buffered |= NGX_HTTP_GZIP_BUFFERED;
    }

    if (ctx->nomem) {

        /* flush busy buffers */

        if (ngx_http_next_body_filter(r, NULL) == NGX_ERROR) {
            goto failed;
        }

        cl = NULL;

        ngx_chain_update_chains(r->pool, &ctx->free, &ctx->busy, &cl,
                                (ngx_buf_tag_t) &ngx_http_brotli_filter_module);
        ctx->nomem = 0;
        flush = 0;

    } else {
        flush = ctx->busy ? 1 : 0;
    }

    for ( ;; ) {

        /* cycle while we can write to a client */

        for ( ;; ) {

            rc = ngx_http_brotli_filter_add_data(r, ctx);

            if (rc == NGX_DECLINED) {
                break;
            }

            if (rc == NGX_AGAIN) {
                continue;
            }

            rc = ngx_http_brotli_filter_process(r, ctx);

            if (rc == NGX_AGAIN) {
                continue;
            }

            if (rc == NGX_ERROR) {
                goto failed;
            }

            rc = ngx_http_brotli_filter_output(r, ctx);

            if (rc == NGX_OK) {
                break;
            }

            if (rc == NGX_ERROR) {
                goto failed;
            }

            /* rc == NGX_AGAIN */
        }

        if (ctx->out == NULL && !flush) {
            return ctx->busy ? NGX_AGAIN : NGX_OK;
        }

        rc = ngx_http_next_body_filter(r, ctx->out);

        if (rc == NGX_ERROR) {
            goto failed;
        }

        ngx_chain_update_chains(r->pool, &ctx->free, &ctx->busy, &ctx->out,
                                (ngx_buf_tag_t) &ngx_http_brotli_filter_module);
        ctx->last_out = &ctx->out;

        ctx->nomem = 0;
        flush = 0;

        if (ctx->done) {
            ctx->sent = 1;

            if (ctx->encoder) {
                BrotliEncoderDestroyInstance(ctx->encoder);
                ctx->encoder = NULL;
            }

            return rc;
        }
    }

    /* unreachable */

failed:

    ctx->done = 1;

    if (ctx->encoder) {
        BrotliEncoderDestroyInstance(ctx->encoder);
        ctx->encoder = NULL;
    }

    return NGX_ERROR;
}


static BrotliEncoderState *
ngx_http_brotli_filter_create_encoder(ngx_http_request_t *r)
{
    int                      wbits;
    BrotliEncoderState      *encoder;
    ngx_http_brotli_ctx_t   *ctx;
    ngx_http_brotli_conf_t  *conf;

    encoder = BrotliEncoderCreateInstance(ngx_http_brotli_filter_alloc,
                                          ngx_http_brotli_filter_free,
                                          r->pool);
    if (encoder == NULL) {
        ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
                      "BrotliEncoderCreateInstance() failed");
        return NULL;
    }

    conf = ngx_http_get_module_loc_conf(r, ngx_http_brotli_filter_module);

    if (!BrotliEncoderSetParameter(encoder, BROTLI_PARAM_QUALITY,
                                   (uint32_t) conf->quality))
    {
        ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
                      "BrotliEncoderSetParameter(QUALITY, %uD) failed",
                      (uint32_t) conf->quality);
        goto failed;
    }

    ctx = ngx_http_get_module_ctx(r, ngx_http_brotli_filter_module);

    wbits = conf->win_bits;

    if (ctx->content_length > 0) {
        while (ctx->content_length < (1 << (wbits - 1))
               && wbits > kBrotliMinWindowBits)
        {
            wbits--;
        }
    }

    if (!BrotliEncoderSetParameter(encoder, BROTLI_PARAM_LGWIN,
                                   (uint32_t) wbits)) {
        ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
                      "BrotliEncoderSetParameter(LGWIN, %uD) failed",
                      (uint32_t) wbits);
        goto failed;
    }

    ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "brotli encoder: lvl:%i win:%d blk:%uz",
                   conf->quality, (1 << wbits),
                   BrotliEncoderInputBlockSize(encoder));

    return encoder;

failed:

    BrotliEncoderDestroyInstance(encoder);

    return NULL;
}


static ngx_int_t
ngx_http_brotli_filter_add_data(ngx_http_request_t *r,
    ngx_http_brotli_ctx_t *ctx)
{
    size_t      size, ring;
    ngx_buf_t  *b;

    if (ctx->brotli_out || ctx->last || ctx->flush) {
        return NGX_OK;
    }

    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "brotli in: %p", ctx->in);

    if (ctx->in == NULL) {
        return NGX_DECLINED;
    }

    b = ctx->in->buf;

    size = ngx_buf_size(b);
    ring = ctx->brotli_ring - ctx->brotli_in;

    if (size > ring) {
        size = ring;

    } else {
        if (b->last_buf) {
            ctx->last = 1;

        } else if (b->flush) {
            ctx->flush = 1;
        }
    }

    if (size == ring) {
        ctx->flush = 1;
    }

    if (size > 0) {
        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "brotli copy: %p, size:%uz", b, size);

        BrotliEncoderCopyInputToRingBuffer(ctx->encoder, size, b->pos);

        ctx->brotli_in += size;
        ctx->bytes_in += size;
        b->pos += size;
    }

    if (ngx_buf_size(b) == 0) {
        ctx->in = ctx->in->next;
        size = 0;
    }

    if (size == 0 && !ctx->flush && !ctx->last) {
        return NGX_AGAIN;
    }

    return NGX_OK;
}


static ngx_int_t
ngx_http_brotli_filter_process(ngx_http_request_t *r,
    ngx_http_brotli_ctx_t *ctx)
{
    size_t   size;
    u_char  *out;

    if (ctx->brotli_out) {
        return NGX_OK;
    }

    ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "brotli process: size:%uz l:%d f:%d",
                   ctx->brotli_in, ctx->last, ctx->flush);

    out = NULL;

    if (!BrotliEncoderWriteData(ctx->encoder, ctx->last, ctx->flush, &size,
                                &out))
    {
        ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
                      "brotli failed: size:%uz l:%d f:%d",
                      ctx->brotli_in, ctx->last, ctx->flush);
        return NGX_ERROR;
    }

    ctx->brotli_in = 0;

    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "brotli encoded: %p, size:%uz", out, size);

    if (size == 0 && !ctx->flush && !ctx->last) {
        return NGX_AGAIN;
    }

    ctx->brotli_out = out;
    ctx->brotli_last = out + size;
    ctx->bytes_out += size;

    return NGX_OK;
}


static ngx_int_t
ngx_http_brotli_filter_output(ngx_http_request_t *r, ngx_http_brotli_ctx_t *ctx)
{
    int           rc;
    size_t        size;
    ngx_chain_t  *cl;

    cl = NULL;

    while (ctx->brotli_out < ctx->brotli_last) {

        rc = ngx_http_brotli_filter_get_buf(r, ctx);

        if (rc == NGX_DECLINED) {
            return NGX_OK;
        }

        if (rc == NGX_ERROR) {
            return NGX_ERROR;
        }

        size = ngx_min(ctx->out_buf->end - ctx->out_buf->last,
                       ctx->brotli_last - ctx->brotli_out);

        ngx_memcpy(ctx->out_buf->last, ctx->brotli_out, size);

        ctx->out_buf->last += size;
        ctx->brotli_out += size;

        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "brotli out: %p, size:%uz",
                       ctx->out_buf, ngx_buf_size(ctx->out_buf));

        cl = ngx_alloc_chain_link(r->pool);
        if (cl == NULL) {
            return NGX_ERROR;
        }

        cl->buf = ctx->out_buf;
        cl->next = NULL;
        *ctx->last_out = cl;
        ctx->last_out = &cl->next;
    }

    ctx->brotli_out = NULL;
    ctx->brotli_last = NULL;

    if (ctx->last || ctx->flush) {

        if (cl == NULL) {
            cl = ngx_alloc_chain_link(r->pool);
            if (cl == NULL) {
                return NGX_ERROR;
            }

            cl->buf = ngx_calloc_buf(r->pool);
            if (cl->buf == NULL) {
                return NGX_ERROR;
            }

            cl->next = NULL;
            *ctx->last_out = cl;
            ctx->last_out = &cl->next;
        }

        if (ctx->last) {
            ctx->done = 1;
            cl->buf->last_buf = 1;

        } else if (ctx->flush) {
            ctx->flush = 0;
            cl->buf->flush = 1;
        }

        r->connection->buffered &= ~NGX_HTTP_GZIP_BUFFERED;

        return NGX_OK;
    }

    return NGX_AGAIN;
}


static ngx_int_t
ngx_http_brotli_filter_get_buf(ngx_http_request_t *r,
    ngx_http_brotli_ctx_t *ctx)
{
    ngx_http_brotli_conf_t  *conf;

    if (ctx->free) {
        ctx->out_buf = ctx->free->buf;
        ctx->free = ctx->free->next;
        return NGX_OK;
    }

    conf = ngx_http_get_module_loc_conf(r, ngx_http_brotli_filter_module);

    if (ctx->bufs < conf->bufs.num) {
        ctx->out_buf = ngx_create_temp_buf(r->pool, conf->bufs.size);
        if (ctx->out_buf == NULL) {
            return NGX_ERROR;
        }

        ctx->out_buf->tag = (ngx_buf_tag_t) &ngx_http_brotli_filter_module;
        ctx->out_buf->recycled = 1;
        ctx->bufs++;

    } else {
        ctx->nomem = 1;
        return NGX_DECLINED;
    }

    return NGX_OK;
}


static void *
ngx_http_brotli_filter_alloc(void *opaque, size_t size)
{
    ngx_pool_t  *pool = opaque;
    void        *p;

    p = ngx_palloc(pool, size);

    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pool->log, 0,
                   "brotli alloc: %p, size:%uz", p, size);

    return p;
}


static void
ngx_http_brotli_filter_free(void *opaque, void *address)
{
#if (NGX_DEBUG)
    ngx_pool_t  *pool = opaque;

    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pool->log, 0,
                   "brotli free: %p", address);
#endif
}


static void
ngx_http_brotli_filter_cleanup(void *data)
{
    ngx_http_brotli_ctx_t  *ctx = data;

    if (ctx->encoder) {
        BrotliEncoderDestroyInstance(ctx->encoder);
        ctx->encoder = NULL;
    }
}


static ngx_int_t
ngx_http_brotli_ok(ngx_http_request_t *r)
{
    ngx_table_elt_t  *ae;

    if (r != r->main) {
        return NGX_DECLINED;
    }

    ae = r->headers_in.accept_encoding;
    if (ae == NULL) {
        return NGX_DECLINED;
    }

    if (ae->value.len < sizeof("br") - 1) {
        return NGX_DECLINED;
    }

    if (ngx_memcmp(ae->value.data, "br,", sizeof("br,") - 1) != 0
        && ngx_http_brotli_accept_encoding(&ae->value) != NGX_OK)
    {
        return NGX_DECLINED;
    }

    r->gzip_tested = 1;
    r->gzip_ok = 0;

    return NGX_OK;
}


static ngx_int_t
ngx_http_brotli_accept_encoding(ngx_str_t *ae)
{
    u_char  *p;

    p = ngx_strcasestrn(ae->data, "br", sizeof("br") - 2);
    if (p == NULL) {
        return NGX_DECLINED;
    }

    if (p == ae->data || (*(p - 1) == ',' || *(p - 1) == ' ')) {

        p += sizeof("br") - 1;

        if (p == ae->data + ae->len || *p == ',' || *p == ';' || *p == ' ') {
            return NGX_OK;
        }
    }

    return NGX_DECLINED;
}


static ngx_int_t
ngx_http_brotli_add_variables(ngx_conf_t *cf)
{
    ngx_http_variable_t  *var;

    var = ngx_http_add_variable(cf, &ngx_http_brotli_ratio, 0);
    if (var == NULL) {
        return NGX_ERROR;
    }

    var->get_handler = ngx_http_brotli_ratio_variable;

    return NGX_OK;
}


static ngx_int_t
ngx_http_brotli_ratio_variable(ngx_http_request_t *r,
    ngx_http_variable_value_t *v, uintptr_t data)
{
    ngx_uint_t              ratio_int, ratio_frac;
    ngx_http_brotli_ctx_t  *ctx;

    v->valid = 1;
    v->no_cacheable = 0;
    v->not_found = 0;

    ctx = ngx_http_get_module_ctx(r, ngx_http_brotli_filter_module);

    if (ctx == NULL || ctx->bytes_out == 0 || !ctx->sent) {
        v->not_found = 1;
        return NGX_OK;
    }

    v->data = ngx_pnalloc(r->pool, NGX_INT32_LEN + 3);
    if (v->data == NULL) {
        return NGX_ERROR;
    }

    ratio_int = (ngx_uint_t) (ctx->bytes_in / ctx->bytes_out);
    ratio_frac = (ngx_uint_t) ((ctx->bytes_in * 100 / ctx->bytes_out) % 100);

    if ((ctx->bytes_in * 1000 / ctx->bytes_out) % 10 > 4) {

        /* the rounding, e.g., 2.125 to 2.13 */

        ratio_frac++;

        if (ratio_frac > 99) {
            ratio_int++;
            ratio_frac = 0;
        }
    }

    v->len = ngx_sprintf(v->data, "%ui.%02ui", ratio_int, ratio_frac) - v->data;

    return NGX_OK;
}


static void *
ngx_http_brotli_create_conf(ngx_conf_t *cf)
{
    ngx_http_brotli_conf_t  *conf;

    conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_brotli_conf_t));
    if (conf == NULL) {
        return NULL;
    }

    /*
     * set by ngx_pcalloc():
     *
     *     conf->bufs.num = 0;
     *     conf->types = { NULL };
     *     conf->types_keys = NULL;
     */

    conf->enable = NGX_CONF_UNSET;

    conf->quality = NGX_CONF_UNSET;
    conf->win_bits = NGX_CONF_UNSET_SIZE;
    conf->min_length = NGX_CONF_UNSET;

    return conf;
}


static char *
ngx_http_brotli_merge_conf(ngx_conf_t *cf, void *parent, void *child)
{
    ngx_http_brotli_conf_t  *prev = parent;
    ngx_http_brotli_conf_t  *conf = child;

    ngx_conf_merge_value(conf->enable, prev->enable, 0);

    ngx_conf_merge_bufs_value(conf->bufs, prev->bufs,
                              (128 * 1024) / ngx_pagesize, ngx_pagesize);

    ngx_conf_merge_value(conf->quality, prev->quality, 6);
    ngx_conf_merge_size_value(conf->win_bits, prev->win_bits, 19);
    ngx_conf_merge_value(conf->min_length, prev->min_length, 20);

    if (ngx_http_merge_types(cf, &conf->types_keys, &conf->types,
                             &prev->types_keys, &prev->types,
                             ngx_http_html_default_types)
        != NGX_OK)
    {
        return NGX_CONF_ERROR;
    }

    return NGX_CONF_OK;
}


static ngx_int_t
ngx_http_brotli_filter_init(ngx_conf_t *cf)
{
    ngx_http_next_header_filter = ngx_http_top_header_filter;
    ngx_http_top_header_filter = ngx_http_brotli_header_filter;

    ngx_http_next_body_filter = ngx_http_top_body_filter;
    ngx_http_top_body_filter = ngx_http_brotli_body_filter;

    return NGX_OK;
}


static char *
ngx_http_brotli_window(ngx_conf_t *cf, void *post, void *data)
{
    size_t  *np = data;
    size_t   wbits, wsize, mbits;

    wbits = kBrotliMaxWindowBits;
    mbits = kBrotliMinWindowBits;

    for (wsize = (1 << wbits); wsize >= (1U << mbits); wsize >>= 1) {

        if (wsize == *np) {
            *np = wbits;

            return NGX_CONF_OK;
        }

        wbits--;
    }

    return "must be 1k, 2k, 4k, 8k, 16k, 32k, 64k, "
           "128k, 256k, 512k, 1m, 2m, 4m, 8m or 16m";
}
