Skip to content
Closed
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 .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* text=auto eol=lf
24 changes: 9 additions & 15 deletions CMakePresets.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
{
"version": 8,
"configurePresets": [
{
"name": "Custom configure preset",
"displayName": "Custom configure preset",
"description": "Sets Ninja generator, build and install directory",
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}"
}
}
]
}
"version": 6,
"cmakeMinimumRequired": {
"major": 3,
"minor": 25,
"patch": 0
},
Comment on lines +2 to +7
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# Check for cmake_minimum_required declarations
rg -n 'cmake_minimum_required' --glob 'CMakeLists.txt'

# Check CI/CD configurations
rg -n 'cmake' --glob '*.yml' --glob '*.yaml' -i

# Check README documentation
rg -n 'cmake' --glob '*README*' -i

# Also check if there are any other CMake configuration files
fd -e 'CMakeLists.txt' -o -e 'CMakePresets.json'

Repository: cppalliance/beast2

Length of output: 450


CMakePresets.json requires CMake 3.25.0 but CMakeLists.txt only supports up to 3.20.

The schema version 6 and cmakeMinimumRequired 3.25.0 in CMakePresets.json create an incompatibility: the main CMakeLists.txt declares cmake_minimum_required(VERSION 3.8...3.20), which allows CMake up to 3.20. Users with CMake 3.21–3.24 will be unable to use presets while the main build remains compatible.

Either update CMakeLists.txt to require CMake 3.25.0, or lower CMakePresets.json's cmakeMinimumRequired to match the actual project minimum (3.8).

🤖 Prompt for AI Agents
In `@CMakePresets.json` around lines 2 - 7, CMakePresets.json currently sets
cmakeMinimumRequired to 3.25.0 which conflicts with the project's CMakeLists.txt
that declares cmake_minimum_required(VERSION 3.8...3.20); fix by making these
consistent: either lower CMakePresets.json cmakeMinimumRequired to 3.8.0 to
match the existing CMakeLists.txt, or update the CMakeLists.txt
cmake_minimum_required declaration to 3.25.0 (and adjust any code requiring
newer CMake features) so both CMakePresets.json and the
cmake_minimum_required(VERSION ...) in CMakeLists.txt reference the same minimum
version.

"configurePresets": [],
"buildPresets": []
}
6 changes: 3 additions & 3 deletions doc/tagfiles/boost-http-doxygen.tag.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<class kind="class">boost::http::is_sink</class>
<class kind="class">boost::http::is_source</class>
<class kind="class">boost::http::route_result</class>
<class kind="class">boost::http::router</class>
<class kind="class">boost::http::basic_router</class>
<class kind="class">boost::http::acceptor_config</class>
<class kind="class">boost::http::any_router</class>
<class kind="class">boost::http::basic_router</class>
Expand Down Expand Up @@ -149,8 +149,8 @@
<filename>boost/http/route_result.adoc</filename>
</compound>
<compound kind="class">
<name>boost::http::router</name>
<filename>boost/http/router.adoc</filename>
<name>boost::http::basic_router</name>
<filename>boost/http/basic_router.adoc</filename>
</compound>
<compound kind="class">
<name>boost::http::acceptor_config</name>
Expand Down
8 changes: 4 additions & 4 deletions example/client/burl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ if (WIN32)
target_link_libraries(beast2_example_client_burl crypt32)
endif()

if (TARGET Boost::capy_zlib)
target_link_libraries(beast2_example_client_burl Boost::capy_zlib)
if (TARGET Boost::http_zlib)
target_link_libraries(beast2_example_client_burl Boost::http_zlib)
endif()

