Formal Works

File Content
Login

Latest version of file 'go/webdav.go':


/*
This is a simple WebDAV server in Go.

It only serves on localhost and doesn't handle TLS or authentication.
It is meant to be deployed with a reverse proxy
like Nginx or Caddy to handle those aspects.

WebDAV is an open specification for editing remote files.

https://nginx.org

https://caddyserver.com/

## Building the App

1. Install Go: https://golang.org/doc/install

2. Download the single-file source code: 

	$ wget https://formal.codes/doc/tip/webdav.go

3. Run `go build` to build the `webdav` executable.

4. Run `./webdav` or move the executable to e.g. `/usr/local/bin/`
to run `webdav` from any directory.

	$ sudo mv webdav /usr/local/bin/

## How to Use It

There are two optional arguments.

1. `-port [8080]`: the port to serve on at localhost
2. `-dir [.]`: the directory to serve over WebDAV
3. `-prefix [/]`: the URL path prefix for WebDAV resources

For example:

	$ webdav -port 9000 -dir /tmp/webdav -prefix /server

*/
package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"
	"os"
	"os/signal"
	"syscall"

	"golang.org/x/net/webdav"
)

func main() {
	// default directory to serve from is current working directory
	cwd, err := os.Getwd()
	if err != nil {
		log.Fatal(err)
		os.Exit(1)
	}

	port := flag.String("port", "8080", "port to serve on")
	dir := flag.String("dir", cwd, "path to the directory to serve")
	prefix := flag.String("prefix", "/", "URL path prefix for resources")
	flag.Parse()

	// set up the webdav server
	server := &http.Server{
		Addr: "localhost:" + *port,
		Handler: &webdav.Handler{
			Prefix: *prefix,
			FileSystem: webdav.Dir(*dir),
			LockSystem: webdav.NewMemLS(),
		},
	}
	// stop the server on the KILL and INTERRUPT signals
	stopper := make(chan os.Signal, 2)
	signal.Notify(stopper, os.Interrupt, syscall.SIGTERM)
	go func() {
		<-stopper
		// kills all current connections
		err := server.Close()
		if err != nil {
			log.Fatal(err)
		}
		os.Exit(1)
	}()
	fmt.Printf("serving WebDAV at http://localhost:%s for %s with prefix %s\n", *port, *dir, *prefix)
	log.Fatal(server.ListenAndServe())
}