internal/service/webdav/README.md
Last Updated: March 7, 2026
internal/service/webdav contains the outbound WebDAV client used by PhotoPrism services and background workers. It wraps github.com/emersion/go-webdav with PhotoPrism-specific URL validation, control-operation timeouts, filesystem mapping, and error/logging behavior for remote uploads, downloads, and synchronization.
services-cidr before opening outbound connections.pkg/fs.FileInfo values.Client.Directories(dir, recursive, timeout) is the main entry point for remote folder discovery.
recursive=true, the client first performs a recursive PROPFIND using Depth: infinity through the upstream WebDAV library.PROPFIND requests using Depth: 1.This behavior exists because some providers and appliances accept Depth: 1 but reject Depth: infinity. The fallback keeps those servers usable for:
entity.Service.Directories(),internal/workers/sync_refresh.go.Available timeout settings for Service.AccTimeout and webdav.Timeout:
| Setting | Value | Effective Timeout |
|---|---|---|
| Default | "" | 60s |
| Medium | "medium" | 60s |
| Low | "low" | 30s |
| High | "high" | 120s |
| None | "none" | no timeout |
Timeout values map to total HTTP request timeouts for non-transfer WebDAV calls such as directory discovery, file listing, directory creation, and delete operations.Upload() and Download() intentionally bypass the service timeout so long-running file transfers are not aborted by a total request deadline.timeout=0 means "use the client's configured default timeout" (c.timeout), not "disable timeouts".MaxRequestDuration is used for long-running recursive directory discovery, including the Depth: 1 fallback.When a recursive PROPFIND fails, the client logs the failure and emits an informational message if it successfully switches to the iterative Depth: 1 fallback. Successful fallback logs include the number of follow-up PROPFIND requests and the elapsed traversal time so operators can diagnose depth-limited servers without reducing the user-facing API response to only "could not connect".
webdav.go — package comment, timeout constants, and shared logger.client.go — outbound WebDAV client wrapper and compatibility fallback.path.go — shared path normalization helpers.client_test.go — unit tests, including a local httptest WebDAV fixture for depth-limited servers.internal/entity/service.go — service-level directory discovery.internal/workers/sync_refresh.go — sync refresh that enumerates remote directories before file listing.scripts/dav-probe.sh — captures PROPFIND responses for troubleshooting remote server behavior.go test ./internal/service/webdav -run 'TestClient_Directories' -count=1go test ./internal/entity -run 'TestService_Directories' -count=1The local test server in client_test.go simulates both compliant servers and depth-1-only servers so the fallback can be validated without relying on the external dummy WebDAV container.