Skip to content
This repository is currently being migrated. It's locked while the migration is in progress.

Commit 8889d4d

Browse files
authored
Merge pull request #9 from peroxyacyl/2021.12.20-fix-gzip-buffer
grow buffer on overflow
2 parents 6e0da13 + 1caca5e commit 8889d4d

File tree

1 file changed

+51
-30
lines changed

1 file changed

+51
-30
lines changed

src/influxdb-cpp-rest/influxdb2_simple_async_api.cpp

Lines changed: 51 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -91,44 +91,65 @@ struct simple_db::impl
9191
{
9292
try
9393
{
94-
std::vector<concurrency::streams::istream> streams;
9594
auto c = make_compressor(algorithm::GZIP);
96-
std::vector<uint8_t> pre;
97-
pre.resize(w->size());
98-
size_t used;
95+
96+
const int rawdata_size = w->size();
97+
const uint8_t* rawdata_ptr =
98+
reinterpret_cast<const uint8_t*>(w->data());
99+
int rawdata_cursor = 0;
100+
101+
std::vector<uint8_t> compression_buffer;
102+
int compressed_size = 0;
99103
bool done = false;
100-
auto got = c->compress(reinterpret_cast<const uint8_t*>(w->data()),
101-
w->size(), pre.data(), pre.size(),
102-
web::http::compression::operation_hint::is_last,
103-
used, done);
104-
streams.emplace_back(
105-
concurrency::streams::rawptr_stream<uint8_t>::open_istream(
106-
pre.data(), got));
107104

108-
for (auto& stream : streams)
105+
compression_buffer.resize(rawdata_size);
106+
while (!done)
109107
{
110-
http_request request;
111-
request.set_request_uri(uri_with_db);
112-
request.set_method(methods::POST);
113-
request.headers().add("Authorization", "Token " + token);
114-
request.headers().add(header_names::content_encoding,
115-
algorithm::GZIP);
116-
117-
request.set_body(stream);
118-
auto response = client.request(request);
119-
try
108+
size_t used = 0;
109+
if (compressed_size >= rawdata_size * 16)
120110
{
121-
response.wait();
122-
if (!(response.get().status_code() == status_codes::OK ||
123-
response.get().status_code() == status_codes::NoContent))
124-
{
125-
throw std::runtime_error(response.get().extract_string().get());
126-
}
111+
throw std::runtime_error(
112+
"gzip data is 16 times larger than raw data. abort "
113+
"compression");
127114
}
128-
catch (const std::exception& e)
115+
if (compressed_size == compression_buffer.size())
129116
{
130-
throw std::runtime_error(e.what());
117+
compression_buffer.resize(compressed_size * 2);
131118
}
119+
const int got = c->compress(
120+
rawdata_ptr + rawdata_cursor, // rawdata ptr
121+
rawdata_size - rawdata_cursor, // remaining rawdata size
122+
compression_buffer.data() +
123+
compressed_size, // buffer ptr to append
124+
compression_buffer.size() -
125+
compressed_size, // buffer available size
126+
web::http::compression::operation_hint::is_last, used, done);
127+
compressed_size += got;
128+
rawdata_cursor += used;
129+
}
130+
131+
http_request request;
132+
request.set_request_uri(uri_with_db);
133+
request.set_method(methods::POST);
134+
request.headers().add("Authorization", "Token " + token);
135+
request.headers().add(header_names::content_encoding, algorithm::GZIP);
136+
137+
request.set_body(
138+
concurrency::streams::rawptr_stream<uint8_t>::open_istream(
139+
compression_buffer.data(), compressed_size));
140+
auto response = client.request(request);
141+
try
142+
{
143+
response.wait();
144+
if (!(response.get().status_code() == status_codes::OK ||
145+
response.get().status_code() == status_codes::NoContent))
146+
{
147+
throw std::runtime_error(response.get().extract_string().get());
148+
}
149+
}
150+
catch (const std::exception& e)
151+
{
152+
throw std::runtime_error(e.what());
132153
}
133154
}
134155
catch (const std::exception& e)

0 commit comments

Comments
 (0)