Brotli: migrate to C API.

Change-Id: Ic1884b068bcb87d85396d22ee1e5a7dd2e3d39d9
Signed-off-by: Piotr Sikora <piotrsikora@google.com>
Reviewed-on: https://nginx-review.googlesource.com/1232
Reviewed-by: Martin Maly <mmaly@google.com>
diff --git a/BUILD b/BUILD
index 8ce09fa..b55f224 100644
--- a/BUILD
+++ b/BUILD
@@ -26,7 +26,7 @@
 
 exports_files(["LICENSE"])
 
-load("//:build.bzl", "nginx_copts", "nginx_cxxopts")
+load("//:build.bzl", "nginx_copts")
 
 genrule(
     name = "ngx_modules_c",
@@ -42,11 +42,10 @@
 cc_library(
     name = "http_brotli_filter",
     srcs = [
-        "src/ngx_http_brotli_filter_module.cc",
+        "src/ngx_http_brotli_filter_module.c",
     ],
-    copts = nginx_cxxopts,
+    copts = nginx_copts,
     defines = [
-        "NGX_HAVE_BROTLI_ENC_COMPRESSOR_H",
         "NGX_HTTP_BROTLI_FILTER",
     ],
     visibility = [
diff --git a/auto/feature b/auto/feature
deleted file mode 100644
index eede183..0000000
--- a/auto/feature
+++ /dev/null
@@ -1,131 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-echo $ngx_n "checking for $ngx_feature ...$ngx_c"
-
-cat << END >> $NGX_AUTOCONF_ERR
-
-----------------------------------------
-checking for $ngx_feature
-
-END
-
-ngx_found=no
-
-if test -n "$ngx_feature_name"; then
-    ngx_have_feature=`echo $ngx_feature_name \
-                   | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`
-fi
-
-if test -n "$ngx_feature_path"; then
-    for ngx_temp in $ngx_feature_path; do
-        ngx_feature_inc_path="$ngx_feature_inc_path -I $ngx_temp"
-    done
-fi
-
-if [ "$ngx_feature_cpp" = "yes" ]; then
-    NGX_AUTOTEST_EXT=cc
-else
-    NGX_AUTOTEST_EXT=c
-fi
-
-cat << END > $NGX_AUTOTEST.$NGX_AUTOTEST_EXT
-
-#include <sys/types.h>
-$NGX_INCLUDE_UNISTD_H
-$ngx_feature_incs
-
-int main() {
-    $ngx_feature_test;
-    return 0;
-}
-
-END
-
-
-ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS $ngx_feature_inc_path \
-          -o $NGX_AUTOTEST $NGX_AUTOTEST.$NGX_AUTOTEST_EXT \
-          $NGX_TEST_LD_OPT $ngx_feature_libs"
-
-ngx_feature_inc_path=
-ngx_feature_cpp=
-
-eval "/bin/sh -c \"$ngx_test\" >> $NGX_AUTOCONF_ERR 2>&1"
-
-
-if [ -x $NGX_AUTOTEST ]; then
-
-    case "$ngx_feature_run" in
-
-        yes)
-            # /bin/sh is used to intercept "Killed" or "Abort trap" messages
-            if /bin/sh -c $NGX_AUTOTEST >> $NGX_AUTOCONF_ERR 2>&1; then
-                echo " found"
-                ngx_found=yes
-
-                if test -n "$ngx_feature_name"; then
-                    have=$ngx_have_feature . auto/have
-                fi
-
-            else
-                echo " found but is not working"
-            fi
-        ;;
-
-        value)
-            # /bin/sh is used to intercept "Killed" or "Abort trap" messages
-            if /bin/sh -c $NGX_AUTOTEST >> $NGX_AUTOCONF_ERR 2>&1; then
-                echo " found"
-                ngx_found=yes
-
-                cat << END >> $NGX_AUTO_CONFIG_H
-
-#ifndef $ngx_feature_name
-#define $ngx_feature_name  `$NGX_AUTOTEST`
-#endif
-
-END
-            else
-                echo " found but is not working"
-            fi
-        ;;
-
-        bug)
-            # /bin/sh is used to intercept "Killed" or "Abort trap" messages
-            if /bin/sh -c $NGX_AUTOTEST >> $NGX_AUTOCONF_ERR 2>&1; then
-                echo " not found"
-
-            else
-                echo " found"
-                ngx_found=yes
-
-                if test -n "$ngx_feature_name"; then
-                    have=$ngx_have_feature . auto/have
-                fi
-            fi
-        ;;
-
-        *)
-            echo " found"
-            ngx_found=yes
-
-            if test -n "$ngx_feature_name"; then
-                have=$ngx_have_feature . auto/have
-            fi
-        ;;
-
-    esac
-
-else
-    echo " not found"
-
-    echo "----------"                    >> $NGX_AUTOCONF_ERR
-    cat $NGX_AUTOTEST.$NGX_AUTOTEST_EXT  >> $NGX_AUTOCONF_ERR
-    echo "----------"                    >> $NGX_AUTOCONF_ERR
-    echo $ngx_test                       >> $NGX_AUTOCONF_ERR
-    echo "----------"                    >> $NGX_AUTOCONF_ERR
-fi
-
-rm -rf $NGX_AUTOTEST*
diff --git a/config b/config
index 0f829c7..5194775 100644
--- a/config
+++ b/config
@@ -54,119 +54,58 @@
 fi
 
 #
