Skip to content
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

Http client #522

Merged
merged 41 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
0b17d46
Ported http work over from smacc1
yassiezar Jul 1, 2023
ade9f85
Added example showasing http requests
yassiezar Jul 1, 2023
ff6b5ab
Fixed some typos in the HTTP example
yassiezar Jul 12, 2023
d265094
Made provision for HTTP GET/POST in the HTTP client
yassiezar Jul 12, 2023
233c502
Moved HTTP client into the client_libraries folder and made separate …
yassiezar Aug 28, 2023
4f80ef0
Update smacc_action_client_base.hpp
brettpac Aug 28, 2023
fcd8932
Update smacc_action_client_base.hpp
brettpac Aug 28, 2023
3049ccd
Update http_client.cpp
brettpac Aug 28, 2023
d7f5baa
Update http_client.cpp
brettpac Aug 28, 2023
f5bbfee
Update cb_http_request.hpp
brettpac Aug 28, 2023
9cffffa
Update sm_atomic_http.py
brettpac Aug 28, 2023
04016a4
- Fixed errors with HTTP requests not triggering,
yassiezar Sep 4, 2023
e99401d
Ported http work over from smacc1
yassiezar Jul 1, 2023
86621de
Added example showasing http requests
yassiezar Jul 1, 2023
ca528c7
Fixed some typos in the HTTP example
yassiezar Jul 12, 2023
8a25ab3
Made provision for HTTP GET/POST in the HTTP client
yassiezar Jul 12, 2023
ebc37a9
Moved HTTP client into the client_libraries folder and made separate …
yassiezar Aug 28, 2023
88ab228
Update http_client.cpp
brettpac Aug 28, 2023
0c1ced9
Update http_client.cpp
brettpac Aug 28, 2023
65c27db
Update cb_http_request.hpp
brettpac Aug 28, 2023
c9b341d
Update sm_atomic_http.py
brettpac Aug 28, 2023
a35d62c
- Fixed errors with HTTP requests not triggering,
yassiezar Sep 4, 2023
ae99229
Added helper class to handle server name related interactions
yassiezar Sep 10, 2023
685ba36
Added SSL implementation, need to make provision for SSL and non-SSLD…
yassiezar Sep 10, 2023
c29befd
Added SLL certs
yassiezar Sep 13, 2023
f2d824c
Split the HTTp session class into own compile unit
yassiezar Sep 13, 2023
bd324d8
Added HTTP session base class and implemented the SSL version. The cl…
yassiezar Sep 13, 2023
89bec11
Implemented non-ssl HTTP session for clients
yassiezar Sep 13, 2023
761f809
Removing hard-coded ssl certs and using the default OpenSSL certs for
yassiezar Jun 9, 2024
dfba4ea
Run through formatter
yassiezar Jun 9, 2024
80e0be1
Merged in with changes from ssl
yassiezar Jun 9, 2024
b5e718e
Fix bad merge
yassiezar Jun 9, 2024
9806285
Merge branch 'humble' into http-client
yassiezar Jun 19, 2024
982ede8
Remove noisy changelog
yassiezar Jun 19, 2024
8ea16b6
Undo change that introduced and error
yassiezar Jun 19, 2024
14b3953
Added missing copyrights
yassiezar Jun 19, 2024
a2f4b9e
Revert change to precommit config
yassiezar Jun 19, 2024
8fbf1c9
Fixing copyright, formatting
yassiezar Jun 19, 2024
b92be2d
Fixed whitespace blocking precommit
yassiezar Jun 20, 2024
d532df1
Revert change to precommit config
yassiezar Jun 20, 2024
3c049b4
Merge branch 'humble' into http-client
yassiezar Jun 28, 2024
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
50 changes: 50 additions & 0 deletions smacc2_client_library/http_client/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
cmake_minimum_required(VERSION 3.5)
project(http_client)

# Default to C++17
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 17)
endif()

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()

# find dependencies
find_package(ament_cmake REQUIRED)
find_package(smacc2 REQUIRED)

include_directories(
include
${smacc2_INCLUDE_DIRS}
)

file(GLOB_RECURSE SRC_FILES src *.cpp)

add_library(http_session
src/http_client/ssl_http_session.cpp
src/http_client/http_session.cpp
)

add_library(${PROJECT_NAME}
src/http_client/http_client.cpp
)

