package server import ( "io" "local/dndex/config" "net/http" "os" "path" "github.com/google/uuid" ) func (rest *REST) files(w http.ResponseWriter, r *http.Request) { if len(r.URL.Path) < 2 { switch r.Method { case http.MethodPost: rest.filesCreate(w, r) default: rest.respNotFound(w) } } else { switch r.Method { case http.MethodPut: rest.filesUpdate(w, r) case http.MethodGet: rest.filesGet(w, r) case http.MethodDelete: rest.filesDelete(w, r) default: rest.respNotFound(w) } } } func (rest *REST) filesCreate(w http.ResponseWriter, r *http.Request) { id := uuid.New().String() r.URL.Path = "/" + id localPath := rest.filesPath(r) if stat, err := os.Stat(localPath); !os.IsNotExist(err) || (stat != nil && stat.IsDir()) { rest.respConflict(w) return } if err := os.MkdirAll(path.Dir(localPath), os.ModePerm); err != nil { rest.respError(w, err) return } f, err := os.Create(localPath) if err != nil { rest.respError(w, err) return } defer f.Close() if _, err := io.Copy(f, r.Body); err != nil { rest.respError(w, err) } w.Write([]byte(id)) } func (rest *REST) filesDelete(w http.ResponseWriter, r *http.Request) { localPath := rest.filesPath(r) if stat, err := os.Stat(localPath); os.IsNotExist(err) { rest.respOK(w) return } else if err != nil || stat.IsDir() { rest.respConflict(w) return } if err := os.Remove(localPath); err != nil { rest.respError(w, err) } rest.respOK(w) } func (rest *REST) filesGet(w http.ResponseWriter, r *http.Request) { localPath := rest.filesPath(r) if stat, err := os.Stat(localPath); os.IsNotExist(err) { rest.respNotFound(w) return } else if err != nil || stat.IsDir() { rest.respConflict(w) return } f, err := os.Open(localPath) if err != nil { rest.respError(w, err) return } defer f.Close() if _, err := io.Copy(w, f); err != nil { rest.respError(w, err) } } func (rest *REST) filesUpdate(w http.ResponseWriter, r *http.Request) { localPath := rest.filesPath(r) if stat, err := os.Stat(localPath); os.IsNotExist(err) { rest.respNotFound(w) return } else if err != nil || stat.IsDir() { rest.respConflict(w) return } f, err := os.Create(localPath + ".tmp") if err != nil { rest.respError(w, err) return } defer f.Close() if _, err := io.Copy(f, r.Body); err != nil { rest.respError(w, err) return } if err := os.Rename(localPath+".tmp", localPath); err != nil { rest.respError(w, err) return } rest.respOK(w) } func (rest *REST) filesPath(r *http.Request) string { scope := rest.scope(r) localPath := path.Join(config.New().FileRoot, scope.Namespace, r.URL.Path) return localPath }