krateng / maloja

Self-hosted music scrobble database to create personal listening statistics and charts
https://maloja.krateng.ch
GNU General Public License v3.0
1.18k stars 69 forks source link

Cached images do not include Content-Type header #349

Open TheLastZombie opened 7 months ago

TheLastZombie commented 7 months ago

When directly accessing a cached image on a Maloja instance (for example, this one), the browser interprets the binary file as text instead of showing the image.

Actual vs. expected behavior:

The problem seems to be that Bottle tries to guess the file's MIME type from its extension (instead of relying on magic bytes). Since the cached images do not have an extension, Bottle falls back to a Content-Type of text/html.

One way to work around this could be to determine the MIME type ourselves (using python-magic):

diff --git a/maloja/server.py b/maloja/server.py
index 9090630..25fc4a0 100644
--- a/maloja/server.py
+++ b/maloja/server.py
@@ -3,6 +3,7 @@ import os
 from threading import Thread
 from importlib import resources
 import time
+from magic import from_file

 # server stuff
@@ -154,7 +155,8 @@ def static_image(pth):

 @webserver.route("/cacheimages/<uuid>")
 def static_proxied_image(uuid):
-   return static_file(uuid,root=data_dir['cache']('images'))
+   mimetype = from_file(os.path.join(data_dir['cache']('images'),uuid),True)
+   return static_file(uuid,root=data_dir['cache']('images'),mimetype=mimetype)

 @webserver.route("/login")
 def login():

But a cleaner way would probably be to save the files with an extension to begin with, so we don't have to retrieve the MIME type over and over.

duckfromdiscord commented 7 months ago

I have also had this issue a couple times