Echoing image gives 404

I am trying to display an image the name of which has been rawurlencode()ed, but it comes up with a 404.

$imgs = glob($dir.'/*.jpg');
foreach ($imgs as $image) {
  echo '  <img src="', $image, '" alt="">', "\n";
}

Given that glob() finds the image, I don’t understand why it doesn’t echo. I included an image called simple Fred and that gets echoed fine.

Echoing $image gives me events/20200123-New%20Year%20drinks%2C%201%20January.jpg which is what I expected.

The comma (%2C) in the url, maybe?

Isn’t that the reason for encoding the URL, so it’s no longer a comma? Or am I missing something?

Did you try a var_dump() of $imgs ?

My guess is a missing slash , but maybe not. Temporarily passing the GLOB_ERR flag might give a clue.
https://www.php.net/manual/en/function.glob.php

  • GLOB_ERR - Stop on read errors (like unreadable directories), by default errors are ignored.
1 Like

var_dump()ing just lists the 2 files and adding GLOB_ERR seems to make no difference.

A missing slash sounds like a goer but I don’t get the error with Fred.

I tried removing the %2C from the file name but that made no difference, but it does look to be something to do with the encoding…

I think that PHP glob(…) returns a PATH and the image SRC expects a URL. It is necessary to prefix the PATH with a leading forward slash or a URL.

Edit:

If it is possible to display a known image in the path then right-click, copy image location and compare with your image script.

1 Like

I’ve copied the image and one by one removed the %20 and %2C characters, and having removed the last one it works. I’ve also tried replacing the spaces with a + and that works. I’m not sure what this tells me…

Hmm, that isn’t intuitive. I would think that the “newer” rawurlencode syntax would work as well as the “historic” urlencode (i.e. both %20 and + for spaces would work)

Me too.

urlencode()ing the comma still doesn’t work, as that becomes the same as if I use rawurlencode().

¯\_(ツ)_/¯

What HTTP server are you using? What do their logs say?

I’m running Apache. There’s nothing in the error log, and the access log has

::1 - - [23/Jan/2020:20:25:49 +0100] “GET /www/~others/playing/noticeboard/events/20200101-New+Year+drinks±+1+January.jpg HTTP/1.1” 304 - “http://localhost/www/~others/playing/noticeboard/” “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36”
::1 - - [23/Jan/2020:20:25:49 +0100] “GET /www/~others/playing/noticeboard/events/20200123-New%20Year%20drinks%2C%201%20January.jpg HTTP/1.1” 404 1239 “http://localhost/www/~others/playing/noticeboard/” “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36”

plus other 304s and 200s

Wait. What’s with the ± after “drinks”?

%2C%201 is not being seen as a comma and space then a 1

An endian BOM thing?

1 Like

Ooh. I missed that!

Edit: Ah, wait - it’s a Discourse thing. Looking at what I copied and it was a plus followed by a minus. BUT that whole entry is a red herring - it’s a different image (one that “works”). :blush:

200 and 304 are to be expected. The 404 is the odd one out. Does the log help at all?

Short answer, I don’t think so, unless I’m missing something.

I have just tidied up my app and started a new access log so I can see the wood amongst the trees.

Again, there’s nowt in the error log.

The access log is thus

::1 - - [24/Jan/2020:09:09:57 +0100] "GET /www/~others/playing/noticeboard/ HTTP/1.1" 200 864 "http://localhost/www/~others/playing/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36"
::1 - - [24/Jan/2020:09:09:57 +0100] "GET /www/~others/playing/noticeboard/css/main.css HTTP/1.1" 304 - "http://localhost/www/~others/playing/noticeboard/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36"
::1 - - [24/Jan/2020:09:09:57 +0100] "GET /www/~others/playing/noticeboard/events/thumbs/20200504-Event+TBA+-+4+May.jpg HTTP/1.1" 304 - "http://localhost/www/~others/playing/noticeboard/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36"
::1 - - [24/Jan/2020:09:09:57 +0100] "GET /www/~others/playing/noticeboard/events/thumbs/20200123-New%20Year%20drinks%2C%201%20January.jpg HTTP/1.1" 404 1239 "http://localhost/www/~others/playing/noticeboard/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36"
::1 - - [24/Jan/2020:09:09:57 +0100] "GET /www/~others/playing/noticeboard/images/cork-board.png HTTP/1.1" 304 - "http://localhost/www/~others/playing/noticeboard/css/main.css" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36"

In this line, if you split it down into sections so you can see it more easily

Field Contents
ip address ::1
local id -
http userid -
date, time of request [24/Jan/2020:09:09:57 +0100]
http request “GET /www/~others/playing/noticeboard/events/thumbs/20200123-New%20Year%20drinks%2C%201%20January.jpg HTTP/1.1”
status code 404
size of object 1239
referrer http://localhost/www/~others/playing/noticeboard/
browser / user-agent “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36”

the 404 in the status code indicates that the file is not found. If you break your log entries down like that (there’s almost certainly a choice of tools to do it for you) you can see it’s getting a 404 when the image is requested.

I’d have thought it would need to be url-decoded when the name is inserted into your img src tag.

Yes, I understand the log, but it’s not telling me anything I didn’t know, that it can’t find the image. :frowning:

You mean

<img src="events/thumbs/20200123-New Year drinks, 1 January.jpg" alt="">

That seems counter-intuitive. However, I’m game to try anything but it didn’t work.

Sorry, I missed the part in your first post where you said the filename had already been URL-encoded. I wonder whether the problem is that it’s been URL-encoded, and when your request is received, the web server tries to URL-decode it, and then can’t find the file.

Interesting that the previous file has spaces encoded as + but this one uses percent format.

Yes, using urlencode() gives +; rawurlencode() gives %20. Both encode a comma as %2C. The script seems to have trouble with any % encoding, so if I want it to work, it seems I have to use urlencode() and avoid any special character other than a space.

Something to be said for uploading photos, storing the original name in a database table and just giving them a unique numeric id.

1 Like