fix download route sending headers too early, improve when file not found on download, other minor related changes
This commit is contained in:
parent
51d6f2dbf2
commit
4f2fe0b015
|
@ -23,7 +23,7 @@ func HandleFileNotFound(relPath string, fullPath string, w http.ResponseWriter)
|
|||
//info, err := os.Lstat(fullPath)
|
||||
//if err != nil {
|
||||
// log.Errorf("HELPERS:HandleFileNotFound - os.Lstat failed: %s", err)
|
||||
// Return500Msg(w)
|
||||
// Return500(w)
|
||||
// return nil
|
||||
//}
|
||||
//if !config.FollowSymlinks && info.Mode()&os.ModeSymlink > 0 {
|
||||
|
@ -35,14 +35,14 @@ func HandleFileNotFound(relPath string, fullPath string, w http.ResponseWriter)
|
|||
start := time.Now()
|
||||
item, err := dc.CrawlNoRecursion(fullPath, nil)
|
||||
if err == nil && (os.IsNotExist(err) || item == nil) {
|
||||
ReturnFake404Msg("path not found", w)
|
||||
ReturnFake404Msg("file not found", w)
|
||||
return nil
|
||||
} else if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
ReturnFake404Msg("path not found", w)
|
||||
ReturnFake404Msg("file not found", w)
|
||||
} else {
|
||||
log.Errorf("HELPERS:HandleFileNotFound:Crawl - Crawl failed: %s", err)
|
||||
Return500Msg(w)
|
||||
Return500(w)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ func HandleFileNotFound(relPath string, fullPath string, w http.ResponseWriter)
|
|||
item, found := sharedcache.Cache.Get(relPath)
|
||||
if !found {
|
||||
// Assume that it doesn't exist.
|
||||
ReturnFake404Msg("path not found", w)
|
||||
ReturnFake404Msg("file not found", w)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -32,10 +32,14 @@ func HandleRejectDuringInitialCrawl(w http.ResponseWriter) {
|
|||
WriteErrorResponse(http.StatusServiceUnavailable, http.StatusServiceUnavailable, "initial file system crawl in progress", w)
|
||||
}
|
||||
|
||||
func Return500Msg(w http.ResponseWriter) {
|
||||
func Return500(w http.ResponseWriter) {
|
||||
WriteErrorResponse(http.StatusInternalServerError, http.StatusInternalServerError, "internal server error", w)
|
||||
}
|
||||
|
||||
func Return500Msg(msg string, w http.ResponseWriter) {
|
||||
WriteErrorResponse(500, http.StatusInternalServerError, msg, w)
|
||||
}
|
||||
|
||||
func Return403Msg(msg string, w http.ResponseWriter) {
|
||||
WriteErrorResponse(http.StatusForbidden, http.StatusForbidden, msg, w)
|
||||
}
|
||||
|
|
|
@ -66,20 +66,20 @@ func ZipHandlerCompressMultiple(paths []string, w http.ResponseWriter, r *http.R
|
|||
if !item.IsDir {
|
||||
writer, err := zipWriter.Create(relPath)
|
||||
if err != nil {
|
||||
Return500Msg(w)
|
||||
Return500(w)
|
||||
return
|
||||
}
|
||||
|
||||
file, err := os.Open(fullPath)
|
||||
if err != nil {
|
||||
Return500Msg(w)
|
||||
Return500(w)
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
_, err = io.Copy(writer, file)
|
||||
if err != nil {
|
||||
Return500Msg(w)
|
||||
Return500(w)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -79,7 +79,7 @@ func APISearch(w http.ResponseWriter, r *http.Request) {
|
|||
resp, err := elastic.SimpleQuery(queryString, excludeElements, queryFields)
|
||||
if err != nil {
|
||||
log.Errorf(`ROUTES:Search - Failed to perform Elasticsearch query "%s" - %s`, queryString, err)
|
||||
helpers.Return500Msg(w)
|
||||
helpers.Return500(w)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,7 @@ func APISearch(w http.ResponseWriter, r *http.Request) {
|
|||
err = json.NewDecoder(resp.Body).Decode(&respData)
|
||||
if err != nil {
|
||||
log.Errorf(`ROUTES:Search - Failed to parse Elasticsearch response for query "%s" - %s`, queryString, err)
|
||||
helpers.Return500Msg(w)
|
||||
helpers.Return500(w)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -82,6 +82,24 @@ func APIDownload(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
if !item.IsDir {
|
||||
var err error
|
||||
// Open the file
|
||||
openFile, err := os.Open(fullPath)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
sharedcache.Cache.Remove(relPath) // Remove item from the cache
|
||||
helpers.ReturnFake404Msg("cache out of date, file missing from disk", w)
|
||||
} else {
|
||||
log.Errorf(`Failed to open file for download: "%s" - "%s"`, fullPath, err)
|
||||
helpers.Return500Msg("internal server error accessing file", w)
|
||||
}
|
||||
return
|
||||
}
|
||||
defer openFile.Close()
|
||||
|
||||
// =============================================================================================================
|
||||
// Get the file info
|
||||
|
||||
// Only files can have inline disposition, zip archives cannot
|
||||
// https://stackoverflow.com/a/57994289
|
||||
contentDownload := r.URL.Query().Get("download")
|
||||
|
@ -95,27 +113,24 @@ func APIDownload(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
// Get the MIME type of the file
|
||||
var mimeType string
|
||||
var err error
|
||||
if item.MimeType == nil { // only if the MIME type of this item has not been set yet
|
||||
if item.MimeType == nil { // Only if the MIME type of this item has not been set yet
|
||||
_, mimeType, _, err = file.GetMimeType(fullPath, true)
|
||||
if err != nil {
|
||||
log.Errorf("ROUTES:Download - Error detecting MIME type: %v", err)
|
||||
} else if mimeType != "" {
|
||||
// GetMimeType() returns an empty string if it was a directory.
|
||||
// Update the cacheitem's MIME in the sharedCache.
|
||||
item.MimeType = &mimeType
|
||||
sharedcache.Cache.Add(relPath, item)
|
||||
sharedcache.Cache.Add(relPath, item) // Update the cacheitem's MIME in the sharedCache.
|
||||
} else {
|
||||
log.Errorf("ROUTES:Download - Failed to match a condition when checking a file's MIME - %s", fullPath)
|
||||
helpers.Return500Msg(w)
|
||||
helpers.Return500(w)
|
||||
}
|
||||
} else {
|
||||
mimeType = *item.MimeType
|
||||
}
|
||||
|
||||
// Get the encoding of this file
|
||||
var encoding string
|
||||
encoding = "utf-8" // fall back to utf-8
|
||||
encoding := "utf-8" // fall back to utf-8
|
||||
if item.Encoding == nil || *item.Encoding == "" { // only if the encoding of this item has not been set yet
|
||||
encoding, err = file.DetectFileEncoding(fullPath)
|
||||
if err != nil {
|
||||
|
@ -128,6 +143,11 @@ func APIDownload(w http.ResponseWriter, r *http.Request) {
|
|||
encoding = *item.Encoding
|
||||
}
|
||||
|
||||
// =============================================================================================================
|
||||
// Send the file to the client.
|
||||
// We are using `http.ServeContent()` since this allows us to catch and handle any missing files. `http.ServeFile()` returns
|
||||
// the default 404 page if the file is missing from the disk.
|
||||
|
||||
if config.GetConfig().HTTPNoMimeSniffHeader {
|
||||
w.Header().Set("X-Content-Type-Options", "nosniff")
|
||||
mimeType = file.CastTextMimes(mimeType)
|
||||
|
@ -138,32 +158,18 @@ func APIDownload(w http.ResponseWriter, r *http.Request) {
|
|||
w.Header().Set("Content-Type", mimeType+"; charset="+encoding)
|
||||
}
|
||||
|
||||
// =============================================================================================================
|
||||
// Send the file to the client.
|
||||
// We are using `http.ServeContent()` since this allows us to catch and handle any missing files. `http.ServeFile()` returns
|
||||
// the default 404 page if the file is missing from the disk.
|
||||
|
||||
// Open the file
|
||||
openFile, err := os.Open(fullPath)
|
||||
if err != nil {
|
||||
sharedcache.Cache.Remove(relPath) // remove it from the cache
|
||||
helpers.ReturnFake404Msg("file missing from disk, cache out of date", w)
|
||||
return
|
||||
}
|
||||
defer openFile.Close()
|
||||
|
||||
// Get the file info
|
||||
fileInfo, err := openFile.Stat()
|
||||
if err != nil {
|
||||
log.Errorf(`ROUTES:Download - Failed to stat file "%s" - %s`, fullPath, err)
|
||||
helpers.Return500Msg(w)
|
||||
helpers.Return500(w)
|
||||
return
|
||||
}
|
||||
|
||||
// If the file exists, serve it
|
||||
// If the file exists, serve it.
|
||||
http.ServeContent(w, r, fileInfo.Name(), fileInfo.ModTime(), openFile)
|
||||
} else {
|
||||
// Stream archive of the directory here
|
||||
// Stream archive of the directory.
|
||||
w.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s.zip"`, item.Name))
|
||||
helpers.ZipHandlerCompress(fullPath, w, r)
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ func APIList(w http.ResponseWriter, r *http.Request) {
|
|||
fileExists, mimeType, ext, err := file.GetMimeType(fullPath, true)
|
||||
if err != nil {
|
||||
log.Warnf("ROUTES:List - Error detecting MIME type: %v", err)
|
||||
helpers.Return500Msg(w)
|
||||
helpers.Return500(w)
|
||||
return
|
||||
}
|
||||
if !fileExists {
|
||||
|
|
|
@ -94,7 +94,7 @@ func APIThumbnail(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
if err != nil {
|
||||
log.Warnf(`ROUTES:Thumb - Error detecting MIME type for "%s". %v`, fullPath, err)
|
||||
helpers.Return500Msg(w)
|
||||
helpers.Return500(w)
|
||||
return
|
||||
}
|
||||
// Update the item's MIME in the cache.
|
||||
|
@ -112,7 +112,7 @@ func APIThumbnail(w http.ResponseWriter, r *http.Request) {
|
|||
imageBytes, err := file.ConvertToPNG(fullPath, mimeType)
|
||||
if err != nil {
|
||||
log.Warnf(`ROUTES:Thumb - Error converting "%s". %v`, fullPath, err)
|
||||
helpers.Return500Msg(w)
|
||||
helpers.Return500(w)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -121,7 +121,7 @@ func APIThumbnail(w http.ResponseWriter, r *http.Request) {
|
|||
img, err = png.Decode(bytes.NewReader(imageBytes))
|
||||
if err != nil {
|
||||
log.Warnf(`ROUTES:Thumb - Error decoding "%s". %v`, fullPath, err)
|
||||
helpers.Return500Msg(w)
|
||||
helpers.Return500(w)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -129,14 +129,14 @@ func APIThumbnail(w http.ResponseWriter, r *http.Request) {
|
|||
img, err = resizeImage(img, width, height, square, autoScale)
|
||||
if err != nil {
|
||||
log.Warnf(`ROUTES:Thumb - Error resizing "%s". %v`, fullPath, err)
|
||||
helpers.Return500Msg(w)
|
||||
helpers.Return500(w)
|
||||
return
|
||||
}
|
||||
|
||||
buf, err := file.CompressPNGFile(img, pngQuality)
|
||||
if err != nil {
|
||||
log.Warnf(`ROUTES:Thumb - Error compressing "%s". %v`, fullPath, err)
|
||||
helpers.Return500Msg(w)
|
||||
helpers.Return500(w)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue