mirror of
https://github.com/nghttp2/nghttp2.git
synced 2025-12-06 18:18:52 +08:00
Compare commits
6 Commits
02a5649343
...
3122a83900
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3122a83900 | ||
|
|
75272a817e | ||
|
|
809d5af43e | ||
|
|
3b549caf90 | ||
|
|
42b659354d | ||
|
|
2275327794 |
3
.github/workflows/build.yml
vendored
3
.github/workflows/build.yml
vendored
@@ -114,8 +114,9 @@ jobs:
|
||||
- name: Build nghttp3
|
||||
if: matrix.http3 == 'http3'
|
||||
run: |
|
||||
git clone --depth 1 -b v0.1.1 https://github.com/ngtcp2/nghttp3
|
||||
git clone https://github.com/ngtcp2/nghttp3
|
||||
cd nghttp3
|
||||
git checkout 207318c92e0578ac393c31dcd797e4a4dca3e31a
|
||||
autoreconf -i
|
||||
./configure --prefix=$PWD/build --enable-lib-only
|
||||
make -j$(nproc) check
|
||||
|
||||
@@ -366,8 +366,9 @@ Build nghttp3:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ git clone --depth 1 -b v0.1.1 https://github.com/ngtcp2/nghttp3
|
||||
$ git clone https://github.com/ngtcp2/nghttp3
|
||||
$ cd nghttp3
|
||||
$ git checkout 207318c92e0578ac393c31dcd797e4a4dca3e31a
|
||||
$ autoreconf -i
|
||||
$ ./configure --prefix=$PWD/build --enable-lib-only
|
||||
$ make -j$(nproc)
|
||||
|
||||
@@ -120,7 +120,7 @@ int stream_close(ngtcp2_conn *conn, uint32_t flags, int64_t stream_id,
|
||||
}
|
||||
|
||||
if (c->quic_stream_close(stream_id, app_error_code) != 0) {
|
||||
return -1;
|
||||
return NGTCP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -140,7 +140,7 @@ int stream_reset(ngtcp2_conn *conn, int64_t stream_id, uint64_t final_size,
|
||||
void *stream_user_data) {
|
||||
auto c = static_cast<Client *>(user_data);
|
||||
if (c->quic_stream_reset(stream_id, app_error_code) != 0) {
|
||||
return -1;
|
||||
return NGTCP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -160,7 +160,7 @@ int stream_stop_sending(ngtcp2_conn *conn, int64_t stream_id,
|
||||
void *stream_user_data) {
|
||||
auto c = static_cast<Client *>(user_data);
|
||||
if (c->quic_stream_stop_sending(stream_id, app_error_code) != 0) {
|
||||
return -1;
|
||||
return NGTCP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -667,6 +667,11 @@ int Client::read_quic() {
|
||||
timestamp(worker->loop));
|
||||
if (rv != 0) {
|
||||
std::cerr << "ngtcp2_conn_read_pkt: " << ngtcp2_strerror(rv) << std::endl;
|
||||
|
||||
if (!quic.last_error.code) {
|
||||
quic.last_error = quic::err_transport(rv);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -98,7 +98,8 @@ int HealthMonitorDownstreamConnection::on_read() { return 0; }
|
||||
|
||||
int HealthMonitorDownstreamConnection::on_write() { return 0; }
|
||||
|
||||
void HealthMonitorDownstreamConnection::on_upstream_change(Upstream *upstream) {}
|
||||
void HealthMonitorDownstreamConnection::on_upstream_change(Upstream *upstream) {
|
||||
}
|
||||
|
||||
bool HealthMonitorDownstreamConnection::poolable() const { return false; }
|
||||
|
||||
|
||||
@@ -1035,7 +1035,9 @@ int Http3Upstream::downstream_eof(DownstreamConnection *dconn) {
|
||||
// downstream_read_data_callback to send RST_STREAM after pending
|
||||
// response body is sent. This is needed to ensure that RST_STREAM
|
||||
// is sent after all pending data are sent.
|
||||
on_downstream_body_complete(downstream);
|
||||
if (on_downstream_body_complete(downstream) != 0) {
|
||||
return -1;
|
||||
}
|
||||
} else if (downstream->get_response_state() !=
|
||||
DownstreamState::MSG_COMPLETE) {
|
||||
// If stream was not closed, then we set MSG_COMPLETE and let
|
||||
@@ -1079,7 +1081,9 @@ int Http3Upstream::downstream_error(DownstreamConnection *dconn, int events) {
|
||||
} else {
|
||||
if (downstream->get_response_state() == DownstreamState::HEADER_COMPLETE) {
|
||||
if (downstream->get_upgraded()) {
|
||||
on_downstream_body_complete(downstream);
|
||||
if (on_downstream_body_complete(downstream) != 0) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
shutdown_stream(downstream, NGHTTP3_H3_INTERNAL_ERROR);
|
||||
}
|
||||
@@ -1366,6 +1370,24 @@ int Http3Upstream::on_downstream_body_complete(Downstream *downstream) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!downstream->get_upgraded()) {
|
||||
const auto &trailers = resp.fs.trailers();
|
||||
if (!trailers.empty()) {
|
||||
std::vector<nghttp3_nv> nva;
|
||||
nva.reserve(trailers.size());
|
||||
http3::copy_headers_to_nva_nocopy(nva, trailers, http2::HDOP_STRIP_ALL);
|
||||
if (!nva.empty()) {
|
||||
auto rv = nghttp3_conn_submit_trailers(
|
||||
httpconn_, downstream->get_stream_id(), nva.data(), nva.size());
|
||||
if (rv != 0) {
|
||||
ULOG(FATAL, this) << "nghttp3_conn_submit_trailers() failed: "
|
||||
<< nghttp3_strerror(rv);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nghttp3_conn_resume_stream(httpconn_, downstream->get_stream_id());
|
||||
downstream->ensure_upstream_wtimer();
|
||||
|
||||
@@ -1943,8 +1965,29 @@ int http_recv_request_header(nghttp3_conn *conn, int64_t stream_id,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (upstream->http_recv_request_header(downstream, token, name, value,
|
||||
flags) != 0) {
|
||||
if (upstream->http_recv_request_header(downstream, token, name, value, flags,
|
||||
/* trailer = */ false) != 0) {
|
||||
return NGHTTP3_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
int http_recv_request_trailer(nghttp3_conn *conn, int64_t stream_id,
|
||||
int32_t token, nghttp3_rcbuf *name,
|
||||
nghttp3_rcbuf *value, uint8_t flags,
|
||||
void *user_data, void *stream_user_data) {
|
||||
auto upstream = static_cast<Http3Upstream *>(user_data);
|
||||
auto downstream = static_cast<Downstream *>(stream_user_data);
|
||||
|
||||
if (!downstream || downstream->get_stop_reading()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (upstream->http_recv_request_header(downstream, token, name, value, flags,
|
||||
/* trailer = */ true) != 0) {
|
||||
return NGHTTP3_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
|
||||
@@ -1955,8 +1998,8 @@ int http_recv_request_header(nghttp3_conn *conn, int64_t stream_id,
|
||||
int Http3Upstream::http_recv_request_header(Downstream *downstream,
|
||||
int32_t h3token,
|
||||
nghttp3_rcbuf *name,
|
||||
nghttp3_rcbuf *value,
|
||||
uint8_t flags) {
|
||||
nghttp3_rcbuf *value, uint8_t flags,
|
||||
bool trailer) {
|
||||
auto namebuf = nghttp3_rcbuf_get_buf(name);
|
||||
auto valuebuf = nghttp3_rcbuf_get_buf(value);
|
||||
auto &req = downstream->request();
|
||||
@@ -1978,8 +2021,13 @@ int Http3Upstream::http_recv_request_header(Downstream *downstream,
|
||||
<< ", num=" << req.fs.num_fields() + 1;
|
||||
}
|
||||
|
||||
// just ignore if this is a trailer part.
|
||||
if (trailer) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (error_reply(downstream, 431) != 0) {
|
||||
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1991,6 +2039,13 @@ int Http3Upstream::http_recv_request_header(Downstream *downstream,
|
||||
downstream->add_rcbuf(name);
|
||||
downstream->add_rcbuf(value);
|
||||
|
||||
if (trailer) {
|
||||
req.fs.add_trailer_token(StringRef{namebuf.base, namebuf.len},
|
||||
StringRef{valuebuf.base, valuebuf.len}, no_index,
|
||||
token);
|
||||
return 0;
|
||||
}
|
||||
|
||||
req.fs.add_header_token(StringRef{namebuf.base, namebuf.len},
|
||||
StringRef{valuebuf.base, valuebuf.len}, no_index,
|
||||
token);
|
||||
@@ -1998,7 +2053,7 @@ int Http3Upstream::http_recv_request_header(Downstream *downstream,
|
||||
}
|
||||
|
||||
namespace {
|
||||
int http_end_request_headers(nghttp3_conn *conn, int64_t stream_id,
|
||||
int http_end_request_headers(nghttp3_conn *conn, int64_t stream_id, int fin,
|
||||
void *user_data, void *stream_user_data) {
|
||||
auto upstream = static_cast<Http3Upstream *>(user_data);
|
||||
auto handler = upstream->get_client_handler();
|
||||
@@ -2008,7 +2063,7 @@ int http_end_request_headers(nghttp3_conn *conn, int64_t stream_id,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (upstream->http_end_request_headers(downstream) != 0) {
|
||||
if (upstream->http_end_request_headers(downstream, fin) != 0) {
|
||||
return NGHTTP3_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
|
||||
@@ -2019,7 +2074,7 @@ int http_end_request_headers(nghttp3_conn *conn, int64_t stream_id,
|
||||
}
|
||||
} // namespace
|
||||
|
||||
int Http3Upstream::http_end_request_headers(Downstream *downstream) {
|
||||
int Http3Upstream::http_end_request_headers(Downstream *downstream, int fin) {
|
||||
auto lgconf = log_config();
|
||||
lgconf->update_tstamp(std::chrono::system_clock::now());
|
||||
auto &req = downstream->request();
|
||||
@@ -2060,7 +2115,7 @@ int Http3Upstream::http_end_request_headers(Downstream *downstream) {
|
||||
auto method_token = http2::lookup_method_token(method->value);
|
||||
if (method_token == -1) {
|
||||
if (error_reply(downstream, 501) != 0) {
|
||||
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -2108,15 +2163,18 @@ int Http3Upstream::http_end_request_headers(Downstream *downstream) {
|
||||
if (connect_proto) {
|
||||
if (connect_proto->value != "websocket") {
|
||||
if (error_reply(downstream, 400) != 0) {
|
||||
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
req.connect_proto = ConnectProto::WEBSOCKET;
|
||||
}
|
||||
|
||||
// We are not sure that request has body or not at the moment.
|
||||
req.http2_expect_body = true;
|
||||
if (!fin) {
|
||||
req.http2_expect_body = true;
|
||||
} else if (req.fs.content_length == -1) {
|
||||
req.fs.content_length = 0;
|
||||
}
|
||||
|
||||
downstream->inspect_http2_request();
|
||||
|
||||
@@ -2130,7 +2188,7 @@ int Http3Upstream::http_end_request_headers(Downstream *downstream) {
|
||||
|
||||
if (mruby_ctx->run_on_request_proc(downstream) != 0) {
|
||||
if (error_reply(downstream, 500) != 0) {
|
||||
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -2426,7 +2484,7 @@ int Http3Upstream::setup_httpconn() {
|
||||
shrpx::http_recv_request_header,
|
||||
shrpx::http_end_request_headers,
|
||||
nullptr, // begin_trailers
|
||||
nullptr, // recv_trailer
|
||||
shrpx::http_recv_request_trailer,
|
||||
nullptr, // end_trailers
|
||||
shrpx::http_stop_sending,
|
||||
shrpx::http_end_stream,
|
||||
|
||||
@@ -124,8 +124,8 @@ public:
|
||||
void http_begin_request_headers(int64_t stream_id);
|
||||
int http_recv_request_header(Downstream *downstream, int32_t token,
|
||||
nghttp3_rcbuf *name, nghttp3_rcbuf *value,
|
||||
uint8_t flags);
|
||||
int http_end_request_headers(Downstream *downstream);
|
||||
uint8_t flags, bool trailer);
|
||||
int http_end_request_headers(Downstream *downstream, int fin);
|
||||
int http_end_stream(Downstream *downstream);
|
||||
void start_downstream(Downstream *downstream);
|
||||
void initiate_downstream(Downstream *downstream);
|
||||
|
||||
Reference in New Issue
Block a user