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