target_link_libraries(${PROJECT_NAME}
http_session
${smacc2_LIBRARIES}
)
ament_target_dependencies(${PROJECT_NAME} smacc2)
ament_export_include_directories(include)
ament_export_libraries(${PROJECT_NAME} http_session)

install(
DIRECTORY include/
DESTINATION include)

install(TARGETS
${PROJECT_NAME}
http_session
DESTINATION lib/)

ament_package()
116 changes: 116 additions & 0 deletions smacc2_client_library/http_client/include/http_client/http_client.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// Copyright 2023 RobosoftAI Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/*****************************************************************************************************************
*
* Authors: Jaycee Lock
*
******************************************************************************************************************/

#pragma once

#include <boost/asio/executor_work_guard.hpp>
#include <boost/asio/strand.hpp>
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/ssl.hpp>
#include <boost/beast/version.hpp>
#include <http_client/http_session.hpp>
#include <http_client/ssl_http_session.hpp>
#include <iostream>
#include <memory>
#include <optional>
#include <smacc2/smacc.hpp>
#include <smacc2/smacc_client.hpp>
#include <string>
#include <thread>
#include <unordered_map>

namespace cl_http
{
class ClHttp : public smacc2::ISmaccClient
{
class Server
{
public:
explicit Server(const std::string & server_name) : server_name_{server_name}, ssl_{true}
{
if (!server_name_.substr(0, 7).compare("http://"))
{
ssl_ = false;
server_name_.erase(0, 7);
}
else if (!server_name_.substr(0, 8).compare("https://"))
{
server_name_.erase(0, 8);
ssl_ = true;
}
}

bool isSSL() const { return ssl_; }

std::string getPort() const { return ssl_ ? "443" : "80"; }

std::string getServerName() const { return server_name_; }

private:
std::string server_name_;
bool ssl_;
};

public:
enum class kHttpRequestMethod
{
GET = static_cast<int>(boost::beast::http::verb::get),
POST = static_cast<int>(boost::beast::http::verb::post),
PUT = static_cast<int>(boost::beast::http::verb::put),
};

using TResponse = http_session_base::TResponse;

template <typename T>
boost::signals2::connection onResponseReceived(void (T::*callback)(const TResponse &), T * object)
{
return this->getStateMachine()->createSignalConnection(onResponseReceived_, callback, object);
}

explicit ClHttp(const std::string & server, const int & timeout = 1500);

virtual ~ClHttp();

void onInitialize() override;

void makeRequest(const kHttpRequestMethod http_method, const std::string & path = "/");

private:
const int HTTP_VERSION = 11;

bool initialized_;
bool is_ssl_;
int timeout_;

Server server_;

boost::asio::io_context io_context_;
boost::asio::executor_work_guard<decltype(io_context_)::executor_type> worker_guard_;
std::thread tcp_connection_runner_;

boost::asio::ssl::context ssl_context_;

smacc2::SmaccSignal<void(const TResponse &)> onResponseReceived_;

std::function<void(TResponse)> callbackHandler = [&](const TResponse & res)
{ onResponseReceived_(res); };
};
} // namespace cl_http
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright 2021 RobosoftAI Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/*****************************************************************************************************************
*

Author: Jacobus Lock

******************************************************************************************************************/

#pragma once

#include <boost/asio/executor_work_guard.hpp>
#include <boost/asio/strand.hpp>
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/version.hpp>
#include <http_client/http_session_base.hpp>
#include <iostream>
#include <string>

namespace cl_http
{
class http_session : public std::enable_shared_from_this<http_session>, public http_session_base
{
public:
// Objects are constructed with a strand to
// ensure that handlers do not execute concurrently.
http_session(
boost::asio::any_io_executor ioc, const std::function<void(const TResponse &)> response);

virtual ~http_session() {}

// Start the asynchronous operation
void run(
const std::string & host, const std::string & target,
const boost::beast::http::verb http_method, const int & version) override;

std::string getPort() override { return kPort; }

private:
const std::string kPort = "80";

void on_resolve(
boost::beast::error_code ec, boost::asio::ip::tcp::resolver::results_type results) override;
void fail(boost::beast::error_code ec, const char * what) override;
void on_connect(
boost::beast::error_code ec,
boost::asio::ip::tcp::resolver::results_type::endpoint_type) override;
void on_write(boost::beast::error_code ec, std::size_t bytes_transferred) override;
void on_read(boost::beast::error_code ec, std::size_t bytes_transferred) override;

std::function<void(const TResponse &)> onResponse;

boost::asio::ip::tcp::resolver resolver_;
boost::beast::tcp_stream stream_;
boost::beast::flat_buffer buffer_; // (Must persist between reads)
boost::beast::http::request<boost::beast::http::empty_body> req_;
boost::beast::http::response<boost::beast::http::string_body> res_;
};
} // namespace cl_http
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright 2021 RobosoftAI Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/*****************************************************************************************************************
*

Author: Jacobus Lock

******************************************************************************************************************/

