LMS-Community / slimserver

Server for Squeezebox and compatible players. This server is also called Lyrion Music Server.
https://lyrion.org
Other
1.17k stars 294 forks source link

ImageProxy failing to resize web https images in now playing cover display - returning 404 #1182

Closed ericpapaluca closed 4 days ago

ericpapaluca commented 4 days ago

Before the issue description, I just want to say I love this project, and appreciate all the hard work that goes into it.

My LMS is Version: 8.5.2 - 1716215514 @ Sun May 26 17:49:55 CEST 2024

I think I've identified some odd behaviour in the ImageProxy service causing https image sources (Favourite radio station images, SoundCloud plugin images) resized via the ImageProxy to return 404. I've done my best to try and diagnose the issue, although this is my first time reading Perl and becoming acquainted with the inner workings of LMS so perhaps I haven't comprehensively covered everything.

Examples: In both these cases, cover art now playing is correctly displayed on Squeezer Android app and on my Squeezebox radio, which made trying to figure out of the cause of this issue more difficult.

Additionally, I am using the built-in image resizer, although switching it to the external option results in the same behaviour.

Radio: Given a config like below:

image You can see that the art is correctly populated in the library view, however the now playing view is simply showing the following:

image

The logs show the following

[24-10-15 20:36:21.8480] Slim::Web::ImageProxy::getImage (116) Get artwork for URL: imageproxy/https:/radiozora.fm/wp-content/uploads/2024/01/RADIO24-ok-1.jpg/image_1024x1024_f.jpg
[24-10-15 20:36:21.8495] Slim::Web::ImageProxy::__ANON__ (169) Found URL to get artwork: https:/radiozora.fm/wp-content/uploads/2024/01/RADIO24-ok-1.jpg
[24-10-15 20:36:21.85f83] Slim::Web::ImageProxy::getImage (116) Get artwork for URL: imageproxy/https:/radiozora.fm/wp-content/uploads/2024/01/RADIO24-ok-1.jpg/image_300x300_f.jpg
[24-10-15 20:36:21.8603] Slim::Web::ImageProxy::__ANON__ (169) Found URL to get artwork: https:/radiozora.fm/wp-content/uploads/2024/01/RADIO24-ok-1.jpg
[24-10-15 20:36:25.8493] Slim::Web::ImageProxy::_gotArtworkError (271) Unexpected failure fetching https:/radiozora.fm/wp-content/uploads/2024/01/RADIO24-ok-1.jpg: Couldn't resolve IP address for: 
[24-10-15 20:36:25.8500] Slim::Web::ImageProxy::_gotArtworkError (284) Artwork not found, returning 404: https:/radiozora.fm/wp-content/uploads/2024/01/RADIO24-ok-1.jpg

Where we see the entry Couldn't resolve IP address for:

Soundcloud:

This behaviour is the same as above, however the SoundCloud CDN image links are emitted into the logs instead:

[24-10-15 20:39:46.8023] Slim::Web::ImageProxy::_gotArtwork (244) Received artwork of type image/jpeg and 72456 bytes length
[24-10-15 20:39:49.8703] Slim::Web::ImageProxy::_gotArtworkError (271) Unexpected failure fetching https:/i1.sndcdn.com/artworks-dVzRbToUrLdgkuoV-Wn1s8Q-t500x500.jpg: Couldn't resolve IP address for: 
[24-10-15 20:39:49.8711] Slim::Web::ImageProxy::_gotArtworkError (284) Artwork not found, returning 404: https:/i1.sndcdn.com/artworks-dVzRbToUrLdgkuoV-Wn1s8Q-t500x500.jpg

One interesting thing of note is the successful got artwork with the byte length, although I am not sure this is relevant for this issue.

Attempted self-diagnosis

The first thing I noticed was the errors specifically referencing https:/<rest_of_url> as opposed to https://<rest_of_url>

Originally thinking this was an issue in LMS-Material passing the incorrect value for the ImageProxy, I noticed it is correct in my displayed HTML:

<img src="/imageproxy/https%3A%2F%2Fradiozora.fm%2Fwp-content%2Fuploads%2F2024%2F01%2FRADIO24-ok-1.jpg/image_1024x1024_f.jpg" loading="lazy" onerror="this.src=DEFAULT_COVER" class="np-cover">

We can see this URL correctly decodes to /imageproxy/https://radiozora.fm/wp-content/uploads/2024/01/RADIO24-ok-1.jpg/image_1024x1024_f.jpg, which rules out LMS-Material as the cause.

To verify this, I also noticed this behaviour is occurring in the default skin, which leads me to believe this issue is within LMS itself.

Interesting differentials:

  1. If I call the ImageProxy service without the resize component - e.g. /imageproxy/https%3A%2F%2Fradiozora.fm%2Fwp-content%2Fuploads%2F2024%2F01%2FRADIO24-ok-1.jpg/ then the image is redirected successfully. Perhaps this is why the SqueezeBox Radio and Squeezer app work - if they perform their own resizing.

  2. In both these cases, the path /music/current/cover.jpg returns the correct image, although it is a redirect, which may explain the behaviour as caused by 1.

