1
0
mirror of https://github.com/dutchcoders/transfer.sh.git synced 2020-11-18 19:53:40 -08:00

ISSUE-44 delete support

This commit is contained in:
Andrea Spacca 2018-06-24 06:46:57 +02:00
parent 8a0e3d39f2
commit 0c9c6e3424
3 changed files with 100 additions and 6 deletions

View File

@ -297,6 +297,8 @@ type Metadata struct {
MaxDownloads int MaxDownloads int
// MaxDate contains the max age of the file // MaxDate contains the max age of the file
MaxDate time.Time MaxDate time.Time
// DeletionToken contains the token to match against for deletion
DeletionToken string
} }
func MetadataForRequest(contentType string, r *http.Request) Metadata { func MetadataForRequest(contentType string, r *http.Request) Metadata {
@ -305,6 +307,7 @@ func MetadataForRequest(contentType string, r *http.Request) Metadata {
MaxDate: time.Now().Add(time.Hour * 24 * 365 * 10), MaxDate: time.Now().Add(time.Hour * 24 * 365 * 10),
Downloads: 0, Downloads: 0,
MaxDownloads: 99999999, MaxDownloads: 99999999,
DeletionToken: Encode(10000000 + int64(rand.Intn(1000000000))) + Encode(10000000 + int64(rand.Intn(1000000000))),
} }
if v := r.Header.Get("Max-Downloads"); v == "" { if v := r.Header.Get("Max-Downloads"); v == "" {
@ -411,11 +414,14 @@ func (s *Server) putHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain") w.Header().Set("Content-Type", "text/plain")
relativeURL, _ := url.Parse(path.Join(token, filename)) relativeURL, _ := url.Parse(path.Join(token, filename))
deleteUrl , _ := url.Parse(path.Join(token, filename, metadata.DeletionToken))
fmt.Fprint(w, escapeFilename(r, relativeURL)) w.Header().Set("X-Url-Delete", resolveUrl(r, deleteUrl, true))
fmt.Fprint(w, resolveUrl(r, relativeURL, false))
} }
func escapeFilename(r *http.Request, u *url.URL) string { func resolveUrl(r *http.Request, u *url.URL, absolutePath bool) string {
if u.RawQuery != "" { if u.RawQuery != "" {
u.Path = fmt.Sprintf("%s?%s", u.Path, url.QueryEscape(u.RawQuery)) u.Path = fmt.Sprintf("%s?%s", u.Path, url.QueryEscape(u.RawQuery))
u.RawQuery = "" u.RawQuery = ""
@ -426,6 +432,10 @@ func escapeFilename(r *http.Request, u *url.URL) string {
u.Fragment = "" u.Fragment = ""
} }
if absolutePath {
r.URL.Path = ""
}
return getURL(r).ResolveReference(u).String() return getURL(r).ResolveReference(u).String()
} }
@ -513,6 +523,54 @@ func (s *Server) CheckMetadata(token, filename string) error {
return nil return nil
} }
func (s *Server) CheckDeletionToken(deletionToken, token, filename string) error {
s.Lock(token, filename)
defer s.Unlock(token, filename)
var metadata Metadata
r, _, _, err := s.storage.Get(token, fmt.Sprintf("%s.metadata", filename))
if s.storage.IsNotExist(err) {
return nil
} else if err != nil {
return err
}
defer r.Close()
if err := json.NewDecoder(r).Decode(&metadata); err != nil {
return err
} else if metadata.DeletionToken != deletionToken {
return errors.New("Deletion token doesn't match.")
}
return nil
}
func (s *Server) deleteHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
token := vars["token"]
filename := vars["filename"]
deletionToken := vars["deletionToken"]
if err := s.CheckDeletionToken(deletionToken, token, filename); err != nil {
log.Printf("Error metadata: %s", err.Error())
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
err := s.storage.Delete(token, filename)
if s.storage.IsNotExist(err) {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
} else if err != nil {
log.Printf("%s", err.Error())
http.Error(w, "Could not delete file.", 500)
return
}
}
func (s *Server) zipHandler(w http.ResponseWriter, r *http.Request) { func (s *Server) zipHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r) vars := mux.Vars(r)

View File

@ -323,6 +323,8 @@ func (s *Server) Run() {
r.HandleFunc("/", s.postHandler).Methods("POST") r.HandleFunc("/", s.postHandler).Methods("POST")
// r.HandleFunc("/{page}", viewHandler).Methods("GET") // r.HandleFunc("/{page}", viewHandler).Methods("GET")
r.HandleFunc("/{token}/{filename}/{deletionToken}", s.deleteHandler).Methods("DELETE")
r.NotFoundHandler = http.HandlerFunc(s.notFoundHandler) r.NotFoundHandler = http.HandlerFunc(s.notFoundHandler)
mime.AddExtensionType(".md", "text/x-markdown") mime.AddExtensionType(".md", "text/x-markdown")

View File

@ -28,6 +28,7 @@ type Storage interface {
Get(token string, filename string) (reader io.ReadCloser, contentType string, contentLength uint64, err error) Get(token string, filename string) (reader io.ReadCloser, contentType string, contentLength uint64, err error)
Head(token string, filename string) (contentType string, contentLength uint64, err error) Head(token string, filename string) (contentType string, contentLength uint64, err error)
Put(token string, filename string, reader io.Reader, contentType string, contentLength uint64) error Put(token string, filename string, reader io.Reader, contentType string, contentLength uint64) error
Delete(token string, filename string) error
IsNotExist(err error) bool IsNotExist(err error) bool
Type() string Type() string
@ -81,6 +82,15 @@ func (s *LocalStorage) Get(token string, filename string) (reader io.ReadCloser,
return return
} }
func (s *LocalStorage) Delete(token string, filename string) (err error) {
metadata := filepath.Join(s.basedir, token, fmt.Sprintf("%s.metadata", filename))
os.Remove(metadata);
path := filepath.Join(s.basedir, token, filename)
err = os.Remove(path);
return
}
func (s *LocalStorage) IsNotExist(err error) bool { func (s *LocalStorage) IsNotExist(err error) bool {
if err == nil { if err == nil {
return false return false
@ -181,6 +191,16 @@ func (s *S3Storage) Get(token string, filename string) (reader io.ReadCloser, co
return return
} }
func (s *S3Storage) Delete(token string, filename string) (err error) {
metadata := fmt.Sprintf("%s/%s.metadata", token, filename)
s.bucket.Del(metadata)
key := fmt.Sprintf("%s/%s", token, filename)
err = s.bucket.Del(key)
return
}
func (s *S3Storage) Put(token string, filename string, reader io.Reader, contentType string, contentLength uint64) (err error) { func (s *S3Storage) Put(token string, filename string, reader io.Reader, contentType string, contentLength uint64) (err error) {
key := fmt.Sprintf("%s/%s", token, filename) key := fmt.Sprintf("%s/%s", token, filename)
@ -580,6 +600,20 @@ func (s *GDrive) Get(token string, filename string) (reader io.ReadCloser, conte
return return
} }
func (s *GDrive) Delete(token string, filename string) (err error) {
metadata, _ := s.findId(fmt.Sprintf("%s.metadata", filename), token)
s.service.Files.Delete(metadata).Do()
var fileId string
fileId, err = s.findId(filename, token)
if err != nil {
return
}
err = s.service.Files.Delete(fileId).Do()
return
}
func (s *GDrive) IsNotExist(err error) bool { func (s *GDrive) IsNotExist(err error) bool {
if err == nil { if err == nil {
return false return false