package web import ( "encoding/json" "io" "net/http" "strconv" "git.kapelle.org/niklas/s3share/internal/client" "github.com/gorilla/mux" "github.com/sirupsen/logrus" ) type createShare struct { Key string `json:"key"` } type deleteShare struct { Slug string `json:"slug"` } func StartWebserver(addr string, client client.Client) error { r := mux.NewRouter() r.HandleFunc("/{slug:[a-zA-Z0-9]{6}}", func(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, "./public/index.html") }) r.HandleFunc("/s/{slug:[a-zA-Z0-9]{6}}", func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) share, err := client.GetShare(r.Context(), vars["slug"]) if err != nil { logrus.Error(err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } if share == nil { http.NotFound(w, r) return } metadata, err := client.GetObjectMetadata(r.Context(), share.Key) if err != nil { logrus.Error(err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Header().Set("Content-Type", metadata.ContentType) w.Header().Set("Content-Length", strconv.FormatInt(metadata.Size, 10)) w.Header().Set("Content-Disposition", "attachment; filename=\""+metadata.Filename+"\"") obj, err := client.GetObjectFromShare(r.Context(), share) if err != nil { logrus.Error(err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } _, err = io.Copy(w, obj) if err != nil { w.WriteHeader(http.StatusInternalServerError) return } }) r.HandleFunc("/api/share", func(w http.ResponseWriter, r *http.Request) { }).Methods("GET") r.HandleFunc("/api/share", func(w http.ResponseWriter, r *http.Request) { // TODO: check auth var shareParams createShare err := json.NewDecoder(r.Body).Decode(&shareParams) if err != nil { logrus.Error(err.Error()) http.Error(w, err.Error(), http.StatusBadRequest) return } share, err := client.CreateShare(r.Context(), shareParams.Key) if err != nil { logrus.Error(err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(share) }).Methods("POST") r.HandleFunc("/api/share", func(w http.ResponseWriter, r *http.Request) { //TODO: check auth var shareParams deleteShare err := json.NewDecoder(r.Body).Decode(&shareParams) if err != nil { logrus.Error(err.Error()) http.Error(w, err.Error(), http.StatusBadRequest) return } err = client.DeleteShare(r.Context(), shareParams.Slug) if err != nil { logrus.Error(err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } }).Methods("DELETE") r.PathPrefix("/").Handler(http.FileServer(http.Dir("./public/"))) logrus.Info("Starting webserver") return http.ListenAndServe(addr, r) }