Skip to content

fix: return ETag header on GET for config resource endpoints#1603

Open
KirylKurnosenka wants to merge 8 commits into
developmentfrom
fix/return_etag_for_config_resources
Open

fix: return ETag header on GET for config resource endpoints#1603
KirylKurnosenka wants to merge 8 commits into
developmentfrom
fix/return_etag_for_config_resources

Conversation

@KirylKurnosenka

@KirylKurnosenka KirylKurnosenka commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Applicable issues

  • fixes #

Description of changes

GET v1/applications/public/{name} (handled by ResourceController) correctly returns an ETag response header and enforces RFC 7232 conditional headers. However, GET v1/roles/platform/{name}, GET v1/models/public/{name}, and other config resource endpoints handled by ConfigResourceController had two issues:

  1. Missing ETag on 200 responsesConfigResourceController already fetched blob metadata (including the ETag) to support If-None-Match / 304 conditional GET, but the fetched ETag was discarded and never added to the response header on the normal 200 path.

  2. If-Match silently ignored on GET — the evaluateConditionalGet method caught all HttpExceptions from EtagHeader.validate() and only surfaced the 304 case, silently swallowing If-Match failures. RFC 7232 §3.1 does not exempt GET from If-Match evaluation, so a mismatched If-Match header should return 412, consistent with ResourceController.

Fix:

  • evaluateConditionalGet now calls etag.validate() without a try-catch, letting HttpException (304 or 412) propagate through the Future failure chain to handleWriteError, exactly as ResourceController does.
  • Simplified the return type of evaluateConditionalGet from a GetResult record to Future<String> (the ETag or null), removing the now-unnecessary wrapper.
  • Both handleSingleGet and handleSchemaGet set the ETag response header on 200 OK when the entity has a blob-backed ETag.
  • Entities without a blob backing (file-sourced, invalid records) return 200 with no ETag header.

Tests (ConfigResourceConditionalHeaderTest):

  • testGet200IncludesEtagHeader — plain GET on a blob-backed model asserts ETag header is present on the 200 response.
  • testGet200OnStaleIfNoneMatch — asserts ETag is returned on 200 when the client sends a stale If-None-Match.
  • testGet200OnMatchingIfMatch — GET with a matching If-Match returns 200 with an ETag header.
  • testGet412OnStaleIfMatch — GET with a mismatched If-Match returns 412.

Checklist

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@ai-dial-actions

This comment has been minimized.

…ests

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@ai-dial-actions

This comment has been minimized.

@ai-dial-actions

This comment has been minimized.

@ai-dial-actions

This comment has been minimized.

astsiapanay
astsiapanay previously approved these changes Jun 11, 2026
Removed the try-catch in evaluateConditionalGet() that was silently
swallowing If-Match failures (412) on GET requests. RFC 7232 does not
exempt GET from If-Match evaluation; only If-None-Match has special
GET/HEAD semantics (304). Both 304 and 412 now propagate as HttpException
through the Future failure path to handleWriteError, consistent with how
ResourceController handles conditional headers. Also simplified GetResult
away — evaluateConditionalGet now returns Future<String> (the ETag or null).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@ai-dial-actions

This comment has been minimized.

@ai-dial-actions

This comment has been minimized.

@ai-dial-actions

This comment has been minimized.

@ai-dial-actions

Copy link
Copy Markdown
Contributor

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@KirylKurnosenka

KirylKurnosenka commented Jun 19, 2026

Copy link
Copy Markdown
Contributor Author

/deploy-review

GitHub actions run: 27817445939

Stage Status
deploy-review Failed ❌
matrix.application Skipped ➖

@KirylKurnosenka

KirylKurnosenka commented Jun 19, 2026

Copy link
Copy Markdown
Contributor Author

/deploy-review

GitHub actions run: 27818241376

Stage Status
deploy-review Success ✅
chat Success ✅

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