Skip to content

Comments

Fix bug with metrics/tracing middleware and HEAD responses#777

Merged
adam-fowler merged 1 commit intomainfrom
response-content-length-bug
Jan 30, 2026
Merged

Fix bug with metrics/tracing middleware and HEAD responses#777
adam-fowler merged 1 commit intomainfrom
response-content-length-bug

Conversation

@adam-fowler
Copy link
Member

Previously when you set the body on a response if that body had a known length it would always fix the content-length header in a didSet call. The metrics and tracing middleware do this for every response so they can alter the response body writer to update timers and spans. This breaks responses from HEAD requests as the body is set on them and it resets the content-length.

This fix changes the didSet to a set and compares the old response body with the new one. If they have the same size then we don't update the content-length header.

  • If you have a response from a head request you can only set the response body to be a body with length zero, so the response body length will not change as it is passed down and any content-length header with be fixed.
  • All other responses the content-length header should be consistent with the response body length so will be changed at the relevant times.

This PR also fixes an issue where if you had a response with a content-length header and you later set the response body to be of an indeterminate length (perhaps you passed the response through a streaming compression middleware) it should clear the content-length header but it wasn't

@adam-fowler adam-fowler requested a review from Joannis as a code owner January 30, 2026 08:21
@codecov
Copy link

codecov bot commented Jan 30, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 83.05%. Comparing base (e0818ae) to head (d066496).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #777      +/-   ##
==========================================
- Coverage   83.08%   83.05%   -0.03%     
==========================================
  Files         124      124              
  Lines        6178     6180       +2     
==========================================
  Hits         5133     5133              
- Misses       1045     1047       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions
Copy link

✅ Pull request no significant performance differences ✅

Summary

New baseline 'pull_request' is WITHIN the 'main' baseline thresholds.

Full Benchmark Comparison

Comparing results between 'main' and 'pull_request'

Host 'a14422710706' with 4 'x86_64' processors with 15 GB memory, running:
#18~24.04.1-Ubuntu SMP Sat Jun 28 04:46:03 UTC 2025

HummingbirdBenchmarks

HTTP:Cookie:Decode metrics

Malloc (total): results within specified thresholds, fold down for details.

Malloc (total) * p0 p25 p50 p75 p90 p99 p100 Samples
main 4 4 4 4 4 4 4 336
pull_request 4 4 4 4 4 4 4 333
Δ 0 0 0 0 0 0 0 -3
Improvement % 0 0 0 0 0 0 0 -3

HTTP:URI:Decode metrics

Malloc (total): results within specified thresholds, fold down for details.

Malloc (total) * p0 p25 p50 p75 p90 p99 p100 Samples
main 1 1 1 1 1 1 1 3418
pull_request 1 1 1 1 1 1 1 3372
Δ 0 0 0 0 0 0 0 -46
Improvement % 0 0 0 0 0 0 0 -46

HTTP:URI:QueryParameters metrics

Malloc (total): results within specified thresholds, fold down for details.

Malloc (total) * p0 p25 p50 p75 p90 p99 p100 Samples
main 7 7 7 7 7 7 7 885
pull_request 7 7 7 7 7 7 7 883
Δ 0 0 0 0 0 0 0 -2
Improvement % 0 0 0 0 0 0 0 -2

Router:Echo metrics

Malloc (total): results within specified thresholds, fold down for details.

Malloc (total) * p0 p25 p50 p75 p90 p99 p100 Samples
main 768 768 768 768 768 768 768 1092
pull_request 768 768 768 768 768 768 768 1049
Δ 0 0 0 0 0 0 0 -43
Improvement % 0 0 0 0 0 0 0 -43

Router:GET metrics

Malloc (total): results within specified thresholds, fold down for details.

