Skip to content

Commit

Permalink
parser: gzip/deflate support
Browse files Browse the repository at this point in the history
  • Loading branch information
ashtum committed Oct 7, 2024
1 parent ae0e9de commit 3556a8d
Show file tree
Hide file tree
Showing 12 changed files with 601 additions and 201 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -915,6 +915,7 @@ jobs:
cp -r "$workspace_root"/buffers-root libs/buffers
python3 tools/boostdep/depinst/depinst.py buffers
python3 tools/boostdep/depinst/depinst.py $module
- name: Boost B2 Workflow
uses: alandefreitas/cpp-actions/[email protected]
Expand Down
3 changes: 3 additions & 0 deletions include/boost/http_proto/detail/header.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//
// Copyright (c) 2019 Vinnie Falco ([email protected])
// Copyright (c) 2024 Mohammad Nejati
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Expand Down Expand Up @@ -211,11 +212,13 @@ struct header
void on_insert_content_length(core::string_view);
void on_insert_expect(core::string_view);
void on_insert_transfer_encoding();
void on_insert_content_encoding(core::string_view);
void on_insert_upgrade(core::string_view);
void on_erase_connection();
void on_erase_content_length();
void on_erase_expect();
void on_erase_transfer_encoding();
void on_erase_content_encoding();
void on_erase_upgrade();
void on_erase_all(field);
void update_payload() noexcept;
Expand Down
4 changes: 4 additions & 0 deletions include/boost/http_proto/error.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//
// Copyright (c) 2021 Vinnie Falco ([email protected])
// Copyright (c) 2024 Mohammad Nejati
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Expand Down Expand Up @@ -55,6 +56,9 @@ enum class error
/// Invalid Connection field value
bad_connection,

/// Syntax error in content-encoding
bad_content_encoding,

/// Invalid Content-Length field value or values
bad_content_length,

Expand Down
46 changes: 46 additions & 0 deletions include/boost/http_proto/metadata.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//
// Copyright (c) 2021 Vinnie Falco ([email protected])
// Copyright (c) 2024 Mohammad Nejati
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Expand Down Expand Up @@ -64,6 +65,11 @@ encoding
*/
identity,

/**
* Indicates the body encoding is unsupported.
*/
unsupported,

/**
* Indicates the body has deflate applied.
*/
Expand Down Expand Up @@ -128,6 +134,42 @@ struct metadata

//--------------------------------------------

/** Metadata for the Content-Encoding field
*/
struct content_encoding_t
{
/** Error status of Content-Encoding
*/
system::error_code ec;

/** The total number of fields
*/
std::size_t count = 0;

/** The body encoding.
*/
http_proto::encoding encoding =
http_proto::encoding::identity;

#ifdef BOOST_HTTP_PROTO_AGGREGATE_WORKAROUND
constexpr
content_encoding_t() = default;

constexpr
content_encoding_t(
system::error_code ec_,
std::size_t count_) noexcept
: ec(ec_)
, count(count_)
, encoding(
http_proto::encoding::identity)
{
}
#endif
};

//--------------------------------------------

/** Metadata for the Content-Length field
*/
struct content_length_t
Expand Down Expand Up @@ -320,6 +362,10 @@ struct metadata
*/
connection_t connection;

/** Metadata for the Content-Encoding field.
*/
content_encoding_t content_encoding;

/** Metadata for the Content-Length field.
*/
content_length_t content_length;
Expand Down
19 changes: 11 additions & 8 deletions include/boost/http_proto/parser.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//
// Copyright (c) 2019 Vinnie Falco ([email protected])
// Copyright (c) 2024 Mohammad Nejati
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Expand Down Expand Up @@ -77,18 +78,20 @@ class BOOST_SYMBOL_VISIBLE

/** True if parser can decode deflate transfer and content encodings.
The deflate decoder must already be
The zlib service must already be
installed thusly, or else an exception
is thrown.
@par Install Deflate Decoder
@code
deflate_decoder_service::config cfg;
cfg.install( ctx );
@endcode
*/
bool apply_deflate_decoder = false;

/** True if parser can decode gzip transfer and content encodings.
The zlib service must already be
installed thusly, or else an exception
is thrown.
*/
bool apply_gzip_decoder = false;

