Added default globe.svg for invalid favicons
Some checks failed
Run Integration Tests / test (push) Failing after 41s
Some checks failed
Run Integration Tests / test (push) Failing after 41s
This commit is contained in:
parent
66414952e8
commit
5032173609
8 changed files with 118 additions and 51 deletions
|
@ -36,7 +36,7 @@ var (
|
|||
imageURLMapMu sync.RWMutex
|
||||
)
|
||||
|
||||
func cacheImage(imageURL, imageID string, isThumbnail bool) (string, bool, error) {
|
||||
func cacheImage(imageURL, imageID string, imageType string) (string, bool, error) {
|
||||
if imageURL == "" {
|
||||
recordInvalidImageID(imageID)
|
||||
return "", false, fmt.Errorf("empty image URL for image ID %s", imageID)
|
||||
|
@ -44,10 +44,15 @@ func cacheImage(imageURL, imageID string, isThumbnail bool) (string, bool, error
|
|||
|
||||
// Construct the filename based on the image ID and type
|
||||
var filename string
|
||||
if isThumbnail {
|
||||
switch imageType {
|
||||
case "thumb":
|
||||
filename = fmt.Sprintf("%s_thumb.webp", imageID)
|
||||
} else {
|
||||
case "icon":
|
||||
filename = fmt.Sprintf("%s_icon.webp", imageID)
|
||||
case "full":
|
||||
filename = fmt.Sprintf("%s_full.webp", imageID)
|
||||
default:
|
||||
return "", false, fmt.Errorf("unknown image type: %s", imageType)
|
||||
}
|
||||
|
||||
// Make sure we store inside: config.DriveCache.Path / images
|
||||
|
@ -228,29 +233,23 @@ func handleImageServe(w http.ResponseWriter, r *http.Request) {
|
|||
// Adjust to read from config.DriveCache.Path / images
|
||||
cachedImagePath := filepath.Join(config.DriveCache.Path, "images", filename)
|
||||
|
||||
if hasExtension && imageType == "thumb" {
|
||||
// Requesting cached image (thumbnail or full)
|
||||
if hasExtension && (imageType == "thumb" || imageType == "icon") {
|
||||
if _, err := os.Stat(cachedImagePath); err == nil {
|
||||
// Update the modification time to now
|
||||
err := os.Chtimes(cachedImagePath, time.Now(), time.Now())
|
||||
if err != nil {
|
||||
printWarn("Failed to update modification time for %s: %v", cachedImagePath, err)
|
||||
}
|
||||
|
||||
// Determine content type based on file extension
|
||||
contentType := "image/webp"
|
||||
w.Header().Set("Content-Type", contentType)
|
||||
// Update the modification time
|
||||
_ = os.Chtimes(cachedImagePath, time.Now(), time.Now())
|
||||
w.Header().Set("Content-Type", "image/webp")
|
||||
w.Header().Set("Cache-Control", "public, max-age=31536000")
|
||||
http.ServeFile(w, r, cachedImagePath)
|
||||
return
|
||||
} else {
|
||||
// Cached image not found
|
||||
if config.DriveCacheEnabled {
|
||||
// Thumbnail should be cached, but not found
|
||||
serveMissingImage(w, r)
|
||||
if imageType == "icon" {
|
||||
serveGlobeImage(w, r)
|
||||
} else {
|
||||
serveMissingImage(w, r)
|
||||
}
|
||||
return
|
||||
}
|
||||
// Else, proceed to proxy if caching is disabled
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -326,8 +325,12 @@ func handleImageStatus(w http.ResponseWriter, r *http.Request) {
|
|||
invalidImageIDsMu.Unlock()
|
||||
|
||||
if isInvalid {
|
||||
// Image is invalid; inform the frontend by setting the missing image URL
|
||||
statusMap[id] = "/static/images/missing.svg"
|
||||
// Image is invalid; provide appropriate fallback
|
||||
if strings.HasSuffix(id, "_icon.webp") || strings.HasSuffix(id, "_icon") {
|
||||
statusMap[id] = "/images/globe.svg"
|
||||
} else {
|
||||
statusMap[id] = "/images/missing.svg"
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -335,11 +338,15 @@ func handleImageStatus(w http.ResponseWriter, r *http.Request) {
|
|||
extensions := []string{"webp", "svg"} // Extensions without leading dots
|
||||
imageReady := false
|
||||
|
||||
// Check thumbnail first
|
||||
for _, ext := range extensions {
|
||||
thumbFilename := fmt.Sprintf("%s_thumb.%s", id, ext)
|
||||
thumbPath := filepath.Join(config.DriveCache.Path, "images", thumbFilename)
|
||||
thumbPath := filepath.Join(config.DriveCache.Path, "images", fmt.Sprintf("%s_thumb.%s", id, ext))
|
||||
iconPath := filepath.Join(config.DriveCache.Path, "images", fmt.Sprintf("%s_icon.%s", id, ext))
|
||||
|
||||
if _, err := os.Stat(iconPath); err == nil {
|
||||
statusMap[id] = fmt.Sprintf("/image/%s_icon.%s", id, ext)
|
||||
imageReady = true
|
||||
break
|
||||
}
|
||||
if _, err := os.Stat(thumbPath); err == nil {
|
||||
statusMap[id] = fmt.Sprintf("/image/%s_thumb.%s", id, ext)
|
||||
imageReady = true
|
||||
|
@ -363,11 +370,13 @@ func handleImageStatus(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
// If neither is ready and image is not invalid
|
||||
if !imageReady {
|
||||
if !config.DriveCacheEnabled {
|
||||
// Hard cache is disabled; use the proxy URL
|
||||
statusMap[id] = fmt.Sprintf("/image/%s_thumb", id)
|
||||
// Distinguish favicon vs image fallback
|
||||
if strings.HasSuffix(id, "_icon.webp") || strings.HasSuffix(id, "_icon") {
|
||||
statusMap[id] = "/images/globe.svg"
|
||||
} else if !config.DriveCacheEnabled {
|
||||
statusMap[id] = "/images/missing.svg"
|
||||
}
|
||||
// Else, do not set statusMap[id]; the frontend will keep checking
|
||||
// else: leave it unset — frontend will retry
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -520,8 +529,25 @@ func serveMissingImage(w http.ResponseWriter, r *http.Request) {
|
|||
w.Header().Set("Cache-Control", "no-store, must-revalidate")
|
||||
w.Header().Set("Pragma", "no-cache")
|
||||
w.Header().Set("Expires", "0")
|
||||
if config.DriveCacheEnabled {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
}
|
||||
http.ServeFile(w, r, missingImagePath)
|
||||
}
|
||||
|
||||
func serveGlobeImage(w http.ResponseWriter, r *http.Request) {
|
||||
globePath := filepath.Join("static", "images", "globe.svg")
|
||||
|
||||
// Set error code FIRST
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
|
||||
// Now read the file and write it manually, to avoid conflict with http.ServeFile
|
||||
data, err := os.ReadFile(globePath)
|
||||
if err != nil {
|
||||
http.Error(w, "globe.svg not found", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "image/svg+xml")
|
||||
w.Header().Set("Cache-Control", "no-store, must-revalidate")
|
||||
w.Header().Set("Pragma", "no-cache")
|
||||
w.Header().Set("Expires", "0")
|
||||
_, _ = w.Write(data)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue