Http Server in C++

Here’s the translation of the HTTP server example from Go to C++, formatted in Markdown suitable for Hugo:

#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <cpprest/http_listener.h>
#include <cpprest/json.h>

using namespace web;
using namespace http;
using namespace utility;
using namespace http::experimental::listener;

void handle_hello(http_request request) {
    request.reply(status_codes::OK, U("hello\n"));
}

void handle_headers(http_request request) {
    std::stringstream response;
    for (const auto& header : request.headers()) {
        response << header.first << ": " << header.second << "\n";
    }
    request.reply(status_codes::OK, response.str());
}

int main() {
    http_listener listener("http://localhost:8090");

    listener.support(methods::GET, [](http_request request) {
        auto path = request.relative_uri().path();
        if (path == "/hello") {
            handle_hello(request);
        } else if (path == "/headers") {
            handle_headers(request);
        } else {
            request.reply(status_codes::NotFound, U("Not found"));
        }
    });

    try {
        listener.open().wait();
        std::cout << "Listening on http://localhost:8090" << std::endl;
        while (true);
    } catch (const std::exception & e) {
        std::cout << e.what() << std::endl;
    }

    return 0;
}

Writing a basic HTTP server in C++ can be done using the C++ REST SDK (also known as Casablanca). This example demonstrates how to create a simple HTTP server that responds to GET requests.

A fundamental concept in HTTP servers is handlers. In C++, we can use functions or lambda expressions to handle different routes.

The handle_hello function serves as a handler for the “/hello” route. It simply responds with “hello\n”.

void handle_hello(http_request request) {
    request.reply(status_codes::OK, U("hello\n"));
}

The handle_headers function is a more sophisticated handler for the “/headers” route. It reads all the HTTP request headers and echoes them into the response body.

void handle_headers(http_request request) {
    std::stringstream response;
    for (const auto& header : request.headers()) {
        response << header.first << ": " << header.second << "\n";
    }
    request.reply(status_codes::OK, response.str());
}

In the main function, we create an http_listener and set up the routes:

http_listener listener("http://localhost:8090");

listener.support(methods::GET, [](http_request request) {
    auto path = request.relative_uri().path();
    if (path == "/hello") {
        handle_hello(request);
    } else if (path == "/headers") {
        handle_headers(request);
    } else {
        request.reply(status_codes::NotFound, U("Not found"));
    }
});

Finally, we open the listener and keep the program running:

try {
    listener.open().wait();
    std::cout << "Listening on http://localhost:8090" << std::endl;
    while (true);
} catch (const std::exception & e) {
    std::cout << e.what() << std::endl;
}

To run the server:

  1. Compile the code with the necessary libraries (you may need to install the C++ REST SDK).
  2. Run the compiled executable.

You can then access the server:

$ curl localhost:8090/hello
hello

$ curl localhost:8090/headers
User-Agent: curl/7.68.0
Accept: */*

This example demonstrates how to create a basic HTTP server in C++ that can handle different routes and respond to requests.