Skip to content

Update nginx to v1.28.3 last stable#98

Merged
MDA2AV merged 1 commit into
MDA2AV:mainfrom
joanhey:nginx-1.28.3
Mar 24, 2026
Merged

Update nginx to v1.28.3 last stable#98
MDA2AV merged 1 commit into
MDA2AV:mainfrom
joanhey:nginx-1.28.3

Conversation

@joanhey
Copy link
Copy Markdown
Contributor

@joanhey joanhey commented Mar 24, 2026

No description provided.

@joanhey joanhey requested a review from MDA2AV as a code owner March 24, 2026 22:46
Copy link
Copy Markdown
Collaborator

@BennyFranciscus BennyFranciscus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean bump — nice touch parameterizing the version in the COPY path too, that hardcoded 1.26.2 in the runtime stage was a landmine waiting to happen. LGTM 👍

@MDA2AV
Copy link
Copy Markdown
Owner

MDA2AV commented Mar 24, 2026

/benchmark

@github-actions
Copy link
Copy Markdown
Contributor

🚀 Benchmark run triggered for nginx (all profiles). Results will be posted here when done.

@joanhey
Copy link
Copy Markdown
Contributor Author

joanhey commented Mar 24, 2026

FAIL [bad method]: expected 4xx, got HTTP 200
But also fail in the main repo with nginx.

@BennyFranciscus
Copy link
Copy Markdown
Collaborator

Yeah, that bad method test has been failing on nginx for a while — it's not something this version bump introduced. Nginx just doesn't reject unknown HTTP methods by default, it'll happily serve a 200 for pretty much anything.

We could handle it in the nginx config with something like limit_except or an if block on $request_method, but that's a separate fix from the version update. Might be worth a follow-up PR if we want nginx to pass that compliance check.

Either way, the upgrade itself looks fine to me 👍

@joanhey
Copy link
Copy Markdown
Contributor Author

joanhey commented Mar 24, 2026

The problem is not nginx, than return a 400 Bad Request without problems, with malformed URLs or methods.
For me the problem is in the module:
https://github.com/MDA2AV/HttpArena/blob/main/frameworks/nginx/ngx_http_httparena_module.c

As all requests are send directly to the module.

@BennyFranciscus
Copy link
Copy Markdown
Collaborator

You're right, my bad — the fix is in the module, not nginx config. The handler at the bottom of ngx_http_httparena_handler returns NGX_DECLINED for any unmatched route, which passes it back to nginx's default handler (→ 200). And for the known routes, there's no method check either — like /pipeline will happily respond 200 to a FOOBAR method.

A simple fix would be adding a method guard near the top of the handler:

if (!(r->method & (NGX_HTTP_GET | NGX_HTTP_POST | NGX_HTTP_HEAD))) {
    return send_resp(r, 405,
                     (u_char *)"text/plain", 10,
                     (u_char *)"Method Not Allowed", 18, 1);
}

And changing the final return NGX_DECLINED to a 404 response so unknown paths don't leak to nginx's default handler.

But that's a separate fix from the version bump — this PR looks good on its own 👍

@github-actions
Copy link
Copy Markdown
Contributor

Benchmark Results

Framework: nginx | Profile: all profiles

nginx / baseline / 512c (p=1, r=0, cpu=64)
  Best: 2497167 req/s (CPU: 6539.8%, Mem: 3.5GiB) ===

nginx / baseline / 4096c (p=1, r=0, cpu=64)
  Best: 2791075 req/s (CPU: 6455.8%, Mem: 3.5GiB) ===

nginx / baseline / 16384c (p=1, r=0, cpu=64)
  Best: 2651714 req/s (CPU: 6146.7%, Mem: 3.6GiB) ===

nginx / pipelined / 512c (p=16, r=0, cpu=unlimited)
  Best: 4321620 req/s (CPU: 7793.9%, Mem: 3.5GiB) ===

nginx / pipelined / 4096c (p=16, r=0, cpu=unlimited)
  Best: 3952942 req/s (CPU: 7192.3%, Mem: 3.5GiB) ===

nginx / pipelined / 16384c (p=16, r=0, cpu=unlimited)
  Best: 3492325 req/s (CPU: 6824.8%, Mem: 3.7GiB) ===

nginx / limited-conn / 512c (p=1, r=10, cpu=unlimited)
  Best: 1608875 req/s (CPU: 5304.6%, Mem: 3.5GiB) ===

nginx / limited-conn / 4096c (p=1, r=10, cpu=unlimited)
  Best: 1987778 req/s (CPU: 5996.5%, Mem: 3.5GiB) ===

nginx / json / 4096c (p=1, r=0, cpu=unlimited)
  Best: 1131068 req/s (CPU: 5003.4%, Mem: 3.5GiB) ===

nginx / json / 16384c (p=1, r=0, cpu=unlimited)
  Best: 1573338 req/s (CPU: 7544.2%, Mem: 3.6GiB) ===

nginx / upload / 64c (p=1, r=0, cpu=unlimited)
  Best: 1094 req/s (CPU: 4364.1%, Mem: 5.3GiB) ===

