comparison src/http/v3/ngx_http_v3_request.c @ 8902:925572184d4a quic

HTTP/3: adjusted QUIC connection finalization. When an HTTP/3 function returns an error in context of a QUIC stream, it's this function's responsibility now to finalize the entire QUIC connection with the right code, if required. Previously, QUIC connection finalization could be done both outside and inside such functions. The new rule follows a similar rule for logging, leads to cleaner code, and allows to provide more details about the error. While here, a few error cases are no longer treated as fatal and QUIC connection is no longer finalized in these cases. A few other cases now lead to stream reset instead of connection finalization.
author Roman Arutyunyan <arut@nginx.com>
date Mon, 18 Oct 2021 15:22:33 +0300
parents 72b304f6207c
children 0d3bf08eaac0
comparison
equal deleted inserted replaced
8901:a951e0809044 8902:925572184d4a
63 ngx_http_v3_session_t *h3c; 63 ngx_http_v3_session_t *h3c;
64 ngx_http_core_loc_conf_t *clcf; 64 ngx_http_core_loc_conf_t *clcf;
65 ngx_http_core_srv_conf_t *cscf; 65 ngx_http_core_srv_conf_t *cscf;
66 66
67 if (ngx_http_v3_init_session(c) != NGX_OK) { 67 if (ngx_http_v3_init_session(c) != NGX_OK) {
68 ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_INTERNAL_ERROR,
69 "internal error");
70 ngx_http_close_connection(c); 68 ngx_http_close_connection(c);
71 return; 69 return;
72 } 70 }
73 71
74 if (c->quic->id & NGX_QUIC_STREAM_UNIDIRECTIONAL) { 72 if (c->quic->id & NGX_QUIC_STREAM_UNIDIRECTIONAL) {
108 > clcf->keepalive_time) 106 > clcf->keepalive_time)
109 { 107 {
110 h3c->goaway = 1; 108 h3c->goaway = 1;
111 109
112 if (ngx_http_v3_send_goaway(c, (n + 1) << 2) != NGX_OK) { 110 if (ngx_http_v3_send_goaway(c, (n + 1) << 2) != NGX_OK) {
113 ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_INTERNAL_ERROR,
114 "goaway error");
115 ngx_http_close_connection(c); 111 ngx_http_close_connection(c);
116 return; 112 return;
117 } 113 }
118 114
119 ngx_http_v3_shutdown_connection(c, NGX_HTTP_V3_ERR_NO_ERROR, 115 ngx_http_v3_shutdown_connection(c, NGX_HTTP_V3_ERR_NO_ERROR,
285 p = b->pos; 281 p = b->pos;
286 282
287 rc = ngx_http_v3_parse_headers(c, st, b); 283 rc = ngx_http_v3_parse_headers(c, st, b);
288 284
289 if (rc > 0) { 285 if (rc > 0) {
290 ngx_http_v3_finalize_connection(c, rc, 286 ngx_quic_reset_stream(c, rc);
291 "could not parse request headers"); 287 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
288 "client sent invalid header");
292 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); 289 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
293 break; 290 break;
294 } 291 }
295 292
296 if (rc == NGX_ERROR) { 293 if (rc == NGX_ERROR) {
297 ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_INTERNAL_ERROR,
298 "internal error");
299 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); 294 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
300 break; 295 break;
301 } 296 }
302 297
303 r->request_length += b->pos - p; 298 r->request_length += b->pos - p;
1165 last = 1; 1160 last = 1;
1166 goto done; 1161 goto done;
1167 } 1162 }
1168 1163
1169 if (rc > 0) { 1164 if (rc > 0) {
1170 ngx_http_v3_finalize_connection(r->connection, rc, 1165 ngx_quic_reset_stream(r->connection, rc);
1171 "client sent invalid body");
1172 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, 1166 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1173 "client sent invalid body"); 1167 "client sent invalid body");
1174 return NGX_HTTP_BAD_REQUEST; 1168 return NGX_HTTP_BAD_REQUEST;
1175 } 1169 }
1176 1170
1177 if (rc == NGX_ERROR) { 1171 if (rc == NGX_ERROR) {
1178 ngx_http_v3_finalize_connection(r->connection,
1179 NGX_HTTP_V3_ERR_INTERNAL_ERROR,
1180 "internal error");
1181 return NGX_HTTP_INTERNAL_SERVER_ERROR; 1172 return NGX_HTTP_INTERNAL_SERVER_ERROR;
1182 } 1173 }
1183 1174
1184 /* rc == NGX_OK */ 1175 /* rc == NGX_OK */
1185 } 1176 }