Пример #1
0
static BROTLI_BOOL CompressFile(Context* context, BrotliEncoderState* s) {
  BROTLI_BOOL is_eof = BROTLI_FALSE;
  InitializeBuffers(context);
  for (;;) {
    if (context->available_in == 0 && !is_eof) {
      if (!ProvideInput(context)) return BROTLI_FALSE;
      is_eof = !HasMoreInput(context);
    }

    if (!BrotliEncoderCompressStream(s,
        is_eof ? BROTLI_OPERATION_FINISH : BROTLI_OPERATION_PROCESS,
        &context->available_in, &context->next_in,
        &context->available_out, &context->next_out, NULL)) {
      /* Should detect OOM? */
      fprintf(stderr, "failed to compress data [%s]\n",
              PrintablePath(context->current_input_path));
      return BROTLI_FALSE;
    }

    if (context->available_out == 0) {
      if (!ProvideOutput(context)) return BROTLI_FALSE;
    }

    if (BrotliEncoderIsFinished(s)) {
      return FlushOutput(context);
    }
  }
}
Пример #2
0
void HttpHandler::BrotliFlush()
{
    do
    {
        this->brotli_available_in = 0;
        if (!BrotliEncoderCompressStream(this->brotli, BROTLI_OPERATION_FINISH, &this->brotli_available_in, &this->brotli_next_in, &this->brotli_available_out, &this->brotli_next_out, NULL)) {
            std::cerr << "failed to compress data" << std::endl;
            return;
        }

        this->response.write(reinterpret_cast<const char*>(this->brotli_out), COMPRESSION_BUFFER_SIZE - this->brotli_available_out);
        this->brotli_available_out = COMPRESSION_BUFFER_SIZE;
        this->brotli_next_out = this->brotli_out;
    } while(BrotliEncoderHasMoreOutput(this->brotli));
}
Пример #3
0
static SquashStatus
squash_brotli_process_stream (SquashStream* stream, SquashOperation operation) {
  SquashBrotliStream* s = (SquashBrotliStream*) stream;

  if (stream->stream_type == SQUASH_STREAM_COMPRESS) {
    const int be_ret =
      BrotliEncoderCompressStream(s->ctx.encoder,
                                  squash_brotli_encoder_operation_from_squash_operation(operation),
                                  &(stream->avail_in), &(stream->next_in),
                                  &(stream->avail_out), &(stream->next_out),
                                  NULL);

    if (SQUASH_UNLIKELY(be_ret != 1))
      return squash_error (SQUASH_FAILED);
    else if (stream->avail_in != 0 || BrotliEncoderHasMoreOutput(s->ctx.encoder))
      return SQUASH_PROCESSING;
    else
      return SQUASH_OK;
  } else if (stream->stream_type == SQUASH_STREAM_DECOMPRESS) {
    const BrotliResult bd_ret =
      BrotliDecompressStream(&(stream->avail_in), &(stream->next_in),
                             &(stream->avail_out), &(stream->next_out),
                             NULL,
                             s->ctx.decoder);

    switch (bd_ret) {
      case BROTLI_RESULT_SUCCESS:
        return SQUASH_OK;
      case BROTLI_RESULT_NEEDS_MORE_INPUT:
        return SQUASH_OK;
      case BROTLI_RESULT_NEEDS_MORE_OUTPUT:
        return SQUASH_PROCESSING;
      case BROTLI_RESULT_ERROR:
        return SQUASH_FAILED;
    }

    if (SQUASH_UNLIKELY(bd_ret != BROTLI_RESULT_SUCCESS))
      return squash_error (SQUASH_FAILED);
  } else {
    squash_assert_unreachable ();
  }

  squash_assert_unreachable ();
}
Пример #4
0
void HttpHandler::BrotliProcess()
{
    this->brotli_available_in = this->buffer_stream->str().length();
    this->buffer_stream->str().copy(reinterpret_cast<char*>(this->brotli_in), this->brotli_available_in, 0);
    this->brotli_next_in = this->brotli_in;

    if (!BrotliEncoderCompressStream(this->brotli, BROTLI_OPERATION_PROCESS, &this->brotli_available_in, &this->brotli_next_in, &this->brotli_available_out, &this->brotli_next_out, NULL)) {
        std::cerr << "failed to compress data" << std::endl;
        return;
    }

    if (this->brotli_available_out != COMPRESSION_BUFFER_SIZE) {
        this->response.write(reinterpret_cast<const char*>(this->brotli_out), COMPRESSION_BUFFER_SIZE - this->brotli_available_out);
        this->brotli_available_out = COMPRESSION_BUFFER_SIZE;
        this->brotli_next_out = this->brotli_out;
    }

    this->buffer_stream->str("");
}
static ngx_int_t
ngx_http_brotli_filter_compress(ngx_http_request_t *r, ngx_http_brotli_ctx_t *ctx)
{
    BROTLI_BOOL              rc;
    ngx_buf_t               *b;
    ngx_chain_t             *cl;

    rc = BrotliEncoderCompressStream(ctx->bro, ctx->flush, &ctx->available_in, (const uint8_t **)&ctx->next_in, &ctx->available_out, &ctx->next_out, NULL);

    if (rc != BROTLI_TRUE) {
        ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
                      "compress() failed: %d, %d", ctx->flush, rc);
        return NGX_ERROR;
    }

    if (ctx->next_in) {
        ctx->in_buf->pos = ctx->next_in;

        if (ctx->available_in == 0) {
            ctx->next_in = NULL;
        }
    }

    ctx->out_buf->last = ctx->next_out;

    if (ctx->available_out == 0) {

        /* brotli wants to output some more compressed data */

        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->redo = 1;

        return NGX_AGAIN;
    }

    ctx->redo = 0;

    if (ctx->flush == BROTLI_OPERATION_FLUSH) {

        ctx->flush = BROTLI_OPERATION_PROCESS;

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

        b = ctx->out_buf;

        if (ngx_buf_size(b) == 0) {

            b = ngx_calloc_buf(ctx->request->pool);
            if (b == NULL) {
                return NGX_ERROR;
            }

        } else {
            ctx->available_out = 0;
        }

        b->flush = 1;

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

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

        return NGX_OK;
    }

    if (BrotliEncoderIsFinished(ctx->bro)) {
        if (ngx_http_brotli_filter_end(r, ctx) != NGX_OK) {
            return NGX_ERROR;
        }
        return NGX_OK;
    }

    return NGX_AGAIN;
}
Пример #6
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;
}