I am running the (very basic) following program in a Linux docker container and I am testing it by calling it from Postman with a POST event or from an HTML page.
When I test this, I get two events where acceptor.accept(*socket) is called. One where it fails on the beast::http::read(*socket, buffer, request) (I get an exception - end of stream [beast.http.1]) and the second one where it succeeds.
#include <iostream>
#include <memory>
#include <boost/asio.hpp>
#include <boost/beast.hpp>
namespace asio = boost::asio;
namespace beast = boost::beast;
using tcp = boost::asio::ip::tcp;
void handle_request(std::shared_ptr<tcp::socket> socket)
{
try
{
beast::http::request<beast::http::string_body> request;
beast::flat_buffer buffer;
if (!socket || !socket->is_open()) {
std::cout << "Invalid or closed socket." << std::endl;
return;
}
// Read the HTTP request
beast::http::read(*socket, buffer, request);
std::cout << request << std::endl;
// Process the JSON data
std::string json_data = request.body();
std::cout << "Received JSON data: " << json_data << std::endl;
// Send an HTTP response
beast::http::response<beast::http::string_body> response{ beast::http::status::ok, request.version() };
response.set(beast::http::field::content_type, "text/plain");
response.set("Access-Control-Allow-Origin", "*");
response.set(beast::http::field::connection, "keep-alive");
response.body() = "This is a response!";
response.prepare_payload();
// Send the HTTP response
beast::http::write(*socket, response);
std::cout << "Shuttting down" << std::endl;
socket->shutdown(tcp::socket::shutdown_send);
std::cout << "All good" << std::endl;
}
catch (std::exception& e)
{
auto what = e.what();
std::cout << "Error while handling request " << what << std::endl;
}
}
int main() {
asio::io_context io_context;
tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v4(), 8085)); // Replace with your desired port
int queryNumber = 1;
while (true) {
std::shared_ptr<tcp::socket> socket(new tcp::socket(io_context));
acceptor.accept(*socket);
//std::thread([&socket,&queryNumber]() {
std::cout << "Running query " << queryNumber++ << std::endl;
handle_request(socket);
// }).detach();
}
return 0;
}
I hope these 3 questions are linked
- 1st question: Why do I get two accept? Is there a way to wait until the buffer is full?
- 2nd question: if I uncomment the thread management, I get a crash
- 3rd question: if I call it from the following HTML, I only get one event (good!) but no JSON data
<!DOCTYPE html>
<html>
<head>
<title>Form Example</title>
</head>
<body>
<form id="myForm">
<label for="name">Name:</label>
<input type="text" id="name" name="name" required><br><br>
<label for="email">Email:</label>
<input type="email" id="email" name="email" required><br><br>
<input type="submit" value="Submit">
</form>
<script>
document.getElementById("myForm").addEventListener("submit", function(event) {
event.preventDefault(); // Prevent the form from submitting normally
// Convert form data to JSON
var formData = new FormData(this);
var jsonData = {};
for (var pair of formData.entries()) {
jsonData[pair[0]] = pair[1];
}
// Send JSON data to the C++ project
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://localhost:3000",true); // Replace with your K8s service endpoint
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(JSON.stringify(jsonData));
});
</script>
</body>
</html>