nginx / upload / 256c (p=1, r=0, cpu=unlimited)
  Best: 977 req/s (CPU: 3729.9%, Mem: 6.2GiB) ===

nginx / upload / 512c (p=1, r=0, cpu=unlimited)
  Best: 900 req/s (CPU: 4243.9%, Mem: 9.2GiB) ===

nginx / compression / 4096c (p=1, r=0, cpu=unlimited)
  Best: 11138 req/s (CPU: 12198.8%, Mem: 3.6GiB) ===

nginx / compression / 16384c (p=1, r=0, cpu=unlimited)
  Best: 11138 req/s (CPU: 11743.6%, Mem: 3.7GiB) ===

nginx / noisy / 512c (p=1, r=0, cpu=unlimited)
  Best: 1920363 req/s (CPU: 6193.5%, Mem: 3.5GiB) ===

nginx / noisy / 4096c (p=1, r=0, cpu=unlimited)
  Best: 2571704 req/s (CPU: 6879.3%, Mem: 3.5GiB) ===

nginx / noisy / 16384c (p=1, r=0, cpu=unlimited)
  Best: 2201721 req/s (CPU: 7057.7%, Mem: 3.6GiB) ===

nginx / mixed / 4096c (p=1, r=5, cpu=unlimited)
  Best: 48376 req/s (CPU: 11313.7%, Mem: 4.6GiB) ===

nginx / mixed / 16384c (p=1, r=5, cpu=unlimited)
  Best: 52629 req/s (CPU: 10284.9%, Mem: 7.0GiB) ===

nginx / baseline-h2 / 256c (p=1, r=0, cpu=unlimited)
  Best: 3240332 req/s (CPU: 6927.1%, Mem: 3.5GiB) ===

nginx / baseline-h2 / 1024c (p=1, r=0, cpu=unlimited)
  Best: 3214007 req/s (CPU: 6897.8%, Mem: 3.6GiB) ===

nginx / static-h2 / 256c (p=1, r=0, cpu=unlimited)
  Best: 1497400 req/s (CPU: 6731.1%, Mem: 3.6GiB) ===

nginx / static-h2 / 1024c (p=1, r=0, cpu=unlimited)
  Best: 1832383 req/s (CPU: 5729.9%, Mem: 4.4GiB) ===

nginx / baseline-h3 / 256c (p=32, r=0, cpu=unlimited)
  Best: 75722 req/s (CPU: 320.6%, Mem: 3.8GiB) ===

nginx / baseline-h3 / 512c (p=32, r=0, cpu=unlimited)
  Best: 84782 req/s (CPU: 530.0%, Mem: 4.0GiB) ===

nginx / static-h3 / 256c (p=32, r=0, cpu=unlimited)
  Best: 57866 req/s (CPU: 5887.9%, Mem: 3.9GiB) ===

nginx / static-h3 / 512c (p=32, r=0, cpu=unlimited)
  Best: 58315 req/s (CPU: 5865.8%, Mem: 4.3GiB) ===
Full log
    "0.11305903": 326017,
    "0.16884187500000003": 30589,
    "0.22462472000000003": 4826,
    "0.280407565": 1185,
    "0.33619041000000005": 342,
    "0.391973255": 119,
    "0.44775610000000005": 24,
    "0.5035389450000001": 10,
    "0.55932179": 2
  },
  "latencyPercentiles": {
    "p10": 0.014787613,
    "p25": 0.022287914,
    "p50": 0.033765411,
    "p75": 0.049875745,
    "p90": 0.070262595,
    "p95": 0.086573794,
    "p99": 0.130858848,
    "p99.9": 0.216394907,
    "p99.99": 0.319008873
  },
  "firstByteHistogram": {
    "0.001491035": 1,
    "0.04313120300000001": 1428880,
    "0.08477137100000001": 531023,
    "0.12641153900000002": 60246,
    "0.16805170700000002": 9514,
    "0.20969187500000003": 2214,
    "0.251332043": 739,
    "0.292972211": 290,
    "0.334612379": 123,
    "0.37625254700000005": 30,
    "0.417892715": 14
  },
  "firstBytePercentiles": {
    "p10": 0.014078143,
    "p25": 0.021160881,
    "p50": 0.03190842,
    "p75": 0.046596086,
    "p90": 0.064440951,
    "p95": 0.078056516,
    "p99": 0.114374143,
    "p99.9": 0.186446351,
    "p99.99": 0.288005759
  },
  "rps": {
    "mean": 405966.65456480463,
    "stddev": 72137.5337705129,
    "max": 568976.5273429295,
    "min": 22.195762899888855,
    "percentiles": {
      "p10": 333177.16383114306,
      "p25": 393626.6690621049,
      "p50": 414166.49493096623,
      "p75": 432569.56727034756,
      "p90": 471821.8925358332,
      "p95": 511029.13706294255,
      "p99": 551278.0058378289,
      "p99.9": 568976.5273429295,
      "p99.99": 568976.5273429295
    }
  },
  "details": {
    "DNSDialup": {
      "average": 0.02672930802183239,
      "fastest": 0.001937652,
      "slowest": 0.091564481
    },
    "DNSLookup": {
      "average": 0.00001406193788568409,
      "fastest": 2.144e-6,
      "slowest": 0.000123862
    },
    "firstByte": {
      "average": 0.036713848061916535,
      "fastest": 0.001491035,
      "slowest": 0.417892715
    }
  },
  "statusCodeDistribution": {
    "200": 2033074
  },
  "errorDistribution": {
    "aborted due to deadline": 11826
  }
}
  CPU: 6054.8% | Mem: 4.3GiB

