]> git.kaiwu.me - nginx.git/commitdiff
HTTP/3: client GOAWAY support.
authorRoman Arutyunyan <arut@nginx.com>
Fri, 11 Jun 2021 10:24:24 +0000 (13:24 +0300)
committerRoman Arutyunyan <arut@nginx.com>
Fri, 11 Jun 2021 10:24:24 +0000 (13:24 +0300)
src/http/v3/ngx_http_v3.c
src/http/v3/ngx_http_v3.h
src/http/v3/ngx_http_v3_filter_module.c
src/http/v3/ngx_http_v3_parse.c
src/http/v3/ngx_http_v3_streams.c
src/http/v3/ngx_http_v3_streams.h

index a1638c504a701449604c59122b3470647e4129d1..2c838f4b525d7982f24c5d5e016dce2857023932 100644 (file)
@@ -37,6 +37,7 @@ ngx_http_v3_init_session(ngx_connection_t *c)
     }
 
     h3c->max_push_id = (uint64_t) -1;
+    h3c->goaway_push_id = (uint64_t) -1;
 
     ngx_queue_init(&h3c->blocked);
     ngx_queue_init(&h3c->pushing);
index 4c25a806ac95e8decbe6362637a15fb6d2f35f65..e693af7d80141579ea29ab10b2e326bd69a7711f 100644 (file)
@@ -129,6 +129,7 @@ struct ngx_http_v3_session_s {
     ngx_uint_t                    npushing;
     uint64_t                      next_push_id;
     uint64_t                      max_push_id;
+    uint64_t                      goaway_push_id;
 
     ngx_uint_t                    goaway;  /* unsigned  goaway:1; */
 
index 93f3318cb7deb3b9c1d9038b0ee34e9a7a2b4277..db40e3737b1eae0087a6f0373cb0ff8c593c77de 100644 (file)
@@ -805,6 +805,12 @@ ngx_http_v3_push_resource(ngx_http_request_t *r, ngx_str_t *path,
         return NGX_ABORT;
     }
 
+    if (h3c->goaway_push_id != (uint64_t) -1) {
+        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                       "http3 abort pushes due to goaway");
+        return NGX_ABORT;
+    }
+
     if (h3c->npushing >= h3scf->max_concurrent_pushes) {
         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
                        "http3 abort pushes due to max_concurrent_pushes");
index 7bd9e6327c7d2ad85e2d6b05238a0b49023716b2..5951dff1055d451f027b9d2e315488ec01b0ab3b 100644 (file)
@@ -1012,6 +1012,7 @@ ngx_http_v3_parse_control(ngx_connection_t *c, ngx_http_v3_parse_control_t *st,
         sw_cancel_push,
         sw_settings,
         sw_max_push_id,
+        sw_goaway,
         sw_skip
     };
 
@@ -1091,6 +1092,10 @@ ngx_http_v3_parse_control(ngx_connection_t *c, ngx_http_v3_parse_control_t *st,
             st->state = sw_max_push_id;
             break;
 
+        case NGX_HTTP_V3_FRAME_GOAWAY:
+            st->state = sw_goaway;
+            break;
+
         default:
             ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
                            "http3 parse skip unknown frame");
@@ -1157,6 +1162,26 @@ ngx_http_v3_parse_control(ngx_connection_t *c, ngx_http_v3_parse_control_t *st,
         st->state = sw_type;
         break;
 
+    case sw_goaway:
+
+        rc = ngx_http_v3_parse_varlen_int(c, &st->vlint, ch);
+
+        if (--st->length == 0 && rc == NGX_AGAIN) {
+            return NGX_HTTP_V3_ERR_FRAME_ERROR;
+        }
+
+        if (rc != NGX_DONE) {
+            return rc;
+        }
+
+        rc = ngx_http_v3_goaway(c, st->vlint.value);
+        if (rc != NGX_OK) {
+            return rc;
+        }
+
+        st->state = sw_type;
+        break;
+
     case sw_skip:
 
         if (--st->length == 0) {
index 0e55dbe0d39b3984b39a9a9eff1970326f0aa026..8b2047f4381cc9d200e580ceaf01582cfb75026a 100644 (file)
@@ -703,6 +703,21 @@ ngx_http_v3_set_max_push_id(ngx_connection_t *c, uint64_t max_push_id)
 }
 
 
+ngx_int_t
+ngx_http_v3_goaway(ngx_connection_t *c, uint64_t push_id)
+{
+    ngx_http_v3_session_t  *h3c;
+
+    h3c = ngx_http_v3_get_session(c);
+
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 GOAWAY:%uL", push_id);
+
+    h3c->goaway_push_id = push_id;
+
+    return NGX_OK;
+}
+
+
 ngx_int_t
 ngx_http_v3_cancel_push(ngx_connection_t *c, uint64_t push_id)
 {
index 75325f5d4b1d91b0c6c9a01e2049977b61c10708..a2126a7f8347800f4bc7e39ec1b77f19d8fd28c6 100644 (file)
@@ -21,6 +21,7 @@ ngx_connection_t *ngx_http_v3_create_push_stream(ngx_connection_t *c,
     uint64_t push_id);
 ngx_int_t ngx_http_v3_set_max_push_id(ngx_connection_t *c,
     uint64_t max_push_id);
+ngx_int_t ngx_http_v3_goaway(ngx_connection_t *c, uint64_t push_id);
 ngx_int_t ngx_http_v3_cancel_push(ngx_connection_t *c, uint64_t push_id);
 ngx_int_t ngx_http_v3_cancel_stream(ngx_connection_t *c, ngx_uint_t stream_id);