]> git.feebdaed.xyz Git - 0xmirror/nginx.git/commitdiff
Proxy: cache support for HTTP/2.
authorZhidao HONG <z.hong@f5.com>
Sun, 30 Nov 2025 16:35:31 +0000 (16:35 +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 44caba8484e18f14c8570e69535906382b6fcb1b..17983a29d1538eb819396542e8e0d01bf5aceef6 100644 (file)
@@ -213,10 +213,13 @@ static u_char  ngx_http_proxy_v2_connection_start[] =
 ngx_int_t
 ngx_http_proxy_v2_handler(ngx_http_request_t *r)
 {
-    ngx_int_t                   rc;
-    ngx_http_upstream_t        *u;
-    ngx_http_proxy_v2_ctx_t    *ctx;
-    ngx_http_proxy_loc_conf_t  *plcf;
+    ngx_int_t                    rc;
+    ngx_http_upstream_t         *u;
+    ngx_http_proxy_v2_ctx_t     *ctx;
+    ngx_http_proxy_loc_conf_t   *plcf;
+#if (NGX_HTTP_CACHE)
+    ngx_http_proxy_main_conf_t  *pmcf;
+#endif
 
     if (ngx_http_upstream_create(r) != NGX_OK) {
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
@@ -258,6 +261,13 @@ ngx_http_proxy_v2_handler(ngx_http_request_t *r)
 
     u->conf = &plcf->upstream;
 
+#if (NGX_HTTP_CACHE)
+    pmcf = ngx_http_get_module_main_conf(r, ngx_http_proxy_module);
+
+    u->caches = &pmcf->caches;
+    u->create_key = ngx_http_proxy_create_key;
+#endif
+
     u->create_request = ngx_http_proxy_v2_create_request;
     u->reinit_request = ngx_http_proxy_v2_reinit_request;
     u->process_header = ngx_http_proxy_v2_process_header;
@@ -330,7 +340,11 @@ ngx_http_proxy_v2_create_request(ngx_http_request_t *r)
 
     plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module);
 
+#if (NGX_HTTP_CACHE)
+    headers = u->cacheable ? &plcf->headers_cache : &plcf->headers;
+#else
     headers = &plcf->headers;
+#endif
 
     if (u->method.len) {
         /* HEAD was changed to GET to cache response */
@@ -1389,9 +1403,27 @@ ngx_http_proxy_v2_process_header(ngx_http_request_t *r)
 
         /* frame payload */
 
-        if (ctx->type == NGX_HTTP_V2_RST_STREAM_FRAME) {
+        if (u->peer.connection) {
 
-            rc = ngx_http_proxy_v2_parse_rst_stream(r, ctx, b);
+            if (ctx->type == NGX_HTTP_V2_RST_STREAM_FRAME) {
+                rc = ngx_http_proxy_v2_parse_rst_stream(r, ctx, b);
+
+                if (rc == NGX_AGAIN) {
+                    return NGX_AGAIN;
+                }
+
+                if (rc == NGX_ERROR) {
+                    return NGX_HTTP_UPSTREAM_INVALID_HEADER;
+                }
+
+                ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+                              "upstream rejected request with error %ui",
+                              ctx->error);
+
+                return NGX_HTTP_UPSTREAM_INVALID_HEADER;
+            }
+
+            rc = ngx_http_proxy_v2_process_control_frame(r, ctx, b);
 
             if (rc == NGX_AGAIN) {
                 return NGX_AGAIN;
@@ -1401,25 +1433,9 @@ ngx_http_proxy_v2_process_header(ngx_http_request_t *r)
                 return NGX_HTTP_UPSTREAM_INVALID_HEADER;
             }
 
-            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
-                          "upstream rejected request with error %ui",
-                          ctx->error);
-
-            return NGX_HTTP_UPSTREAM_INVALID_HEADER;
-        }
-
-        rc = ngx_http_proxy_v2_process_control_frame(r, ctx, b);
-
-        if (rc == NGX_AGAIN) {
-            return NGX_AGAIN;
-        }
-
-        if (rc == NGX_ERROR) {
-            return NGX_HTTP_UPSTREAM_INVALID_HEADER;
-        }
-
-        if (rc == NGX_OK) {
-            continue;
+            if (rc == NGX_OK) {
+                continue;
+            }
         }
 
         if (ctx->type != NGX_HTTP_V2_HEADERS_FRAME
@@ -4052,6 +4068,15 @@ ngx_http_proxy_v2_get_connection_data(ngx_http_request_t *r,
 
     c = pc->connection;
 
+    if (c == NULL) {
+        ctx->connection = ngx_palloc(r->pool, sizeof(ngx_http_proxy_v2_conn_t));
+        if (ctx->connection == NULL) {
+            return NGX_ERROR;
+        }
+
+        goto done;
+    }
+
     if (pc->cached) {
 
         /*
@@ -4090,6 +4115,8 @@ ngx_http_proxy_v2_get_connection_data(ngx_http_request_t *r,
     cln->handler = ngx_http_proxy_v2_cleanup;
     ctx->connection = cln->data;
 
+done:
+
     ctx->connection->init_window = NGX_HTTP_V2_DEFAULT_WINDOW;
     ctx->connection->send_window = NGX_HTTP_V2_DEFAULT_WINDOW;
     ctx->connection->recv_window = NGX_HTTP_V2_MAX_WINDOW;