Optimize response header handling for HTTP/2 (P2)#48463
Optimize response header handling for HTTP/2 (P2)#48463xinlian12 wants to merge 8 commits intoAzure:mainfrom
Conversation
beb48da to
8ba91eb
Compare
Option A: Skip redundant toLowerCase() for HTTP/2 headers - Add keysAlreadyLowerCase flag to Cosmos HttpHeaders - When true, set() skips the toLowerCase() call on header names - Detect HTTP/2 in ReactorNettyHttpResponse.headers() via version check - Saves ~15-25 toLowerCase calls + String allocations per response - HTTP/2 headers are guaranteed lowercase per RFC 7540 §8.1.2 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
8ba91eb to
63c1521
Compare
|
@sdkReviewAgent |
|
sdkReviewAgent | Status: ⏳ Queued Review requested by @xinlian12. I'll start shortly. |
|
sdkReviewAgent | Status: 🔍 Reviewing I'm reviewing this PR now. I'll post my findings as comments when done. |
| public HttpHeaders(int size, boolean isHttp2Headers) { | ||
| this.headers = new HashMap<>(size); | ||
| this.isHttp2Headers = isHttp2Headers; | ||
| } | ||
|
|
There was a problem hiding this comment.
This constructor and the conditional toLowerCase() skip in set() are added, but ReactorNettyClient.java:412 — the sole production site where HTTP response headers are constructed — still calls:
new HttpHeaders(reactorNettyResponse.responseHeaders().size())which defaults isHttp2Headers to false. Grepping for the new constructor across sdk/cosmos/ returns zero production matches.
This means the PR's claimed saving of ~15-25 toLowerCase() calls per HTTP/2 response is not realized. The flag and constructor are dead code.
Suggestion: Either wire the flag into ReactorNettyHttpResponse.headers() in this PR (e.g. checking reactorNettyResponse.version() for HTTP/2), or defer this infrastructure to the PR that includes the wiring. Shipping dead infrastructure creates maintenance burden without delivering value.
Powered by AI
|
@sdkReviewBot |
|
@sdkReviewAgent |
|
sdkReviewAgent | Status: ⏳ Queued Review requested by @xinlian12. I'll start shortly. |
|
sdkReviewAgent | Status: 🔍 Reviewing I'm reviewing this PR now. I'll post my findings as comments when done. |
| */ | ||
| public class HttpHeaders implements Iterable<HttpHeader>, JsonSerializable { | ||
| private Map<String, HttpHeader> headers; | ||
| private final boolean isHttp2Headers; |
There was a problem hiding this comment.
What this PR does: Two changes: (1) refactors Http2ResponseHeaderCleanerHandler from O(n) forEach to O(1) AsciiString lookup — clean and correct; (2) adds this isHttp2Headers flag to skip toLowerCase() in set() for HTTP/2 responses.
Handler changes are likely already merged from PR #48455 (P1). The branch may need rebasing — after rebase, those handler changes should disappear from the diff.
Option C is described but not implemented. The PR description mentions "Eliminate toLowerCaseMap() as redundant", "revert RxGatewayStoreModel to toMap()", and "fix direct-connect mode (ResponseUtils, HttpClientUtils)". None of these changes are in the diff. Consider updating the description to reflect only the actual changes.
Architecture note: This flag introduces transport-protocol awareness into HttpHeaders, which is otherwise a generic data container. The existing pattern isolates HTTP/2 concerns in pipeline handlers, not in data structures that flow through business logic. If the flag stays, document that it must only be set by the reactor-netty response path.
Powered by AI
| */ | ||
| public HttpHeaders set(String name, String value) { | ||
| final String headerKey = name.toLowerCase(Locale.ROOT); | ||
| final String headerKey = isHttp2Headers ? name : name.toLowerCase(Locale.ROOT); |
There was a problem hiding this comment.
When isHttp2Headers=true, set() stores the map key without lowercasing, but getHeader() (line 102) always lowercases the lookup key:
// In set():
final String headerKey = isHttp2Headers ? name : name.toLowerCase(Locale.ROOT);
// In getHeader():
final String headerKey = headerName.toLowerCase(Locale.ROOT); // always lowercasesIf anyone calls set("Content-Type", value) on an isHttp2Headers=true instance, the header is stored under key "Content-Type" but value("Content-Type") looks up "content-type" → silent miss. The header appears set but is unretrievable.
This is safe today because HTTP/2 guarantees lowercase and the constructor has no production callers. But when it gets wired up, a future developer could easily misuse it. Consider adding a defensive assertion:
assert !isHttp2Headers || name.equals(name.toLowerCase(Locale.ROOT))
: "isHttp2Headers requires lowercase names, got: " + name;Or, make getHeader() also honor the flag to keep the two paths symmetric.
Powered by AI
| public void keysAlreadyLowerCaseSkipsNormalization() { | ||
| String headerName = "etag"; | ||
| String headerValue = "456"; | ||
|
|
||
| // Simulates HTTP/2 where header names are already lowercase | ||
| HttpHeaders headers = new HttpHeaders(4, true); | ||
| headers.set(headerName, headerValue); | ||
|
|
||
| Map<String, String> map = headers.toMap(); | ||
| assertThat(map.get(headerName)).isEqualTo(headerValue); |
There was a problem hiding this comment.
Two gaps:
-
The test uses
"etag"(already lowercase), so"etag".toLowerCase()=="etag"— the result is identical whether or not the flag istrue. Changingnew HttpHeaders(4, true)tonew HttpHeaders(4)would still pass. The test proves correctness but not that the optimization path is actually different. -
value()lookup is not tested withisHttp2Headers=true. The primary consumer API (value()/getHeader()) is uncovered for this flag. Add assertions like:
assertThat(headers.value("etag")).isEqualTo(headerValue);
assertThat(headers.value("ETag")).isEqualTo(headerValue); // verifies getHeader() lowercases lookupThis would also serve as a regression guard against the set()/getHeader() asymmetry noted in HttpHeaders.java.
Powered by AI
Imports the shared review pipeline from xinlian12/sdk-auto-pr-review. Triggers on PR open/push/ready_for_review. Posts inline review comments with severity tags and AI disclaimer. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add sdkReviewAgent agentic workflow for automated PR review
|
@sdkReviewAgent |
|
sdkReviewAgent | Status: ⏳ Queued Review requested by @xinlian12. I'll start shortly. |
|
sdkReviewAgent | Status: 🔍 Reviewing I'm reviewing this PR now. I'll post my findings as comments when done. |
Option A: Skip redundant toLowerCase() for HTTP/2 headers
Option C: Eliminate toLowerCaseMap() as redundant
Description
Please add an informative description that covers that changes made by the pull request and link all relevant issues.
If an SDK is being regenerated based on a new swagger spec, a link to the pull request containing these swagger spec changes has been included above.
All SDK Contribution checklist:
General Guidelines and Best Practices
Testing Guidelines