-# filter module (depends on Brotli C++ library)
+# filter module (depends on Brotli library)
 #
 
-# new C++ API header (compressor.h)
-
-ngx_feature_name=NGX_HAVE_BROTLI_ENC_COMPRESSOR_H
+ngx_feature_name=
 ngx_feature_run=no
-ngx_feature_cpp=yes
-ngx_feature_incs="#include <brotli/enc/compressor.h>"
-ngx_feature_test="brotli::BrotliParams  params;
-                  params.quality = 11"
+ngx_feature_incs="#include <brotli/enc/encode.h>"
+ngx_feature_test="BrotliEncoderCreateInstance(NULL, NULL, NULL)"
 
 # auto-discovery
-ngx_feature="Brotli C++ library (compressor.h)"
-ngx_feature_cpp=yes
+ngx_feature="Brotli library"
 ngx_feature_path=
-ngx_feature_libs="-lbrotlienc -lstdc++"
-. $ngx_addon_dir/auto/feature
+ngx_feature_libs="-lbrotlienc"
+. auto/feature
 
 if [ $ngx_found = no ]; then
     # FreeBSD, OpenBSD
-    ngx_feature="Brotli C++ library (compressor.h) in /usr/local/"
-    ngx_feature_cpp=yes
+    ngx_feature="Brotli library in /usr/local/"
     ngx_feature_path="/usr/local/include"
     if [ $NGX_RPATH = YES ]; then
-        ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -lbrotlienc -lstdc++"
+        ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -lbrotlienc"
     else
-        ngx_feature_libs="-L/usr/local/lib -lbrotlienc -lstdc++"
+        ngx_feature_libs="-L/usr/local/lib -lbrotlienc"
     fi
-    . $ngx_addon_dir/auto/feature
+    . auto/feature
 fi
 
 if [ $ngx_found = no ]; then
     # NetBSD
-    ngx_feature="Brotli C++ library (compressor.h) in /usr/pkg/"
-    ngx_feature_cpp=yes
+    ngx_feature="Brotli library in /usr/pkg/"
     ngx_feature_path="/usr/pkg/include"
     if [ $NGX_RPATH = YES ]; then
-        ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lbrotlienc -lstdc++"
+        ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lbrotlienc"
     else
-        ngx_feature_libs="-L/usr/pkg/lib -lbrotlienc -lstdc++"
+        ngx_feature_libs="-L/usr/pkg/lib -lbrotlienc"
     fi
-    . $ngx_addon_dir/auto/feature
+    . auto/feature
 fi
 
 if [ $ngx_found = no ]; then
     # MacPorts
-    ngx_feature="Brotli C++ library (compressor.h) in /opt/local/"
-    ngx_feature_cpp=yes
+    ngx_feature="Brotli library in /opt/local/"
     ngx_feature_path="/opt/local/include"
     if [ $NGX_RPATH = YES ]; then
