Переглянути джерело

Merge pull request #128 from aspacca/ISSUE-44

ISSUE-44 delete support
tags/v1.0.0
Andrea Spacca 5 роки тому
committed by GitHub
джерело
коміт
b31e6acd71
Не вдалося знайти GPG ключ що відповідає даному підпису Ідентифікатор GPG ключа: 4AEE18F83AFDEB23
3 змінених файлів з 100 додано та 6 видалено
  1. +64
    -6
      server/handlers.go
  2. +2
    -0
      server/server.go
  3. +34
    -0
      server/storage.go

+ 64
- 6
server/handlers.go Переглянути файл

@@ -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)



+ 2
- 0
server/server.go Переглянути файл

@@ -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")


+ 34
- 0
server/storage.go Переглянути файл

@@ -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


Завантаження…
Відмінити
Зберегти