void ngx_quic_shutdown_connection(ngx_connection_t *c, ngx_uint_t err,
const char *reason);
ngx_int_t ngx_quic_reset_stream(ngx_connection_t *c, ngx_uint_t err);
+ngx_int_t ngx_quic_shutdown_stream(ngx_connection_t *c, int how);
uint32_t ngx_quic_version(ngx_connection_t *c);
ngx_int_t ngx_quic_handle_read_event(ngx_event_t *rev, ngx_uint_t flags);
ngx_int_t ngx_quic_handle_write_event(ngx_event_t *wev, size_t lowat);
}
+ngx_int_t
+ngx_quic_shutdown_stream(ngx_connection_t *c, int how)
+{
+ ngx_event_t *wev;
+ ngx_connection_t *pc;
+ ngx_quic_frame_t *frame;
+ ngx_quic_stream_t *qs;
+ ngx_quic_connection_t *qc;
+
+ if (how != NGX_WRITE_SHUTDOWN) {
+ return NGX_OK;
+ }
+
+ wev = c->write;
+
+ if (wev->error) {
+ return NGX_OK;
+ }
+
+ qs = c->quic;
+ pc = qs->parent;
+ qc = ngx_quic_get_connection(pc);
+
+ frame = ngx_quic_alloc_frame(pc);
+ if (frame == NULL) {
+ return NGX_ERROR;
+ }
+
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "quic stream id:0x%xL shutdown", qs->id);
+
+ frame->level = ssl_encryption_application;
+ frame->type = NGX_QUIC_FT_STREAM;
+ frame->u.stream.off = 1;
+ frame->u.stream.len = 1;
+ frame->u.stream.fin = 1;
+
+ frame->u.stream.stream_id = qs->id;
+ frame->u.stream.offset = c->sent;
+ frame->u.stream.length = 0;
+
+ ngx_quic_queue_frame(qc, frame);
+
+ wev->ready = 1;
+ wev->error = 1;
+
+ return NGX_OK;
+}
+
+
static ngx_quic_stream_t *
ngx_quic_create_client_stream(ngx_connection_t *c, uint64_t id)
{
if (dst->type == SOCK_STREAM && pscf->half_close
&& src->read->eof && !u->half_closed && !dst->buffered)
{
+
+#if (NGX_STREAM_QUIC)
+ if (dst->quic) {
+
+ if (ngx_quic_shutdown_stream(dst, NGX_WRITE_SHUTDOWN)
+ != NGX_OK)
+ {
+ ngx_stream_proxy_finalize(s,
+ NGX_STREAM_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
+ } else
+#endif
+
if (ngx_shutdown_socket(dst->fd, NGX_WRITE_SHUTDOWN) == -1) {
ngx_connection_error(c, ngx_socket_errno,
ngx_shutdown_socket_n " failed");