Skip to content
Open
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": []
}
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
4 changes: 2 additions & 2 deletions example/client/burl/connect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ connect_socks5_proxy(
asio::awaitable<void>
connect_http_proxy(
const operation_config& oc,
capy::polystore& capy_ctx,
http::polystore& capy_ctx,
asio::ip::tcp::socket& stream,
const urls::url_view& url,
const urls::url_view& proxy)
Expand Down Expand Up @@ -225,7 +225,7 @@ asio::awaitable<void>
connect(
const operation_config& oc,
ssl::context& ssl_ctx,
capy::polystore& capy_ctx,
http::polystore& capy_ctx,
any_stream& stream,
urls::url url)
{
Expand Down
6 changes: 3 additions & 3 deletions example/client/burl/connect.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,19 @@

#include <boost/asio/awaitable.hpp>
#include <boost/asio/ssl/context.hpp>
#include <boost/capy/polystore.hpp>
#include <boost/http/core/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,
http::polystore& capy_ctx,
any_stream& stream,
urls::url url);

Expand Down
37 changes: 9 additions & 28 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>
#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,7 +345,7 @@ perform_request(
boost::optional<cookie_jar>& cookie_jar,
core::string_view exp_cookies,
ssl::context& ssl_ctx,
capy::polystore& capy_ctx,
http::polystore& capy_ctx,
message msg,
request_opt request_opt)
{
Expand Down Expand Up @@ -376,26 +376,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 @@ -759,7 +740,7 @@ 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 capy_ctx = http::polystore{};
auto cookie_jar = boost::optional<::cookie_jar>{};
auto header_output = boost::optional<any_ostream>{};
auto exp_cookies = std::string{};
Expand All @@ -778,13 +759,13 @@ 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(capy_ctx);
}
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(capy_ctx);
}
http::install_parser_service(capy_ctx, cfg);
}
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
51 changes: 1 addition & 50 deletions example/client/burl/message.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@
#ifndef BURL_MESSAGE_HPP
#define BURL_MESSAGE_HPP

#include "multipart_form.hpp"

#include <boost/http/file_source.hpp>
#include <boost/http/request.hpp>
#include <boost/http/serializer.hpp>

Expand Down Expand Up @@ -41,57 +38,11 @@ class string_body
body() const noexcept;
};

class file_body
{
std::string path_;

public:
file_body(std::string path);

http::method
method() const noexcept;

core::string_view
content_type() const noexcept;

std::uint64_t
content_length() const;

http::file_source
body() const;
};

class stdin_body
{
public:
class source : public http::source
{
public:
results
on_read(capy::mutable_buffer mb) override;
};

http::method
method() const noexcept;

core::string_view
content_type() const noexcept;

boost::optional<std::size_t>
content_length() const noexcept;

source
body() const;
};

class message
{
std::variant<
std::monostate,
string_body,
multipart_form,
file_body,
stdin_body>
string_body>
body_;

public:
Expand Down
Loading
Loading