# WebDAV Copyparty Troubleshooting Guide This document captures the issues encountered and solutions found while setting up WebDAV with copyparty behind an nginx reverse proxy. ## Initial Problem WebDAV clients (X-plore File Manager) could browse folders but could not upload files, receiving HTTP 301 redirects instead of successful uploads. ## Root Causes Identified ### 1. Nginx Automatic Redirects **Problem**: Nginx was automatically adding trailing slashes and performing internal redirects that broke WebDAV PUT requests. **Symptoms**: - PROPFIND (directory listing) worked: `HTTP/1.1 207 Multi-Status` - PUT (file upload) failed: `HTTP/1.1 301 Moved Permanently` - Web interface worked normally - Direct curl uploads worked through nginx **Solution**: Disable nginx automatic redirects: ```nginx server { # Critical: Disable automatic redirects for WebDAV merge_slashes off; location ~ ^/files(/.*)?$ { # Critical: Disable nginx response modifications proxy_redirect off; } } ``` ### 2. Copyparty Permissions **Problem**: Copyparty required explicit delete permissions for WebDAV DELETE operations. **Symptoms**: - File uploads worked after nginx fix - File deletions failed: `'delete' not allowed for user hoborg` - Error: `HTTP/1.1 403 Forbidden` **Solution**: Add `d` (delete) permission to user accounts: ### 3. URL Encoding Issues **Problem**: Files/folders with spaces or special characters in names caused HTTP 400 errors. **Symptoms**: - Files without spaces upload successfully - Files with spaces in path fail: `HTTP/1.1 400 Bad Request` - Logs show "bad headers" errors from copyparty - URLs like `/files/folder/file%20name.txt` fail **Solution**: Pass original request URI to preserve URL encoding: ```nginx location ~ ^/files(/.*)?$ { # Pass original request URI to preserve URL encoding proxy_pass http://127.0.0.1:8082; # ... other proxy settings } ``` Instead of `proxy_pass http://127.0.0.1:8082/files$1;` which manipulates the path. ```ini [/shared] /home/hoborg/shared accs: rw: guest rwmd: hoborg # Changed from 'rwm' to 'rwmd' ``` **Copyparty Permission Flags**: - `r` (read): List folders, download files - `w` (write): Upload files - `m` (move): Move/rename files and folders - `d` (delete): Permanently delete files and folders - `a` (admin): See uploader IPs, config reload ## Debugging Process ### Step 1: Isolate the Problem Test direct copyparty connection vs nginx proxy: ```bash # Test direct copyparty (bypassing nginx) curl -X PUT "http://127.0.0.1:8082/files/shared/test.txt" \ -u "hoborg:password" -d "test content" -v # Test through nginx proxy curl -X PUT "https://ak-homelab.duckdns.org/files/shared/test.txt" \ -u "hoborg:password" -d "test content" -v ``` **Result**: Direct copyparty worked, nginx proxy returned 301 → nginx issue ### Step 2: Monitor Logs Check what HTTP methods are actually reaching copyparty: ```bash # Monitor copyparty logs in real-time sudo journalctl -u copyparty -f # Monitor nginx access logs sudo tail -f /var/log/nginx/access.log ``` **Finding**: X-plore PUT requests never reached copyparty logs → nginx blocking ### Step 3: Test WebDAV Methods ```bash # Test PROPFIND (directory listing) curl -X PROPFIND "https://ak-homelab.duckdns.org/files/shared/" \ -u "hoborg:password" -H "Depth: 1" -v # Test PUT (file upload) curl -X PUT "https://ak-homelab.duckdns.org/files/shared/test.txt" \ -u "hoborg:password" -d "test content" -v # Test DELETE (file deletion) curl -X DELETE "https://ak-homelab.duckdns.org/files/shared/test.txt" \ -u "hoborg:password" -v ``` ## Final Working Configuration ### Nginx Configuration (`/etc/nginx/sites-available/homelab`) ```nginx server { listen 443 ssl; server_name ak-homelab.duckdns.org; # Critical: Disable automatic redirects for WebDAV merge_slashes off; # Copyparty file server - WORKING WebDAV config location ~ ^/files(/.*)?$ { # Explicitly allow WebDAV methods limit_except GET POST PUT DELETE PROPFIND PROPPATCH MKCOL COPY MOVE LOCK UNLOCK { deny all; } # Pass original request URI to preserve URL encoding proxy_pass http://127.0.0.1:8082; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # WebDAV specific headers proxy_set_header Depth $http_depth; proxy_set_header Destination $http_destination; proxy_set_header Overwrite $http_overwrite; proxy_set_header If $http_if; proxy_set_header Lock-Token $http_lock_token; # Large file upload support client_max_body_size 10G; client_body_buffer_size 128k; # Upload timeout settings proxy_connect_timeout 300s; proxy_send_timeout 300s; proxy_read_timeout 300s; # Critical: Streaming uploads for WebDAV proxy_buffering off; proxy_request_buffering off; # Critical: Use HTTP/1.1 and fix connection headers proxy_http_version 1.1; proxy_set_header Connection ""; # Critical: Disable nginx response modifications proxy_redirect off; } } ``` ### Copyparty Configuration (`~/.config/copyparty/copyparty.conf`) ```ini [global] i: 127.0.0.1 p: 8082 rp-loc: /files rproxy: -1 usernames chpw [accounts] hoborg: password [/shared] /home/hoborg/shared accs: rwmd: hoborg # r=read, w=write, m=move, d=delete ``` ## X-plore Client Settings - **Server**: `ak-homelab.duckdns.org` - **Path**: `/files/shared/` (or other folder paths) - **Protocol**: HTTPS (port 443) - **Username**: `hoborg` - **Password**: [user password] ## Key Lessons Learned 1. **Nginx proxy_redirect off is critical** - Prevents nginx from modifying WebDAV responses 2. **merge_slashes off prevents automatic redirects** - Stops nginx from "fixing" WebDAV paths 3. **Copyparty needs explicit 'd' permission** - Delete operations require separate permission flag 4. **Test direct vs proxied connections** - Isolates nginx vs backend issues 5. **Monitor logs during troubleshooting** - Shows exactly what requests reach the backend ## Commands for Future Troubleshooting ```bash # Test WebDAV connectivity curl -X PROPFIND "https://ak-homelab.duckdns.org/files/shared/" \ -u "username:password" -H "Depth: 1" -v # Monitor copyparty service sudo journalctl -u copyparty -f # Check nginx configuration sudo nginx -t sudo systemctl reload nginx # Test file operations curl -X PUT "https://ak-homelab.duckdns.org/files/shared/test.txt" \ -u "username:password" -d "test" -v curl -X DELETE "https://ak-homelab.duckdns.org/files/shared/test.txt" \ -u "username:password" -v ```