if (TARGET Boost::capy_brotli)
target_link_libraries(beast2_example_client_burl Boost::capy_brotli)
if (TARGET Boost::http_brotli)
target_link_libraries(beast2_example_client_burl Boost::http_brotli)
endif()

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
Expand Down
8 changes: 3 additions & 5 deletions example/client/burl/connect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,6 @@ connect_socks5_proxy(
asio::awaitable<void>
connect_http_proxy(
const operation_config& oc,
capy::polystore& capy_ctx,
asio::ip::tcp::socket& stream,
const urls::url_view& url,
const urls::url_view& proxy)
Expand Down Expand Up @@ -190,8 +189,8 @@ connect_http_proxy(
request.set(field::proxy_authorization, basic_auth);
}

auto serializer = http::serializer{ capy_ctx };
auto parser = http::response_parser{ capy_ctx };
auto serializer = http::serializer{};
auto parser = http::response_parser{};
Comment on lines +192 to +193
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a brief implementation overview block after the includes.
This file contains non-trivial proxy/TLS setup logic; a short /* */ overview near the top would help maintainability. As per coding guidelines, ...

📝 Suggested block comment
 `#include` <boost/url.hpp>

+/*
+Overview:
+ - Establishes TCP connections (direct, HTTP proxy, SOCKS5).
+ - Performs CONNECT handshake for HTTP proxies.
+ - Upgrades to TLS when required.
+*/
🤖 Prompt for AI Agents
In `@example/client/burl/connect.cpp` around lines 192 - 193, Add a brief /* ...
*/ implementation overview block immediately after the `#include` section that
summarizes the file's proxy and TLS setup, the HTTP flow, and any key components
used such as http::serializer and http::response_parser (variables serializer
and parser) so future readers understand purpose and high-level flow before
diving into connect.cpp; keep it concise (3–5 lines) and mention any external
dependencies or sequence of steps (proxy negotiation, TLS handshake, HTTP
request/response parsing) and where serializer/parser are used.


serializer.start(request);
co_await beast2::async_write(stream, serializer);
Expand Down Expand Up @@ -225,7 +224,6 @@ asio::awaitable<void>
connect(
const operation_config& oc,
ssl::context& ssl_ctx,
capy::polystore& capy_ctx,
any_stream& stream,
urls::url url)
{
Expand Down Expand Up @@ -261,7 +259,7 @@ connect(
{
if(oc.proxy.scheme() == "http")
{
co_await connect_http_proxy(oc, capy_ctx, socket, url, oc.proxy);
co_await connect_http_proxy(oc, socket, url, oc.proxy);
}
else if(oc.proxy.scheme() == "socks5")
{
Expand Down
4 changes: 1 addition & 3 deletions example/client/burl/connect.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,17 @@

#include <boost/asio/awaitable.hpp>
#include <boost/asio/ssl/context.hpp>
#include <boost/capy/polystore.hpp>
#include <boost/url/url.hpp>

namespace asio = boost::asio;
namespace capy = boost::capy;
namespace http = boost::http;
namespace ssl = boost::asio::ssl;
namespace urls = boost::urls;

asio::awaitable<void>
connect(
const operation_config& oc,
ssl::context& ssl_ctx,
capy::polystore& capy_ctx,
any_stream& stream,
urls::url url);

Expand Down
46 changes: 12 additions & 34 deletions example/client/burl/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
#include <boost/capy/buffers.hpp>
#include <boost/beast2.hpp>
#include <boost/http.hpp>
#include <boost/capy/brotli/decode.hpp>
#include <boost/capy/zlib/inflate.hpp>
#include <boost/http/brotli/decode.hpp>
#include <boost/http/zlib/inflate.hpp>
Comment on lines +34 to +35
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a brief implementation overview block after the includes.
Given the size and complexity of this file, a short /* */ overview after the includes would help future maintenance. As per coding guidelines, ...

📝 Suggested block comment
 `#include` <boost/url/url.hpp>

+/*
+Overview:
+ - Builds requests, manages redirects, cookies, and retries.
+ - Streams responses with optional progress reporting.
+ - Installs parser/serializer services and decoders for content encodings.
+*/
🤖 Prompt for AI Agents
In `@example/client/burl/main.cpp` around lines 34 - 35, Add a concise C-style
block comment immediately after the include section that briefly describes the
file's purpose and high-level implementation: one-sentence purpose, main
execution flow (mention main), key components used (e.g., usage of
boost::http::brotli::decode and boost::http::zlib::inflate), any concurrency or
error-handling assumptions, and external dependencies; keep it short (3–6 lines)
to aid future maintenance.

#include <boost/scope/scope_exit.hpp>
#include <boost/scope/scope_fail.hpp>
#include <boost/url/parse.hpp>
Expand All @@ -45,13 +45,13 @@ namespace capy = boost::capy;
namespace scope = boost::scope;
using system_error = boost::system::system_error;

#ifdef BOOST_CAPY_HAS_ZLIB
#ifdef BOOST_HTTP_HAS_ZLIB
constexpr bool capy_has_zlib = true;
#else
constexpr bool capy_has_zlib = false;
#endif

#ifdef BOOST_CAPY_HAS_BROTLI
#ifdef BOOST_HTTP_HAS_BROTLI
constexpr bool capy_has_brotli = true;
#else
constexpr bool capy_has_brotli = false;
Expand Down Expand Up @@ -345,15 +345,14 @@ perform_request(
boost::optional<cookie_jar>& cookie_jar,
core::string_view exp_cookies,
ssl::context& ssl_ctx,
capy::polystore& capy_ctx,
message msg,
request_opt request_opt)
{
using field = http::field;
auto executor = co_await asio::this_coro::executor;
auto stream = any_stream{ asio::ip::tcp::socket{ executor } };
auto parser = http::response_parser{ capy_ctx };
auto serializer = http::serializer{ capy_ctx };
auto parser = http::response_parser{};
auto serializer = http::serializer{};

urls::url url = [&]()
{
Expand All @@ -376,26 +375,7 @@ perform_request(

if(!request_opt.input.empty())
{
msg = [&]() -> message
{
if(request_opt.input == "-")
return stdin_body{};

auto path = request_opt.input;

// Append filename to URL if missing
auto segs = url.encoded_segments();
if(segs.empty())
{
segs.push_back(path.filename().string());
}
else if(auto back = --segs.end(); back->empty())
{
segs.replace(back, path.filename().string());
}

return file_body{ path.string() };
}();
throw std::runtime_error{ "File upload is not available" };
}

fs::path output_path = [&]()
Expand Down Expand Up @@ -465,7 +445,7 @@ perform_request(

co_await asio::co_spawn(
executor,
connect(oc, ssl_ctx, capy_ctx, stream, url),
connect(oc, ssl_ctx, stream, url),
asio::cancel_after(oc.connect_timeout));

if(oc.recvpersecond)
Expand Down Expand Up @@ -759,7 +739,6 @@ co_main(int argc, char* argv[])

auto executor = co_await asio::this_coro::executor;
auto task_group = ::task_group{ executor, oc.parallel_max };
auto capy_ctx = capy::polystore{};
auto cookie_jar = boost::optional<::cookie_jar>{};
auto header_output = boost::optional<any_ostream>{};
auto exp_cookies = std::string{};
Expand All @@ -778,22 +757,22 @@ co_main(int argc, char* argv[])
if constexpr(capy_has_brotli)
{
cfg.apply_brotli_decoder = true;
capy::brotli::install_decode_service(capy_ctx);
http::brotli::install_decode_service();
}
if constexpr(capy_has_zlib)
{
cfg.apply_deflate_decoder = true;
cfg.apply_gzip_decoder = true;
capy::zlib::install_inflate_service(capy_ctx);
http::zlib::install_inflate_service();
}
http::install_parser_service(capy_ctx, cfg);
http::install_parser_service(cfg);
}

// serializer service
{
http::serializer::config cfg;
cfg.payload_buffer = 1024 * 1024;
http::install_serializer_service(capy_ctx, cfg);
http::install_serializer_service(cfg);
}

if(!oc.headerfile.empty())
Expand Down Expand Up @@ -831,7 +810,6 @@ co_main(int argc, char* argv[])
cookie_jar,
exp_cookies,
ssl_ctx,
capy_ctx,
oc.msg,
ropt.value());
};
Expand Down
103 changes: 6 additions & 97 deletions example/client/burl/message.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,10 @@
//

#include "message.hpp"
#include "mime_type.hpp"

#include <boost/capy/file.hpp>
#include <boost/http/field.hpp>
#include <boost/system/system_error.hpp>

Comment on lines 10 to 13
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a file-level implementation overview after the includes.

This file contains non-trivial request/body handling logic but lacks the required high-level /* */ overview comment. As per coding guidelines, non-trivial implementation files should include a post-include overview.

📝 Suggested addition
 `#include` "message.hpp"

 `#include` <boost/http/field.hpp>

+/*
+ * High-level overview:
+ * - Implements string_body helpers used for request setup.
+ * - Computes Content-Length and starts the serializer for message bodies.
+ */
 namespace capy = boost::capy;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#include "message.hpp"
#include "mime_type.hpp"
#include <boost/capy/file.hpp>
#include <boost/http/field.hpp>
#include <boost/system/system_error.hpp>
`#include` "message.hpp"
`#include` <boost/http/field.hpp>
/*
* High-level overview:
* - Implements string_body helpers used for request setup.
* - Computes Content-Length and starts the serializer for message bodies.
*/
namespace capy = boost::capy;
🤖 Prompt for AI Agents
In `@example/client/burl/message.cpp` around lines 10 - 13, Add a file-level block
comment (/* ... */) immediately after the includes in message.cpp that provides
a short implementation overview of the non-trivial request/body handling
performed in this translation unit; describe the main responsibilities (e.g.,
parsing/building messages, lifetime/ownership of body buffers, error handling
strategy, and key interactions with any public functions or classes defined in
message.hpp) so readers can quickly understand the file's purpose and high-level
flow before diving into the function-level code.

#include <filesystem>
#include <iostream>

namespace capy = boost::capy;
namespace fs = std::filesystem;
using system_error = boost::system::system_error;
namespace capy = boost::capy;

string_body::string_body(std::string body, std::string content_type)
: body_{ std::move(body) }
Expand Down Expand Up @@ -53,79 +45,6 @@ string_body::body() const noexcept

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

file_body::file_body(std::string path)
: path_{ std::move(path) }
{
}

http::method
file_body::method() const noexcept
{
return http::method::put;
}

core::string_view
file_body::content_type() const noexcept
{
return mime_type(path_);
}

std::uint64_t
file_body::content_length() const
{
return fs::file_size(path_);
}

http::file_source
file_body::body() const
{
boost::capy::file file;
error_code ec;
file.open(path_.c_str(), boost::capy::file_mode::read, ec);
if(ec)
throw system_error{ ec };

return http::file_source{ std::move(file), content_length() };
}

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

boost::http::source::results
stdin_body::source::on_read(capy::mutable_buffer mb)
{
std::cin.read(static_cast<char*>(mb.data()), mb.size());

return { .ec = {},
.bytes = static_cast<std::size_t>(std::cin.gcount()),
.finished = std::cin.eof() };
}

http::method
stdin_body::method() const noexcept
{
return http::method::put;
}

core::string_view
stdin_body::content_type() const noexcept
{
return "application/octet-stream";
}

boost::optional<std::size_t>
stdin_body::content_length() const noexcept
{
return boost::none;
}

stdin_body::source
stdin_body::body() const
{
return {};
}

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

void
message::set_headers(http::request& request) const
{
Expand All @@ -138,20 +57,11 @@ message::set_headers(http::request& request) const
request.set_method(f.method());
request.set(field::content_type, f.content_type());

boost::optional<std::size_t> content_length =
f.content_length();
if(content_length.has_value())
{
request.set_content_length(content_length.value());
if(content_length.value() >= 1024 * 1024 &&
request.version() == http::version::http_1_1)
request.set(field::expect, "100-continue");
}
else
{
request.set_chunked(true);
std::size_t content_length = f.content_length();
request.set_content_length(content_length);
if(content_length >= 1024 * 1024 &&
request.version() == http::version::http_1_1)
request.set(field::expect, "100-continue");
}
}
},
body_);
Expand All @@ -167,8 +77,7 @@ message::start_serializer(
{
if constexpr(!std::is_same_v<decltype(f), const std::monostate&>)
{
serializer.start<std::decay_t<decltype(f.body())>>(
request, f.body());
serializer.start(request, f.body());
}
else
{
Expand Down
Loading
Loading