p3lim
(p3lim)
March 17, 2017, 11:39pm
1
I could not find any support or mention about WebDAV server with Caddy, other than a handful of issues posted on these forums about passing through for owncloud.
I don’t have any experience with Go myself so implementing support through a plugin is out of my scope, even though it seems to be supported by Go directly[1] and shouldn’t (in my mind atleast) be hard to implement.
If anyone wants to take a jab at this that would be most appreciated.
[1] webdav package - golang.org/x/net/webdav - pkg.go.dev
matt
(Matt Holt)
March 17, 2017, 11:43pm
2
This would be cool. Any takers?
p3lim
(p3lim)
March 19, 2017, 6:47pm
3
So, I spent a day learning the basics of Go and looking through other plugin implementations, ended up with this:
package cwebdav
import (
"strings"
"net/http"
"golang.org/x/net/webdav"
"github.com/mholt/caddy"
"github.com/mholt/caddy/caddyhttp/httpserver"
)
const debugging = true
func init() {
// register plugin
caddy.RegisterPlugin("webdav", caddy.Plugin{
ServerType: "http",
Action: setup,
})
if debugging {
// we're not part of Caddy yet, register us
// as a directive here until release
httpserver.RegisterDevDirective("webdav", "")
}
}
func setup(c *caddy.Controller) error {
// caddy's config
config := httpserver.GetConfig(c)
// assign default path
var path string = "/"
for c.Next() {
// get path if provided
args := c.RemainingArgs()
if len(args) > 0 {
path = args[0]
}
// validate path and prefix with full URL
path = strings.TrimPrefix(path, "/")
path = strings.TrimSuffix(path, "/")
path = strings.TrimSuffix(config.Addr.Path, "/") + "/" + path
}
// add handler from net/webdav
handler := &webdav.Handler{
Prefix: path,
FileSystem: webdav.Dir(config.Root), // using dir set by the `root` plugin
LockSystem: webdav.NewMemLS(),
}
// create middleware
middleware := func(next httpserver.Handler) httpserver.Handler {
return WebDAV{
Next: next,
Handler: handler,
Path: path,
}
}
// register middleware
config.AddMiddleware(middleware)
return nil
}
type WebDAV struct {
Next httpserver.Handler
Handler *webdav.Handler
Path string
}
func (h WebDAV) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
if httpserver.Path(r.URL.Path).Matches(h.Path) {
// if accessed path equals webdav path, serve it through WebDAV
h.Handler.ServeHTTP(w, r)
return 1, nil
} else {
// if not, pass it through to the next
return h.Next.ServeHTTP(w, r)
}
}
With this config (showing all available options):
localhost:2015 {
root /home/user/webdav
basicauth / admin test
webdav /
log stdout
errors stdout
}
Now, I have no idea if there’s any faults with this, but it seemed to work fine for me using Gnome’s file browser connecting to the server.
4 Likes
matt
(Matt Holt)
March 19, 2017, 9:21pm
4
Ah, and there we go. I didn’t realize WebDAV integrates with http like this, I thought it would have been its own server type.
Nice work.
When the new website is launched, do you want to add some tests and make this available as a plugin?
p3lim
(p3lim)
March 19, 2017, 9:40pm
5
@matt Sure, but with the current rather cumbersome build/include system I won’t really bother with that.
I would still need to thoroughly test this, as the above code is more of a PoC.
matt
(Matt Holt)
March 19, 2017, 9:54pm
6
Sounds good. I wouldn’t want you to submit it to this build server, wait until the new one is ready. Almost there.
system
(system)
Closed
June 17, 2017, 10:03pm
7
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.