2 * nghttp2 - HTTP/2 C Library
4 * Copyright (c) 2014 Tatsuhiro Tsujikawa
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice shall be
15 * included in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 #ifndef HTTP2_HANDLER_H
26 #define HTTP2_HANDLER_H
28 #include "nghttp2_config.h"
34 #include <boost/array.hpp>
35 #include <boost/asio.hpp>
37 #include <nghttp2/nghttp2.h>
39 #include <nghttp2/asio_http2.h>
42 namespace asio_http2 {
47 void post(void_cb cb);
48 void strand(boost::asio::io_service::strand *strand);
51 boost::asio::io_service::strand *strand_;
63 const std::vector<header> &headers() const;
64 const std::string &method() const;
65 const std::string &scheme() const;
66 const std::string &authority() const;
67 const std::string &host() const;
68 const std::string &path() const;
70 bool push(std::string method, std::string path,
71 std::vector<header> headers = {});
76 void on_data(data_cb cb);
77 void on_end(void_cb cb);
79 bool run_task(thread_cb start);
81 void set_header(std::vector<header> headers);
82 void add_header(std::string name, std::string value);
83 void method(std::string method);
84 void scheme(std::string scheme);
85 void authority(std::string authority);
86 void host(std::string host);
87 void path(std::string path);
89 void handler(std::weak_ptr<http2_handler> h);
90 void stream(std::weak_ptr<http2_stream> s);
91 void call_on_data(const uint8_t *data, std::size_t len);
95 std::vector<header> headers_;
98 std::string authority_;
103 std::weak_ptr<http2_handler> handler_;
104 std::weak_ptr<http2_stream> stream_;
108 class response_impl {
111 void write_head(unsigned int status_code, std::vector<header> headers = {});
112 void end(std::string data = "");
113 void end(read_cb cb);
117 unsigned int status_code() const;
118 const std::vector<header> &headers() const;
119 bool started() const;
120 void handler(std::weak_ptr<http2_handler> h);
121 void stream(std::weak_ptr<http2_stream> s);
122 read_cb::result_type call_read(uint8_t *data, std::size_t len);
125 std::vector<header> headers_;
127 std::weak_ptr<http2_handler> handler_;
128 std::weak_ptr<http2_stream> stream_;
129 unsigned int status_code_;
135 http2_stream(int32_t stream_id);
137 int32_t get_stream_id() const;
138 const std::shared_ptr<request> &get_request();
139 const std::shared_ptr<response> &get_response();
142 std::shared_ptr<request> request_;
143 std::shared_ptr<response> response_;
147 struct callback_guard {
148 callback_guard(http2_handler &h);
150 http2_handler &handler;
153 typedef std::function<void(void)> connection_write;
155 class http2_handler : public std::enable_shared_from_this<http2_handler> {
157 http2_handler(boost::asio::io_service &io_service,
158 boost::asio::io_service &task_io_service,
159 connection_write writefun, request_cb cb);
165 std::shared_ptr<http2_stream> create_stream(int32_t stream_id);
166 void close_stream(int32_t stream_id);
167 std::shared_ptr<http2_stream> find_stream(int32_t stream_id);
169 void call_on_request(http2_stream &stream);
171 bool should_stop() const;
173 int start_response(http2_stream &stream);
175 void stream_error(int32_t stream_id, uint32_t error_code);
177 void initiate_write();
179 void enter_callback();
180 void leave_callback();
181 bool inside_callback() const;
183 void resume(http2_stream &stream);
185 int push_promise(http2_stream &stream, std::string method, std::string path,
186 std::vector<header> headers);
188 bool run_task(thread_cb start);
190 boost::asio::io_service &io_service();
193 int on_read(const boost::array<uint8_t, N> &buffer, std::size_t len) {
194 callback_guard cg(*this);
198 rv = nghttp2_session_mem_recv(session_, buffer.data(), len);
208 int on_write(boost::array<uint8_t, N> &buffer, std::size_t &len) {
209 callback_guard cg(*this);
214 std::copy_n(buf_, buflen_, std::begin(buffer));
224 auto nread = nghttp2_session_mem_send(session_, &data);
233 if (len + nread > buffer.size()) {
240 std::copy_n(data, nread, std::begin(buffer) + len);
249 std::map<int32_t, std::shared_ptr<http2_stream>> streams_;
250 connection_write writefun_;
251 request_cb request_cb_;
252 boost::asio::io_service &io_service_;
253 boost::asio::io_service &task_io_service_;
254 std::shared_ptr<boost::asio::io_service::strand> strand_;
255 nghttp2_session *session_;
258 bool inside_callback_;
261 } // namespace server
262 } // namespace asio_http2
263 } // namespace nghttp
265 #endif // HTTP2_HANDLER_H