zhanghai / zhanghai/MaterialFiles

Feature Request: Preserve file modification time on WebDAV upload via `X-OC-MTime` header

Open
#1,569 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Kotlin
Stars
9k
Forks
736
PR merge metrics
No merged PRs in 30d

Description

The issue description is generated by Claude and reviewed/modified by me

Summary

When uploading files to a WebDAV server, Material Files does not preserve the original file modification time (mtime). The server receives PROPFIND and PUT requests, but no mtime-setting mechanism is used. This can be addressed by sending the X-OC-MTime request header alongside PUT.

Why PROPPATCH on getlastmodified does not work

This is a plausible approach. However, RFC 4918 §15.7 specifies that {DAV:}getlastmodified "SHOULD be protected because some clients may rely on the value for appropriate caching behavior, or on the value of the Last-Modified header to which this property is linked." (RFC 4918 §15.7)

In practice, most WebDAV servers implement this recommendation and reject PROPPATCH on getlastmodified with 403 Forbidden. Apache mod_dav, sabre/dav (sabre/dav issue #1277), and others all protect this property by default.

The X-OC-MTime header

Specification

The X-OC-MTime header is a WebDAV extension for setting resource modification time during PUT. It is documented in the ownCloud developer API reference:

Request header: X-OC-Mtime: <unix-timestamp> — an integer Unix timestamp (seconds since epoch) sent with a PUT request.
Response header: X-OC-Mtime: accepted — returned by the server if the mtime was successfully applied.

(ownCloud WebDAV API reference — Upload File)

Example from the ownCloud documentation:

PUT /dav/spaces/.../test.txt HTTP/1.1
X-OC-Mtime: 1692369418
...

HTTP/1.1 204 No Content
X-Oc-Mtime: accepted
Last-Modified: Fri, 18 Aug 2023 14:36:58 +0000

Server support

The header is now supported by a range of WebDAV servers:

Server Source
ownCloud ownCloud WebDAV API reference
Nextcloud Nextcloud WebDAV API
OpenCloud OpenCloud WebDAV API docs
Apache mod_dav (trunk/2.5) New DavHonorMtimeHeader directive — commit 2d92bae, mod_dav docs
rclone serve webdav rclone WebDAV docs
Fastmail Files rclone WebDAV docs for Fastmail Files
SFTPGo SFTPGo commit
Client support

Existing WebDAV clients that send X-OC-MTime include the Nextcloud desktop client, rclone (when vendor is set to owncloud, nextcloud, or fastmail), and Cyberduck / Mountain Duck.

Proposed behavior

When uploading a file to a WebDAV server, Material Files should include the X-OC-MTime header in the PUT request with the source file's modification time as an integer Unix timestamp in seconds:

X-OC-MTime: 1718000000

If the server responds with X-OC-MTime: accepted, the mtime was successfully applied. If the header is absent from the response, it can be silently ignored. Servers that do not recognize the header will ignore it, so sending it unconditionally is safe.

Scope

This request covers PUT only. MOVE and COPY operations are out of scope, as X-OC-MTime is not defined for those methods in existing implementations either.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by locating the WebDAV upload entry point and the code that constructs PUT requests, then trace how the source file modification time is obtained. Add the X-OC-MTime request value for PUT uploads only and verify that existing uploads still work with servers that ignore the header.

Written by the indexing model from the issue text.

Assessment

Tech stack
kotlin
Domain
mobile, networking
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.