0

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>
BadJerry
  • 154
  • 1
  • 12

0 Answers0