Skip to content

refactor, add client and visit #36

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 27, 2025
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
9 changes: 5 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,14 @@ endif ()
#-------------------------------------------------
set_property(GLOBAL PROPERTY USE_FOLDERS ON)

file(GLOB_RECURSE BOOST_HTTP_IO_HEADERS CONFIGURE_DEPENDS include/boost/*.hpp include/boost/*.natvis)
file(GLOB_RECURSE BOOST_HTTP_IO_HEADERS CONFIGURE_DEPENDS include/boost/http_io/*.hpp include/boost/*.natvis)
file(GLOB_RECURSE BOOST_HTTP_IO_SOURCES CONFIGURE_DEPENDS src/*.cpp src/*.hpp)

source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/include/boost PREFIX "" FILES ${BOOST_HTTP_IO_HEADERS})
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/src PREFIX "http_io" FILES ${BOOST_HTTP_IO_SOURCES})
source_group("" FILES "include/boost/http_io.hpp" "build/Jamfile")
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/include/boost/http_io PREFIX "include" FILES ${BOOST_HTTP_IO_HEADERS})
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/src PREFIX "src" FILES ${BOOST_HTTP_IO_SOURCES})

add_library(boost_http_io ${BOOST_HTTP_IO_HEADERS} ${BOOST_HTTP_IO_SOURCES})
add_library(boost_http_io include/boost/http_io.hpp build/Jamfile ${BOOST_HTTP_IO_HEADERS} ${BOOST_HTTP_IO_SOURCES})
add_library(Boost::http_io ALIAS boost_http_io)
target_compile_features(boost_http_io PUBLIC cxx_constexpr)
target_include_directories(boost_http_io PUBLIC "${PROJECT_SOURCE_DIR}/include")
Expand Down
12 changes: 12 additions & 0 deletions build/Jamfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,28 @@ constant c11-requires :
]
;

explicit
[ searched-lib ws2_32 : : <target-os>windows ] # NT
[ searched-lib mswsock : : <target-os>windows ] # NT
;

project boost/http_io
: requirements
$(c11-requires)
<link>shared:<define>BOOST_HTTP_IO_DYN_LINK=1
<link>static:<define>BOOST_HTTP_IO_STATIC_LINK=1
<target-os>windows:<define>_WIN32_WINNT=0x0601 # VFALCO?
<target-os>windows,<toolset>gcc:<library>ws2_32
<target-os>windows,<toolset>gcc:<library>mswsock
<target-os>windows,<toolset>gcc-cygwin:<define>__USE_W32_SOCKETS
<define>BOOST_HTTP_IO_SOURCE
: usage-requirements
<link>shared:<define>BOOST_HTTP_IO_DYN_LINK=1
<link>static:<define>BOOST_HTTP_IO_STATIC_LINK=1
<target-os>windows:<define>_WIN32_WINNT=0x0601 # VFALCO?
<target-os>windows,<toolset>gcc:<library>ws2_32
<target-os>windows,<toolset>gcc:<library>mswsock
<target-os>windows,<toolset>gcc-cygwin:<define>__USE_W32_SOCKETS
: source-location ../src
;

Expand Down
1 change: 1 addition & 0 deletions cmake/toolchains/msvc.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ add_compile_options(
/permissive- # strict C++
/W4 # enable all warnings
/MP # multi-processor compilation
/bigobj
)
if("${CMAKE_GENERATOR_PLATFORM}" STREQUAL "Win32") # 32-bit
add_compile_options(
Expand Down
1 change: 1 addition & 0 deletions example/client/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@
#

add_subdirectory(burl)
add_subdirectory(visit)
1 change: 1 addition & 0 deletions example/client/Jamfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@
#

build-project burl ;
build-project visit ;
42 changes: 42 additions & 0 deletions example/client/visit/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#
# 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)
#
# Official repository: https://github.com/cppalliance/http_io
#

file(GLOB_RECURSE PFILES CONFIGURE_DEPENDS *.cpp *.hpp
CMakeLists.txt
Jamfile)

source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX "" FILES ${PFILES})

add_executable(http_io_example_client_visit ${PFILES})

target_compile_definitions(http_io_example_client_visit
PRIVATE BOOST_ASIO_NO_DEPRECATED)

set_property(TARGET http_io_example_client_visit
PROPERTY FOLDER "examples")

find_package(OpenSSL REQUIRED)
find_package(ZLIB)

target_link_libraries(http_io_example_client_visit
boost_http_io
boost_program_options
boost_scope
OpenSSL::SSL
OpenSSL::Crypto)

if (WIN32)
target_link_libraries(http_io_example_client_visit
crypt32)
endif()

if (ZLIB_FOUND)
target_link_libraries(http_io_example_client_visit
boost_http_proto_zlib)
endif()
32 changes: 32 additions & 0 deletions example/client/visit/Jamfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#
# Copyright (c) 2024 Mohammad Nejati
# Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot com)
#
# 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/http_io
#

import ../../../../config/checks/config : requires ;

using openssl ;
import ac ;

project
: requirements
$(c11-requires)
<library>/boost/http_proto//boost_http_proto
[ ac.check-library /boost/http_proto//boost_http_proto_zlib : <library>/boost/http_proto//boost_http_proto_zlib : ]
<library>/boost/http_io//boost_http_io
<library>/boost/program_options//boost_program_options
<library>/boost/scope//scope
<library>/openssl//ssl/<link>shared
<library>/openssl//crypto/<link>shared
<target-os>windows:<library>crypt32
<include>.
;

exe visit :
[ glob *.cpp ]
;
144 changes: 144 additions & 0 deletions example/client/visit/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
//
// Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// 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/http_io
//

#include <cstdlib>
#include <boost/asio/basic_stream_socket.hpp>
#include <boost/asio/connect.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/core/detail/string_view.hpp>
#include <boost/http_proto/context.hpp>
#include <boost/http_proto/request.hpp>
#include <boost/http_proto/response_parser.hpp>
#include <boost/url/url_view.hpp>

struct worker
{
using executor_type =
boost::asio::io_context::executor_type;
using resolver_type =
boost::asio::ip::basic_resolver<
boost::asio::ip::tcp, executor_type>;
using socket_type = boost::asio::basic_stream_socket<
boost::asio::ip::tcp, executor_type>;

socket_type sock;
resolver_type resolver;
boost::http_proto::response_parser pr;
boost::urls::url_view url;

explicit
worker(
executor_type ex,
boost::http_proto::context& ctx)
: sock(ex)
, resolver(ex)
, pr(ctx)
{
sock.open(boost::asio::ip::tcp::v4());
}

void
do_next()
{
do_visit("http://www.boost.org");
}

void
do_visit(boost::urls::url_view url_)
{
url = url_;
do_resolve();
}

void
do_resolve()
{
resolver.async_resolve(
url.encoded_host(),
url.scheme(),
[&](
boost::system::error_code ec,
resolver_type::results_type results)
{
if(ec.failed())
{
// log (target, ec.message())
auto s = ec.message();
return do_next();
}
do_connect(results);
});
}

void
do_connect(
resolver_type::results_type results)
{
boost::asio::async_connect(
sock,
results.begin(),
results.end(),
[&](
boost::system::error_code ec,
resolver_type::results_type::const_iterator it)
{
if(ec.failed())
{
// log (target, ec.message())
return do_next();
}
do_request();
});
}

void
do_request()
{
boost::http_proto::request req;
auto path = url.encoded_path();
req.set_start_line(
boost::http_proto::method::get,
path.empty() ? "/" : path,
boost::http_proto::version::http_1_1);

do_shutdown();
}

void
do_shutdown()
{
boost::system::error_code ec;
sock.shutdown(socket_type::shutdown_both, ec);
if(ec.failed())
{
// log(ec.message())
return do_next();
}
do_next();
}
};

int
main(int argc, char* argv[])
{
boost::http_proto::context ctx;
boost::http_proto::parser::config_base cfg;
boost::http_proto::install_parser_service(ctx, cfg);

boost::asio::io_context ioc;

worker w(ioc.get_executor(), ctx);

w.do_next();

ioc.run();

return EXIT_SUCCESS;
}
73 changes: 73 additions & 0 deletions include/boost/http_io/client.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//
// Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// 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/http_io
//

#ifndef BOOST_HTTP_IO_CLIENT_HPP
#define BOOST_HTTP_IO_CLIENT_HPP

#include <boost/http_io/detail/config.hpp>
#include <type_traits>
#include <utility>

namespace boost {
namespace http_io {

template<
class AsyncStream
/*,class Derived*/ // VFALCO CRTP for things like shutdown()
>
class client
{
public:
using stream_type = typename
std::remove_reference<AsyncStream>::type;

using executor_type = decltype(
std::declval<stream_type&>().get_executor());

template<
class... Args,
class = std::enable_if<
std::is_constructible<
AsyncStream, Args...>::value>
>
explicit
client(
Args&&... args) noexcept(
std::is_nothrow_constructible<
AsyncStream, Args...>::value)
: stream_(std::forward<Args>(args)...)
{
}

stream_type const&
stream() const noexcept
{
return stream_;
}

stream_type&
stream() noexcept
{
return stream_;
}

executor_type
get_executor() const
{
return stream_.get_executor();
}

private:
AsyncStream stream_;
};

} // http_io
} // boost

#endif
Loading
Loading