lablup / lablup/backend.ai

Advertise TUS Expiration extension and emit Upload-Expires header (spec-compliance follow-up)

Open
#11,910 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
670
Forks
183
Avg merge
15h 13m
Merged PRs (30d)
368

Description

## Background

The storage-proxy TUS implementation after the BA-3974 fix stack advertises only `Tus-Resumable: 1.0.0` plus `Tus-Extension: checksum` (added by BA-6158). However, it already implements server-side behavior that maps to the TUS Expiration extension — Valkey-backed session metadata expires by a 24h TTL refreshed on every successful PATCH — but does not advertise the extension and does not emit the standard `Upload-Expires` response header that a spec-compliant client expects.

This issue tracks closing that spec-compliance gap. The race-correctness scope of BA-3974 is unaffected; this is a follow-up focused on protocol conformance and client interoperability.

## Current state (after BA-3974 stack)

- Core (HEAD + PATCH): implemented, advertised
- Checksum: implemented (sha256), advertised via BA-6158
- Expiration: behavior present (Valkey TTL = 24h, sliding via every PATCH), but NOT advertised and no Upload-Expires header
- Creation: partially supported via non-standard POST /folder/file/upload (manager API), not advertised
- Termination: not implemented, not advertised
- Concatenation: not implemented, not advertised

## Work needed (minimum scope to close this issue)

### 1. Advertise the Expiration extension

The Valkey-backed session TTL already implements exactly what the Expiration extension describes. Advertise it.

- In `tus_options`: set `Tus-Extension: checksum,expiration`
- Add `Upload-Expires` to `Access-Control-Allow-Headers` and `Access-Control-Expose-Headers`

### 2. Emit Upload-Expires response header

PATCH and HEAD responses must include `Upload-Expires: `. Simplest source: `now + REDIS_TUS_TTL` since the TTL is refreshed on every successful PATCH. For HEAD, can either query Valkey `TTL` for the exact remaining seconds or emit `now + REDIS_TUS_TTL` as a conservative upper bound.

### 3. (Optional) 410 Gone for expired sessions

Currently a request hitting an expired session returns 404 `TusSessionNotFoundError`. The spec recommends 410 Gone for expired sessions. Distinguishing 'never created' from 'expired' requires a tombstone marker in Valkey with longer TTL or inference from the JWT issue time. Low ROI; can be deferred to a separate follow-up.

## Out of scope (separate follow-ups)

- 410 Gone on expired sessions (item 3 above).
- Adding a standard Creation extension endpoint (currently uses a non-standard manager API).
- Termination extension (DELETE).
- Concatenation extension (partial/final, parallel uploads).

## Acceptance criteria

- `Tus-Extension` header advertises `expiration` in addition to whatever is already advertised.
- PATCH and HEAD responses include a valid `Upload-Expires` HTTP-date header reflecting the Valkey TTL.
- `Access-Control-Allow-Headers` and `Access-Control-Expose-Headers` list `Upload-Expires`.
- Unit tests verify the header values.

## References

- TUS 1.0.0 spec: [https://tus.io/protocols/resumable-upload](https://tus.io/protocols/resumable-upload)
- Parent epic: BA-6153
- Related fix stack: BA-6155 / BA-6156 / BA-6157 / BA-6158 / BA-6159

JIRA Issue: BA-6272

Contributor guide

Open the contributing guide

Research direction

Start at `tus_options`, the PATCH and HEAD handlers, and `REDIS_TUS_TTL`; inspect the existing unit tests for TUS responses. Done means the expiration extension is advertised, PATCH and HEAD emit valid `Upload-Expires` dates, CORS headers expose it, and unit tests verify the header values.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, redis
Domain
api, backend
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.