diff src/http/v3/ngx_http_v3_streams.c @ 8226:268f4389130d quic

Refactored HTTP/3 parser.
author Roman Arutyunyan <arut@nginx.com>
date Wed, 18 Mar 2020 13:46:35 +0300
parents 38c0898b6df7
children ac41c53e446d
line wrap: on
line diff
--- a/src/http/v3/ngx_http_v3_streams.c
+++ b/src/http/v3/ngx_http_v3_streams.c
@@ -10,42 +10,30 @@
 #include <ngx_http.h>
 
 
-#define NGX_HTTP_V3_CONTROL_STREAM  0x00
-#define NGX_HTTP_V3_PUSH_STREAM     0x01
-#define NGX_HTTP_V3_ENCODER_STREAM  0x02
-#define NGX_HTTP_V3_DECODER_STREAM  0x03
+typedef ngx_int_t (*ngx_http_v3_handler_pt)(ngx_connection_t *c, void *data,
+    u_char ch);
 
 
 typedef struct {
-    uint32_t    signature; /* QSTR */
-    u_char      buf[4];
+    uint32_t                        signature; /* QSTR */
 
-    ngx_uint_t  len;
-    ngx_uint_t  type;
-    ngx_uint_t  state;
-    ngx_uint_t  index;
-    ngx_uint_t  offset;
+    ngx_http_v3_handler_pt          handler;
+    void                           *data;
 
-    ngx_str_t   name;
-    ngx_str_t   value;
-
-    unsigned    client:1;
-    unsigned    dynamic:1;
-    unsigned    huffman:1;
+    ngx_uint_t                      type;
+    ngx_uint_t                      client;  /* unsigned  client:1; */
 } ngx_http_v3_uni_stream_t;
 
 
 static void ngx_http_v3_close_uni_stream(ngx_connection_t *c);
 static void ngx_http_v3_uni_stream_cleanup(void *data);
 static void ngx_http_v3_read_uni_stream_type(ngx_event_t *rev);
-static void ngx_http_v3_dummy_stream_handler(ngx_event_t *rev);
-static void ngx_http_v3_client_encoder_handler(ngx_event_t *rev);
-static void ngx_http_v3_client_decoder_handler(ngx_event_t *rev);
-
+static void ngx_http_v3_uni_read_handler(ngx_event_t *rev);
 static ngx_connection_t *ngx_http_v3_create_uni_stream(ngx_connection_t *c,
     ngx_uint_t type);
-static ngx_connection_t *ngx_http_v3_get_server_encoder(ngx_connection_t *c);
-static ngx_connection_t *ngx_http_v3_get_server_decoder(ngx_connection_t *c);
+static ngx_connection_t *ngx_http_v3_get_control(ngx_connection_t *c);
+static ngx_connection_t *ngx_http_v3_get_encoder(ngx_connection_t *c);
+static ngx_connection_t *ngx_http_v3_get_decoder(ngx_connection_t *c);
 
 
 void
