Created
June 21, 2017 21:31
restic plugin for Caddy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
example.com | |
# specifying an empty root is not strictly necessary but not a bad | |
# idea if all you are serving on this site is the backups | |
root empty_www/ | |
# authentication is required when using the Caddy plugin; | |
# this line assumes all requests are protected | |
basicauth / user pass | |
# enable restic for all requests, and store repos in /mnt/backup | |
restic / /home/matt/mybackups | |
# All valid restic syntaxes: | |
# | |
# restic | |
# This enables restic for all requests and uses the default data path | |
# | |
# restic /backups | |
# This enables restic for all requests to /backups with default data path | |
# | |
# restic /backups /datapath | |
# This enables restic for all requests to /backups and stores data in /datapath |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package restic | |
import ( | |
"net/http" | |
"strings" | |
"github.com/mholt/caddy/caddyhttp/httpserver" | |
) | |
type ResticHandler struct { | |
Next httpserver.Handler | |
BasePath string | |
RestServerMux http.Handler | |
} | |
func (h ResticHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) { | |
if !httpserver.Path(r.URL.Path).Matches(h.BasePath) { | |
return h.Next.ServeHTTP(w, r) | |
} | |
// basic auth is required (some authentication is required, for obvious reasons) | |
basicAuthUser, ok := r.Context().Value(httpserver.RemoteUserCtxKey).(string) | |
if !ok || basicAuthUser == "" { | |
return http.StatusForbidden, nil | |
} | |
// strip the base path from the request so that the restic mux can load | |
// the repo relative to its Config.Path base path. | |
r.URL.Path = strings.TrimPrefix(r.URL.Path, h.BasePath) | |
if !strings.HasPrefix(r.URL.Path, "/") { | |
r.URL.Path = "/" + r.URL.Path | |
} | |
// TODO: this doesn't return values so errors may not be handled properly. Oh well. | |
h.RestServerMux.ServeHTTP(w, r) | |
return 0, nil | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package restic | |
import ( | |
"github.com/mholt/caddy" | |
"github.com/mholt/caddy/caddyhttp/httpserver" | |
restserver "github.com/restic/rest-server" | |
) | |
func init() { | |
caddy.RegisterPlugin("restic", caddy.Plugin{ | |
ServerType: "http", | |
Action: setup, | |
}) | |
} | |
func setup(c *caddy.Controller) error { | |
var basePath string | |
for c.Next() { | |
if c.NextArg() { | |
basePath = c.Val() | |
} | |
if c.NextArg() { | |
restserver.Config.Path = c.Val() | |
} | |
if c.NextArg() { | |
return c.ArgErr() | |
} | |
} | |
if basePath == "" { | |
basePath = "/" | |
} | |
cfg := httpserver.GetConfig(c) | |
mid := func(next httpserver.Handler) httpserver.Handler { | |
return ResticHandler{ | |
Next: next, | |
BasePath: basePath, | |
RestServerMux: restserver.NewMux(), | |
} | |
} | |
cfg.AddMiddleware(mid) | |
return nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment