- Add section on URL encoding issues causing HTTP 400 errors - Document nginx proxy_pass solution for preserving request URI - Update final working configuration with HTTP/1.1 fixes - Include Connection header and proxy_http_version settings 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
6.7 KiB
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:
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.txtfail
Solution: Pass original request URI to preserve URL encoding:
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.
[/shared]
/home/hoborg/shared
accs:
rw: guest
rwmd: hoborg # Changed from 'rwm' to 'rwmd'
Copyparty Permission Flags:
r(read): List folders, download filesw(write): Upload filesm(move): Move/rename files and foldersd(delete): Permanently delete files and foldersa(admin): See uploader IPs, config reload
Debugging Process
Step 1: Isolate the Problem
Test direct copyparty connection vs nginx proxy:
# 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:
# 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
# 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)
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)
[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
- Nginx proxy_redirect off is critical - Prevents nginx from modifying WebDAV responses
- merge_slashes off prevents automatic redirects - Stops nginx from "fixing" WebDAV paths
- Copyparty needs explicit 'd' permission - Delete operations require separate permission flag
- Test direct vs proxied connections - Isolates nginx vs backend issues
- Monitor logs during troubleshooting - Shows exactly what requests reach the backend
Commands for Future Troubleshooting
# 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