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;
}
예제 #2
0
파일: brotli.c 프로젝트: chipsec/chipsec
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;
}
예제 #3
0
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);
    }
}
예제 #4
0
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();
  }
}
예제 #5
0
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;
}