http_handler.h
1 // Copyright 2020, Beeri 15. All rights reserved.
2 // Author: Roman Gershman (romange@gmail.com)
3 //
4 
5 #pragma once
6 
7 #include <boost/beast/http/serializer.hpp>
8 #include <boost/beast/http/write.hpp>
9 
10 #include "util/uring/accept_server.h"
11 #include "strings/unique_strings.h"
12 #include "util/http/http_common.h"
13 
14 namespace util {
15 namespace uring {
16 
17 class HttpContext {
18  template <typename Body>
19  using Response = ::boost::beast::http::response<Body>;
20  using error_code = ::boost::system::error_code;
21 
22  AsioStreamAdapter<>& asa_;
23 
24 public:
25  explicit HttpContext(AsioStreamAdapter<>& asa) : asa_(asa) {}
26 
27  template <typename Body> void Invoke(Response<Body>&& msg) {
28  // Determine if we should close the connection after
29  // close_ = msg.need_eof();
30 
31  // We need the serializer here because the serializer requires
32  // a non-const file_body, and the message oriented version of
33  // http::write only works with const messages.
34  msg.prepare_payload();
35  ::boost::beast::http::response_serializer<Body> sr{msg};
36 
37  ::boost::system::error_code ec;
38  ::boost::beast::http::write(asa_, sr, ec);
39  }
40 };
41 
42 // Should be one per process. Represents http server interface.
43 // Currently does not support on the fly updates - requires
44 // multi-threading support.
45 class HttpHandler2;
46 
48  friend class HttpHandler2;
49 
50  public:
51  using RequestType = ::boost::beast::http::request<::boost::beast::http::string_body>;
52  typedef std::function<void(const http::QueryArgs&, HttpContext*)> RequestCb;
53 
55 
56  // Returns true if a callback was registered.
57  bool RegisterCb(StringPiece path, RequestCb cb);
58 
59  void set_resource_prefix(const char* prefix) { resource_prefix_ = prefix; }
60  void set_favicon(const char* favicon) { favicon_ = favicon;}
61 
62  private:
63  bool HandleRoot(const RequestType& rt, HttpContext* cntx) const;
64 
65  struct CbInfo {
66  RequestCb cb;
67  };
68  StringPieceMap<CbInfo> cb_map_;
69 
70  const char* favicon_;
71  const char* resource_prefix_;
72 };
73 
74 class HttpHandler2 : public Connection {
75  public:
76  using RequestType = ::boost::beast::http::request<::boost::beast::http::string_body>;
77 
78  HttpHandler2(const HttpListenerBase* base);
79 
80  void HandleRequests() final;
81 
82  protected:
83  void HandleOne(const RequestType& req, HttpContext* cntx);
84 
85  private:
86  const HttpListenerBase* base_;
87 };
88 
89 // http Listener + handler factory. By default creates HttpHandler.
90 template <typename Handler = HttpHandler2>
92  public:
93  static_assert(std::is_base_of<HttpHandler2, Handler>::value,
94  "Handler must be derived from HttpHandler");
95 
97  return new Handler(this);
98  }
99 };
100 
101 } // namespace uring
102 } // namespace util
Connection * NewConnection(Proactor *) final
Definition: http_handler.h:96
Abstracts away connections implementation and their life-cycle.
Definition: accept_server.h:69