Skip to content

Commit 7e813e2

Browse files
committed
Expose X-Modified-At via CORS for module reads
ModuleRoute already sets the header on GET responses (and ModuleFlowTest pins its presence). Cross-origin browsers can't read it without Access-Control-Expose-Headers, so octi-web's cross-origin fetch saw it as null. octi-web's multi-connector merge orders peer data by newest X-Modified-At per (deviceId, moduleId). Without this exposure, the merge falls back to deterministic-tiebreak in production while still working in dev (where same-origin or localhost relaxes the restriction). Sister web change: d4rken-org/octi-web#21.
1 parent 9d29fc2 commit 7e813e2

2 files changed

Lines changed: 8 additions & 0 deletions

File tree

src/main/kotlin/eu/darken/octi/server/Server.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,13 @@ class Server @Inject constructor(
100100
allowHeader("Upload-Offset")
101101
exposeHeader(HttpHeaders.ETag)
102102
exposeHeader(HttpHeaders.LastModified)
103+
// ModuleRoute sets X-Modified-At with the payload's server-side
104+
// modification timestamp. Browsers can only read non-safelisted
105+
// response headers cross-origin when they're listed here.
106+
// octi-web's multi-connector merge uses it to order data when the
107+
// same peer device is reachable via two connectors — newest
108+
// X-Modified-At per (deviceId, moduleId) wins.
109+
exposeHeader("X-Modified-At")
103110
exposeHeader(HttpHeaders.ContentRange)
104111
exposeHeader(HttpHeaders.AcceptRanges)
105112
exposeHeader(HttpHeaders.RetryAfter)

src/test/kotlin/eu/darken/octi/server/common/CorsFlowTest.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ class CorsFlowTest : TestRunner() {
128128
"upload-expires",
129129
"upload-state",
130130
"x-blob-id",
131+
"x-modified-at",
131132
)
132133
withClue("Access-Control-Expose-Headers='$exposed' missing: ${expected.filterNot { it in exposed }}") {
133134
expected.forEach { (it in exposed) shouldBe true }

0 commit comments

Comments
 (0)