Next steps Please let me know if I can provide other information - if it's suitable and you can guide me on the right path - I would be happy to submit a PR for review.

I think potentially the error may be occurring here based on the URL generation via regex, although that doesn't explain why it works for the library view (and this is without me fully understanding Perl's regex capabilities and with the assumption that this behaviour is being caused by the missing / in the request).

Additionally, the error Couldn't resolve IP address for: makes me wonder if there's some network problem going on here, although I'm not sure how to start a development environment for LMS to play around with these ideas and not compromise my existing server.

Once again thanks and please let me know how else I can help 😄

ericpapaluca commented 4 days ago

Adding on further, this is also applying to Spotty for me - with the following error:

[24-10-15 22:21:03.8468] Slim::Web::ImageProxy::getImage (116) Get artwork for URL: imageproxy/https:/i.scdn.co/image/ab67616d0000b273475ca6e5c1ce0ef70740c3c6/image_300x300_f.png
[24-10-15 22:21:03.8483] Slim::Web::ImageProxy::__ANON__ (169) Found URL to get artwork: https:/i.scdn.co/image/ab67616d0000b273475ca6e5c1ce0ef70740c3c6
[24-10-15 22:21:03.8540] Slim::Web::ImageProxy::getImage (116) Get artwork for URL: imageproxy/https:/i.scdn.co/image/ab67616d0000b273475ca6e5c1ce0ef70740c3c6/image_1024x1024_f.png
[24-10-15 22:21:03.8552] Slim::Web::ImageProxy::__ANON__ (169) Found URL to get artwork: https:/i.scdn.co/image/ab67616d0000b273475ca6e5c1ce0ef70740c3c6
[24-10-15 22:21:07.8615] Slim::Web::ImageProxy::_gotArtworkError (271) Unexpected failure fetching https:/i.scdn.co/image/ab67616d0000b273475ca6e5c1ce0ef70740c3c6: Couldn't resolve IP address for: 
[24-10-15 22:21:07.8622] Slim::Web::ImageProxy::_gotArtworkError (284) Artwork not found, returning 404: https:/i.scdn.co/image/ab67616d0000b273475ca6e5c1ce0ef70740c3c6
michaelherger commented 4 days ago

I'm a bit confused, as I'm using Spotty all day long (like thousands of other users). But all your URLs seem to be invalid: they have https:/some.domain.com: there should be a double slash after the https: https://some.domain.com. Are these all items played from favorites?

ericpapaluca commented 4 days ago

Hi @michaelherger, thanks for replying to this so quickly.

Yes you're right about the https:// missing, I tested something here (keep in mind I'm very Perl naive) and everything started working again!

The question is, why are my now playing URLs missing a slash?

To answer your question - no these aren't from favourites, most are directly from plugins (spotty, soundcloud), I always assumed this wasn't supported but after I noticed the favourites URL not loading either I decided to investigate further with the logs and found the case of the missing slash - very interesting!

From what I can see its the $path that's being passed to ImageProxy, where would that be coming from?

ericpapaluca commented 4 days ago

and I think I have found the problemo!

Usually I'm using LMS behind an nginx reverse proxy mylmsserver.home.network (for example) - this results in the following http://mylmsserver.home.network/imageproxy/https%3A%2F%2Fi1.sndcdn.com%2Fartworks-TNI6OCcsB6dAckHK-m8EuoA-t500x500.jpg/image_1024x1024_f.jpg which results in the missing slash.

If I go around nginx and instead go to LMS directly like this: http://192.168.1.65:9001/imageproxy/https%3A%2F%2Fi1.sndcdn.com%2Fartworks-TNI6OCcsB6dAckHK-m8EuoA-t500x500.jpg/image_1024x1024_f.jpg then it works as it is!

I'm going to call this an nginx/bad reverse proxy issue - and hope this helps someone in the future if they ever have this behaviour!

Thanks again @michaelherger, going to close this one off 😄 .. now to figure out how to fix nginx!

ericpapaluca commented 4 days ago

and before I blow up github any further, here's the nginx fix:

Per https://www.mattgerega.com/2022/05/20/nginx-reverse-proxy-a-slash-makes-all-the-difference/

I modified my server block in my nginx.conf from

 server {
                listen                          80;
                server_name                     mylmsserver.home.network;

                location / {
                        proxy_pass              http://192.168.1.65:9001/;
                        proxy_set_header        Host $host;
                }

to

 server {
                listen                          80;
                server_name                     mylmsserver.home.network;

                location / {
                        proxy_pass              http://192.168.1.65:9001;
                        proxy_set_header        Host $host;
                }

and all was right in the world, hope this maybe helps someone else!