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
27 changes: 27 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,33 @@ if (Libpsl_FOUND)
target_compile_definitions(boost_burl PRIVATE BOOST_BURL_HAS_LIBPSL)
endif ()

#-------------------------------------------------
#
# Compression backends (optional)
#
#-------------------------------------------------

# zlib: deflate and gzip content codings
find_package(ZLIB)
if (ZLIB_FOUND)
target_link_libraries(boost_burl PRIVATE ZLIB::ZLIB)
target_compile_definitions(boost_burl PUBLIC BOOST_BURL_HAS_ZLIB)
endif ()

# Brotli: br content coding (decoding only)
find_package(Brotli)
if (Brotli_FOUND)
target_link_libraries(boost_burl PRIVATE Brotli::common Brotli::decoder)
target_compile_definitions(boost_burl PUBLIC BOOST_BURL_HAS_BROTLI)
endif ()

# Zstandard: zstd content coding
find_package(Zstd)
if (Zstd_FOUND)
target_link_libraries(boost_burl PRIVATE Zstd::Zstd)
target_compile_definitions(boost_burl PUBLIC BOOST_BURL_HAS_ZSTD)
endif ()

#-------------------------------------------------
#
# Tests
Expand Down
11 changes: 7 additions & 4 deletions build/Jamfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import config : requires ;

using openssl ;
using zlib ;
using brotli ;
using zstd ;

