dndex/server/files.go

125 lines
2.6 KiB
Go

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
}