#pragma once

#include <boost/asio/executor_work_guard.hpp>
#include <boost/asio/strand.hpp>
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/ssl.hpp>
#include <boost/beast/version.hpp>
#include <string>

namespace cl_http
{
class http_session_base
{
public:
virtual ~http_session_base() {}

using TResponse = boost::beast::http::response<boost::beast::http::string_body>;

// Start the asynchronous operation
virtual void run(
const std::string & host, const std::string & target,
const boost::beast::http::verb http_method, const int & version) = 0;

virtual std::string getPort() = 0;

protected:
virtual void on_resolve(
boost::beast::error_code ec, boost::asio::ip::tcp::resolver::results_type results) = 0;
virtual void fail(boost::beast::error_code ec, const char * what) = 0;
virtual void on_connect(
boost::beast::error_code ec, boost::asio::ip::tcp::resolver::results_type::endpoint_type) = 0;
virtual void on_write(boost::beast::error_code ec, std::size_t bytes_transferred) = 0;
virtual void on_read(boost::beast::error_code ec, std::size_t bytes_transferred) = 0;

// Optional, needed for SSL connections
virtual void on_handshake(boost::beast::error_code ec) {}
virtual void on_shutdown(boost::beast::error_code ec) {}
};
} // namespace cl_http
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copyright 2021 RobosoftAI Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/*****************************************************************************************************************
*

Author: Jacobus Lock

******************************************************************************************************************/

#pragma once

#include <boost/asio/executor_work_guard.hpp>
#include <boost/asio/strand.hpp>
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/ssl.hpp>
#include <boost/beast/version.hpp>
#include <http_client/http_session_base.hpp>
#include <iostream>
#include <string>

namespace cl_http
{
class ssl_http_session : public std::enable_shared_from_this<ssl_http_session>,
public http_session_base
{
public:
// Objects are constructed with a strand to
// ensure that handlers do not execute concurrently.
ssl_http_session(
boost::asio::any_io_executor ioc, boost::asio::ssl::context & ssl_context,
const std::function<void(const TResponse &)> response);

virtual ~ssl_http_session() {}

// Start the asynchronous operation
void run(
const std::string & host, const std::string & target,
const boost::beast::http::verb http_method, const int & version) override;

std::string getPort() override { return kPort; }

private:
const std::string kPort = "443";

void on_resolve(
boost::beast::error_code ec, boost::asio::ip::tcp::resolver::results_type results) override;
void fail(boost::beast::error_code ec, const char * what) override;
void on_connect(
boost::beast::error_code ec,
boost::asio::ip::tcp::resolver::results_type::endpoint_type) override;
void on_handshake(boost::beast::error_code ec) override;
void on_write(boost::beast::error_code ec, std::size_t bytes_transferred) override;
void on_read(boost::beast::error_code ec, std::size_t bytes_transferred) override;
void on_shutdown(boost::beast::error_code ec) override;

std::function<void(const TResponse &)> onResponse;

boost::asio::ip::tcp::resolver resolver_;
// boost::beast::tcp_stream stream_;
boost::beast::ssl_stream<boost::beast::tcp_stream> stream_;
boost::beast::flat_buffer buffer_; // (Must persist between reads)
boost::beast::http::request<boost::beast::http::empty_body> req_;
boost::beast::http::response<boost::beast::http::string_body> res_;
};
} // namespace cl_http
17 changes: 17 additions & 0 deletions smacc2_client_library/http_client/package.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>http_client</name>
<version>2.3.18</version>
<description>The http_client package</description>
<maintainer email="[email protected]">Jaycee Lock</maintainer>
<license>Apache-2.0</license>

<buildtool_depend>ament_cmake</buildtool_depend>

<depend>smacc2</depend>

<export>
<build_type>ament_cmake</build_type>
</export>
</package>
Loading
Loading