Skip to content
Merged

Work #49

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
1 change: 1 addition & 0 deletions include/boost/burl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <boost/burl/conversion.hpp>
#include <boost/burl/cookie.hpp>
#include <boost/burl/cookie_jar.hpp>
#include <boost/burl/encoder_config.hpp>
#include <boost/burl/error.hpp>
#include <boost/burl/fields.hpp>
#include <boost/burl/fields_base.hpp>
Expand Down
134 changes: 134 additions & 0 deletions include/boost/burl/encoder_config.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
//
// Copyright (c) 2026 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)
//
// Official repository: https://github.com/cppalliance/burl
//

#ifndef BOOST_BURL_ENCODER_CONFIG_HPP
#define BOOST_BURL_ENCODER_CONFIG_HPP

#include <boost/burl/detail/config.hpp>

#include <boost/http/brotli/encode.hpp>
#include <boost/http/zstd/compress.hpp>

#include <optional>

namespace boost
{
namespace burl
{

/** Settings for the content encoders. */
struct encoder_config
{
/** Settings for the gzip and deflate codings. */
struct zlib_settings
{
/** The compression level.

Ranges from 0, no compression, to 9,
best compression; this is the lever
trading CPU for ratio.
*/
int level = 5;

/** The base-2 logarithm of the window size.

Ranges from 9 to 15. A stream uses about
twice the window size in memory for the
window.
*/
int window_bits = 15;

/** The memory level.

Ranges from 1 to 9 and sizes the internal
state independently of the window, at
about `1 << (mem_level + 9)` octets.
*/
int mem_level = 8;
};

/** Settings for the br coding. */
struct brotli_settings
{
/** The compression quality.

Ranges from 0, fastest, to 11, best
compression. Quality 4 is comparable in
speed to zlib level 6; the library
default of 11 is unsuitable for encoding
on the fly.
*/
int quality = 4;

/** The base-2 logarithm of the window size.

Ranges from 10 to 24; the window holds
`(1 << lgwin) - 16` octets. The library
default of 22 costs about sixteen times
the memory of 18 for a marginal gain on
typical bodies.
*/
int lgwin = 18;

/** The base-2 logarithm of the input block size.

Ranges from 16 to 24, or zero to let the
encoder choose. Pinning it only serves
to bound the memory footprint.
*/
int lgblock = 0;

/** The encoder mode.

Describes the input; `text` improves the
ratio for UTF-8 text.
*/
http::brotli::encoder_mode mode =
http::brotli::encoder_mode::generic;
};

/** Settings for the zstd coding. */
struct zstd_settings
{
/** The compression level.

Ranges from the most negative level the
library allows, fastest, to 22, best
compression. Negative levels suit
high-throughput proxying.
*/
int level = 3;

/** The base-2 logarithm of the window size.

Ranges from 10 to 31, or zero to derive
it from the level. The decoder allocates
a window of the same size, and HTTP has
no way to signal it.
*/
int window_log = 0;

/** The compression strategy.

When unset, the strategy is derived from
the level; set it only to decouple speed
from level.
*/
std::optional<http::zstd::strategy> strategy;
};

zlib_settings zlib = {};
brotli_settings brotli = {};
zstd_settings zstd = {};
};

} // namespace burl
} // namespace boost

#endif
14 changes: 6 additions & 8 deletions include/boost/burl/head_parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <boost/burl/response_head_base.hpp>

#include <boost/http/error.hpp>
#include <boost/system/result.hpp>
#include <system_error>

#include <cstdint>
Expand Down Expand Up @@ -246,20 +247,17 @@ class head_parser
@param n The total number of bytes received at
the parse base.

@param ec Set to:
- Zero if the header completed and its
payload framing is valid.
@return Nothing if the header completed and
its payload framing is valid, otherwise:
- @ref http::error::need_data if more input is
required and room remains below @ref ceiling.
- @ref http::error::in_place_overflow if more
input is required but no room remains.
- A syntax, framing, or limit error otherwise.
- A syntax, framing, or limit error.
*/
BOOST_BURL_DECL
void
parse(
std::size_t n,
std::error_code& ec) noexcept;
system::result<void, std::error_code>
parse(std::size_t n) noexcept;

