mirror of
https://github.com/boostorg/website-v2-docs.git
synced 2026-01-19 04:42:17 +00:00
Code/Comments tweak to Networking scenario (#488)
This commit is contained in:
@@ -545,35 +545,63 @@ namespace http = beast::http;
|
||||
namespace json = boost::json;
|
||||
using tcp = asio::ip::tcp;
|
||||
|
||||
// Function to handle incoming HTTP requests
|
||||
void handle_request(http::request<http::string_body> req, http::response<http::string_body>& res) {
|
||||
// Function to handle incoming HTTP requests and produce appropriate responses
|
||||
void handle_request(
|
||||
http::request<http::string_body> req, // Incoming HTTP request
|
||||
http::response<http::string_body>& res // Outgoing HTTP response (to be filled in)
|
||||
) {
|
||||
// JSON object to hold the response body
|
||||
json::object response_json;
|
||||
|
||||
// Log request information to the console for debugging
|
||||
std::cout << "Method: " << req.method() << "...\n";
|
||||
std::cout << "Target: " << req.target() << "...\n";
|
||||
std::cout << "Body: " << req.body() << "...\n\n";
|
||||
|
||||
// Route: GET /status — return a simple status message
|
||||
if (req.method() == http::verb::get && req.target() == "/status") {
|
||||
response_json["status"] = "Server is running!";
|
||||
}
|
||||
|
||||
// Route: POST /greet — expects JSON input and returns a personalized greeting
|
||||
else if (req.method() == http::verb::post && req.target() == "/greet") {
|
||||
try {
|
||||
|
||||
// Parse the incoming request body as JSON
|
||||
json::value parsed_body = json::parse(req.body());
|
||||
|
||||
// Extract the "name" field from the JSON object
|
||||
std::string name = parsed_body.as_object()["name"].as_string().c_str();
|
||||
|
||||
// Compose a greeting message
|
||||
response_json["message"] = "Hello, " + name + "!";
|
||||
}
|
||||
catch (...) {
|
||||
|
||||
// If parsing fails or "name" field is missing, return an error
|
||||
response_json["error"] = "Invalid JSON format.";
|
||||
}
|
||||
}
|
||||
|
||||
// Handle all other unknown endpoints or unsupported methods
|
||||
else {
|
||||
response_json["error"] = "Unknown endpoint.";
|
||||
}
|
||||
|
||||
// Set the response status to 200 OK
|
||||
res.result(http::status::ok);
|
||||
|
||||
// Specify the content type as JSON
|
||||
res.set(http::field::content_type, "application/json");
|
||||
|
||||
// Serialize the JSON object and assign it to the response body
|
||||
res.body() = json::serialize(response_json);
|
||||
|
||||
// Finalize the response by preparing content-length and other headers
|
||||
res.prepare_payload();
|
||||
}
|
||||
|
||||
|
||||
// HTTP Server function
|
||||
void run_server(asio::io_context& ioc, unsigned short port) {
|
||||
tcp::acceptor acceptor(ioc, tcp::endpoint(tcp::v4(), port));
|
||||
@@ -623,37 +651,62 @@ namespace http = beast::http;
|
||||
namespace json = boost::json;
|
||||
using tcp = asio::ip::tcp;
|
||||
|
||||
// Function to send an HTTP request
|
||||
std::string send_request(const std::string& host, const std::string& port, http::verb method, const std::string& target, const std::string& body = "") {
|
||||
// Function to send a basic HTTP request using Boost.Beast (synchronous, plain TCP)
|
||||
std::string send_request(
|
||||
const std::string& host, // e.g., "api.example.com"
|
||||
const std::string& port, // e.g., "80" or "443" (for HTTPS you'd need SSL setup)
|
||||
http::verb method, // HTTP method, e.g., http::verb::post or http::verb::get
|
||||
const std::string& target, // The path/resource being requested, e.g., "/v1/data"
|
||||
const std::string& body = "" // Optional request body (for POST/PUT)
|
||||
) {
|
||||
try {
|
||||
// Create an I/O context required for all I/O operations
|
||||
asio::io_context ioc;
|
||||
|
||||
// Create a resolver to turn the host name into a TCP endpoint
|
||||
tcp::resolver resolver(ioc);
|
||||
|
||||
// Create the TCP stream for connecting and communicating
|
||||
beast::tcp_stream stream(ioc);
|
||||
|
||||
// Resolve the host and port into a list of endpoints
|
||||
auto const results = resolver.resolve(host, port);
|
||||
|
||||
// Establish a connection to one of the resolved endpoints
|
||||
stream.connect(results);
|
||||
|
||||
http::request<http::string_body> req{ method, target, 11 };
|
||||
req.set(http::field::host, host);
|
||||
req.set(http::field::user_agent, BOOST_BEAST_VERSION_STRING);
|
||||
req.set(http::field::content_type, "application/json");
|
||||
req.body() = body;
|
||||
req.prepare_payload();
|
||||
|
||||
if (!body.empty()) req.body() = body;
|
||||
// Build the HTTP request message
|
||||
http::request<http::string_body> req{ method, target, 11 }; // HTTP/1.1
|
||||
req.set(http::field::host, host); // Required: Host header
|
||||
req.set(http::field::user_agent, BOOST_BEAST_VERSION_STRING); // Optional: Identifies the client
|
||||
req.set(http::field::content_type, "application/json"); // Optional: for JSON bodies
|
||||
req.body() = body; // Set the request body (if any)
|
||||
req.prepare_payload(); // Sets Content-Length and finalizes headers
|
||||
|
||||
// Send the HTTP request to the remote host
|
||||
http::write(stream, req);
|
||||
|
||||
// Buffer for receiving data
|
||||
beast::flat_buffer buffer;
|
||||
|
||||
// Container for the HTTP response
|
||||
http::response<http::string_body> res;
|
||||
|
||||
// Receive the response
|
||||
http::read(stream, buffer, res);
|
||||
|
||||
// Return only the response body as a string
|
||||
return res.body();
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
|
||||
// Return the exception message prefixed with "Client error:"
|
||||
return std::string("Client error: ") + e.what();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main() {
|
||||
std::string host = "127.0.0.1";
|
||||
std::string port = "8080";
|
||||
|
||||
Reference in New Issue
Block a user