aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRoman Arutyunyan <arut@nginx.com>2021-05-05 15:00:17 +0300
committerRoman Arutyunyan <arut@nginx.com>2021-05-05 15:00:17 +0300
commit32f98ecbb13acc9c22db4dd7e9bec20eb30b945a (patch)
tree50927ef303aa1746840b2f511ded98280ad8df8b /src
parent891fedf52d2c4a85e724e9abbb403334ec55c861 (diff)
downloadnginx-32f98ecbb13acc9c22db4dd7e9bec20eb30b945a.tar.gz
nginx-32f98ecbb13acc9c22db4dd7e9bec20eb30b945a.zip
HTTP/3: moved parsing uni stream type to ngx_http_v3_parse.c.
Previously it was parsed in ngx_http_v3_streams.c, while the streams were parsed in ngx_http_v3_parse.c. Now all parsing is done in one file. This simplifies parsing API and cleans up ngx_http_v3_streams.c.
Diffstat (limited to 'src')
-rw-r--r--src/http/v3/ngx_http_v3.h1
-rw-r--r--src/http/v3/ngx_http_v3_parse.c123
-rw-r--r--src/http/v3/ngx_http_v3_parse.h17
-rw-r--r--src/http/v3/ngx_http_v3_streams.c143
4 files changed, 159 insertions, 125 deletions
diff --git a/src/http/v3/ngx_http_v3.h b/src/http/v3/ngx_http_v3.h
index 32d1fd509..736d448b5 100644
--- a/src/http/v3/ngx_http_v3.h
+++ b/src/http/v3/ngx_http_v3.h
@@ -169,6 +169,7 @@ uintptr_t ngx_http_v3_encode_header_lpbi(u_char *p, ngx_uint_t index,
ngx_int_t ngx_http_v3_init_session(ngx_connection_t *c);
void ngx_http_v3_init_uni_stream(ngx_connection_t *c);
+ngx_int_t ngx_http_v3_register_uni_stream(ngx_connection_t *c, uint64_t type);
ngx_connection_t *ngx_http_v3_create_push_stream(ngx_connection_t *c,
uint64_t push_id);
ngx_int_t ngx_http_v3_send_goaway(ngx_connection_t *c, uint64_t id);
diff --git a/src/http/v3/ngx_http_v3_parse.c b/src/http/v3/ngx_http_v3_parse.c
index def9aadc7..fcb39b209 100644
--- a/src/http/v3/ngx_http_v3_parse.c
+++ b/src/http/v3/ngx_http_v3_parse.c
@@ -14,9 +14,6 @@
((type) == 0x02 || (type) == 0x06 || (type) == 0x08 || (type) == 0x09)
-static ngx_int_t ngx_http_v3_parse_settings(ngx_connection_t *c,
- ngx_http_v3_parse_settings_t *st, u_char ch);
-
static ngx_int_t ngx_http_v3_parse_varlen_int(ngx_connection_t *c,
ngx_http_v3_parse_varlen_int_t *st, u_char ch);
static ngx_int_t ngx_http_v3_parse_prefix_int(ngx_connection_t *c,
@@ -39,11 +36,21 @@ static ngx_int_t ngx_http_v3_parse_header_pbi(ngx_connection_t *c,
static ngx_int_t ngx_http_v3_parse_header_lpbi(ngx_connection_t *c,
ngx_http_v3_parse_header_t *st, u_char ch);
+static ngx_int_t ngx_http_v3_parse_control(ngx_connection_t *c,
+ ngx_http_v3_parse_control_t *st, u_char ch);
+static ngx_int_t ngx_http_v3_parse_settings(ngx_connection_t *c,
+ ngx_http_v3_parse_settings_t *st, u_char ch);
+
+static ngx_int_t ngx_http_v3_parse_encoder(ngx_connection_t *c,
+ ngx_http_v3_parse_encoder_t *st, u_char ch);
static ngx_int_t ngx_http_v3_parse_header_inr(ngx_connection_t *c,
ngx_http_v3_parse_header_t *st, u_char ch);
static ngx_int_t ngx_http_v3_parse_header_iwnr(ngx_connection_t *c,
ngx_http_v3_parse_header_t *st, u_char ch);
+static ngx_int_t ngx_http_v3_parse_decoder(ngx_connection_t *c,
+ ngx_http_v3_parse_decoder_t *st, u_char ch);
+
static ngx_int_t ngx_http_v3_parse_lookup(ngx_connection_t *c,
ngx_uint_t dynamic, ngx_uint_t index, ngx_str_t *name, ngx_str_t *value);
@@ -986,11 +993,10 @@ ngx_http_v3_parse_lookup(ngx_connection_t *c, ngx_uint_t dynamic,
}
-ngx_int_t
-ngx_http_v3_parse_control(ngx_connection_t *c, void *data, u_char ch)
+static ngx_int_t
+ngx_http_v3_parse_control(ngx_connection_t *c, ngx_http_v3_parse_control_t *st,
+ u_char ch)
{
- ngx_http_v3_parse_control_t *st = data;
-
ngx_int_t rc;
enum {
sw_start = 0,
@@ -1208,11 +1214,10 @@ done:
}
-ngx_int_t
-ngx_http_v3_parse_encoder(ngx_connection_t *c, void *data, u_char ch)
+static ngx_int_t
+ngx_http_v3_parse_encoder(ngx_connection_t *c, ngx_http_v3_parse_encoder_t *st,
+ u_char ch)
{
- ngx_http_v3_parse_encoder_t *st = data;
-
ngx_int_t rc;
enum {
sw_start = 0,
@@ -1500,11 +1505,10 @@ done:
}
-ngx_int_t
-ngx_http_v3_parse_decoder(ngx_connection_t *c, void *data, u_char ch)
+static ngx_int_t
+ngx_http_v3_parse_decoder(ngx_connection_t *c, ngx_http_v3_parse_decoder_t *st,
+ u_char ch)
{
- ngx_http_v3_parse_decoder_t *st = data;
-
ngx_int_t rc;
enum {
sw_start = 0,
@@ -1674,3 +1678,92 @@ done:
st->state = sw_start;
return NGX_DONE;
}
+
+
+ngx_int_t
+ngx_http_v3_parse_uni(ngx_connection_t *c, ngx_http_v3_parse_uni_t *st,
+ u_char ch)
+{
+ ngx_int_t rc;
+ enum {
+ sw_start = 0,
+ sw_type,
+ sw_control,
+ sw_encoder,
+ sw_decoder,
+ sw_unknown
+ };
+
+ switch (st->state) {
+ case sw_start:
+
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse uni");
+
+ st->state = sw_type;
+
+ /* fall through */
+
+ case sw_type:
+
+ rc = ngx_http_v3_parse_varlen_int(c, &st->vlint, ch);
+ if (rc != NGX_DONE) {
+ return rc;
+ }
+
+ rc = ngx_http_v3_register_uni_stream(c, st->vlint.value);
+ if (rc != NGX_OK) {
+ return rc;
+ }
+
+ switch (st->vlint.value) {
+ case NGX_HTTP_V3_STREAM_CONTROL:
+ st->state = sw_control;
+ break;
+
+ case NGX_HTTP_V3_STREAM_ENCODER:
+ st->state = sw_encoder;
+ break;
+
+ case NGX_HTTP_V3_STREAM_DECODER:
+ st->state = sw_decoder;
+ break;
+
+ default:
+ st->state = sw_unknown;
+ }
+
+ break;
+
+ case sw_control:
+
+ rc = ngx_http_v3_parse_control(c, &st->u.control, ch);
+ if (rc != NGX_OK) {
+ return rc;
+ }
+
+ break;
+
+ case sw_encoder:
+
+ rc = ngx_http_v3_parse_encoder(c, &st->u.encoder, ch);
+ if (rc != NGX_OK) {
+ return rc;
+ }
+
+ break;
+
+ case sw_decoder:
+
+ rc = ngx_http_v3_parse_decoder(c, &st->u.decoder, ch);
+ if (rc != NGX_OK) {
+ return rc;
+ }
+
+ break;
+
+ case sw_unknown:
+ break;
+ }
+
+ return NGX_AGAIN;
+}
diff --git a/src/http/v3/ngx_http_v3_parse.h b/src/http/v3/ngx_http_v3_parse.h
index f039ac28d..c187b7bc2 100644
--- a/src/http/v3/ngx_http_v3_parse.h
+++ b/src/http/v3/ngx_http_v3_parse.h
@@ -108,6 +108,17 @@ typedef struct {
typedef struct {
ngx_uint_t state;
+ ngx_http_v3_parse_varlen_int_t vlint;
+ union {
+ ngx_http_v3_parse_encoder_t encoder;
+ ngx_http_v3_parse_decoder_t decoder;
+ ngx_http_v3_parse_control_t control;
+ } u;
+} ngx_http_v3_parse_uni_t;
+
+
+typedef struct {
+ ngx_uint_t state;
ngx_uint_t type;
ngx_uint_t length;
ngx_http_v3_parse_varlen_int_t vlint;
@@ -128,10 +139,8 @@ ngx_int_t ngx_http_v3_parse_headers(ngx_connection_t *c,
ngx_http_v3_parse_headers_t *st, u_char ch);
ngx_int_t ngx_http_v3_parse_data(ngx_connection_t *c,
ngx_http_v3_parse_data_t *st, u_char ch);
-
-ngx_int_t ngx_http_v3_parse_control(ngx_connection_t *c, void *data, u_char ch);
-ngx_int_t ngx_http_v3_parse_encoder(ngx_connection_t *c, void *data, u_char ch);
-ngx_int_t ngx_http_v3_parse_decoder(ngx_connection_t *c, void *data, u_char ch);
+ngx_int_t ngx_http_v3_parse_uni(ngx_connection_t *c,
+ ngx_http_v3_parse_uni_t *st, u_char ch);
#endif /* _NGX_HTTP_V3_PARSE_H_INCLUDED_ */
diff --git a/src/http/v3/ngx_http_v3_streams.c b/src/http/v3/ngx_http_v3_streams.c
index a20008c19..292e6653b 100644
--- a/src/http/v3/ngx_http_v3_streams.c
+++ b/src/http/v3/ngx_http_v3_streams.c
@@ -10,13 +10,8 @@
#include <ngx_http.h>
-typedef ngx_int_t (*ngx_http_v3_handler_pt)(ngx_connection_t *c, void *data,
- u_char ch);
-
-
typedef struct {
- ngx_http_v3_handler_pt handler;
- void *data;
+ ngx_http_v3_parse_uni_t parse;
ngx_int_t index;
} ngx_http_v3_uni_stream_t;
@@ -32,7 +27,6 @@ typedef struct {
static void ngx_http_v3_keepalive_handler(ngx_event_t *ev);
static void ngx_http_v3_cleanup_session(void *data);
static void ngx_http_v3_close_uni_stream(ngx_connection_t *c);
-static void ngx_http_v3_read_uni_stream_type(ngx_event_t *rev);
static void ngx_http_v3_uni_read_handler(ngx_event_t *rev);
static void ngx_http_v3_dummy_write_handler(ngx_event_t *wev);
static void ngx_http_v3_push_cleanup(void *data);
@@ -131,10 +125,10 @@ ngx_http_v3_init_uni_stream(ngx_connection_t *c)
c->data = us;
- c->read->handler = ngx_http_v3_read_uni_stream_type;
+ c->read->handler = ngx_http_v3_uni_read_handler;
c->write->handler = ngx_http_v3_dummy_write_handler;
- ngx_http_v3_read_uni_stream_type(c->read);
+ ngx_http_v3_uni_read_handler(c->read);
}
@@ -164,118 +158,59 @@ ngx_http_v3_close_uni_stream(ngx_connection_t *c)
}
-static void
-ngx_http_v3_read_uni_stream_type(ngx_event_t *rev)
+ngx_int_t
+ngx_http_v3_register_uni_stream(ngx_connection_t *c, uint64_t type)
{
- u_char ch;
- ssize_t n;
- ngx_int_t index, rc;
- ngx_connection_t *c;
+ ngx_int_t index;
ngx_http_v3_session_t *h3c;
ngx_http_v3_uni_stream_t *us;
- c = rev->data;
- us = c->data;
- h3c = ngx_http_v3_get_session(c);
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 read stream type");
-
- while (rev->ready) {
-
- n = c->recv(c, &ch, 1);
-
- if (n == NGX_AGAIN) {
- break;
- }
-
- if (n == 0) {
- rc = NGX_HTTP_V3_ERR_GENERAL_PROTOCOL_ERROR;
- goto failed;
- }
-
- if (n != 1) {
- rc = NGX_HTTP_V3_ERR_INTERNAL_ERROR;
- goto failed;
- }
-
- switch (ch) {
-
- case NGX_HTTP_V3_STREAM_ENCODER:
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http3 encoder stream");
-
- index = NGX_HTTP_V3_STREAM_CLIENT_ENCODER;
- us->handler = ngx_http_v3_parse_encoder;
- n = sizeof(ngx_http_v3_parse_encoder_t);
-
- break;
-
- case NGX_HTTP_V3_STREAM_DECODER:
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http3 decoder stream");
+ switch (type) {
- index = NGX_HTTP_V3_STREAM_CLIENT_DECODER;
- us->handler = ngx_http_v3_parse_decoder;
- n = sizeof(ngx_http_v3_parse_decoder_t);
+ case NGX_HTTP_V3_STREAM_ENCODER:
- break;
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
+ "http3 encoder stream");
+ index = NGX_HTTP_V3_STREAM_CLIENT_ENCODER;
+ break;
- case NGX_HTTP_V3_STREAM_CONTROL:
+ case NGX_HTTP_V3_STREAM_DECODER:
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http3 control stream");
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
+ "http3 decoder stream");
+ index = NGX_HTTP_V3_STREAM_CLIENT_DECODER;
+ break;
- index = NGX_HTTP_V3_STREAM_CLIENT_CONTROL;
- us->handler = ngx_http_v3_parse_control;
- n = sizeof(ngx_http_v3_parse_control_t);
+ case NGX_HTTP_V3_STREAM_CONTROL:
- break;
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
+ "http3 control stream");
+ index = NGX_HTTP_V3_STREAM_CLIENT_CONTROL;
- default:
+ break;
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http3 stream 0x%02xi", (ngx_int_t) ch);
- index = -1;
- n = 0;
- }
+ default:
- if (index >= 0) {
- if (h3c->known_streams[index]) {
- ngx_log_error(NGX_LOG_INFO, c->log, 0, "stream exists");
- rc = NGX_HTTP_V3_ERR_STREAM_CREATION_ERROR;
- goto failed;
- }
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
+ "http3 stream 0x%02xL", type);
+ index = -1;
+ }
- us->index = index;
- h3c->known_streams[index] = c;
- }
+ if (index >= 0) {
+ h3c = ngx_http_v3_get_session(c);
- if (n) {
- us->data = ngx_pcalloc(c->pool, n);
- if (us->data == NULL) {
- rc = NGX_HTTP_V3_ERR_INTERNAL_ERROR;
- goto failed;
- }
+ if (h3c->known_streams[index]) {
+ ngx_log_error(NGX_LOG_INFO, c->log, 0, "stream exists");
+ return NGX_HTTP_V3_ERR_STREAM_CREATION_ERROR;
}
- rev->handler = ngx_http_v3_uni_read_handler;
- ngx_http_v3_uni_read_handler(rev);
- return;
- }
+ h3c->known_streams[index] = c;
- if (ngx_handle_read_event(rev, 0) != NGX_OK) {
- rc = NGX_HTTP_V3_ERR_INTERNAL_ERROR;
- goto failed;
+ us = c->data;
+ us->index = index;
}
- return;
-
-failed:
-
- ngx_http_v3_finalize_connection(c, rc, "could not read stream type");
- ngx_http_v3_close_uni_stream(c);
+ return NGX_OK;
}
@@ -317,13 +252,9 @@ ngx_http_v3_uni_read_handler(ngx_event_t *rev)
break;
}
- if (us->handler == NULL) {
- continue;
- }
-
for (i = 0; i < n; i++) {
- rc = us->handler(c, us->data, buf[i]);
+ rc = ngx_http_v3_parse_uni(c, &us->parse, buf[i]);
if (rc == NGX_DONE) {
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,