|
|
@@ -61,6 +61,8 @@ import ( |
|
|
|
|
|
|
|
"encoding/base64" |
|
|
|
qrcode "github.com/skip2/go-qrcode" |
|
|
|
|
|
|
|
"github.com/klauspost/compress/zstd" |
|
|
|
) |
|
|
|
|
|
|
|
var ( |
|
|
@@ -838,23 +840,34 @@ func (s *Server) headHandler(w http.ResponseWriter, r *http.Request) { |
|
|
|
filename := vars["filename"] |
|
|
|
|
|
|
|
if err := s.CheckMetadata(token, filename); err != nil { |
|
|
|
log.Printf("Error metadata: %s", err.Error()) |
|
|
|
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) |
|
|
|
return |
|
|
|
if err2 := s.CheckMetadata(token, filename + ".zst"); err2 != nil { |
|
|
|
log.Printf("Error metadata: %s", err.Error()) |
|
|
|
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
contentType, contentLength, err := s.storage.Head(token, filename) |
|
|
|
if s.storage.IsNotExist(err) { |
|
|
|
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) |
|
|
|
return |
|
|
|
_, _, err := s.storage.Head(token, filename + ".zst") |
|
|
|
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 retrieve file.", 500) |
|
|
|
return |
|
|
|
} |
|
|
|
contentType = mime.TypeByExtension(filepath.Ext(filename)) |
|
|
|
} else if err != nil { |
|
|
|
log.Printf("%s", err.Error()) |
|
|
|
http.Error(w, "Could not retrieve file.", 500) |
|
|
|
return |
|
|
|
} else { |
|
|
|
w.Header().Set("Content-Length", strconv.FormatUint(contentLength, 10)) |
|
|
|
} |
|
|
|
|
|
|
|
w.Header().Set("Content-Type", contentType) |
|
|
|
w.Header().Set("Content-Length", strconv.FormatUint(contentLength, 10)) |
|
|
|
w.Header().Set("Connection", "close") |
|
|
|
} |
|
|
|
|
|
|
@@ -866,19 +879,45 @@ func (s *Server) getHandler(w http.ResponseWriter, r *http.Request) { |
|
|
|
filename := vars["filename"] |
|
|
|
|
|
|
|
if err := s.CheckMetadata(token, filename); err != nil { |
|
|
|
log.Printf("Error metadata: %s", err.Error()) |
|
|
|
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) |
|
|
|
return |
|
|
|
if err2 := s.CheckMetadata(token, filename + ".zst"); err2 != nil { |
|
|
|
log.Printf("Error metadata: %s and %s", err.Error(), err2.Error()) |
|
|
|
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
reader, contentType, contentLength, err := s.storage.Get(token, filename) |
|
|
|
if s.storage.IsNotExist(err) { |
|
|
|
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) |
|
|
|
return |
|
|
|
reader, _, _, err = s.storage.Get(token, filename + ".zst") |
|
|
|
if s.storage.IsNotExist(err) { |
|
|
|
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) |
|
|
|
return |
|
|
|
} else if err != nil { |
|
|
|
log.Printf("Failed to get .zst from storage: %s", err.Error()) |
|
|
|
http.Error(w, "Could not retrieve file.", 500) |
|
|
|
return |
|
|
|
} |
|
|
|
defer reader.Close() |
|
|
|
if w.Header().Get("Range") != "" { |
|
|
|
log.Printf("Range request with decompression") |
|
|
|
http.Error(w, "Range requests with decompression are not supported", 400) |
|
|
|
return |
|
|
|
} |
|
|
|
d, err := zstd.NewReader(reader) |
|
|
|
if err != nil { |
|
|
|
log.Printf("Failed to create zstd reader: %s", err.Error()) |
|
|
|
http.Error(w, "Could not retrieve file.", 500) |
|
|
|
return |
|
|
|
} |
|
|
|
reader = d.IOReadCloser() |
|
|
|
contentType = mime.TypeByExtension(filepath.Ext(filename)) |
|
|
|
w.Header().Set("Transfer-Encoding", "chunked") |
|
|
|
} else if err != nil { |
|
|
|
log.Printf("%s", err.Error()) |
|
|
|
log.Printf("Failed to get from storage: %s", err.Error()) |
|
|
|
http.Error(w, "Could not retrieve file.", 500) |
|
|
|
return |
|
|
|
} else { |
|
|
|
w.Header().Set("Content-Length", strconv.FormatUint(contentLength, 10)) |
|
|
|
} |
|
|
|
|
|
|
|
defer reader.Close() |
|
|
@@ -892,7 +931,6 @@ func (s *Server) getHandler(w http.ResponseWriter, r *http.Request) { |
|
|
|
} |
|
|
|
|
|
|
|
w.Header().Set("Content-Type", contentType) |
|
|
|
w.Header().Set("Content-Length", strconv.FormatUint(contentLength, 10)) |
|
|
|
w.Header().Set("Content-Disposition", fmt.Sprintf("%s; filename=\"%s\"", disposition, filename)) |
|
|
|
w.Header().Set("Connection", "keep-alive") |
|
|
|
|
|
|
|