Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions doc/admin-guide/plugins/esi.en.rst
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@ Enabling ESI

2. There are four options you can add to the above.

- "--private-response" will add private cache control and expires header to the processed ESI document.
- "--packed-node-support" will enable the support for using packed node, which will improve the performance of parsing
- ``--private-response`` will add private cache control and expires header to the processed ESI document.
- ``--packed-node-support`` will enable the support for using packed node, which will improve the performance of parsing
cached ESI document.
- "--disable-gzip-output" will disable gzipped output, which will NOT gzip the output anyway.
- "--first-byte-flush" will enable the first byte flush feature, which will flush content to users as soon as the entire
- ``--disable-gzip-output`` will disable gzipped output, which will NOT gzip the output anyway.
- ``--first-byte-flush`` will enable the first byte flush feature, which will flush content to users as soon as the entire
ESI document is received and parsed without all ESI includes fetched (the flushing will stop at the ESI include markup
till that include is fetched).

Expand Down
7 changes: 2 additions & 5 deletions plugins/esi/esi.cc
Original file line number Diff line number Diff line change
Expand Up @@ -774,7 +774,7 @@ transformData(TSCont contp)
out_data_len = 0;
out_data = "";
} else {
TSDebug(cont_data->debug_tag, "[%s] Compressed document from size %d to %d bytes", __FUNCTION__, out_data_len,
TSDebug(cont_data->debug_tag, "[%s] Compressed document from size %d to %d bytes via gzip", __FUNCTION__, out_data_len,
static_cast<int>(cdata.size()));
out_data_len = cdata.size();
out_data = cdata.data();
Expand Down Expand Up @@ -839,12 +839,9 @@ transformData(TSCont contp)
if (!cont_data->esi_gzip->stream_encode(out_data, cdata)) {
TSError("[esi][%s] Error while gzipping content", __FUNCTION__);
} else {
TSDebug(cont_data->debug_tag, "[%s] Compressed document from size %d to %d bytes", __FUNCTION__,
TSDebug(cont_data->debug_tag, "[%s] Compressed document from size %d to %d bytes via EsiGzip", __FUNCTION__,
static_cast<int>(out_data.size()), static_cast<int>(cdata.size()));
}
}

if (cont_data->gzip_output) {
if (TSIOBufferWrite(TSVIOBufferGet(cont_data->output_vio), cdata.data(), cdata.size()) == TS_ERROR) {
TSError("[esi][%s] Error while writing bytes to downstream VC", __FUNCTION__);
return 0;
Expand Down
19 changes: 15 additions & 4 deletions plugins/esi/lib/EsiGzip.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ using std::string;
using namespace EsiLib;

EsiGzip::EsiGzip(const char *debug_tag, ComponentBase::Debug debug_func, ComponentBase::Error error_func)
: ComponentBase(debug_tag, debug_func, error_func), _downstream_length(0), _total_data_length(0)
: ComponentBase(debug_tag, debug_func, error_func), _downstream_length(0), _total_data_length(0), _crc(0)
{
// Zlib _zstrm variables are initialized when they are required in runDeflateLoop
// coverity[uninit_member]
Expand Down Expand Up @@ -71,6 +71,7 @@ runDeflateLoop(z_stream &zstrm, int flush, std::string &cdata)
bool
EsiGzip::stream_encode(const char *data, int data_len, std::string &cdata)
{
const auto initial_cdata_size = cdata.size();
if (_downstream_length == 0) {
cdata.assign(GZIP_HEADER_SIZE, 0); // reserving space for the header
cdata[0] = MAGIC_BYTE_1;
Expand Down Expand Up @@ -102,10 +103,9 @@ EsiGzip::stream_encode(const char *data, int data_len, std::string &cdata)
return false;
}
_crc = crc32(_crc, reinterpret_cast<const Bytef *>(data), data_len);
_downstream_length += cdata.size();
_total_data_length += data_len;
}

_downstream_length += cdata.size() - initial_cdata_size;
deflateEnd(&_zstrm);

return true;
Expand All @@ -114,6 +114,17 @@ EsiGzip::stream_encode(const char *data, int data_len, std::string &cdata)
bool
EsiGzip::stream_finish(std::string &cdata, int &downstream_length)
{
if (_downstream_length == 0) {
// We need to run encode first to get the gzip header inserted.
if (!stream_encode(nullptr, 0, cdata)) {
return false;
}
}
// Note that a call to stream_encode will update cdata to apply the gzip
// header and that call itself will update _downstream_length. Since we don't
// want to double count the gzip header bytes, we capture initial_cdata_size
// here after any possible call to stream_encode above.
const auto initial_cdata_size = cdata.size();
char buf[BUF_SIZE];

_zstrm.zalloc = Z_NULL;
Expand All @@ -136,7 +147,7 @@ EsiGzip::stream_finish(std::string &cdata, int &downstream_length)
}
append(cdata, static_cast<uint32_t>(_crc));
append(cdata, static_cast<int32_t>(_total_data_length));
_downstream_length += cdata.size();
_downstream_length += cdata.size() - initial_cdata_size;
downstream_length = _downstream_length;
return true;
}
Expand Down
27 changes: 25 additions & 2 deletions plugins/esi/lib/EsiGzip.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "ComponentBase.h"
#include <zlib.h>
#include <string>
#include <string_view>

class EsiGzip : private EsiLib::ComponentBase
{
Expand All @@ -34,19 +35,41 @@ class EsiGzip : private EsiLib::ComponentBase

~EsiGzip() override;

/** Compress the provided content.
*
* @param[in] data The input data to compress.
* @param[in] data_len The length of the input data to compress.
* @param[in,out] The result of compressing the input data will be appended
* to cdata.
*
* @return True if the compression succeeded, false otherwise.
*/
bool stream_encode(const char *data, int data_len, std::string &cdata);

/** A string_view overload of stream_encode. */
inline bool
stream_encode(std::string data, std::string &cdata)
stream_encode(std::string_view data, std::string &cdata)
{
return stream_encode(data.data(), data.size(), cdata);
}

/** Finish the compression stream.
*
* @param[out] cdata The compressed data is appended to this.
* @param[out] downstream_length The total number of compressed stream bytes
* across all calls to stream_encode and stream_finish.
*
* @return True if the compression succeeded, false otherwise.
*/
bool stream_finish(std::string &cdata, int &downstream_length);

private:
// int runDeflateLoop(z_stream &zstrm, int flush, std::string &cdata);
/** The cumulative total number of bytes for the compressed stream. */
int _downstream_length;

/** The cumulative total number of uncompressed bytes that have been
* compressed.
*/
int _total_data_length;
z_stream _zstrm;
uLong _crc;
Expand Down
Loading