63 lines
1.8 KiB
Go
63 lines
1.8 KiB
Go
package main
|
|
|
|
import (
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"golang.org/x/net/webdav"
|
|
)
|
|
|
|
const (
|
|
rootDir = "/data"
|
|
addr = ":80"
|
|
)
|
|
|
|
func main() {
|
|
if err := os.MkdirAll(rootDir, 0o777); err != nil {
|
|
log.Fatalf("mkdir %s: %v", rootDir, err)
|
|
}
|
|
abs, err := filepath.Abs(rootDir)
|
|
if err != nil {
|
|
log.Fatalf("abs %s: %v", rootDir, err)
|
|
}
|
|
|
|
var fs webdav.FileSystem = webdav.Dir(abs)
|
|
if os.Getenv("WEBDAV_IMAGES_ONLY") == "1" {
|
|
fs = &imageOnlyFS{FileSystem: fs}
|
|
log.Print("WebDAV images-only mode: only image and SVG uploads allowed")
|
|
}
|
|
|
|
h := &webdav.Handler{
|
|
FileSystem: fs,
|
|
LockSystem: webdav.NewMemLS(),
|
|
}
|
|
// Wrap so GET / returns a simple page instead of 403 for directory
|
|
http.Handle("/", &rootGETWrapper{Handler: h})
|
|
|
|
log.Printf("WebDAV listening on %s (root %s)", addr, abs)
|
|
if err := http.ListenAndServe(addr, nil); err != nil {
|
|
log.Fatalf("listen: %v", err)
|
|
}
|
|
}
|
|
|
|
// rootGETWrapper serves a minimal HTML page for GET / and passes everything else to WebDAV.
|
|
type rootGETWrapper struct {
|
|
*webdav.Handler
|
|
}
|
|
|
|
func (w *rootGETWrapper) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
|
if r.Method == http.MethodGet && (r.URL.Path == "" || r.URL.Path == "/") {
|
|
rw.Header().Set("Content-Type", "text/html; charset=utf-8")
|
|
rw.WriteHeader(http.StatusOK)
|
|
host := r.Host
|
|
rw.Write([]byte(`<!DOCTYPE html><html><head><title>WebDAV</title></head><body><h1>WebDAV</h1>
|
|
<h2>Mac</h2><p>Finder → Go → Connect to Server… (⌘K) → <code>https://` + host + `</code></p>
|
|
<h2>Windows</h2><p>File Explorer → right-click This PC → Map network drive → Choose a drive letter → Folder: <code>https://` + host + `</code> → Finish (use the same login when prompted).</p>
|
|
<p>Or: File Explorer → This PC → Computer tab → Map network drive.</p></body></html>`))
|
|
return
|
|
}
|
|
w.Handler.ServeHTTP(rw, r)
|
|
}
|