From bc3949db9e580dcc3f35f6e48949dd3c59fb6bd6 Mon Sep 17 00:00:00 2001 From: Matt Way Date: Tue, 11 Apr 2017 16:38:42 -0400 Subject: [PATCH] Support specifying stream priority via session::submit() --- src/asio_client_session.cc | 31 +++++++++++++++++++----- src/asio_client_session_impl.cc | 4 +-- src/asio_client_session_impl.h | 2 +- src/includes/nghttp2/asio_http2_client.h | 31 +++++++++++++++++++++--- 4 files changed, 56 insertions(+), 12 deletions(-) diff --git a/src/asio_client_session.cc b/src/asio_client_session.cc index 5762c4c5..8c4a8742 100644 --- a/src/asio_client_session.cc +++ b/src/asio_client_session.cc @@ -96,29 +96,48 @@ boost::asio::io_service &session::io_service() const { const request *session::submit(boost::system::error_code &ec, const std::string &method, - const std::string &uri, header_map h) const { - return impl_->submit(ec, method, uri, generator_cb(), std::move(h)); + const std::string &uri, header_map h, + priority_spec prio) const { + return impl_->submit(ec, method, uri, generator_cb(), std::move(h), + std::move(prio)); } const request *session::submit(boost::system::error_code &ec, const std::string &method, const std::string &uri, std::string data, - header_map h) const { + header_map h, priority_spec prio) const { return impl_->submit(ec, method, uri, string_generator(std::move(data)), - std::move(h)); + std::move(h), std::move(prio)); } const request *session::submit(boost::system::error_code &ec, const std::string &method, const std::string &uri, generator_cb cb, - header_map h) const { - return impl_->submit(ec, method, uri, std::move(cb), std::move(h)); + header_map h, priority_spec prio) const { + return impl_->submit(ec, method, uri, std::move(cb), std::move(h), + std::move(prio)); } void session::read_timeout(const boost::posix_time::time_duration &t) { impl_->read_timeout(t); } +priority_spec::priority_spec(const int32_t stream_id, const int32_t weight, + const bool exclusive) + : valid_(true) { + nghttp2_priority_spec_init(&spec_, stream_id, weight, exclusive); +} + +const nghttp2_priority_spec *priority_spec::get() const { + if (!valid_) { + return nullptr; + } + + return &spec_; +} + +const bool priority_spec::valid() const { return valid_; } + } // namespace client } // namespace asio_http2 } // nghttp2 diff --git a/src/asio_client_session_impl.cc b/src/asio_client_session_impl.cc index ac7b4a89..025254b4 100644 --- a/src/asio_client_session_impl.cc +++ b/src/asio_client_session_impl.cc @@ -479,7 +479,7 @@ std::unique_ptr session_impl::create_stream() { const request *session_impl::submit(boost::system::error_code &ec, const std::string &method, const std::string &uri, generator_cb cb, - header_map h) { + header_map h, priority_spec prio) { ec.clear(); if (stopped_) { @@ -559,7 +559,7 @@ const request *session_impl::submit(boost::system::error_code &ec, prdptr = &prd; } - auto stream_id = nghttp2_submit_request(session_, nullptr, nva.data(), + auto stream_id = nghttp2_submit_request(session_, prio.get(), nva.data(), nva.size(), prdptr, strm.get()); if (stream_id < 0) { ec = make_error_code(static_cast(stream_id)); diff --git a/src/asio_client_session_impl.h b/src/asio_client_session_impl.h index ec8a9193..694ac208 100644 --- a/src/asio_client_session_impl.h +++ b/src/asio_client_session_impl.h @@ -70,7 +70,7 @@ public: const request *submit(boost::system::error_code &ec, const std::string &method, const std::string &uri, - generator_cb cb, header_map h); + generator_cb cb, header_map h, priority_spec spec); virtual void start_connect(tcp::resolver::iterator endpoint_it) = 0; virtual tcp::socket &socket() = 0; diff --git a/src/includes/nghttp2/asio_http2_client.h b/src/includes/nghttp2/asio_http2_client.h index c3662e2e..c6c1947b 100644 --- a/src/includes/nghttp2/asio_http2_client.h +++ b/src/includes/nghttp2/asio_http2_client.h @@ -118,6 +118,28 @@ private: std::unique_ptr impl_; }; +// Wrapper around an nghttp2_priority_spec. +class priority_spec { +public: + // The default ctor is used only by sentinel values. + priority_spec() = default; + + // Create a priority spec with the given priority settings. + explicit priority_spec(const int32_t stream_id, const int32_t weight, + const bool exclusive = false); + + // Return a pointer to a valid nghttp2 priority spec, or null. + const nghttp2_priority_spec *get() const; + + // Indicates whether or not this spec is valid (i.e. was constructed with + // values). + const bool valid() const; + +private: + nghttp2_priority_spec spec_; + bool valid_ = false; +}; + class session_impl; class session { @@ -177,7 +199,8 @@ public: // succeeds, or nullptr and |ec| contains error message. const request *submit(boost::system::error_code &ec, const std::string &method, const std::string &uri, - header_map h = header_map{}) const; + header_map h = header_map{}, + priority_spec prio = priority_spec()) const; // Submits request to server using |method| (e.g., "GET"), |uri| // (e.g., "http://localhost/") and optionally additional header @@ -186,7 +209,8 @@ public: // contains error message. const request *submit(boost::system::error_code &ec, const std::string &method, const std::string &uri, - std::string data, header_map h = header_map{}) const; + std::string data, header_map h = header_map{}, + priority_spec prio = priority_spec()) const; // Submits request to server using |method| (e.g., "GET"), |uri| // (e.g., "http://localhost/") and optionally additional header @@ -195,7 +219,8 @@ public: // nullptr and |ec| contains error message. const request *submit(boost::system::error_code &ec, const std::string &method, const std::string &uri, - generator_cb cb, header_map h = header_map{}) const; + generator_cb cb, header_map h = header_map{}, + priority_spec prio = priority_spec()) const; private: std::shared_ptr impl_;