Skip to content

Commit ee7eb57

Browse files
authored
Code/Comments tweak to Networking scenario (#488)
1 parent 250ee60 commit ee7eb57

File tree

1 file changed

+65
-12
lines changed

1 file changed

+65
-12
lines changed

user-guide/modules/ROOT/pages/task-networking.adoc

Lines changed: 65 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -545,35 +545,63 @@ namespace http = beast::http;
545545
namespace json = boost::json;
546546
using tcp = asio::ip::tcp;
547547
548-
// Function to handle incoming HTTP requests
549-
void handle_request(http::request<http::string_body> req, http::response<http::string_body>& res) {
548+
// Function to handle incoming HTTP requests and produce appropriate responses
549+
void handle_request(
550+
http::request<http::string_body> req, // Incoming HTTP request
551+
http::response<http::string_body>& res // Outgoing HTTP response (to be filled in)
552+
) {
553+
// JSON object to hold the response body
550554
json::object response_json;
555+
556+
// Log request information to the console for debugging
551557
std::cout << "Method: " << req.method() << "...\n";
552558
std::cout << "Target: " << req.target() << "...\n";
553559
std::cout << "Body: " << req.body() << "...\n\n";
560+
561+
// Route: GET /status — return a simple status message
554562
if (req.method() == http::verb::get && req.target() == "/status") {
555563
response_json["status"] = "Server is running!";
556564
}
565+
566+
// Route: POST /greet — expects JSON input and returns a personalized greeting
557567
else if (req.method() == http::verb::post && req.target() == "/greet") {
558568
try {
569+
570+
// Parse the incoming request body as JSON
559571
json::value parsed_body = json::parse(req.body());
572+
573+
// Extract the "name" field from the JSON object
560574
std::string name = parsed_body.as_object()["name"].as_string().c_str();
575+
576+
// Compose a greeting message
561577
response_json["message"] = "Hello, " + name + "!";
562578
}
563579
catch (...) {
580+
581+
// If parsing fails or "name" field is missing, return an error
564582
response_json["error"] = "Invalid JSON format.";
565583
}
566584
}
585+
586+
// Handle all other unknown endpoints or unsupported methods
567587
else {
568588
response_json["error"] = "Unknown endpoint.";
569589
}
570590
591+
// Set the response status to 200 OK
571592
res.result(http::status::ok);
593+
594+
// Specify the content type as JSON
572595
res.set(http::field::content_type, "application/json");
596+
597+
// Serialize the JSON object and assign it to the response body
573598
res.body() = json::serialize(response_json);
599+
600+
// Finalize the response by preparing content-length and other headers
574601
res.prepare_payload();
575602
}
576603
604+
577605
// HTTP Server function
578606
void run_server(asio::io_context& ioc, unsigned short port) {
579607
tcp::acceptor acceptor(ioc, tcp::endpoint(tcp::v4(), port));
@@ -623,37 +651,62 @@ namespace http = beast::http;
623651
namespace json = boost::json;
624652
using tcp = asio::ip::tcp;
625653
626-
// Function to send an HTTP request
627-
std::string send_request(const std::string& host, const std::string& port, http::verb method, const std::string& target, const std::string& body = "") {
654+
// Function to send a basic HTTP request using Boost.Beast (synchronous, plain TCP)
655+
std::string send_request(
656+
const std::string& host, // e.g., "api.example.com"
657+
const std::string& port, // e.g., "80" or "443" (for HTTPS you'd need SSL setup)
658+
http::verb method, // HTTP method, e.g., http::verb::post or http::verb::get
659+
const std::string& target, // The path/resource being requested, e.g., "/v1/data"
660+
const std::string& body = "" // Optional request body (for POST/PUT)
661+
) {
628662
try {
663+
// Create an I/O context required for all I/O operations
629664
asio::io_context ioc;
665+
666+
// Create a resolver to turn the host name into a TCP endpoint
630667
tcp::resolver resolver(ioc);
668+
669+
// Create the TCP stream for connecting and communicating
631670
beast::tcp_stream stream(ioc);
632671
672+
// Resolve the host and port into a list of endpoints
633673
auto const results = resolver.resolve(host, port);
634-
stream.connect(results);
635674
636-
http::request<http::string_body> req{ method, target, 11 };
637-
req.set(http::field::host, host);
638-
req.set(http::field::user_agent, BOOST_BEAST_VERSION_STRING);
639-
req.set(http::field::content_type, "application/json");
640-
req.body() = body;
641-
req.prepare_payload();
675+
// Establish a connection to one of the resolved endpoints
676+
stream.connect(results);
642677
643-
if (!body.empty()) req.body() = body;
678+
// Build the HTTP request message
679+
http::request<http::string_body> req{ method, target, 11 }; // HTTP/1.1
680+
req.set(http::field::host, host); // Required: Host header
681+
req.set(http::field::user_agent, BOOST_BEAST_VERSION_STRING); // Optional: Identifies the client
682+
req.set(http::field::content_type, "application/json"); // Optional: for JSON bodies
683+
req.body() = body; // Set the request body (if any)
684+
req.prepare_payload(); // Sets Content-Length and finalizes headers
644685
686+
// Send the HTTP request to the remote host
645687
http::write(stream, req);
688+
689+
// Buffer for receiving data
646690
beast::flat_buffer buffer;
691+
692+
// Container for the HTTP response
647693
http::response<http::string_body> res;
694+
695+
// Receive the response
648696
http::read(stream, buffer, res);
649697
698+
// Return only the response body as a string
650699
return res.body();
651700
}
652701
catch (std::exception& e) {
702+
703+
// Return the exception message prefixed with "Client error:"
653704
return std::string("Client error: ") + e.what();
654705
}
655706
}
656707
708+
709+
657710
int main() {
658711
std::string host = "127.0.0.1";
659712
std::string port = "8080";

0 commit comments

Comments
 (0)