#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 useunique_ptr
nor free manually. - more elegant/correct code.
-
\$\begingroup\$ lokiastari.com/blog/2016/05/26/c-plus-plus-wrapper-for-socket/… \$\endgroup\$Loki Astari– Loki Astari2019年10月10日 19:35:08 +00:00Commented Oct 10, 2019 at 19:35
1 Answer 1
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()
?