constant c11-requires :
Expand Down Expand Up @@ -40,8 +41,9 @@ lib boost_burl
<library>/boost//capy
<library>/boost//corosio
[ ac.check-library /boost/corosio//boost_corosio_openssl : <library>/boost/corosio//boost_corosio_openssl : ]
[ ac.check-library /zlib//zlib : <library>/zlib//zlib : ]
[ ac.check-library /zstd//zstd : <library>/zstd//zstd : ]
[ ac.check-library /zlib//zlib : <library>/zlib//zlib <define>BOOST_BURL_HAS_ZLIB : ]
[ ac.check-library /brotli//brotlidec : <library>/brotli//brotlicommon <library>/brotli//brotlidec <define>BOOST_BURL_HAS_BROTLI : ]
[ ac.check-library /zstd//zstd : <library>/zstd//zstd <define>BOOST_BURL_HAS_ZSTD : ]
<library>/boost//http
<library>/boost//json
<library>/boost//url
Expand All @@ -51,8 +53,9 @@ lib boost_burl
<library>/boost//capy
<library>/boost//corosio
[ ac.check-library /boost/corosio//boost_corosio_openssl : <library>/boost/corosio//boost_corosio_openssl : ]
[ ac.check-library /zlib//zlib : <library>/zlib//zlib : ]
[ ac.check-library /zstd//zstd : <library>/zstd//zstd : ]
[ ac.check-library /zlib//zlib : <library>/zlib//zlib <define>BOOST_BURL_HAS_ZLIB : ]
[ ac.check-library /brotli//brotlidec : <library>/brotli//brotlicommon <library>/brotli//brotlidec <define>BOOST_BURL_HAS_BROTLI : ]
[ ac.check-library /zstd//zstd : <library>/zstd//zstd <define>BOOST_BURL_HAS_ZSTD : ]
<library>/boost//http
<library>/boost//json
<library>/boost//url
Expand Down
50 changes: 50 additions & 0 deletions cmake/FindBrotli.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#
# 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
#

# Provides imported targets:
# Brotli::common
# Brotli::decoder
# Brotli::encoder

find_path(Brotli_INCLUDE_DIR NAMES "brotli/decode.h")
find_library(Brotli_COMMON_LIBRARY NAMES "brotlicommon")
find_library(Brotli_DEC_LIBRARY NAMES "brotlidec")
find_library(Brotli_ENC_LIBRARY NAMES "brotlienc")

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Brotli
REQUIRED_VARS
Brotli_INCLUDE_DIR
Brotli_COMMON_LIBRARY
Brotli_DEC_LIBRARY
Brotli_ENC_LIBRARY
)

if(Brotli_FOUND)
add_library(Brotli::common UNKNOWN IMPORTED)
set_target_properties(Brotli::common PROPERTIES
IMPORTED_LOCATION "${Brotli_COMMON_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${Brotli_INCLUDE_DIR}")

add_library(Brotli::decoder UNKNOWN IMPORTED)
set_target_properties(Brotli::decoder PROPERTIES
IMPORTED_LOCATION "${Brotli_DEC_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${Brotli_INCLUDE_DIR}")

add_library(Brotli::encoder UNKNOWN IMPORTED)
set_target_properties(Brotli::encoder PROPERTIES
IMPORTED_LOCATION "${Brotli_ENC_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${Brotli_INCLUDE_DIR}")
endif()

mark_as_advanced(
Brotli_INCLUDE_DIR
Brotli_COMMON_LIBRARY
Brotli_DEC_LIBRARY
Brotli_ENC_LIBRARY)
33 changes: 33 additions & 0 deletions cmake/FindZstd.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#
# 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
#

# Provides imported targets:
# Zstd::Zstd

find_path(Zstd_INCLUDE_DIR NAMES "zstd.h")
find_library(Zstd_LIBRARY NAMES zstd libzstd zstd_static)

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Zstd
REQUIRED_VARS
Zstd_INCLUDE_DIR
Zstd_LIBRARY
)

if(Zstd_FOUND)
add_library(Zstd::Zstd UNKNOWN IMPORTED)
set_target_properties(Zstd::Zstd PROPERTIES
IMPORTED_LOCATION "${Zstd_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${Zstd_INCLUDE_DIR}"
)
endif()

mark_as_advanced(
Zstd_INCLUDE_DIR
Zstd_LIBRARY)
8 changes: 0 additions & 8 deletions example/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,6 @@
add_executable(burl_example_usage usage.cpp)
target_link_libraries(burl_example_usage PRIVATE Boost::burl Boost::hash2)

if (TARGET Boost::http_zlib)
target_link_libraries(burl_example_usage PRIVATE Boost::http_zlib)
endif()

if (TARGET Boost::http_brotli)
target_link_libraries(burl_example_usage PRIVATE Boost::http_brotli)
endif()

find_package(nlohmann_json QUIET)
if (nlohmann_json_FOUND)
add_executable(burl_example_nlohmann_json nlohmann_json.cpp)
Expand Down
9 changes: 0 additions & 9 deletions example/usage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
#include <boost/burl.hpp>
#include <boost/capy.hpp>
#include <boost/corosio.hpp>
#include <boost/http/brotli.hpp>
#include <boost/http/zlib.hpp>
#include <boost/json.hpp>
#include <boost/hash2/sha2.hpp>

Expand Down Expand Up @@ -569,13 +567,6 @@ main(int argc, char* argv[])
corosio::io_context ioc;
corosio::tls_context tls_ctx;

#ifdef BOOST_HTTP_HAS_BROTLI
http::brotli::install_decode_service(capy::get_system_context());
#endif
#ifdef BOOST_HTTP_HAS_ZLIB
http::zlib::install_inflate_service(capy::get_system_context());
#endif

capy::run_async(
ioc.get_executor(),
[] {},
Expand Down
39 changes: 26 additions & 13 deletions include/boost/burl/client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,11 @@ class client
When enabled, `br` is included in the
`Accept-Encoding` header and response
bodies are decoded transparently.
Effective only when the Brotli decode
service is installed in the system
context. Not applied when the request
carries an explicit `Accept-Encoding`
header.
Effective only when the library was built
with Brotli support
(`BOOST_BURL_HAS_BROTLI`). Not applied
when the request carries an explicit
`Accept-Encoding` header.
*/
bool brotli = true;

Expand All @@ -154,9 +154,9 @@ class client
the `Accept-Encoding` header and
response bodies are decoded
transparently. Effective only when the
zlib inflate service is installed in the
system context. Not applied when the
request carries an explicit
library was built with zlib support
(`BOOST_BURL_HAS_ZLIB`). Not applied when
the request carries an explicit
`Accept-Encoding` header.
*/
bool deflate = true;
Expand All @@ -166,14 +166,27 @@ class client
When enabled, `gzip` is included in the
`Accept-Encoding` header and response
bodies are decoded transparently.
Effective only when the zlib inflate
service is installed in the system
context. Not applied when the request
carries an explicit `Accept-Encoding`
header.
Effective only when the library was built
with zlib support
(`BOOST_BURL_HAS_ZLIB`). Not applied when
the request carries an explicit
`Accept-Encoding` header.
*/
bool gzip = true;

/** Advertise and decode the zstd content coding.

When enabled, `zstd` is included in the
`Accept-Encoding` header and response
bodies are decoded transparently.
Effective only when the library was built
with zstd support
(`BOOST_BURL_HAS_ZSTD`). Not applied when
the request carries an explicit
`Accept-Encoding` header.
*/
bool zstd = true;

/** Maximum allowed size of a response body.

Reading a body which exceeds the limit
Expand Down
3 changes: 1 addition & 2 deletions include/boost/burl/detail/parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,7 @@ class parser

capy::io_task<std::size_t>
do_read_some(
std::span<capy::mutable_buffer const> buffers,
bool skip_out = false);
std::span<capy::mutable_buffer const> buffers);

struct header_deleter
{
Expand Down
8 changes: 8 additions & 0 deletions include/boost/burl/error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@ enum class error
request.
*/
body_size_mismatch,

/** The response body could not be decoded.

Decoding the response body according to its
`Content-Encoding` failed because the compressed
data was corrupt or invalid.
*/
decode_error,
};

/** Error conditions corresponding to sets of error codes.
Expand Down
22 changes: 13 additions & 9 deletions src/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,13 @@

#include <boost/capy/buffers/make_buffer.hpp>
#include <boost/capy/ex/execution_context.hpp>
#include <boost/capy/ex/system_context.hpp>
#include <boost/capy/timeout.hpp>
#include <boost/capy/write.hpp>
#include <boost/burl/detail/response_parser.hpp>
#include <boost/http/brotli/decode.hpp>
#include <boost/http/field.hpp>
#include <boost/http/request.hpp>
#include <boost/http/response_base.hpp>
#include <boost/http/status.hpp>
#include <boost/http/zlib/inflate.hpp>

#include <chrono>
#include <optional>
Expand Down Expand Up @@ -66,6 +63,9 @@ set_accept_encoding(
if(cfg.gzip)
accept("gzip");

if(cfg.zstd)
accept("zstd");

if(!accept_encoding.empty())
headers.set(http::field::accept_encoding, accept_encoding);
}
Expand Down Expand Up @@ -96,12 +96,16 @@ client::client(
std::make_shared<detail::connection_pool>(
exec, std::move(tls_ctx), cfg))
{
// Disable codings whose decoder service is unavailable.
auto const& ctx = capy::get_system_context();
if(!ctx.has_service<http::brotli::decode_service>())
config_.brotli = false;
if(!ctx.has_service<http::zlib::inflate_service>())
config_.deflate = config_.gzip = false;
// Disable codings whose decoder was not compiled in.
#ifndef BOOST_BURL_HAS_BROTLI
config_.brotli = false;
#endif
#ifndef BOOST_BURL_HAS_ZLIB
config_.deflate = config_.gzip = false;
#endif
#ifndef BOOST_BURL_HAS_ZSTD
config_.zstd = false;
#endif
}

void
Expand Down
Loading
Loading