4
\$\begingroup\$
#include "fmt/format.h"
#include <cstdint>
#include <cstdio>
#include <event2/event-config.h>
#include <event2/util.h>
#include <evhttp.h>
#include <memory>
#include <type_traits>
auto
main() -> int
{
    constexpr char host[] = "127.0.0.1";
    std::uint16_t port = 5555;

    using event_base_new_type
        = std::pointer_traits<decltype(event_base_new())>::element_type;
    using event_base_deleter_type = decltype(&event_base_free);
    auto event_base
        = std::unique_ptr<event_base_new_type, event_base_deleter_type>(
            event_base_new(), &event_base_free);

    if(!(event_base))
    {
        fmt::print(stderr, "Failed to init libevent.\n");
        return -1;
    }

    using evhttp_new_type
        = std::pointer_traits<decltype(evhttp_new(event_base.get()))>::element_type;
    using evhttp_deleter_type = decltype(&evhttp_free);
    auto http = std::unique_ptr<evhttp_new_type, evhttp_deleter_type>(evhttp_new(event_base.get()), &evhttp_free);

    auto handle = evhttp_bind_socket_with_handle(http.get(), host, port);
    if(!handle)
    {
        fmt::print(stderr, "Failed to init http server.\n");
        return -1;
    }
    auto callback = [](evhttp_request* req, void*) {
        auto* OutBuf = evhttp_request_get_output_buffer(req);
        if(!OutBuf)
            return;
        evbuffer_add_printf(OutBuf,
            "<html><body><center><h1>Hello World!</h1></center></body></html>");
        evhttp_send_reply(req, HTTP_OK, "", OutBuf);
    };
    evhttp_set_gencb(http.get(), callback, nullptr);
    if(event_base_dispatch(event_base.get()) == -1)
    {
        fmt::print(stderr, "Failed to run messahe loop.\n");
        return -1;
    }

    return 0;
}

Compile

g++ a.cpp -lfmt -levent

Run

$ ./a.out
$ ab -c 1000 -k -r -t 10 http://127.0.0.1:5555/

Open http://127.0.0.1:5555/ in browser

What I want to know:

  • Is my unique_ptr necessary? valgrind reports no memory leak even though I don't use unique_ptr nor free manually.
  • more elegant/correct code.
\$\endgroup\$
1
\$\begingroup\$

Not too much to review as the code uses evhttp to handle HTTP and provide a basic, static reply for each request.

Why is host constexpr, but not the port?

All those using statements, combined with traits and decltype one after the other makes the code very hard to read, almost obscuring the fact that evhttp is being initialized at that point. I would try to rewrite that part in a simpler way.

Why auto main() -> int instead of the simple, classic int main()?

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.