-        ngx_feature_libs="-R/opt/local/lib -L/opt/local/lib -lbrotlienc -lstdc++"
+        ngx_feature_libs="-R/opt/local/lib -L/opt/local/lib -lbrotlienc"
     else
-        ngx_feature_libs="-L/opt/local/lib -lbrotlienc -lstdc++"
+        ngx_feature_libs="-L/opt/local/lib -lbrotlienc"
     fi
-    . $ngx_addon_dir/auto/feature
-fi
-
-# original C++ API header (encode.h)
-
-ngx_feature_name=
-ngx_feature_incs="#include <brotli/enc/encode.h>"
-
-if [ $ngx_found = no ]; then
-    # auto-discovery
-    ngx_feature="Brotli C++ library (encode.h)"
-    ngx_feature_cpp=yes
-    ngx_feature_path=
-    ngx_feature_libs="-lbrotlienc -lstdc++"
-    . $ngx_addon_dir/auto/feature
+    . auto/feature
 fi
 
 if [ $ngx_found = no ]; then
-    # FreeBSD, OpenBSD
-    ngx_feature="Brotli C++ library (encode.h) in /usr/local/"
-    ngx_feature_cpp=yes
-    ngx_feature_path="/usr/local/include"
-    if [ $NGX_RPATH = YES ]; then
-        ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -lbrotlienc -lstdc++"
-    else
-        ngx_feature_libs="-L/usr/local/lib -lbrotlienc -lstdc++"
-    fi
-    . $ngx_addon_dir/auto/feature
-fi
-
-if [ $ngx_found = no ]; then
-    # NetBSD
-    ngx_feature="Brotli C++ library (encode.h) in /usr/pkg/"
-    ngx_feature_cpp=yes
-    ngx_feature_path="/usr/pkg/include"
-    if [ $NGX_RPATH = YES ]; then
-        ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lbrotlienc -lstdc++"
-    else
-        ngx_feature_libs="-L/usr/pkg/lib -lbrotlienc -lstdc++"
-    fi
-    . $ngx_addon_dir/auto/feature
-fi
-
-if [ $ngx_found = no ]; then
-    # MacPorts
-    ngx_feature="Brotli C++ library (encode.h) in /opt/local/"
-    ngx_feature_cpp=yes
-    ngx_feature_path="/opt/local/include"
-    if [ $NGX_RPATH = YES ]; then
-        ngx_feature_libs="-R/opt/local/lib -L/opt/local/lib -lbrotlienc -lstdc++"
-    else
-        ngx_feature_libs="-L/opt/local/lib -lbrotlienc -lstdc++"
-    fi
-    . $ngx_addon_dir/auto/feature
-fi
-
-if [ $ngx_found = no ]; then
-    echo "$0: error: ngx_brotli filter module requires Brotli C++ library."
+    echo "$0: error: ngx_brotli filter module requires Brotli library."
     exit 1
 fi
 
@@ -184,7 +123,7 @@
     ngx_module_name=ngx_http_brotli_filter_module
     ngx_module_incs="$ngx_feature_path"
     ngx_module_deps=
