]> git.kaiwu.me - nginx.git/commitdiff
Proxy: extracted ngx_http_proxy_v2_process_frames() function.
authorZhidao HONG <z.hong@f5.com>
Sun, 30 Nov 2025 16:24:24 +0000 (16:24 +0000)
committerRoman Arutyunyan <arutyunyan.roman@gmail.com>
Mon, 8 Dec 2025 03:49:16 +0000 (07:49 +0400)
src/http/modules/ngx_http_proxy_v2_module.c

index a6bc80fbd4f951cf5848a1a0c76576684e9b04bd..fc93ca71ca9ed84f3c4a5ed4f65efcf2abe89cc2 100644 (file)
@@ -117,6 +117,8 @@ static ngx_int_t ngx_http_proxy_v2_process_header(ngx_http_request_t *r);
 static ngx_int_t ngx_http_proxy_v2_filter_init(void *data);
 static ngx_int_t ngx_http_proxy_v2_non_buffered_filter(void *data,
     ssize_t bytes);
+static ngx_int_t ngx_http_proxy_v2_process_frames(ngx_http_request_t *r,
+    ngx_http_proxy_v2_ctx_t *ctx, ngx_buf_t *b);
 
 static ngx_int_t ngx_http_proxy_v2_parse_frame(ngx_http_request_t *r,
     ngx_http_proxy_v2_ctx_t *ctx, ngx_buf_t *b);
@@ -1714,7 +1716,6 @@ ngx_http_proxy_v2_non_buffered_filter(void *data, ssize_t bytes)
     ngx_int_t                 rc;
     ngx_buf_t                *b, *buf;
     ngx_chain_t              *cl, **ll;
-    ngx_table_elt_t          *h;
     ngx_http_upstream_t      *u;
     ngx_http_proxy_v2_ctx_t  *ctx;
 
@@ -1737,6 +1738,85 @@ ngx_http_proxy_v2_non_buffered_filter(void *data, ssize_t bytes)
         ll = &cl->next;
     }
 
+    for ( ;; ) {
+
+        rc = ngx_http_proxy_v2_process_frames(r, ctx, b);
+
+        if (rc == NGX_OK) {
+
+            cl = ngx_chain_get_free_buf(r->pool, &u->free_bufs);
+            if (cl == NULL) {
+                return NGX_ERROR;
+            }
+
+            *ll = cl;
+            ll = &cl->next;
+
+            buf = cl->buf;
+
+            buf->flush = 1;
+            buf->memory = 1;
+
+            buf->pos = b->pos;
+            buf->tag = u->output.tag;
+
+            if (b->last - b->pos >= (ssize_t) ctx->rest - ctx->padding) {
+                b->pos += ctx->rest - ctx->padding;
+                buf->last = b->pos;
+                ctx->rest = ctx->padding;
+
+            } else {
+                ctx->rest -= b->last - b->pos;
+                b->pos = b->last;
+                buf->last = b->pos;
+            }
+
+            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                           "http proxy output buf %p", buf->pos);
+
+            if (ctx->length != -1) {
+
+                if (buf->last - buf->pos > ctx->length) {
+                    ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+                                  "upstream sent response body larger "
+                                  "than indicated content length");
+                    return NGX_ERROR;
+                }
+
+                ctx->length -= buf->last - buf->pos;
+            }
+
+            continue;
+        }
+
+        if (rc == NGX_DONE) {
+            u->length = 0;
+            break;
+        }
+
+        if (rc == NGX_AGAIN) {
+            return NGX_AGAIN;
+        }
+
+        /* invalid response */
+
+        return NGX_ERROR;
+    }
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_proxy_v2_process_frames(ngx_http_request_t *r,
+    ngx_http_proxy_v2_ctx_t *ctx, ngx_buf_t *b)
+{
+    ngx_int_t             rc;
+    ngx_table_elt_t      *h;
+    ngx_http_upstream_t  *u;
+
+    u = r->upstream;
+
     for ( ;; ) {
 
         if (ctx->state < ngx_http_proxy_v2_st_payload) {
@@ -1765,8 +1845,6 @@ ngx_http_proxy_v2_non_buffered_filter(void *data, ssize_t bytes)
                         return NGX_AGAIN;
                     }
 
-                    u->length = 0;
-
                     if (ctx->in == NULL
                         && ctx->output_closed
                         && !ctx->output_blocked
@@ -1776,7 +1854,7 @@ ngx_http_proxy_v2_non_buffered_filter(void *data, ssize_t bytes)
                         u->keepalive = 1;
                     }
 
-                    break;
+                    return NGX_DONE;
                 }
 
                 return NGX_AGAIN;
@@ -2145,85 +2223,28 @@ ngx_http_proxy_v2_non_buffered_filter(void *data, ssize_t bytes)
             continue;
         }
 
-        if (ctx->rest == ctx->padding) {
-            goto done;
-        }
-
-        if (b->pos == b->last) {
-            return NGX_AGAIN;
-        }
-
-        cl = ngx_chain_get_free_buf(r->pool, &u->free_bufs);
-        if (cl == NULL) {
-            return NGX_ERROR;
-        }
-
-        *ll = cl;
-        ll = &cl->next;
-
-        buf = cl->buf;
-
-        buf->flush = 1;
-        buf->memory = 1;
-
-        buf->pos = b->pos;
-        buf->tag = u->output.tag;
-
-        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                       "http proxy output buf %p", buf->pos);
-
-        if (b->last - b->pos < (ssize_t) ctx->rest - ctx->padding) {
+        if (ctx->padding == ctx->rest) {
 
-            ctx->rest -= b->last - b->pos;
-            b->pos = b->last;
-            buf->last = b->pos;
+            if (ctx->padding) {
+                ctx->state = ngx_http_proxy_v2_st_padding;
 
-            if (ctx->length != -1) {
+            } else {
+                ctx->state = ngx_http_proxy_v2_st_start;
 
-                if (buf->last - buf->pos > ctx->length) {
-                    ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
-                                  "upstream sent response body larger "
-                                  "than indicated content length");
-                    return NGX_ERROR;
+                if (ctx->flags & NGX_HTTP_V2_END_STREAM_FLAG) {
+                    ctx->done = 1;
                 }
-
-                ctx->length -= buf->last - buf->pos;
             }
 
-            return NGX_AGAIN;
-        }
-
-        b->pos += ctx->rest - ctx->padding;
-        buf->last = b->pos;
-        ctx->rest = ctx->padding;
-
-        if (ctx->length != -1) {
-
-            if (buf->last - buf->pos > ctx->length) {
-                ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
-                              "upstream sent response body larger "
-                              "than indicated content length");
-                return NGX_ERROR;
-            }
-
-            ctx->length -= buf->last - buf->pos;
-        }
-
-    done:
-
-        if (ctx->padding) {
-            ctx->state = ngx_http_proxy_v2_st_padding;
             continue;
         }
 
-        ctx->state = ngx_http_proxy_v2_st_start;
-
-        if (ctx->flags & NGX_HTTP_V2_END_STREAM_FLAG) {
-            ctx->done = 1;
+        if (b->pos == b->last) {
+            return NGX_AGAIN;
         }
-    }
 
-    return NGX_OK;
+        return NGX_OK;
+    }
 }