staticlib_pion  2.0.2
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Friends Macros
http_server.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2015, alex at staticlibs.net
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /*
18  * File: streaming_server.hpp
19  * Author: alex
20  *
21  * Created on March 23, 2015, 8:10 PM
22  */
23 
24 #ifndef STATICLIB_PION_HTTP_SERVER_HPP
25 #define STATICLIB_PION_HTTP_SERVER_HPP
26 
27 #include <cstdint>
28 #include <vector>
29 #include <map>
30 #include <set>
31 #include <unordered_map>
32 #include <utility>
33 
34 #include "asio.hpp"
35 
36 #include "staticlib/config.hpp"
37 #include "staticlib/support.hpp"
38 
45 
46 namespace staticlib {
47 namespace pion {
48 
49 class http_request_reader;
50 
54 class http_server : public tcp_server {
55  friend class http_request_reader;
56 
57 public:
61  using request_handler_type = std::function<void(http_request_ptr, response_writer_ptr)>;
62 
66  using payload_handler_creator_type = std::function<http_parser::payload_handler_type(http_request_ptr&)>;
67 
71  using handlers_map_type = std::unordered_map<std::string, request_handler_type>;
72 
76  using payloads_map_type = std::unordered_map<std::string, payload_handler_creator_type>;
77 
81  using websocket_map_type = std::unordered_map<std::string, websocket_handler_type>;
82 
83  // path -> (id, connection)
84  using websocket_conn_registry_type = std::multimap<std::string, std::pair<std::string, std::weak_ptr<tcp_connection>>>;
85 
86 private:
90  uint32_t read_timeout;
91 
95  handlers_map_type get_handlers;
96 
100  handlers_map_type post_handlers;
101 
105  handlers_map_type put_handlers;
106 
110  handlers_map_type delete_handlers;
111 
115  handlers_map_type options_handlers;
116 
120  request_handler_type bad_request_handler;
121 
125  request_handler_type not_found_handler;
126 
130  // GET payload won't happen, but lets be consistent here
131  // to simplify clients implementation and to make sure that
132  // pion's form-data parsing won't be triggered
133  payloads_map_type get_payloads;
134 
138  payloads_map_type post_payloads;
139 
143  payloads_map_type put_payloads;
144 
148  payloads_map_type delete_payloads;
149 
153  payloads_map_type options_payloads;
154 
158  websocket_map_type wsopen_handlers;
159 
163  websocket_map_type wsmessage_handlers;
164 
168  websocket_map_type wsclose_handlers;
169 
170  websocket_conn_registry_type websocket_conn_registry;
171 
172  std::mutex websocket_conn_registry_mtx;
173 
174 public:
175  ~http_server() STATICLIB_NOEXCEPT { }
176 
192  http_server(uint32_t number_of_threads, uint16_t port,
193  asio::ip::address_v4 ip_address = asio::ip::address_v4::any(),
194  uint32_t read_timeout_millis = 10000,
195  const std::string& ssl_key_file = std::string(),
196  std::function<std::string(std::size_t, asio::ssl::context::password_purpose)> ssl_key_password_callback =
197  [](std::size_t, asio::ssl::context::password_purpose) { return std::string(); },
198  const std::string& ssl_verify_file = std::string(),
199  std::function<bool(bool, asio::ssl::verify_context&)> ssl_verify_callback =
200  [](bool, asio::ssl::verify_context&) { return true; });
201 
209  void add_handler(const std::string& method, const std::string& resource,
210  request_handler_type request_handler);
211 
217  void set_bad_request_handler(request_handler_type handler) {
218  bad_request_handler = std::move(handler);
219  }
220 
226  void set_not_found_handler(request_handler_type handler) {
227  not_found_handler = std::move(handler);
228  }
229 
237  void add_payload_handler(const std::string& method, const std::string& resource,
238  payload_handler_creator_type payload_handler);
239 
247  void add_websocket_handler(const std::string& event, const std::string& resource,
248  websocket_handler_type handler);
249 
260  void broadcast_websocket(const std::string& path, sl::io::span<const char> message,
261  sl::websocket::frame_type frame_type = sl::websocket::frame_type::text,
262  const std::set<std::string>& dest_ids = std::set<std::string>());
263 private:
269  virtual void handle_connection(tcp_connection_ptr& conn) override;
270 
279  void handle_request_after_headers_parsed(http_request_ptr& request,
280  tcp_connection_ptr& conn, const std::error_code& ec, sl::support::tribool& rc);
281 
289  void handle_request(http_request_ptr request,
290  tcp_connection_ptr& conn, const std::error_code& ec);
291 
292 
293 };
294 
295 } // namespace
296 }
297 
298 #endif /* STATICLIB_PION_HTTP_SERVER_HPP */
299