[run 3/3]
{
  "summary": {
    "successRate": 1.0,
    "total": 35.074638363,
    "slowest": 0.59890217,
    "fastest": 0.001768041,
    "average": 0.039476383784035354,
    "requestsPerSec": 58315.32684190601,
    "totalData": 32977485807,
    "sizePerRequest": 16212,
    "sizePerSec": 940208861.6197318
  },
  "responseTimeHistogram": {
    "0.001768041": 1,
    "0.0614814539": 1731302,
    "0.1211948668": 272740,
    "0.1809082797": 24652,
    "0.2406216926": 4049,
    "0.3003351055": 920,
    "0.3600485184": 248,
    "0.4197619313": 107,
    "0.4794753442": 29,
    "0.5391887571": 8,
    "0.59890217": 1
  },
  "latencyPercentiles": {
    "p10": 0.014654778,
    "p25": 0.021961739,
    "p50": 0.033427904,
    "p75": 0.04968926,
    "p90": 0.07062896,
    "p95": 0.087389862,
    "p99": 0.133740793,
    "p99.9": 0.220767489,
    "p99.99": 0.339958536
  },
  "firstByteHistogram": {
    "0.000907324": 1,
    "0.04541567590000001": 1499707,
    "0.08992402780000001": 473883,
    "0.1344323797": 49294,
    "0.1789407316": 8256,
    "0.22344908350000003": 2002,
    "0.2679574354": 550,
    "0.3124657873": 191,
    "0.35697413920000004": 94,
    "0.40148249110000006": 60,
    "0.4459908430000001": 19
  },
  "firstBytePercentiles": {
    "p10": 0.013944382,
    "p25": 0.020834895,
    "p50": 0.031568323,
    "p75": 0.046397715,
    "p90": 0.064766398,
    "p95": 0.078786541,
    "p99": 0.116630259,
    "p99.9": 0.192478387,
    "p99.99": 0.303084519
  },
  "rps": {
    "mean": 407808.9664434528,
    "stddev": 70076.87184123379,
    "max": 587931.3367402427,
    "min": 15.103598071264486,
    "percentiles": {
      "p10": 340824.3668114547,
      "p25": 392275.12068561604,
      "p50": 414686.75589169626,
      "p75": 436726.51967275376,
      "p90": 476878.92346183467,
      "p95": 505322.84737569554,
      "p99": 555317.5607276037,
      "p99.9": 587931.3367402427,
      "p99.99": 587931.3367402427
    }
  },
  "details": {
    "DNSDialup": {
      "average": 0.03349924343685908,
      "fastest": 0.002361429,
      "slowest": 0.101919372
    },
    "DNSLookup": {
      "average": 0.000013466167113311168,
      "fastest": 2.675e-6,
      "slowest": 0.000149298
    },
    "firstByte": {
      "average": 0.03663855484623537,
      "fastest": 0.000907324,
      "slowest": 0.445990843
    }
  },
  "statusCodeDistribution": {
    "200": 2034057
  },
  "errorDistribution": {
    "aborted due to deadline": 11332
  }
}
  CPU: 5865.8% | Mem: 4.3GiB

=== Best: 58315 req/s (CPU: 5865.8%, Mem: 4.3GiB) ===
[dry-run] Results not saved (use --save to persist)
httparena-bench-nginx
httparena-bench-nginx
[skip] nginx does not subscribe to unary-grpc
[skip] nginx does not subscribe to unary-grpc-tls
[skip] nginx does not subscribe to echo-ws
[restore] Restoring CPU governor to performance...

@joanhey
Copy link
Copy Markdown
Contributor Author

joanhey commented Mar 24, 2026

I'll add a PR with ngx-php.
But now I'm familiarizing with the bench, and both need to use the same nginx version.

Later will come Workerman.

@MDA2AV
Copy link
Copy Markdown
Owner

MDA2AV commented Mar 24, 2026

I'll merge this.

@BennyFranciscus open another PR to fix the validation issue. h2o has same problem.

@MDA2AV MDA2AV merged commit 7417d7a into MDA2AV:main Mar 24, 2026
1 of 2 checks passed
@joanhey joanhey deleted the nginx-1.28.3 branch March 24, 2026 23:14
@MDA2AV
Copy link
Copy Markdown
Owner

MDA2AV commented Mar 24, 2026

I'll add a PR with ngx-php. But now I'm familiarizing with the bench, and both need to use the same nginx version.

Later will come Workerman.

To add a new framework you can either check how to do it manually @ the website Knowledge Base or open an issue and tag @BennyFranciscus - this is an AI agent with instructions how to add new frameworks and then you only need to polish what he creates by giving him instructions on the PR he creates

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants