static ngx_int_t ngx_http_brotli_filter_start(ngx_http_request_t *r, 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); ctx->bro = BrotliEncoderCreateInstance(NULL, NULL, NULL); if (ctx->bro == NULL) { return NGX_ERROR; } ctx->last_out = &ctx->out; BrotliEncoderSetParameter(ctx->bro, BROTLI_PARAM_QUALITY, conf->level); BrotliEncoderSetParameter(ctx->bro, BROTLI_PARAM_LGWIN, BROTLI_DEFAULT_WINDOW); ctx->input = NULL; ctx->output = NULL; ctx->next_in = NULL; ctx->next_out = NULL; ctx->available_in = 0; ctx->available_out = 0; return NGX_OK; }
static BROTLI_BOOL CompressFiles(Context* context) { while (NextFile(context)) { BROTLI_BOOL is_ok = BROTLI_TRUE; BrotliEncoderState* s = BrotliEncoderCreateInstance(NULL, NULL, NULL); if (!s) { fprintf(stderr, "out of memory\n"); return BROTLI_FALSE; } BrotliEncoderSetParameter(s, BROTLI_PARAM_QUALITY, (uint32_t)context->quality); if (context->lgwin > 0) { /* Specified by user. */ /* Do not enable "large-window" extension, if not required. */ if (context->lgwin > BROTLI_MAX_WINDOW_BITS) { BrotliEncoderSetParameter(s, BROTLI_PARAM_LARGE_WINDOW, 1u); } BrotliEncoderSetParameter(s, BROTLI_PARAM_LGWIN, (uint32_t)context->lgwin); } else { /* 0, or not specified by user; could be chosen by compressor. */ uint32_t lgwin = DEFAULT_LGWIN; /* Use file size to limit lgwin. */ if (context->input_file_length >= 0) { int32_t size = 1 << BROTLI_MIN_WINDOW_BITS; lgwin = BROTLI_MIN_WINDOW_BITS; while (size < context->input_file_length) { size <<= 1; lgwin++; if (lgwin == BROTLI_MAX_WINDOW_BITS) break; } } BrotliEncoderSetParameter(s, BROTLI_PARAM_LGWIN, lgwin); } if (context->input_file_length > 0) { uint32_t size_hint = context->input_file_length < (1 << 30) ? (uint32_t)context->input_file_length : (1u << 30); BrotliEncoderSetParameter(s, BROTLI_PARAM_SIZE_HINT, size_hint); } is_ok = OpenFiles(context); if (is_ok && !context->current_output_path && !context->force_overwrite && isatty(STDOUT_FILENO)) { fprintf(stderr, "Use -h help. Use -f to force output to a terminal.\n"); is_ok = BROTLI_FALSE; } if (is_ok) is_ok = CompressFile(context, s); BrotliEncoderDestroyInstance(s); if (!CloseFiles(context, is_ok)) is_ok = BROTLI_FALSE; if (!is_ok) return BROTLI_FALSE; } return BROTLI_TRUE; }
void HttpHandler::prepareEncoding(const char* accept_encoding) { if (accept_encoding == nullptr) { this->encoding = Encoding::Normal; return; } auto enc = trimAndLower(std::strtok(const_cast<char*>(accept_encoding), ",")); while (!enc.empty()) { if (enc == "gzip" && this->encoding != Encoding::Brotli) { //this->encoding = Encoding::Gzip; } else if (enc == "br") { // Prefer brotli over gzip this->encoding = Encoding::Brotli; break; } enc = trimAndLower(std::strtok(NULL, " ")); } if (isCompressionActive()) { this->buffer_stream = new std::ostringstream(); } if (this->encoding == Encoding::Brotli) { // Init brotli this->buffer = new uint8_t[2 * COMPRESSION_BUFFER_SIZE]; this->brotli_in = buffer; this->brotli_out = buffer + COMPRESSION_BUFFER_SIZE; this->brotli_available_in = 0; this->brotli_next_in = NULL; this->brotli_available_out = COMPRESSION_BUFFER_SIZE; this->brotli_next_out = this->brotli_out; this->brotli = BrotliEncoderCreateInstance(nullptr, nullptr, 0); BrotliEncoderSetParameter(this->brotli, BROTLI_PARAM_MODE, BROTLI_MODE_TEXT); BrotliEncoderSetParameter(this->brotli, BROTLI_PARAM_QUALITY, 2); } }
static void squash_brotli_stream_init (SquashBrotliStream* s, SquashCodec* codec, SquashStreamType stream_type, SquashOptions* options, SquashDestroyNotify destroy_notify) { SquashStream* stream = (SquashStream*) s; squash_stream_init (stream, codec, stream_type, (SquashOptions*) options, destroy_notify); if (stream_type == SQUASH_STREAM_COMPRESS) { s->ctx.encoder = BrotliEncoderCreateInstance(squash_brotli_malloc, squash_brotli_free, NULL); BrotliEncoderSetParameter(s->ctx.encoder, BROTLI_PARAM_QUALITY, squash_options_get_int_at (options, codec, SQUASH_BROTLI_OPT_LEVEL)); BrotliEncoderSetParameter(s->ctx.encoder, BROTLI_PARAM_LGWIN, squash_options_get_int_at (options, codec, SQUASH_BROTLI_OPT_WINDOW_SIZE)); BrotliEncoderSetParameter(s->ctx.encoder, BROTLI_PARAM_LGBLOCK, squash_options_get_int_at (options, codec, SQUASH_BROTLI_OPT_BLOCK_SIZE)); BrotliEncoderSetParameter(s->ctx.encoder, BROTLI_PARAM_MODE, squash_options_get_int_at (options, codec, SQUASH_BROTLI_OPT_MODE)); } else if (stream_type == SQUASH_STREAM_DECOMPRESS) { s->ctx.decoder = BrotliCreateState(squash_brotli_malloc, squash_brotli_free, NULL); } else { squash_assert_unreachable(); } }
static int Compress(int quality, int lgwin, FILE* fin, FILE* fout, const char *dictionary_path) { BrotliEncoderState* s = BrotliEncoderCreateInstance(0, 0, 0); uint8_t* buffer = (uint8_t*)malloc(kFileBufferSize << 1); uint8_t* input = buffer; uint8_t* output = buffer + kFileBufferSize; size_t available_in = 0; const uint8_t* next_in = NULL; size_t available_out = kFileBufferSize; uint8_t* next_out = output; int is_eof = 0; int is_ok = 1; if (!s || !buffer) { is_ok = 0; goto finish; } BrotliEncoderSetParameter(s, BROTLI_PARAM_QUALITY, (uint32_t)quality); BrotliEncoderSetParameter(s, BROTLI_PARAM_LGWIN, (uint32_t)lgwin); if (dictionary_path != NULL) { size_t dictionary_size = 0; uint8_t* dictionary = ReadDictionary(dictionary_path, &dictionary_size); BrotliEncoderSetCustomDictionary(s, dictionary_size, dictionary); free(dictionary); } while (1) { if (available_in == 0 && !is_eof) { available_in = fread(input, 1, kFileBufferSize, fin); next_in = input; if (ferror(fin)) break; is_eof = feof(fin); } if (!BrotliEncoderCompressStream(s, is_eof ? BROTLI_OPERATION_FINISH : BROTLI_OPERATION_PROCESS, &available_in, &next_in, &available_out, &next_out, NULL)) { is_ok = 0; break; } if (available_out != kFileBufferSize) { size_t out_size = kFileBufferSize - available_out; fwrite(output, 1, out_size, fout); if (ferror(fout)) break; available_out = kFileBufferSize; next_out = output; } if (BrotliEncoderIsFinished(s)) break; } finish: free(buffer); BrotliEncoderDestroyInstance(s); if (!is_ok) { /* Should detect OOM? */ fprintf(stderr, "failed to compress data\n"); return 0; } else if (ferror(fout)) { fprintf(stderr, "failed to write output\n"); return 0; } else if (ferror(fin)) { fprintf(stderr, "failed to read input\n"); return 0; } return 1; }