Malloc (total) * p0 p25 p50 p75 p90 p99 p100 Samples
main 468 468 468 468 468 468 468 2909
pull_request 468 468 468 468 468 468 468 2906
Δ 0 0 0 0 0 0 0 -3
Improvement % 0 0 0 0 0 0 0 -3

Router:Middleware metrics

Malloc (total): results within specified thresholds, fold down for details.

Malloc (total) * p0 p25 p50 p75 p90 p99 p100 Samples
main 373 373 373 373 373 373 373 2710
pull_request 373 373 373 373 373 373 373 2612
Δ 0 0 0 0 0 0 0 -98
Improvement % 0 0 0 0 0 0 0 -98

Router:PUT metrics

Malloc (total): results within specified thresholds, fold down for details.

Malloc (total) * p0 p25 p50 p75 p90 p99 p100 Samples
main 1270 1270 1270 1270 1270 1270 1270 821
pull_request 1270 1270 1270 1270 1270 1270 1270 841
Δ 0 0 0 0 0 0 0 20
Improvement % 0 0 0 0 0 0 0 20

Router:Parameters metrics

Malloc (total): results within specified thresholds, fold down for details.

Malloc (total) * p0 p25 p50 p75 p90 p99 p100 Samples
main 668 668 668 668 668 668 668 2430
pull_request 668 668 668 668 668 668 668 2256
Δ 0 0 0 0 0 0 0 -174
Improvement % 0 0 0 0 0 0 0 -174

RouterBuilder:Middleware metrics

Malloc (total): results within specified thresholds, fold down for details.

Malloc (total) * p0 p25 p50 p75 p90 p99 p100 Samples
main 372 372 372 372 372 372 372 2712
pull_request 372 372 372 372 372 372 372 2655
Δ 0 0 0 0 0 0 0 -57
Improvement % 0 0 0 0 0 0 0 -57

TrieRouter:LongPaths metrics

Malloc (total): results within specified thresholds, fold down for details.

Malloc (total) * p0 p25 p50 p75 p90 p99 p100 Samples
main 2 2 2 2 2 2 2 231
pull_request 2 2 2 2 2 2 2 232
Δ 0 0 0 0 0 0 0 1
Improvement % 0 0 0 0 0 0 0 1

TrieRouter:Parameters metrics

Malloc (total): results within specified thresholds, fold down for details.

Malloc (total) * p0 p25 p50 p75 p90 p99 p100 Samples
main 7 7 7 7 7 7 7 186
pull_request 7 7 7 7 7 7 7 188
Δ 0 0 0 0 0 0 0 2
Improvement % 0 0 0 0 0 0 0 2

TrieRouter:Routing metrics

Malloc (total): results within specified thresholds, fold down for details.

Malloc (total) * p0 p25 p50 p75 p90 p99 p100 Samples
main 2 2 2 2 2 2 2 244
pull_request 2 2 2 2 2 2 2 247
Δ 0 0 0 0 0 0 0 3
Improvement % 0 0 0 0 0 0 0 3

URLEncodedForm:Decode metrics

Malloc (total): results within specified thresholds, fold down for details.

Malloc (total) * p0 p25 p50 p75 p90 p99 p100 Samples
main 29 29 29 29 29 29 29 54
pull_request 29 29 29 29 29 29 29 53
Δ 0 0 0 0 0 0 0 -1
Improvement % 0 0 0 0 0 0 0 -1

URLEncodedForm:Encode metrics

Malloc (total): results within specified thresholds, fold down for details.

Malloc (total) * p0 p25 p50 p75 p90 p99 p100 Samples
main 24 24 24 24 24 24 24 209
pull_request 24 24 24 24 24 24 24 208
Δ 0 0 0 0 0 0 0 -1
Improvement % 0 0 0 0 0 0 0 -1

@adam-fowler adam-fowler merged commit 960fd08 into main Jan 30, 2026
8 of 9 checks passed
@adam-fowler adam-fowler deleted the response-content-length-bug branch January 30, 2026 09:19
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.

2 participants