diff options
Diffstat (limited to 'plugins/caldav/plugin.go')
-rw-r--r-- | plugins/caldav/plugin.go | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/plugins/caldav/plugin.go b/plugins/caldav/plugin.go new file mode 100644 index 0000000..1915646 --- /dev/null +++ b/plugins/caldav/plugin.go @@ -0,0 +1,71 @@ +package koushincaldav + +import ( + "fmt" + "net/http" + "net/url" + + "git.sr.ht/~emersion/koushin" +) + +func sanityCheckURL(u *url.URL) error { + req, err := http.NewRequest(http.MethodOptions, u.String(), nil) + if err != nil { + return err + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return err + } + resp.Body.Close() + + // Servers might require authentication to perform an OPTIONS request + if resp.StatusCode/100 != 2 && resp.StatusCode != http.StatusUnauthorized { + return fmt.Errorf("HTTP request failed: %v %v", resp.StatusCode, resp.Status) + } + return nil +} + +func newPlugin(srv *koushin.Server) (koushin.Plugin, error) { + u, err := srv.Upstream("caldavs", "caldav+insecure", "https", "http+insecure") + if _, ok := err.(*koushin.NoUpstreamError); ok { + return nil, nil + } else if err != nil { + return nil, fmt.Errorf("caldav: failed to parse upstream caldav server: %v", err) + } + switch u.Scheme { + case "caldavs": + u.Scheme = "https" + case "caldav+insecure", "http+insecure": + u.Scheme = "http" + } + if u.Scheme == "" { + return nil, fmt.Errorf("caldav: discovery not yet implemented") // TODO + } + + if err := sanityCheckURL(u); err != nil { + return nil, fmt.Errorf("caldav: failed to connect to CalDAV server %q: %v", u, err) + } + + srv.Logger().Printf("Configured upstream CalDAV server: %v", u) + + p := koushin.GoPlugin{Name: "caldav"} + + registerRoutes(&p, u) + + return p.Plugin(), nil +} + +func init() { + koushin.RegisterPluginLoader(func(s *koushin.Server) ([]koushin.Plugin, error) { + p, err := newPlugin(s) + if err != nil { + return nil, err + } + if p == nil { + return nil, nil + } + return []koushin.Plugin{p}, err + }) +} |