asio: server: Move push member function to response object
This commit is contained in:
parent
ff0eaf8399
commit
726e6c087d
|
@ -100,8 +100,8 @@ int main(int argc, char *argv[]) {
|
||||||
std::cerr << "push response header was received" << std::endl;
|
std::cerr << "push response header was received" << std::endl;
|
||||||
|
|
||||||
res.on_data([](const uint8_t *data, std::size_t len) {
|
res.on_data([](const uint8_t *data, std::size_t len) {
|
||||||
// std::cerr.write(reinterpret_cast<const char *>(data), len);
|
std::cerr.write(reinterpret_cast<const char *>(data), len);
|
||||||
// std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -47,12 +47,6 @@ const std::string &request::method() const { return impl_->method(); }
|
||||||
|
|
||||||
const uri_ref &request::uri() const { return impl_->uri(); }
|
const uri_ref &request::uri() const { return impl_->uri(); }
|
||||||
|
|
||||||
bool request::push(std::string method, std::string path, header_map h) const {
|
|
||||||
return impl_->push(std::move(method), std::move(path), std::move(h));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool request::pushed() const { return impl_->pushed(); }
|
|
||||||
|
|
||||||
void request::on_data(data_cb cb) const {
|
void request::on_data(data_cb cb) const {
|
||||||
return impl_->on_data(std::move(cb));
|
return impl_->on_data(std::move(cb));
|
||||||
}
|
}
|
||||||
|
@ -69,6 +63,12 @@ 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::end(read_cb cb) const { impl_->end(std::move(cb)); }
|
||||||
|
|
||||||
|
const response *response::push(boost::system::error_code &ec,
|
||||||
|
std::string method, std::string path,
|
||||||
|
header_map h) const {
|
||||||
|
return impl_->push(ec, std::move(method), std::move(path), std::move(h));
|
||||||
|
}
|
||||||
|
|
||||||
void response::resume() const { impl_->resume(); }
|
void response::resume() const { impl_->resume(); }
|
||||||
|
|
||||||
unsigned int response::status_code() const { return impl_->status_code(); }
|
unsigned int response::status_code() const { return impl_->status_code(); }
|
||||||
|
@ -77,7 +77,7 @@ bool response::started() const { return impl_->started(); }
|
||||||
|
|
||||||
response_impl &response::impl() const { return *impl_; }
|
response_impl &response::impl() const { return *impl_; }
|
||||||
|
|
||||||
request_impl::request_impl() : stream_(nullptr), pushed_(false) {}
|
request_impl::request_impl() : stream_(nullptr) {}
|
||||||
|
|
||||||
const header_map &request_impl::header() const { return header_; }
|
const header_map &request_impl::header() const { return header_; }
|
||||||
|
|
||||||
|
@ -93,17 +93,6 @@ header_map &request_impl::header() { return header_; }
|
||||||
|
|
||||||
void request_impl::method(std::string arg) { method_ = std::move(arg); }
|
void request_impl::method(std::string arg) { method_ = std::move(arg); }
|
||||||
|
|
||||||
bool request_impl::push(std::string method, std::string path, header_map h) {
|
|
||||||
auto handler = stream_->handler();
|
|
||||||
auto rv = handler->push_promise(*stream_, std::move(method), std::move(path),
|
|
||||||
std::move(h));
|
|
||||||
return rv == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool request_impl::pushed() const { return pushed_; }
|
|
||||||
|
|
||||||
void request_impl::pushed(bool f) { pushed_ = f; }
|
|
||||||
|
|
||||||
void request_impl::on_data(data_cb cb) { on_data_cb_ = std::move(cb); }
|
void request_impl::on_data(data_cb cb) { on_data_cb_ = std::move(cb); }
|
||||||
|
|
||||||
void request_impl::stream(http2_stream *s) { stream_ = s; }
|
void request_impl::stream(http2_stream *s) { stream_ = s; }
|
||||||
|
@ -115,7 +104,8 @@ void request_impl::call_on_data(const uint8_t *data, std::size_t len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
response_impl::response_impl()
|
response_impl::response_impl()
|
||||||
: stream_(nullptr), status_code_(200), started_(false) {}
|
: stream_(nullptr), status_code_(200), started_(false), pushed_(false),
|
||||||
|
push_promise_sent_(false) {}
|
||||||
|
|
||||||
unsigned int response_impl::status_code() const { return status_code_; }
|
unsigned int response_impl::status_code() const { return status_code_; }
|
||||||
|
|
||||||
|
@ -140,6 +130,14 @@ void response_impl::end(read_cb cb) {
|
||||||
read_cb_ = std::move(cb);
|
read_cb_ = std::move(cb);
|
||||||
started_ = true;
|
started_ = true;
|
||||||
|
|
||||||
|
start_response();
|
||||||
|
}
|
||||||
|
|
||||||
|
void response_impl::start_response() {
|
||||||
|
if (!started_ || (pushed_ && !push_promise_sent_)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto handler = stream_->handler();
|
auto handler = stream_->handler();
|
||||||
|
|
||||||
if (handler->start_response(*stream_) != 0) {
|
if (handler->start_response(*stream_) != 0) {
|
||||||
|
@ -152,6 +150,13 @@ void response_impl::end(read_cb cb) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
response *response_impl::push(boost::system::error_code &ec, std::string method,
|
||||||
|
std::string raw_path_query, header_map h) const {
|
||||||
|
auto handler = stream_->handler();
|
||||||
|
return handler->push_promise(ec, *stream_, std::move(method),
|
||||||
|
std::move(raw_path_query), std::move(h));
|
||||||
|
}
|
||||||
|
|
||||||
void response_impl::resume() {
|
void response_impl::resume() {
|
||||||
auto handler = stream_->handler();
|
auto handler = stream_->handler();
|
||||||
handler->resume(*stream_);
|
handler->resume(*stream_);
|
||||||
|
@ -163,6 +168,10 @@ void response_impl::resume() {
|
||||||
|
|
||||||
bool response_impl::started() const { return started_; }
|
bool response_impl::started() const { return started_; }
|
||||||
|
|
||||||
|
void response_impl::pushed(bool f) { pushed_ = f; }
|
||||||
|
|
||||||
|
void response_impl::push_promise_sent(bool f) { push_promise_sent_ = f; }
|
||||||
|
|
||||||
const header_map &response_impl::header() const { return header_; }
|
const header_map &response_impl::header() const { return header_; }
|
||||||
|
|
||||||
void response_impl::stream(http2_stream *s) { stream_ = s; }
|
void response_impl::stream(http2_stream *s) { stream_ = s; }
|
||||||
|
@ -345,7 +354,9 @@ int on_frame_send_callback(nghttp2_session *session, const nghttp2_frame *frame,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
handler->call_on_request(*stream);
|
auto &res = stream->response().impl();
|
||||||
|
res.push_promise_sent(true);
|
||||||
|
res.start_response();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -508,10 +519,14 @@ void http2_handler::resume(http2_stream &stream) {
|
||||||
nghttp2_session_resume_data(session_, stream.get_stream_id());
|
nghttp2_session_resume_data(session_, stream.get_stream_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
int http2_handler::push_promise(http2_stream &stream, std::string method,
|
response *http2_handler::push_promise(boost::system::error_code &ec,
|
||||||
std::string raw_path_query, header_map h) {
|
http2_stream &stream, std::string method,
|
||||||
|
std::string raw_path_query,
|
||||||
|
header_map h) {
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
|
ec.clear();
|
||||||
|
|
||||||
auto &req = stream.request().impl();
|
auto &req = stream.request().impl();
|
||||||
|
|
||||||
auto nva = std::vector<nghttp2_nv>();
|
auto nva = std::vector<nghttp2_nv>();
|
||||||
|
@ -531,20 +546,24 @@ int http2_handler::push_promise(http2_stream &stream, std::string method,
|
||||||
nva.size(), nullptr);
|
nva.size(), nullptr);
|
||||||
|
|
||||||
if (rv < 0) {
|
if (rv < 0) {
|
||||||
return -1;
|
ec = make_error_code(static_cast<nghttp2_error>(rv));
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto promised_stream = create_stream(rv);
|
auto promised_stream = create_stream(rv);
|
||||||
auto &promised_req = promised_stream->request().impl();
|
auto &promised_req = promised_stream->request().impl();
|
||||||
promised_req.pushed(true);
|
|
||||||
promised_req.header(std::move(h));
|
promised_req.header(std::move(h));
|
||||||
promised_req.method(std::move(method));
|
promised_req.method(std::move(method));
|
||||||
|
|
||||||
auto &uref = promised_req.uri();
|
auto &uref = promised_req.uri();
|
||||||
uref.scheme = req.uri().scheme;
|
uref.scheme = req.uri().scheme;
|
||||||
uref.host = req.uri().host;
|
uref.host = req.uri().host;
|
||||||
split_path(uref, std::begin(raw_path_query), std::end(raw_path_query));
|
split_path(uref, std::begin(raw_path_query), std::end(raw_path_query));
|
||||||
|
|
||||||
return 0;
|
auto &promised_res = promised_stream->response().impl();
|
||||||
|
promised_res.pushed(true);
|
||||||
|
|
||||||
|
return &promised_stream->response();
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::asio::io_service &http2_handler::io_service() { return io_service_; }
|
boost::asio::io_service &http2_handler::io_service() { return io_service_; }
|
||||||
|
|
|
@ -57,13 +57,8 @@ public:
|
||||||
const uri_ref &uri() const;
|
const uri_ref &uri() const;
|
||||||
uri_ref &uri();
|
uri_ref &uri();
|
||||||
|
|
||||||
bool push(std::string method, std::string raw_path_query, header_map h = {});
|
|
||||||
|
|
||||||
bool pushed() const;
|
|
||||||
|
|
||||||
void on_data(data_cb cb);
|
void on_data(data_cb cb);
|
||||||
|
|
||||||
void pushed(bool f);
|
|
||||||
void stream(http2_stream *s);
|
void stream(http2_stream *s);
|
||||||
void call_on_data(const uint8_t *data, std::size_t len);
|
void call_on_data(const uint8_t *data, std::size_t len);
|
||||||
|
|
||||||
|
@ -73,7 +68,6 @@ private:
|
||||||
std::string method_;
|
std::string method_;
|
||||||
uri_ref uri_;
|
uri_ref uri_;
|
||||||
data_cb on_data_cb_;
|
data_cb on_data_cb_;
|
||||||
bool pushed_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class response_impl {
|
class response_impl {
|
||||||
|
@ -84,9 +78,16 @@ public:
|
||||||
void end(read_cb cb);
|
void end(read_cb cb);
|
||||||
void resume();
|
void resume();
|
||||||
|
|
||||||
|
response *push(boost::system::error_code &ec, std::string method,
|
||||||
|
std::string raw_path_query, header_map h = {}) const;
|
||||||
|
|
||||||
|
void start_response();
|
||||||
|
|
||||||
unsigned int status_code() const;
|
unsigned int status_code() const;
|
||||||
const header_map &header() const;
|
const header_map &header() const;
|
||||||
bool started() const;
|
bool started() const;
|
||||||
|
void pushed(bool f);
|
||||||
|
void push_promise_sent(bool f);
|
||||||
void stream(http2_stream *s);
|
void stream(http2_stream *s);
|
||||||
read_cb::result_type call_read(uint8_t *data, std::size_t len,
|
read_cb::result_type call_read(uint8_t *data, std::size_t len,
|
||||||
uint32_t *data_flags);
|
uint32_t *data_flags);
|
||||||
|
@ -96,7 +97,13 @@ private:
|
||||||
header_map header_;
|
header_map header_;
|
||||||
read_cb read_cb_;
|
read_cb read_cb_;
|
||||||
unsigned int status_code_;
|
unsigned int status_code_;
|
||||||
|
// true if response started (end() is called)
|
||||||
bool started_;
|
bool started_;
|
||||||
|
// true if this is pushed stream's response
|
||||||
|
bool pushed_;
|
||||||
|
// true if PUSH_PROMISE is sent if this is response of a pushed
|
||||||
|
// stream
|
||||||
|
bool push_promise_sent_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class http2_stream {
|
class http2_stream {
|
||||||
|
@ -153,8 +160,9 @@ public:
|
||||||
|
|
||||||
void resume(http2_stream &stream);
|
void resume(http2_stream &stream);
|
||||||
|
|
||||||
int push_promise(http2_stream &stream, std::string method,
|
response *push_promise(boost::system::error_code &ec, http2_stream &stream,
|
||||||
std::string raw_path_query, header_map h);
|
std::string method, std::string raw_path_query,
|
||||||
|
header_map h);
|
||||||
|
|
||||||
boost::asio::io_service &io_service();
|
boost::asio::io_service &io_service();
|
||||||
|
|
||||||
|
|
|
@ -54,16 +54,6 @@ public:
|
||||||
// Sets callback when chunk of request body is received.
|
// Sets callback when chunk of request body is received.
|
||||||
void on_data(data_cb cb) const;
|
void on_data(data_cb cb) const;
|
||||||
|
|
||||||
// Pushes resource denoted by |path| using |method|. The additional
|
|
||||||
// headers can be given in |h|. request_cb will be called for
|
|
||||||
// pushed resource later on. This function returns true if it
|
|
||||||
// succeeds, or false.
|
|
||||||
bool push(std::string method, std::string raw_path_query,
|
|
||||||
header_map h = {}) const;
|
|
||||||
|
|
||||||
// Returns true if this is pushed request.
|
|
||||||
bool pushed() const;
|
|
||||||
|
|
||||||
// Application must not call this directly.
|
// Application must not call this directly.
|
||||||
request_impl &impl() const;
|
request_impl &impl() const;
|
||||||
|
|
||||||
|
@ -91,6 +81,13 @@ public:
|
||||||
// Resumes deferred response.
|
// Resumes deferred response.
|
||||||
void resume() const;
|
void resume() const;
|
||||||
|
|
||||||
|
// Pushes resource denoted by |raw_path_query| using |method|. The
|
||||||
|
// additional headers can be given in |h|. This function returns
|
||||||
|
// pointer to response object for promised stream, otherwise nullptr
|
||||||
|
// and error code is filled in |ec|.
|
||||||
|
const response *push(boost::system::error_code &ec, std::string method,
|
||||||
|
std::string raw_path_query, header_map h = {}) const;
|
||||||
|
|
||||||
// Returns status code.
|
// Returns status code.
|
||||||
unsigned int status_code() const;
|
unsigned int status_code() const;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue