mirror of
https://github.com/dutchcoders/transfer.sh.git
synced 2024-11-27 06:30:19 +01:00
commit
b31e6acd71
3 changed files with 100 additions and 6 deletions
|
@ -301,14 +301,17 @@ type Metadata struct {
|
|||
MaxDownloads int
|
||||
// MaxDate contains the max age of the file
|
||||
MaxDate time.Time
|
||||
// DeletionToken contains the token to match against for deletion
|
||||
DeletionToken string
|
||||
}
|
||||
|
||||
func MetadataForRequest(contentType string, r *http.Request) Metadata {
|
||||
metadata := Metadata{
|
||||
ContentType: contentType,
|
||||
MaxDate: time.Now().Add(time.Hour * 24 * 365 * 10),
|
||||
Downloads: 0,
|
||||
MaxDownloads: 99999999,
|
||||
ContentType: contentType,
|
||||
MaxDate: time.Now().Add(time.Hour * 24 * 365 * 10),
|
||||
Downloads: 0,
|
||||
MaxDownloads: 99999999,
|
||||
DeletionToken: Encode(10000000 + int64(rand.Intn(1000000000))) + Encode(10000000 + int64(rand.Intn(1000000000))),
|
||||
}
|
||||
|
||||
if v := r.Header.Get("Max-Downloads"); v == "" {
|
||||
|
@ -415,11 +418,14 @@ func (s *Server) putHandler(w http.ResponseWriter, r *http.Request) {
|
|||
w.Header().Set("Content-Type", "text/plain")
|
||||
|
||||
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 != "" {
|
||||
u.Path = fmt.Sprintf("%s?%s", u.Path, url.QueryEscape(u.RawQuery))
|
||||
u.RawQuery = ""
|
||||
|
@ -430,6 +436,10 @@ func escapeFilename(r *http.Request, u *url.URL) string {
|
|||
u.Fragment = ""
|
||||
}
|
||||
|
||||
if absolutePath {
|
||||
r.URL.Path = ""
|
||||
}
|
||||
|
||||
return getURL(r).ResolveReference(u).String()
|
||||
}
|
||||
|
||||
|
@ -517,6 +527,54 @@ func (s *Server) CheckMetadata(token, filename string) error {
|
|||
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) {
|
||||
vars := mux.Vars(r)
|
||||
|
||||
|
|
|
@ -348,6 +348,8 @@ func (s *Server) Run() {
|
|||
r.HandleFunc("/", s.BasicAuthHandler(http.HandlerFunc(s.putHandler))).Methods("POST")
|
||||
// r.HandleFunc("/{page}", viewHandler).Methods("GET")
|
||||
|
||||
r.HandleFunc("/{token}/{filename}/{deletionToken}", s.deleteHandler).Methods("DELETE")
|
||||
|
||||
r.NotFoundHandler = http.HandlerFunc(s.notFoundHandler)
|
||||
|
||||
mime.AddExtensionType(".md", "text/x-markdown")
|
||||
|
|
|
@ -27,6 +27,7 @@ type Storage interface {
|
|||
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)
|
||||
Put(token string, filename string, reader io.Reader, contentType string, contentLength uint64) error
|
||||
Delete(token string, filename string) error
|
||||
IsNotExist(err error) bool
|
||||
|
||||
Type() string
|
||||
|
@ -80,6 +81,15 @@ func (s *LocalStorage) Get(token string, filename string) (reader io.ReadCloser,
|
|||
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 {
|
||||
if err == nil {
|
||||
return false
|
||||
|
@ -180,6 +190,16 @@ func (s *S3Storage) Get(token string, filename string) (reader io.ReadCloser, co
|
|||
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) {
|
||||
key := fmt.Sprintf("%s/%s", token, filename)
|
||||
|
||||
|
@ -480,6 +500,20 @@ func (s *GDrive) Get(token string, filename string) (reader io.ReadCloser, conte
|
|||
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 {
|
||||
if err == nil {
|
||||
return false
|
||||
|
|
Loading…
Reference in a new issue