150 lines
3.1 KiB
Go
150 lines
3.1 KiB
Go
package server
|
|
|
|
import (
|
|
"io"
|
|
"io/ioutil"
|
|
"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 := rest.filesStream(r, f); err != nil {
|
|
rest.respError(w, err)
|
|
return
|
|
}
|
|
w.Write([]byte(id))
|
|
}
|
|
|
|
func (rest *REST) filesStream(r *http.Request, f io.Writer) error {
|
|
var reader io.Reader = r.Body
|
|
_, direct := r.URL.Query()["direct"]
|
|
if direct {
|
|
target, err := ioutil.ReadAll(r.Body)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
resp, err := http.Get(string(target))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
reader = resp.Body
|
|
}
|
|
if _, err := io.Copy(f, reader); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
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 := rest.filesStream(r, f); 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
|
|
}
|