diff --git a/src/asio_http2_handler.cc b/src/asio_http2_handler.cc index df5bae17..3437b0f1 100644 --- a/src/asio_http2_handler.cc +++ b/src/asio_http2_handler.cc @@ -63,6 +63,10 @@ void response::end(std::string data) const { impl_->end(std::move(data)); } void response::end(read_cb cb) const { impl_->end(std::move(cb)); } +void response::on_close(close_cb cb) const { impl_->on_close(std::move(cb)); } + +void response::cancel() const { impl_->cancel(); } + const response *response::push(boost::system::error_code &ec, std::string method, std::string path, header_map h) const { @@ -133,6 +137,20 @@ void response_impl::end(read_cb cb) { start_response(); } +void response_impl::on_close(close_cb cb) { close_cb_ = std::move(cb); } + +void response_impl::call_on_close(uint32_t error_code) { + if (close_cb_) { + close_cb_(error_code); + } +} + +void response_impl::cancel() { + auto handler = stream_->handler(); + + handler->stream_error(stream_->get_stream_id(), NGHTTP2_CANCEL); +} + void response_impl::start_response() { if (!started_ || (pushed_ && !push_promise_sent_)) { return; @@ -333,6 +351,13 @@ int on_stream_close_callback(nghttp2_session *session, int32_t stream_id, uint32_t error_code, void *user_data) { auto handler = static_cast(user_data); + auto stream = handler->find_stream(stream_id); + if (!stream) { + return 0; + } + + stream->response().impl().call_on_close(error_code); + handler->close_stream(stream_id); return 0; diff --git a/src/asio_http2_handler.h b/src/asio_http2_handler.h index 38b44e5c..c8d49898 100644 --- a/src/asio_http2_handler.h +++ b/src/asio_http2_handler.h @@ -76,8 +76,11 @@ public: void write_head(unsigned int status_code, header_map h = {}); void end(std::string data = ""); void end(read_cb cb); + void on_close(close_cb cb); void resume(); + void cancel(); + response *push(boost::system::error_code &ec, std::string method, std::string raw_path_query, header_map h = {}) const; @@ -91,11 +94,13 @@ public: void stream(http2_stream *s); read_cb::result_type call_read(uint8_t *data, std::size_t len, uint32_t *data_flags); + void call_on_close(uint32_t error_code); private: http2_stream *stream_; header_map header_; read_cb read_cb_; + close_cb close_cb_; unsigned int status_code_; // true if response started (end() is called) bool started_; diff --git a/src/includes/nghttp2/asio_http2_server.h b/src/includes/nghttp2/asio_http2_server.h index c7bdad17..f669fa64 100644 --- a/src/includes/nghttp2/asio_http2_server.h +++ b/src/includes/nghttp2/asio_http2_server.h @@ -78,6 +78,10 @@ public: // further call of end() is allowed. void end(read_cb cb) const; + void on_close(close_cb cb) const; + + void cancel() const; + // Resumes deferred response. void resume() const;