What: dav.get sends Accept-Encoding: identity, and unpacks a body a server
gzips anyway (Go only unpacks what it asked gzip for itself).
Why: Go's client asks for gzip on every GET. InfiniCLOUD's (TeraCloud's)
WebDAV is Apache mod_dav_fs, whose PUT answers with no ETag (mod_dav.c's
dav_created: "### insert an ETag header?"), so the sync after the first
reads the file in full and pushes over the ETag that read gave. Apache's
mod_deflate (DeflateAlterETag AddSuffix, the default) gives the gzip copy
"<etag>-gzip", which no If-Match on the file matches: every write after the
first was 412, the retry read the same -gzip tag, and the state left the
local change pending, so every sync after failed. A read asked for as it
is gets the file's own ETag. nginx-style proxies that weaken the ETag
(W/"...") on gzip are covered by the same change.
TeraCloud behaviour assumed: seen without an account on 2026-10-09 against
https://domi.teracloud.jp: OPTIONS /dav/ says Server: Apache and
DAV: <http://apache.org/dav/propset/fs/1>; GET / with Accept-Encoding: gzip
gives ETag "fb-5d88268abcf08-gzip" + Content-Encoding: gzip, without it
"fb-5d88268abcf08"; GET with If-Match the -gzip tag is 412, with the plain
tag 200. Not seen: that mod_deflate compresses files under /dav/ (needs an
account). The fake (apacheDAV in teracloud_test.go) does: no ETag on PUT,
gzip + "-gzip" ETag on a GET that accepts gzip, If-Match strong against
the file's own ETag.
Real conflict detection is unchanged: If-Match is still sent with the
version read; TestSyncTeraCloudStillSeesOtherWrites lands another
computer's write between a's read and write on the same fake and checks
the 412, the merge over it, and b's file kept aside.
Run:
- new tests fail on the old code: without identity,
TestSyncTeraCloudGzipETag "sync 2 after the first: the file on the
server changed meanwhile (2 writes refused, 2 reads sent gzip)"; with
If-Match dropped, TestSyncTeraCloudStillSeesOtherWrites "write over a
replaced version: <nil>, want errChanged"; without the unpack,
TestDAVGetGzipAnyway reads gzip bytes. All pass restored.
- sandbox HOME, pinned caches: go test -race -tags nogui ./internal/davsync/
./internal/gui/ . ok; -race -count=5 on the davsync sync/conditional/
short-write/Nutstore tests ok
- gofmt -l clean; go vet (darwin, darwin nogui, linux nogui, windows) of
internal/davsync; go build darwin, linux nogui, windows
Not run: a real TeraCloud account.