mirror of
https://github.com/johannesjo/super-productivity.git
synced 2026-07-24 00:17:23 +00:00
- Add WebdavServerCapabilities interface to detect server features - Implement detectServerCapabilities() method in WebdavApi - Support detection of ETags, Last-Modified, If headers, and locking - Add comprehensive test coverage for capability detection - Cache detected capabilities to avoid repeated requests - Support configuration-based capability overrides - Add documentation for WebDAV conditional headers analysis - Maintain 100% backward compatibility with existing ETag behavior This is Phase 2 of WebDAV non-ETag server support implementation. All existing 180 tests continue to pass.
5.2 KiB
5.2 KiB
WebDAV Conditional Headers Analysis
Executive Summary
Analysis of ETag vs Last-Modified conditional header mappings for WebDAV implementation, including verification against RFC 7232 (HTTP Conditional Requests) and RFC 4918 (WebDAV specification).
Key Finding: The proposed mapping contains a critical conceptual error for resource creation operations.
Original Proposed Mapping (INCORRECT)
| ETag Operation | Current Header | Last-Modified Equivalent | |
|---|---|---|---|
| Create new file | If-None-Match: * |
If-None-Match: * |
❌ |
| Update existing | If-Match: <etag> |
If-Unmodified-Since: <timestamp> |
✅ |
| Check for changes | If-None-Match: <etag> |
If-Modified-Since: <timestamp> |
✅ |
| Success response | ETag: <etag> |
Last-Modified: <timestamp> |
✅ |
| Not modified | 304 + ETag |
304 + Last-Modified |
✅ |
| Conflict | 412 (ETag mismatch) |
412 (timestamp mismatch) |
✅ |
Corrected Analysis
Critical Error Identified
The "Create new file" row contains a fundamental conceptual error:
If-None-Match: *is an ETag-based header, not a Last-Modified equivalent- Last-Modified headers cannot provide safe resource creation functionality
Corrected Mapping
| ETag Operation | ETag Header | Last-Modified Equivalent |
|---|---|---|
| Create new file | If-None-Match: * |
❌ NO EQUIVALENT (concept doesn't apply) |
| Update existing | If-Match: <etag> |
If-Unmodified-Since: <timestamp> |
| Check for changes | If-None-Match: <etag> |
If-Modified-Since: <timestamp> |
| Success response | ETag: <etag> |
Last-Modified: <timestamp> |
| Not modified | 304 + ETag |
304 + Last-Modified |
| Conflict | 412 (ETag mismatch) |
412 (timestamp mismatch) |
RFC Analysis
RFC 7232 (HTTP Conditional Requests)
-
Header Evaluation Order:
- If-Match (if present)
- If-Unmodified-Since (if If-Match not present)
- If-None-Match
- If-Modified-Since (only for GET/HEAD, if If-None-Match not present)
-
Validator Precedence:
- ETags take precedence over Last-Modified when both present
- Strong ETags preferred over weak ETags
-
Method Restrictions:
If-Modified-SinceandIf-Unmodified-Sinceonly valid for GET/HEAD requestsIf-None-MatchandIf-Matchvalid for all HTTP methods
RFC 4918 (WebDAV Specification)
-
Security Requirements:
- "The server MUST do authorization checks before checking any HTTP conditional header"
-
ETag Importance:
- "Correct use of ETags is even more important in a distributed authoring environment"
- "ETags are necessary along with locks to avoid the lost-update problem"
- "Strong ETags are much more useful for authoring use cases than weak ETags"
-
Namespace Operations:
- For COPY/MOVE operations, servers must ensure ETag values are not reused
- ETag semantics must be preserved across namespace operations
Current WebDAV Implementation Verification
The current implementation in webdav-api.ts:197-212 correctly follows RFC standards:
private _createConditionalHeaders(
isOverwrite?: boolean,
expectedEtag?: string | null,
): Record<string, string> {
const headers: Record<string, string> = {};
if (!isOverwrite) {
if (expectedEtag) {
headers['If-Match'] = expectedEtag; // Update existing
} else {
headers['If-None-Match'] = '*'; // Create new
}
} else if (expectedEtag) {
headers['If-Match'] = expectedEtag; // Force overwrite
}
return headers;
}
Why Last-Modified Cannot Handle Resource Creation
-
Existence vs. Temporal Comparison:
If-None-Match: *checks for resource existence- Last-Modified headers only handle temporal comparisons of existing resources
-
Method Limitations:
- Last-Modified conditionals (If-Modified-Since/If-Unmodified-Since) are restricted to GET/HEAD
- Resource creation typically uses PUT/POST which cannot use these headers
-
Conceptual Mismatch:
- You cannot compare timestamps for non-existent resources
- Resource creation requires existence checking, not temporal validation
Recommendations
- For ETag-capable servers: Use
If-None-Match: *for safe resource creation - For Last-Modified-only servers: Research alternative approaches (see separate analysis)
- Implementation priority: ETags are strongly preferred for WebDAV authoring scenarios
- Fallback strategy: Implement alternative creation safety mechanisms for Last-Modified-only environments
References
- RFC 7232: Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests
- RFC 4918: HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)
- Current WebDAV implementation:
src/app/pfapi/api/sync/providers/webdav/webdav-api.ts