/** Return the limits enforced by the parser.

Expand Down
38 changes: 20 additions & 18 deletions include/boost/burl/message_reader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ class message_reader
@return An awaitable yielding
`(error_code,std::string_view)`.

@see @ref parser::body.
@see @ref parser::flatten_body.
*/
capy::io_task<std::string_view>
read_body()
Expand Down Expand Up @@ -268,12 +268,11 @@ read_header_(S& stream, parser& pr)
{
for(;;)
{
std::error_code ec;
pr.parse_header(ec);
if(!ec)
auto const rv = pr.parse_header();
if(rv.has_value())
co_return {};
if(ec != http::error::need_data)
co_return { std::error_code(ec) };
if(rv.error() != http::error::need_data)
co_return { rv.error() };
if(auto [rec] = co_await refill_(stream, pr); rec)
co_return { rec };
}
Expand All @@ -286,10 +285,11 @@ read_body_(S& stream, parser& pr)
{
for(;;)
{
std::error_code ec;
auto const sv = pr.flatten_body(ec);
if(ec != http::error::need_data)
co_return { std::error_code(ec), sv };
auto const r = pr.flatten_body();
if(r.has_value())
co_return { std::error_code(), *r };
if(r.error() != http::error::need_data)
co_return { r.error(), {} };
if(auto [rec] = co_await refill_(stream, pr); rec)
co_return { rec, {} };
}
Expand All @@ -306,10 +306,11 @@ read_some_(
{
for(;;)
{
std::error_code ec;
auto const n = pr.read_some(buffers, ec);
if(ec != http::error::need_data)
co_return { std::error_code(ec), n };
auto const r = pr.read_some(buffers);
if(r.has_value())
co_return { std::error_code(), *r };
if(r.error() != http::error::need_data)
co_return { r.error(), 0 };

if(auto const lim = pr.direct_capacity(); lim != 0)
{
Expand Down Expand Up @@ -365,10 +366,11 @@ pull_(
{
for(;;)
{
std::error_code ec;
auto const bufs = pr.pull(dest, ec);
if(ec != http::error::need_data)
co_return { std::error_code(ec), bufs };
auto const r = pr.pull(dest);
if(r.has_value())
co_return { std::error_code(), *r };
if(r.error() != http::error::need_data)
co_return { r.error(), {} };
if(auto [rec] = co_await refill_(stream, pr); rec)
co_return { rec, {} };
}
Expand Down
21 changes: 8 additions & 13 deletions include/boost/burl/message_writer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#include <boost/burl/serializer.hpp>

#include <boost/assert.hpp>
#include <boost/capy/buffers/buffer_param.hpp>
#include <boost/capy/buffers/consuming_buffers.hpp>
#include <boost/capy/concept/write_stream.hpp>
#include <boost/capy/io_task.hpp>

Expand Down Expand Up @@ -256,25 +256,20 @@ drive_(
CB buffers,
bool more)
{
capy::const_buffer_param<CB> bp(buffers);
capy::consuming_buffers cb(buffers);
capy::const_buffer dest[16];
std::size_t total = 0;
for(;;)
{
std::error_code ec;
auto const body = bp.data();
auto const bufs = sr.frame(
dest, body, more || bp.more(), ec);
auto [wec, n] = co_await stream.write_some(bufs);
auto const fr = sr.frame(dest, cb.data(), more);
if(fr.has_error())
co_return { fr.error(), total };
auto [ec, n] = co_await stream.write_some(*fr);
auto const k = sr.consume(n);
bp.consume(k);
cb.consume(k);
total += k;
if(ec)
if(ec || n == 0)
co_return { ec, total };
if(wec)
co_return { wec, total };
if(bufs.empty() && !bp.more())
co_return { std::error_code(), total };
}
}

Expand Down
Loading
Loading