/** Minimum space for payload buffering.
This value controls the following
Expand Down Expand Up @@ -420,7 +423,7 @@ class BOOST_SYMBOL_VISIBLE

buffers::circular_buffer* body_buf_ = nullptr;
buffers::any_dynamic_buffer* eb_ = nullptr;
detail::filter* filt_ = nullptr;
detail::filter* filter_ = nullptr;
sink* sink_ = nullptr;

state st_ = state::start;
Expand Down
73 changes: 73 additions & 0 deletions src/detail/header.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//
// Copyright (c) 2019 Vinnie Falco ([email protected])
// Copyright (c) 2024 Mohammad Nejati
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Expand Down Expand Up @@ -357,6 +358,8 @@ maybe_count(
{
case field::connection:
return md.connection.count;
case field::content_encoding:
return md.content_encoding.count;
case field::content_length:
return md.content_length.count;
case field::expect:
Expand All @@ -381,6 +384,7 @@ is_special(
switch(id)
{
case field::connection:
case field::content_encoding:
case field::content_length:
case field::expect:
case field::transfer_encoding:
Expand Down Expand Up @@ -419,6 +423,8 @@ on_insert(
return;
switch(id)
{
case field::content_encoding:
return on_insert_content_encoding(v);
case field::content_length:
return on_insert_content_length(v);
case field::connection:
Expand All @@ -445,6 +451,8 @@ on_erase(field id)
{
case field::connection:
return on_erase_connection();
case field::content_encoding:
return on_erase_content_encoding();
case field::content_length:
return on_erase_content_length();
case field::expect:
Expand Down Expand Up @@ -648,6 +656,52 @@ on_insert_transfer_encoding()
update_payload();
}

void
header::
on_insert_content_encoding(
core::string_view v)
{
++md.content_encoding.count;
if( md.content_encoding.ec.failed() )
return;

auto rv = grammar::parse(
v, list_rule(token_rule, 1));
if( !rv )
{
md.content_encoding.ec =
BOOST_HTTP_PROTO_ERR(
error::bad_content_encoding);
return;
}

if( rv->size() > 1 ||
md.content_encoding.count > 1)
{
md.content_encoding.encoding =
encoding::unsupported;
return;
}

if( grammar::ci_is_equal(*(rv->begin()),
"deflate") )
{
md.content_encoding.encoding =
encoding::deflate;
}
else if( grammar::ci_is_equal(*(rv->begin()),
"gzip") )
{
md.content_encoding.encoding =
encoding::gzip;
}
else
{
md.content_encoding.encoding =
encoding::unsupported;
}
}

void
header::
on_insert_upgrade(
Expand Down Expand Up @@ -807,6 +861,25 @@ on_erase_transfer_encoding()
on_insert_transfer_encoding();
}

void
header::
on_erase_content_encoding()
{
BOOST_ASSERT(
md.content_encoding.count > 0);
--md.content_encoding.count;
if(md.content_encoding.count == 0)
{
// no Content-Encoding
md.content_encoding = {};
return;
}
// re-insert everything
--md.content_encoding.count;
// TODO
// on_insert_content_encoding();
}

// called when Upgrade is erased
void
header::
Expand Down
26 changes: 13 additions & 13 deletions src/detail/impl/filter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,6 @@ process_impl(
auto ib = *it_i;
for(;;)
{
results rs = process_impl(ob, ib, more);

rv.out_bytes += rs.out_bytes;
rv.in_bytes += rs.in_bytes;
rv.ec = rs.ec;
rv.finished = rs.finished;

if(rv.finished || rv.ec)
return rv;

ob = buffers::sans_prefix(ob, rs.out_bytes);
ib = buffers::sans_prefix(ib, rs.in_bytes);

if(ob.size() == 0)
{
if(++it_o == buffers::end(out))
Expand All @@ -65,6 +52,19 @@ process_impl(
return rv;
ib = *it_i;
}

results rs = process_impl(ob, ib, more);

rv.out_bytes += rs.out_bytes;
rv.in_bytes += rs.in_bytes;
rv.ec = rs.ec;
rv.finished = rs.finished;

if(rv.finished || rv.ec)
return rv;

ob = buffers::sans_prefix(ob, rs.out_bytes);
ib = buffers::sans_prefix(ib, rs.in_bytes);
}
}

Expand Down
Loading

0 comments on commit 3556a8d

Please sign in to comment.