package bokofs import ( "context" "fmt" "log" "net/http" "os" "sync" "time" "golang.org/x/net/webdav" "imuslab.com/bokofs/bokofsd/mod/bokofs/bokoworker" ) /* WebDAV module This module handle the interfacing to the underlying file system through the middle ware */ type Options struct { ListeningAddress string //Listening address, e.g. 0.0.0.0:8443 SecureServe bool //Use TLS to serve the WebDAV request PublicKeyPath string PrivateKeyPath string } type Server struct { LoadedWorkers sync.Map //Storing uuid to bokoworker pointer (*bokoworker.Worker) RootRouter FlowRouter Options *Options } /* NewWebdavInterfaceServer creates a new WebDAV server instance */ func NewWebdavInterfaceServer(options Options) (*Server, error) { thisServer := Server{ LoadedWorkers: sync.Map{}, Options: &options, } //TODO: Load all the middlewares //Initiate the root router file system err := thisServer.InitiateRootRouter() if err != nil { return nil, err } return &thisServer, nil } func (s *Server) AddWorker(worker *bokoworker.Worker) { s.LoadedWorkers.Store(worker.RootPath, worker) } func (s *Server) RemoveWorker(workerRootPath string) { s.LoadedWorkers.Delete(workerRootPath) } func (s *Server) Start() error { srv := &webdav.Handler{ FileSystem: s.RootRouter, LockSystem: webdav.NewMemLS(), Logger: func(r *http.Request, err error) { if err != nil { log.Printf("WEBDAV [%s]: %s, ERROR: %s\n", r.Method, r.URL, err) } else { log.Printf("WEBDAV [%s]: %s \n", r.Method, r.URL) } }, } http.Handle("/", srv) if s.Options.SecureServe { if _, err := os.Stat(s.Options.PublicKeyPath); err != nil { fmt.Println("Public ket not found") return err } if _, err := os.Stat(s.Options.PrivateKeyPath); err != nil { fmt.Println("Private key not found") return err } } ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) defer cancel() done := make(chan error) go func() { if s.Options.SecureServe { if err := http.ListenAndServeTLS(s.Options.ListeningAddress, s.Options.PublicKeyPath, s.Options.PrivateKeyPath, nil); err != nil { done <- err } } else { if err := http.ListenAndServe(s.Options.ListeningAddress, nil); err != nil { log.Fatalf("Error with WebDAV server: %v", err) done <- err } } }() select { case <-ctx.Done(): //No error in 3 seconds. Assume all green return nil case success := <-done: if success != nil { log.Fatalf("Error with WebDAV server") return success } } return nil }