-    ngx_module_srcs="$ngx_addon_dir/src/ngx_http_brotli_filter_module.cc"
+    ngx_module_srcs="$ngx_addon_dir/src/ngx_http_brotli_filter_module.c"
     ngx_module_libs="$ngx_feature_libs"
     ngx_module_order="$ngx_module_name \
                       ngx_pagespeed \
@@ -216,14 +155,7 @@
                          | sed "s/$next/$next ngx_http_brotli_filter_module/"`
 
     NGX_ADDON_SRCS="$NGX_ADDON_SRCS \
-                    $ngx_addon_dir/src/ngx_http_brotli_filter_module.cc"
-fi
-
-# workaround for a bug in nginx-1.9.11, see:
-# http://hg.nginx.org/nginx/rev/ff1e625ae55b
-NGX_VERSION=`grep nginx_version src/core/nginx.h | sed -e 's/^.* \(.*\)$/\1/'`
-if [ "$NGX_VERSION" = "1009011" ]; then
-    CFLAGS="$CFLAGS -Wno-write-strings"
+                    $ngx_addon_dir/src/ngx_http_brotli_filter_module.c"
 fi
 
 have=NGX_HTTP_BROTLI_FILTER . auto/have
diff --git a/src/ngx_http_brotli_filter_module.cc b/src/ngx_http_brotli_filter_module.c
similarity index 79%
rename from src/ngx_http_brotli_filter_module.cc
rename to src/ngx_http_brotli_filter_module.c
index 2a6406b..e0ecc5c 100644
--- a/src/ngx_http_brotli_filter_module.cc
+++ b/src/ngx_http_brotli_filter_module.c
@@ -6,65 +6,60 @@
  */
 
 
-extern "C" {
-  #include <ngx_config.h>
-  #include <ngx_core.h>
-  #include <ngx_http.h>
-}
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_http.h>
 
-#if (NGX_HAVE_BROTLI_ENC_COMPRESSOR_H)
-#include <brotli/enc/compressor.h>
-#else
 #include <brotli/enc/encode.h>
-#endif
 
 
 typedef struct {
-    ngx_flag_t                  enable;
+    ngx_flag_t            enable;
 
-    ngx_hash_t                  types;
+    ngx_hash_t            types;
 
-    ngx_bufs_t                  bufs;
+    ngx_bufs_t            bufs;
 
-    ngx_int_t                   quality;
-    size_t                      win_bits;
-    ssize_t                     min_length;
+    ngx_int_t             quality;
+    size_t                win_bits;
+    ssize_t               min_length;
 
-    ngx_array_t                *types_keys;
+    ngx_array_t          *types_keys;
 } ngx_http_brotli_conf_t;
 
 
 typedef struct {
-    brotli::BrotliCompressor   *compressor;
-    brotli::BrotliParams        params;
+    BrotliEncoderState   *encoder;
 
-    size_t                      brotli_ring;
-    size_t                      brotli_in;
-    u_char                     *brotli_out;
-    u_char                     *brotli_last;
+    size_t                brotli_ring;
+    size_t                brotli_in;
+    u_char               *brotli_out;
+    u_char               *brotli_last;
 
-    size_t                      bytes_in;
-    size_t                      bytes_out;
+    off_t                 content_length;
 
-    ngx_chain_t                *in;
-    ngx_chain_t                *free;
-    ngx_chain_t                *busy;
-    ngx_chain_t                *out;
-    ngx_chain_t               **last_out;
+    size_t                bytes_in;
+    size_t                bytes_out;
 
-    ngx_buf_t                  *out_buf;
-    ngx_int_t                   bufs;
+    ngx_chain_t          *in;
+    ngx_chain_t          *free;
+    ngx_chain_t          *busy;
+    ngx_chain_t          *out;
+    ngx_chain_t         **last_out;
 
-    unsigned                    done:1;
-    unsigned                    sent:1;
-    unsigned                    last:1;
-    unsigned                    flush:1;
-    unsigned                    nomem:1;
+    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 void ngx_http_brotli_filter_params(ngx_http_request_t *r,
-    ngx_http_brotli_ctx_t *ctx);
+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,
@@ -191,8 +186,7 @@
     ngx_http_brotli_ctx_t   *ctx;
     ngx_http_brotli_conf_t  *conf;
 
-    conf = reinterpret_cast<ngx_http_brotli_conf_t *>(
-               ngx_http_get_module_loc_conf(r, ngx_http_brotli_filter_module));
+    conf = ngx_http_get_module_loc_conf(r, ngx_http_brotli_filter_module);
 
     if (!conf->enable
         || (r->headers_out.status != NGX_HTTP_OK
@@ -214,20 +208,18 @@
         return ngx_http_next_header_filter(r);
     }
 
-    ctx = reinterpret_cast<ngx_http_brotli_ctx_t *>(
-              ngx_pcalloc(r->pool, sizeof(ngx_http_brotli_ctx_t)));
+    ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_brotli_ctx_t));
     if (ctx == NULL) {
         return NGX_ERROR;
     }
 
     ctx->last_out = &ctx->out;
 
-    ngx_http_brotli_filter_params(r, ctx);
+    ctx->content_length = r->headers_out.content_length_n;
 
     ngx_http_set_ctx(r, ctx, ngx_http_brotli_filter_module);
 
-    h = reinterpret_cast<ngx_table_elt_t *>(
-            ngx_list_push(&r->headers_out.headers));
+    h = ngx_list_push(&r->headers_out.headers);
     if (h == NULL) {
         return NGX_ERROR;
     }
@@ -256,8 +248,7 @@
     ngx_pool_cleanup_t     *cln;
     ngx_http_brotli_ctx_t  *ctx;
 
-    ctx = reinterpret_cast<ngx_http_brotli_ctx_t *>(
-              ngx_http_get_module_ctx(r, ngx_http_brotli_filter_module));
+    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);
@@ -266,18 +257,13 @@
     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                    "http brotli filter");
 
-    if (ctx->compressor == NULL) {
-        ctx->compressor = new brotli::BrotliCompressor(ctx->params);
-        if (ctx->compressor == NULL) {
+    if (ctx->encoder == NULL) {
+        ctx->encoder = ngx_http_brotli_filter_create_encoder(r);
+        if (ctx->encoder == NULL) {
             goto failed;
         }
 
-        ctx->brotli_ring = ctx->compressor->input_block_size();
-
-        ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                       "brotli compressor: lvl:%d win:%d blk:%uz",
-                       ctx->params.quality, (1 << ctx->params.lgwin),
-                       ctx->brotli_ring);
+        ctx->brotli_ring = BrotliEncoderInputBlockSize(ctx->encoder);
 
         cln = ngx_pool_cleanup_add(r->pool, 0);
         if (cln == NULL) {
@@ -374,9 +360,9 @@
         if (ctx->done) {
             ctx->sent = 1;
 
-            if (ctx->compressor) {
-                delete ctx->compressor;
-                ctx->compressor = NULL;
+            if (ctx->encoder) {
+                BrotliEncoderDestroyInstance(ctx->encoder);
+                ctx->encoder = NULL;
             }
 
             return rc;
@@ -389,36 +375,73 @@
 
     ctx->done = 1;
 
-    if (ctx->compressor) {
-        delete ctx->compressor;
-        ctx->compressor = NULL;
+    if (ctx->encoder) {
+        BrotliEncoderDestroyInstance(ctx->encoder);
+        ctx->encoder = NULL;
     }
 
     return NGX_ERROR;
 }
 
 
-static void
-ngx_http_brotli_filter_params(ngx_http_request_t *r, ngx_http_brotli_ctx_t *ctx)
+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;
 
-    conf = reinterpret_cast<ngx_http_brotli_conf_t *>(
-               ngx_http_get_module_loc_conf(r, ngx_http_brotli_filter_module));
+    encoder = BrotliEncoderCreateInstance(NULL, NULL, NULL);
+    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 (r->headers_out.content_length_n > 0) {
-        while (r->headers_out.content_length_n < (1 << (wbits - 1))
-               && wbits > brotli::kMinWindowBits)
+    if (ctx->content_length > 0) {
+        while (ctx->content_length < (1 << (wbits - 1))
+               && wbits > kBrotliMinWindowBits)
         {
             wbits--;
         }
     }
 
-    ctx->params.quality = conf->quality;
-    ctx->params.lgwin = 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;
 }
 
 
@@ -465,7 +488,7 @@
         ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                        "brotli copy: %p, size:%uz", b, size);
 
-        ctx->compressor->CopyInputToRingBuffer(size, b->pos);
+        BrotliEncoderCopyInputToRingBuffer(ctx->encoder, size, b->pos);
 
         ctx->brotli_in += size;
         ctx->bytes_in += size;
@@ -502,7 +525,9 @@
 
     out = NULL;
 
-    if (!ctx->compressor->WriteBrotliData(ctx->last, ctx->flush, &size, &out)) {
+    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);
@@ -581,7 +606,7 @@
                 return NGX_ERROR;
             }
 
-            cl->buf = reinterpret_cast<ngx_buf_t *>(ngx_calloc_buf(r->pool));
+            cl->buf = ngx_calloc_buf(r->pool);
             if (cl->buf == NULL) {
                 return NGX_ERROR;
             }
@@ -621,8 +646,7 @@
         return NGX_OK;
     }
 
-    conf = reinterpret_cast<ngx_http_brotli_conf_t *>(
-               ngx_http_get_module_loc_conf(r, ngx_http_brotli_filter_module));
+    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);
@@ -646,13 +670,11 @@
 static void
 ngx_http_brotli_cleanup(void *data)
 {
-    ngx_http_brotli_ctx_t  *ctx;
+    ngx_http_brotli_ctx_t  *ctx = data;
 
-    ctx = reinterpret_cast<ngx_http_brotli_ctx_t *>(data);
-
-    if (ctx->compressor) {
-        delete ctx->compressor;
-        ctx->compressor = NULL;
+    if (ctx->encoder) {
+        BrotliEncoderDestroyInstance(ctx->encoder);
+        ctx->encoder = NULL;
     }
 }
 
@@ -693,7 +715,7 @@
 {
     u_char  *p;
 
-    p = ngx_strcasestrn(ae->data, const_cast<char *>("br"), sizeof("br") - 2);
+    p = ngx_strcasestrn(ae->data, "br", sizeof("br") - 2);
     if (p == NULL) {
         return NGX_DECLINED;
     }
@@ -738,16 +760,14 @@
     v->no_cacheable = 0;
     v->not_found = 0;
 
-    ctx = reinterpret_cast<ngx_http_brotli_ctx_t *>(
-              ngx_http_get_module_ctx(r, ngx_http_brotli_filter_module));
+    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 = reinterpret_cast<u_char *>(
-                  ngx_pnalloc(r->pool, NGX_INT32_LEN + 3));
+    v->data = ngx_pnalloc(r->pool, NGX_INT32_LEN + 3);
     if (v->data == NULL) {
         return NGX_ERROR;
     }
@@ -778,8 +798,7 @@
 {
     ngx_http_brotli_conf_t  *conf;
 
-    conf = reinterpret_cast<ngx_http_brotli_conf_t *>(
-               ngx_pcalloc(cf->pool, sizeof(ngx_http_brotli_conf_t)));
+    conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_brotli_conf_t));
     if (conf == NULL) {
         return NULL;
     }
@@ -805,11 +824,8 @@
 static char *
 ngx_http_brotli_merge_conf(ngx_conf_t *cf, void *parent, void *child)
 {
-    ngx_http_brotli_conf_t  *prev;
-    ngx_http_brotli_conf_t  *conf;
-
-    prev = reinterpret_cast<ngx_http_brotli_conf_t *>(parent);
-    conf = reinterpret_cast<ngx_http_brotli_conf_t *>(child);
+    ngx_http_brotli_conf_t  *prev = parent;
+    ngx_http_brotli_conf_t  *conf = child;
 
     ngx_conf_merge_value(conf->enable, prev->enable, 0);
 
@@ -825,7 +841,7 @@
                              ngx_http_html_default_types)
         != NGX_OK)
     {
-        return reinterpret_cast<char *>(NGX_CONF_ERROR);
+        return NGX_CONF_ERROR;
     }
 
     return NGX_CONF_OK;
@@ -848,12 +864,11 @@
 static char *
 ngx_http_brotli_window(ngx_conf_t *cf, void *post, void *data)
 {
-    size_t *np = reinterpret_cast<size_t *>(data);
+    size_t  *np = data;
+    size_t   wbits, wsize, mbits;
 
-    size_t  wbits, wsize, mbits;
-
-    wbits = brotli::kMaxWindowBits;
-    mbits = brotli::kMinWindowBits;
+    wbits = kBrotliMaxWindowBits;
+    mbits = kBrotliMinWindowBits;
 
     for (wsize = (1 << wbits); wsize >= (1U << mbits); wsize >>= 1) {
 
@@ -866,6 +881,6 @@
         wbits--;
     }
 
-    return const_cast<char *>("must be 1k, 2k, 4k, 8k, 16k, 32k, 64k, "
-                              "128k, 256k, 512k, 1m, 2m, 4m, 8m or 16m");
+    return "must be 1k, 2k, 4k, 8k, 16k, 32k, 64k, "
+           "128k, 256k, 512k, 1m, 2m, 4m, 8m or 16m";
 }