asio: Rewrite response body handling if response body is not expected
This commit is contained in:
parent
d6f810d91a
commit
94ca9705ef
|
@ -325,18 +325,21 @@ int http2_handler::start_response(stream &strm) {
|
||||||
hd.second.sensitive));
|
hd.second.sensitive));
|
||||||
}
|
}
|
||||||
|
|
||||||
nghttp2_data_provider prd;
|
nghttp2_data_provider *prd_ptr = nullptr, prd;
|
||||||
prd.source.ptr = &strm;
|
auto &req = strm.request().impl();
|
||||||
prd.read_callback =
|
if (::nghttp2::http2::expect_response_body(req.method(), res.status_code())) {
|
||||||
[](nghttp2_session *session, int32_t stream_id, uint8_t *buf,
|
prd.source.ptr = &strm;
|
||||||
size_t length, uint32_t *data_flags, nghttp2_data_source *source,
|
prd.read_callback =
|
||||||
void *user_data) -> ssize_t {
|
[](nghttp2_session *session, int32_t stream_id, uint8_t *buf,
|
||||||
auto &strm = *static_cast<stream *>(source->ptr);
|
size_t length, uint32_t *data_flags, nghttp2_data_source *source,
|
||||||
return strm.response().impl().call_read(buf, length, data_flags);
|
void *user_data) -> ssize_t {
|
||||||
};
|
auto &strm = *static_cast<stream *>(source->ptr);
|
||||||
|
return strm.response().impl().call_read(buf, length, data_flags);
|
||||||
|
};
|
||||||
|
prd_ptr = &prd;
|
||||||
|
}
|
||||||
rv = nghttp2_submit_response(session_, strm.get_stream_id(), nva.data(),
|
rv = nghttp2_submit_response(session_, strm.get_stream_id(), nva.data(),
|
||||||
nva.size(), &prd);
|
nva.size(), prd_ptr);
|
||||||
|
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -62,6 +62,13 @@ request_cb redirect_handler(int status_code, std::string uri) {
|
||||||
|
|
||||||
request_cb status_handler(int status_code) {
|
request_cb status_handler(int status_code) {
|
||||||
return [status_code](const request &req, const response &res) {
|
return [status_code](const request &req, const response &res) {
|
||||||
|
if (!::nghttp2::http2::expect_response_body(status_code)) {
|
||||||
|
res.write_head(status_code);
|
||||||
|
res.end();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// we supply content-length for HEAD request, but body will not be
|
||||||
|
// sent.
|
||||||
auto html = create_html(status_code);
|
auto html = create_html(status_code);
|
||||||
header_map h;
|
header_map h;
|
||||||
h.emplace("content-length", header_value{util::utos(html.size())});
|
h.emplace("content-length", header_value{util::utos(html.size())});
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
#include "asio_server_http2_handler.h"
|
#include "asio_server_http2_handler.h"
|
||||||
#include "asio_common.h"
|
#include "asio_common.h"
|
||||||
|
|
||||||
|
#include "http2.h"
|
||||||
|
|
||||||
namespace nghttp2 {
|
namespace nghttp2 {
|
||||||
namespace asio_http2 {
|
namespace asio_http2 {
|
||||||
namespace server {
|
namespace server {
|
||||||
|
@ -79,23 +81,13 @@ void response_impl::end(generator_cb cb) {
|
||||||
state_ = response_state::BODY_STARTED;
|
state_ = response_state::BODY_STARTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
|
||||||
bool expect_response_body(const std::string &method, int status_code) {
|
|
||||||
return method != "HEAD" && status_code / 100 != 1 && status_code != 304 &&
|
|
||||||
status_code != 204;
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
void response_impl::start_response() {
|
void response_impl::start_response() {
|
||||||
auto handler = strm_->handler();
|
auto handler = strm_->handler();
|
||||||
|
|
||||||
auto &req = strm_->request().impl();
|
auto &req = strm_->request().impl();
|
||||||
|
|
||||||
// if response body is not expected, nullify it so that HEADERS has
|
if (!::nghttp2::http2::expect_response_body(req.method(), status_code_)) {
|
||||||
// END_STREAM flag set.
|
|
||||||
if (!expect_response_body(req.method(), status_code_)) {
|
|
||||||
state_ = response_state::BODY_STARTED;
|
state_ = response_state::BODY_STARTED;
|
||||||
generator_cb_ = generator_cb();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handler->start_response(*strm_) != 0) {
|
if (handler->start_response(*strm_) != 0) {
|
||||||
|
|
|
@ -1092,6 +1092,14 @@ std::string path_join(const char *base_path, size_t base_pathlen,
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool expect_response_body(int status_code) {
|
||||||
|
return status_code / 100 != 1 && status_code != 304 && status_code != 204;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool expect_response_body(const std::string &method, int status_code) {
|
||||||
|
return method != "HEAD" && expect_response_body(status_code);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace http2
|
} // namespace http2
|
||||||
|
|
||||||
} // namespace nghttp2
|
} // namespace nghttp2
|
||||||
|
|
|
@ -282,6 +282,13 @@ std::string path_join(const char *base_path, size_t base_pathlen,
|
||||||
const char *rel_path, size_t rel_pathlen,
|
const char *rel_path, size_t rel_pathlen,
|
||||||
const char *rel_query, size_t rel_querylen);
|
const char *rel_query, size_t rel_querylen);
|
||||||
|
|
||||||
|
// true if response has body, taking into account the request method
|
||||||
|
// and status code.
|
||||||
|
bool expect_response_body(const std::string &method, int status_code);
|
||||||
|
|
||||||
|
// true if response has body, taking into account status code only.
|
||||||
|
bool expect_response_body(int status_code);
|
||||||
|
|
||||||
} // namespace http2
|
} // namespace http2
|
||||||
|
|
||||||
} // namespace nghttp2
|
} // namespace nghttp2
|
||||||
|
|
Loading…
Reference in New Issue