@@ -56,8 +44,13 @@ ngx_http_v3_handle_client_uni_stream(ngx
 
     c->log->connection = c->number;
 
+    /* XXX */
+    (void) ngx_http_v3_get_control(c);
+    (void) ngx_http_v3_get_encoder(c);
+    (void) ngx_http_v3_get_decoder(c);
+
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
-                   "http3 new uni stream id:0x%uXL", c->qs->id);
+                   "http3 new uni stream id:0x%uxL", c->qs->id);
 
     us = ngx_pcalloc(c->pool, sizeof(ngx_http_v3_uni_stream_t));
     if (us == NULL) {
@@ -81,7 +74,7 @@ ngx_http_v3_handle_client_uni_stream(ngx
     cln->data = c;
 
     c->read->handler = ngx_http_v3_read_uni_stream_type;
-    c->read->handler(c->read);
+    ngx_http_v3_read_uni_stream_type(c->read);
 }
 
 
@@ -115,7 +108,7 @@ ngx_http_v3_uni_stream_cleanup(void *dat
 
     switch (us->type) {
 
-    case NGX_HTTP_V3_ENCODER_STREAM:
+    case NGX_HTTP_V3_STREAM_ENCODER:
 
         if (us->client) {
             h3c->client_encoder = NULL;
@@ -125,7 +118,7 @@ ngx_http_v3_uni_stream_cleanup(void *dat
 
         break;
 
-    case NGX_HTTP_V3_DECODER_STREAM:
+    case NGX_HTTP_V3_STREAM_DECODER:
 
         if (us->client) {
             h3c->client_decoder = NULL;
@@ -134,6 +127,16 @@ ngx_http_v3_uni_stream_cleanup(void *dat
         }
 
         break;
+
+    case NGX_HTTP_V3_STREAM_CONTROL:
+
+        if (us->client) {
+            h3c->client_control = NULL;
+        } else {
+            h3c->server_control = NULL;
+        }
+
+        break;
     }
 }
 
@@ -141,112 +144,96 @@ ngx_http_v3_uni_stream_cleanup(void *dat
 static void
 ngx_http_v3_read_uni_stream_type(ngx_event_t *rev)
 {
-    u_char                    *p;
-    ssize_t                    n, len;
+    u_char                     ch;
+    ssize_t                    n;
     ngx_connection_t          *c;
     ngx_http_v3_connection_t  *h3c;
-    ngx_http_v3_uni_stream_t  *us;
+    ngx_http_v3_uni_stream_t  *st;
 
     c = rev->data;
-    us = c->data;
+    st = c->data;
     h3c = c->qs->parent->data;
 
     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 read stream type");
 
     while (rev->ready) {
 
-        p = &us->buf[us->len];
-
-        if (us->len == 0) {
-            len = 1;
-        } else {
-            len = (us->buf[0] >> 6) + 1 - us->len;
-        }
-
-        n = c->recv(c, p, len);
+        n = c->recv(c, &ch, 1);
 
         if (n == NGX_ERROR) {
             goto failed;
         }
 
-        if (n == NGX_AGAIN) {
-            break;
-        }
-
-        us->len += n;
-
-        if (n != len) {
+        if (n == NGX_AGAIN || n != 1) {
             break;
         }
 
-        if ((us->buf[0] >> 6) + 1 == us->len) {
-            us->type = ngx_http_v3_decode_varlen_int(us->buf);
+        st->type = ch;
+
+        switch (st->type) {
+
+        case NGX_HTTP_V3_STREAM_ENCODER:
+
+            ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                           "http3 encoder stream");
+
+            if (h3c->client_encoder) {
+                goto failed;
+            }
+
+            h3c->client_encoder = c;
+            st->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");
+
+            if (h3c->client_decoder) {
+                goto failed;
+            }
+
+            h3c->client_decoder = c;
+            st->handler = ngx_http_v3_parse_decoder;
+            n = sizeof(ngx_http_v3_parse_decoder_t);
+
+            break;
+
+        case NGX_HTTP_V3_STREAM_CONTROL:
+
+            ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                           "http3 control stream");
+
+            if (h3c->client_control) {
+                goto failed;
+            }
+
+            h3c->client_control = c;
+            st->handler = ngx_http_v3_parse_control;
+            n = sizeof(ngx_http_v3_parse_control_t);
+
+            break;
+
+        default:
 
             ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
-                           "http3 stream type:%ui", us->type);
-
-            switch (us->type) {
-
-            case NGX_HTTP_V3_ENCODER_STREAM:
-                if (h3c->client_encoder) {
-                    goto failed;
-                }
-
-                h3c->client_encoder = c;
-                rev->handler = ngx_http_v3_client_encoder_handler;
-                break;
-
-            case NGX_HTTP_V3_DECODER_STREAM:
-                if (h3c->client_decoder) {
-                    goto failed;
-                }
-
-                h3c->client_decoder = c;
-                rev->handler = ngx_http_v3_client_decoder_handler;
-                break;
-
-            case NGX_HTTP_V3_CONTROL_STREAM:
-            case NGX_HTTP_V3_PUSH_STREAM:
-
-                /* ignore these */
-
-            default:
-                rev->handler = ngx_http_v3_dummy_stream_handler;
-            }
+                           "http3 stream 0x%02xi", st->type);
+            n = 0;
+        }
 
-            rev->handler(rev);
-            return;
+        if (n) {
+            st->data = ngx_pcalloc(c->pool, n);
+            if (st->data == NULL) {
+                goto failed;
+            }
         }
-    }
-
-    if (ngx_handle_read_event(rev, 0) != NGX_OK) {
-        goto failed;
-    }
-
-    return;
-
-failed:
-
-    ngx_http_v3_close_uni_stream(c);
-}
-
 
-static void
-ngx_http_v3_dummy_stream_handler(ngx_event_t *rev)
-{
-    u_char             buf[128];
-    ngx_connection_t  *c;
-
-    /* read out and ignore */
-
-    c = rev->data;
-
-    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 dummy stream reader");
-
-    while (rev->ready) {
-        if (c->recv(c, buf, sizeof(buf)) == NGX_ERROR) {
-            goto failed;
-        }
+        rev->handler = ngx_http_v3_uni_read_handler;
+        ngx_http_v3_uni_read_handler(rev);
+        return;
     }
 
     if (ngx_handle_read_event(rev, 0) != NGX_OK) {
@@ -262,519 +249,60 @@ failed:
 
 
 static void
-ngx_http_v3_client_encoder_handler(ngx_event_t *rev)
+ngx_http_v3_uni_read_handler(ngx_event_t *rev)
 {
-    u_char                     v;
+    u_char                     buf[128];
     ssize_t                    n;
-    ngx_str_t                  name, value;
-    ngx_uint_t                 dynamic, huffman, index, offset;
-    ngx_connection_t          *c, *pc;
+    ngx_int_t                  rc, i;
+    ngx_connection_t          *c;
     ngx_http_v3_uni_stream_t  *st;
-    enum {
-        sw_start = 0,
-        sw_inr_name_index,
-        sw_inr_value_length,
-        sw_inr_read_value_length,
-        sw_inr_value,
-        sw_iwnr_name_length,
-        sw_iwnr_name,
-        sw_iwnr_value_length,
-        sw_iwnr_read_value_length,
-        sw_iwnr_value,
-        sw_capacity,
-        sw_duplicate
-    } state;
 
     c = rev->data;
     st = c->data;
-    pc = c->qs->parent;
 
-    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 client encoder");
-
-    state = st->state;
-    dynamic = st->dynamic;
-    huffman = st->huffman;
-    index = st->index;
-    offset = st->offset;
-    name = st->name;
-    value = st->value;
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 read handler");
 
     while (rev->ready) {
 
-        /* XXX limit checks */
-        /* XXX buffer input */
-
-        n = c->recv(c, &v, 1);
+        n = c->recv(c, buf, sizeof(buf));
 
         if (n == NGX_ERROR || n == 0) {
             goto failed;
         }
 
-        if (n != 1) {
+        if (n == NGX_AGAIN) {
             break;
         }
 
-        /* XXX v -> ch */
-
-        switch (state) {
-
-        case sw_start:
-
-            if (v & 0x80) {
-                /* Insert With Name Reference */
-
-                dynamic = (v & 0x40) ? 0 : 1;
-                index = v & 0x3f;
-
-                if (index != 0x3f) {
-                    state = sw_inr_value_length;
-                    break;
-                }
-
-                index = 0;
-                state = sw_inr_name_index;
-                break;
-            }
-
-            if (v & 0x40) {
-                /*  Insert Without Name Reference */
-
-                huffman = (v & 0x20) ? 1 : 0;
-                name.len = v & 0x1f;
-
-                if (name.len != 0x1f) {
-                    offset = 0;
-                    state = sw_iwnr_name;
-                    break;
-                }
-
-                name.len = 0;
-                state = sw_iwnr_name_length;
-                break;
-            }
-
-            if (v & 0x20) {
-                /*  Set Dynamic Table Capacity */
-
-                index = v & 0x1f;
-
-                if (index != 0x1f) {
-                    if (ngx_http_v3_set_capacity(c, index) != NGX_OK) {
-                        goto failed;
-                    }
-
-                    break;
-                }
-
-                index = 0;
-                state = sw_capacity;
-                break;
-            }
-
-            /* Duplicate */
-
-            index = v & 0x1f;
+        if (st->handler == NULL) {
+            continue;
+        }
 
-            if (index != 0x1f) {
-                if (ngx_http_v3_duplicate(c, index) != NGX_OK) {
-                    goto failed;
-                }
-
-                break;
-            }
-
-            index = 0;
-            state = sw_duplicate;
-            break;
-
-        case sw_inr_name_index:
-
-            index = (index << 7) + (v & 0x7f);
-            if (v & 0x80) {
-                break;
-            }
-
-            index += 0x3f;
-            state = sw_inr_value_length;
-            break;
-
-        case sw_inr_value_length:
-
-            huffman = (v & 0x80) ? 1 : 0;
-            value.len = v & 0x7f;
-
-            if (value.len == 0) {
-                value.data = NULL;
+        for (i = 0; i < n; i++) {
 
-                if (ngx_http_v3_ref_insert(c, dynamic, index, &value) != NGX_OK)
-                {
-                    goto failed;
-                }
-
-                state = sw_start;
-                break;
-            }
-
-            if (value.len != 0x7f) {
-                value.data = ngx_pnalloc(pc->pool, value.len);
-                if (value.data == NULL) {
-                    goto failed;
-                }
+            rc = st->handler(c, st->data, buf[i]);
 
-                state = sw_inr_value;
-                offset = 0;
-                break;
-            }
-
-            value.len = 0;
-            state = sw_inr_read_value_length;
-            break;
-
-        case sw_inr_read_value_length:
-
-            value.len = (value.len << 7) + (v & 0x7f);
-            if (v & 0x80) {
-                break;
-            }
-
-            value.len += 0x7f;
-
-            value.data = ngx_pnalloc(pc->pool, value.len);
-            if (value.data == NULL) {
+            if (rc == NGX_ERROR) {
                 goto failed;
             }
 
-            state = sw_inr_value;
-            offset = 0;
-            break;
-
-        case sw_inr_value:
-
-            value.data[offset++] = v;
-            if (offset != value.len) {
-                break;
-            }
-
-            if (huffman) {
-                if (ngx_http_v3_decode_huffman(pc, &value) != NGX_OK) {
-                    goto failed;
-                }
-            }
-
-            if (ngx_http_v3_ref_insert(c, dynamic, index, &value) != NGX_OK) {
-                goto failed;
-            }
-
-            state = sw_start;
-            break;
-
-        case sw_iwnr_name_length:
-
-            name.len = (name.len << 7) + (v & 0x7f);
-            if (v & 0x80) {
-                break;
-            }
-
-            name.len += 0x1f;
-
-            name.data = ngx_pnalloc(pc->pool, name.len);
-            if (name.data == NULL) {
-                goto failed;
-            }
-
-            offset = 0;
-            state = sw_iwnr_name;
-            break;
-
-        case sw_iwnr_name:
-
-            name.data[offset++] = v;
-            if (offset != name.len) {
-                break;
-            }
-
-            if (huffman) {
-                if (ngx_http_v3_decode_huffman(pc, &name) != NGX_OK) {
-                    goto failed;
-                }
-            }
-
-            state = sw_iwnr_value_length;
-            break;
-
-        case sw_iwnr_value_length:
-
-            huffman = (v & 0x80) ? 1 : 0;
-            value.len = v & 0x7f;
-
-            if (value.len == 0) {
-                value.data = NULL;
-
-                if (ngx_http_v3_insert(c, &name, &value) != NGX_OK) {
-                    goto failed;
-                }
-
-                state = sw_start;
-                break;
+            if (rc == NGX_DONE) {
+                goto done;
             }
 
-            if (value.len != 0x7f) {
-                value.data = ngx_pnalloc(pc->pool, value.len);
-                if (value.data == NULL) {
-                    goto failed;
-                }
-
-                offset = 0;
-                state = sw_iwnr_value;
-                break;
-            }
-
-            state = sw_iwnr_read_value_length;
-            break;
-
-        case sw_iwnr_read_value_length:
-
-            value.len = (value.len << 7) + (v & 0x7f);
-            if (v & 0x80) {
-                break;
-            }
-
-            value.data = ngx_pnalloc(pc->pool, value.len);
-            if (value.data == NULL) {
-                goto failed;
-            }
-
-            offset = 0;
-            state = sw_iwnr_value;
-            break;
-
-        case sw_iwnr_value:
-
-            value.data[offset++] = v;
-            if (offset != value.len) {
-                break;
-            }
-
-            if (huffman) {
-                if (ngx_http_v3_decode_huffman(pc, &value) != NGX_OK) {
-                    goto failed;
-                }
-            }
-
-            if (ngx_http_v3_insert(c, &name, &value) != NGX_OK) {
-                goto failed;
-            }
-
-            state = sw_start;
-            break;
-
-
-        case sw_capacity:
-
-            index = (index << 7) + (v & 0x7f);
-            if (v & 0x80) {
-                break;
-            }
-
-            index += 0x1f;
-
-            if (ngx_http_v3_set_capacity(c, index) != NGX_OK) {
-                goto failed;
-            }
-
-            state = sw_start;
-            break;
-
-        case sw_duplicate:
-
-            index = (index << 7) + (v & 0x7f);
-            if (v & 0x80) {
-                break;
-            }
-
-            index += 0x1f;
-
-            if (ngx_http_v3_duplicate(c, index) != NGX_OK) {
-                goto failed;
-            }
-
-            state = sw_start;
-            break;
+            /* rc == NGX_AGAIN */
         }
     }
 
-    st->state = state;
-    st->dynamic = dynamic;
-    st->huffman = huffman;
-    st->index = index;
-    st->offset = offset;
-    st->name = name;
-    st->value = value;
-
     if (ngx_handle_read_event(rev, 0) != NGX_OK) {
         goto failed;
     }
 
     return;
 
-failed:
-
-    ngx_http_v3_close_uni_stream(c);
-}
-
-
-static void
-ngx_http_v3_client_decoder_handler(ngx_event_t *rev)
-{
-    u_char                     v;
-    ssize_t                    n;
-    ngx_uint_t                 index;
-    ngx_connection_t          *c;
-    ngx_http_v3_uni_stream_t  *st;
-    enum {
-        sw_start = 0,
-        sw_ack_header,
-        sw_cancel_stream,
-        sw_inc_insert_count
-    } state;
-
-    c = rev->data;
-    st = c->data;
-
-    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 client decoder");
-
-    state = st->state;
-    index = st->index;
-
-    while (rev->ready) {
-
-        /* XXX limit checks */
-        /* XXX buffer input */
-
-        n = c->recv(c, &v, 1);
-
-        if (n == NGX_ERROR || n == 0) {
-            goto failed;
-        }
-
-        if (n != 1) {
-            break;
-        }
-
-        switch (state) {
-
-        case sw_start:
-
-            if (v & 0x80) {
-                /* Header Acknowledgement */
-
-                index = v & 0x7f;
-
-                if (index != 0x7f) {
-                    if (ngx_http_v3_ack_header(c, index) != NGX_OK) {
-                        goto failed;
-                    }
-
-                    break;
-                }
-
-                index = 0;
-                state = sw_ack_header;
-                break;
-            }
-
-            if (v & 0x40) {
-                /*  Stream Cancellation */
-
-                index = v & 0x3f;
-
-                if (index != 0x3f) {
-                    if (ngx_http_v3_cancel_stream(c, index) != NGX_OK) {
-                        goto failed;
-                    }
-
-                    break;
-                }
+done:
 
-                index = 0;
-                state = sw_cancel_stream;
-                break;
-            }
-
-            /*  Insert Count Increment */
-
-            index = v & 0x3f;
-
-            if (index != 0x3f) {
-                if (ngx_http_v3_inc_insert_count(c, index) != NGX_OK) {
-                    goto failed;
-                }
-
-                break;
-            }
-
-            index = 0;
-            state = sw_inc_insert_count;
-            break;
-
-        case sw_ack_header:
-
-            index = (index << 7) + (v & 0x7f);
-            if (v & 0x80) {
-                break;
-            }
-
-            index += 0x7f;
-
-            if (ngx_http_v3_ack_header(c, index) != NGX_OK) {
-                goto failed;
-            }
-
-            state = sw_start;
-            break;
-
-        case sw_cancel_stream:
-
-            index = (index << 7) + (v & 0x7f);
-            if (v & 0x80) {
-                break;
-            }
-
-            index += 0x3f;
-
-            if (ngx_http_v3_cancel_stream(c, index) != NGX_OK) {
-                goto failed;
-            }
-
-            state = sw_start;
-            break;
-
-        case sw_inc_insert_count:
-
-            index = (index << 7) + (v & 0x7f);
-            if (v & 0x80) {
-                break;
-            }
-
-            index += 0x3f;
-
-            if (ngx_http_v3_inc_insert_count(c, index) != NGX_OK) {
-                goto failed;
-            }
-
-            state = sw_start;
-            break;
-        }
-    }
-
-    st->state = state;
-    st->index = index;
-
-    if (ngx_handle_read_event(rev, 0) != NGX_OK) {
-        goto failed;
-    }
-
-    return;
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 read done");
 
 failed:
 
@@ -835,7 +363,7 @@ failed:
 
 
 static ngx_connection_t *
-ngx_http_v3_get_server_encoder(ngx_connection_t *c)
+ngx_http_v3_get_control(ngx_connection_t *c)
 {
     ngx_http_v3_connection_t  *h3c;
 
@@ -843,7 +371,7 @@ ngx_http_v3_get_server_encoder(ngx_conne
 
     if (h3c->server_encoder == NULL) {
         h3c->server_encoder = ngx_http_v3_create_uni_stream(c,
-                                                   NGX_HTTP_V3_ENCODER_STREAM);
+                                                   NGX_HTTP_V3_STREAM_CONTROL);
     }
 
     return h3c->server_encoder;
@@ -851,18 +379,34 @@ ngx_http_v3_get_server_encoder(ngx_conne
 
 
 static ngx_connection_t *
-ngx_http_v3_get_server_decoder(ngx_connection_t *c)
+ngx_http_v3_get_encoder(ngx_connection_t *c)
 {
     ngx_http_v3_connection_t  *h3c;
 
     h3c = c->qs->parent->data;
 
-    if (h3c->server_decoder == NULL) {
-        h3c->server_decoder = ngx_http_v3_create_uni_stream(c,
-                                                   NGX_HTTP_V3_DECODER_STREAM);
+    if (h3c->server_encoder == NULL) {
+        h3c->server_encoder = ngx_http_v3_create_uni_stream(c,
+                                                   NGX_HTTP_V3_STREAM_ENCODER);
     }
 
-    return h3c->server_decoder;
+    return h3c->server_encoder;
+}
+
+
+static ngx_connection_t *
+ngx_http_v3_get_decoder(ngx_connection_t *c)
+{
+    ngx_http_v3_connection_t  *h3c;
+
+    h3c = c->qs->parent->data;
+
+    if (h3c->server_encoder == NULL) {
+        h3c->server_encoder = ngx_http_v3_create_uni_stream(c,
+                                                   NGX_HTTP_V3_STREAM_DECODER);
+    }
+
+    return h3c->server_encoder;
 }
 
 
@@ -878,7 +422,7 @@ ngx_http_v3_client_ref_insert(ngx_connec
                    "http3 client ref insert, %s[%ui] \"%V\"",
                    dynamic ? "dynamic" : "static", index, value);
 
-    ec = ngx_http_v3_get_server_encoder(c);
+    ec = ngx_http_v3_get_encoder(c);
     if (ec == NULL) {
         return NGX_ERROR;
     }
@@ -923,7 +467,7 @@ ngx_http_v3_client_insert(ngx_connection
     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
                    "http3 client insert \"%V\":\"%V\"", name, value);
 
-    ec = ngx_http_v3_get_server_encoder(c);
+    ec = ngx_http_v3_get_encoder(c);
     if (ec == NULL) {
         return NGX_ERROR;
     }
@@ -972,7 +516,7 @@ ngx_http_v3_client_set_capacity(ngx_conn
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
                    "http3 client set capacity %ui", capacity);
 
-    ec = ngx_http_v3_get_server_encoder(c);
+    ec = ngx_http_v3_get_encoder(c);
     if (ec == NULL) {
         return NGX_ERROR;
     }
@@ -999,7 +543,7 @@ ngx_http_v3_client_duplicate(ngx_connect
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
                    "http3 client duplicate %ui", index);
 
-    ec = ngx_http_v3_get_server_encoder(c);
+    ec = ngx_http_v3_get_encoder(c);
     if (ec == NULL) {
         return NGX_ERROR;
     }
@@ -1026,7 +570,7 @@ ngx_http_v3_client_ack_header(ngx_connec
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
                    "http3 client ack header %ui", stream_id);
 
-    dc = ngx_http_v3_get_server_decoder(c);
+    dc = ngx_http_v3_get_decoder(c);
     if (dc == NULL) {
         return NGX_ERROR;
     }
@@ -1053,7 +597,7 @@ ngx_http_v3_client_cancel_stream(ngx_con
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
                    "http3 client cancel stream %ui", stream_id);
 
-    dc = ngx_http_v3_get_server_decoder(c);
+    dc = ngx_http_v3_get_decoder(c);
     if (dc == NULL) {
         return NGX_ERROR;
     }
@@ -1080,7 +624,7 @@ ngx_http_v3_client_inc_insert_count(ngx_
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
                    "http3 client increment insert count %ui", inc);
 
-    dc = ngx_http_v3_get_server_decoder(c);
+    dc = ngx_http_v3_get_decoder(c);
     if (dc == NULL) {
         return NGX_ERROR;
     }