By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,825 Members | 1,685 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,825 IT Pros & Developers. It's quick & easy.

how can I tell if a remote file is an image

P: n/a
I've written a link aliasing script that allows users to rewrite urls
on their web pages. The crux of the script is the following:

if(getimagesize($redirect_to) == 0)
header("Location: $redirect_to");
else
include("$redirect_to");

Which uses getimagesize() to determine if the link specified in
$redirect_to points to an image (i.e img src) in which case it should
include the image in the page, or if the link points to another
website (i.e. a href), in which case I use the header method to
redirect to that page when the link alias is called.

So far this script has been working great, but I recently had a
customer run it under php4.2.2 and the getimagesize is taking approx.
160 seconds to execute.

Can anyone think of a different way to tell if a remote file is an
image? And also, has anyone else experienced this kind of behavior
with getimagesize when running php4.2.2?

Assistance is really appreciated.

Thanks,

Esoos
Jul 17 '05 #1
Share this Question
Share on Google+
13 Replies


P: n/a
Try to look on extension of $redirect_to. If it will image extension (.jpg,
..gif, .png, etc), so that is picture, otherwise other file type

"ebobnar" <eb*******@yahoo.com> ???????/???????? ? ???????? ?????????:
news:c9**************************@posting.google.c om...
I've written a link aliasing script that allows users to rewrite urls
on their web pages. The crux of the script is the following:

if(getimagesize($redirect_to) == 0)
header("Location: $redirect_to");
else
include("$redirect_to");

Which uses getimagesize() to determine if the link specified in
$redirect_to points to an image (i.e img src) in which case it should
include the image in the page, or if the link points to another
website (i.e. a href), in which case I use the header method to
redirect to that page when the link alias is called.

So far this script has been working great, but I recently had a
customer run it under php4.2.2 and the getimagesize is taking approx.
160 seconds to execute.

Can anyone think of a different way to tell if a remote file is an
image? And also, has anyone else experienced this kind of behavior
with getimagesize when running php4.2.2?

Assistance is really appreciated.

Thanks,

Esoos

Jul 17 '05 #2

P: n/a
Please learn to post correctly...

[ http://tk.digiserv.net/tofu.txt ]
On Fri, 02 Apr 2004 12:03:30 +0300, Dennis Biletsky wrote:
Try to look on extension of $redirect_to. If it will image extension (.jpg,
.gif, .png, etc), so that is picture, otherwise other file type

LOL!

This is m$ "thinking".. and most certainly _not_ how it _really_ works.

fopen() / fread() / fclose() would work a _lot_ more effectively than this
proposed solution.. although I cna only guess that this is pretty much
what getimagesize() does too.. although it may be faster to jkust read the
header compared to whatever other tests getimagesize() performs too.

Regards,

Ian

--
Ian.H
digiServ Network
London, UK
http://digiserv.net/

Jul 17 '05 #3

P: n/a

"ebobnar" <eb*******@yahoo.com> ???????/???????? ? ???????? ?????????:
news:c9**************************@posting.google.c om...
I've written a link aliasing script that allows users to rewrite urls
on their web pages. The crux of the script is the following:

if(getimagesize($redirect_to) == 0)
header("Location: $redirect_to");
else
include("$redirect_to");

Which uses getimagesize() to determine if the link specified in
$redirect_to points to an image (i.e img src) in which case it should
include the image in the page, or if the link points to another
website (i.e. a href), in which case I use the header method to
redirect to that page when the link alias is called.

So far this script has been working great, but I recently had a
customer run it under php4.2.2 and the getimagesize is taking approx.
160 seconds to execute.

Can anyone think of a different way to tell if a remote file is an
image? And also, has anyone else experienced this kind of behavior
with getimagesize when running php4.2.2?

Assistance is really appreciated.

Thanks,

Esoos


Perhaps, this function will work better.
http://www.php.net/manual/en/functio...-imagetype.php
Jul 17 '05 #4

P: n/a
On Fri, 02 Apr 2004 16:50:07 +0300, Dennis Biletsky wrote:
[ snip ]

Can anyone think of a different way to tell if a remote file is an
image? And also, has anyone else experienced this kind of behavior
with getimagesize when running php4.2.2?

Assistance is really appreciated.

Thanks,

Esoos


Perhaps, this function will work better.
http://www.php.net/manual/en/functio...-imagetype.php

If the image hasn't been optiomised (ie: had the thumbnail (exif image)
removed).

Regards,

Ian

--
Ian.H
digiServ Network
London, UK
http://digiserv.net/

Jul 17 '05 #5

P: n/a
"Ian.H" <ia*@WINDOZEdigiserv.net> ???????/???????? ? ???????? ?????????:
news:pa****************************@bubbleboy.digi serv.net...
Please learn to post correctly...

[ http://tk.digiserv.net/tofu.txt ]
On Fri, 02 Apr 2004 12:03:30 +0300, Dennis Biletsky wrote:
Try to look on extension of $redirect_to. If it will image extension (.jpg, .gif, .png, etc), so that is picture, otherwise other file type

LOL!

This is m$ "thinking".. and most certainly _not_ how it _really_ works.

fopen() / fread() / fclose() would work a _lot_ more effectively than this
proposed solution.. although I cna only guess that this is pretty much
what getimagesize() does too.. although it may be faster to jkust read the
header compared to whatever other tests getimagesize() performs too.

Regards,

Ian

--
Ian.H
digiServ Network
London, UK
http://digiserv.net/


fread() is way that works in any case, but you will need analyze file
signature to identify what type of that file and you should now how to do
that. You should know file structure of various pictures' formats.
Jul 17 '05 #6

P: n/a
On Fri, 02 Apr 2004 17:45:05 +0300, Dennis Biletsky wrote:
"Ian.H" <ia*@WINDOZEdigiserv.net> ???????/???????? ? ???????? ?????????:
news:pa****************************@bubbleboy.digi serv.net...
Please learn to post correctly...

[ http://tk.digiserv.net/tofu.txt ]
On Fri, 02 Apr 2004 12:03:30 +0300, Dennis Biletsky wrote:
> Try to look on extension of $redirect_to. If it will image extension (.jpg, > .gif, .png, etc), so that is picture, otherwise other file type

LOL!

This is m$ "thinking".. and most certainly _not_ how it _really_ works.

fopen() / fread() / fclose() would work a _lot_ more effectively than this
proposed solution.. although I cna only guess that this is pretty much
what getimagesize() does too.. although it may be faster to jkust read the
header compared to whatever other tests getimagesize() performs too.


fread() is way that works in any case, but you will need analyze file
signature to identify what type of that file and you should now how to do
that. You should know file structure of various pictures' formats.

Like.. the first 4 bytes of the file (in most cases)? Don't really need to
know much about the actual structure of the rest of the data.. just the
header.

$fp = @fopen('foo.jpg'm 'rb');
if ($fp) {
$fh = @fread($fp, 4);
@fclose($fp);
}

switch ($fh) {
'JPEG': /* File is a JPEG image */; break;
'GIF.': /* File is a GIF image */; break;
[...]
default: /* File == unknown / invalid type */
}

This example is _very_ crude and I haven't double checked to see exactly
how many bytes of the header would need to be read in (I think it
differs between 2 and 4.. but maybe wrong).. but should work just fine and
possible quicker than getimagesize().. although I haven't tested any of
this =)

Regards,

Ian

--
Ian.H
digiServ Network
London, UK
http://digiserv.net/

Jul 17 '05 #7

P: n/a

"Ian.H" <ia*@WINDOZEdigiserv.net> ???????/???????? ? ???????? ?????????:
news:pa****************************@bubbleboy.digi serv.net...
On Fri, 02 Apr 2004 17:45:05 +0300, Dennis Biletsky wrote:
"Ian.H" <ia*@WINDOZEdigiserv.net> ???????/???????? ? ???????? ?????????:
news:pa****************************@bubbleboy.digi serv.net...
Please learn to post correctly...

[ http://tk.digiserv.net/tofu.txt ]
On Fri, 02 Apr 2004 12:03:30 +0300, Dennis Biletsky wrote:

> Try to look on extension of $redirect_to. If it will image extension

(.jpg,
> .gif, .png, etc), so that is picture, otherwise other file type
LOL!

This is m$ "thinking".. and most certainly _not_ how it _really_ works.

fopen() / fread() / fclose() would work a _lot_ more effectively than this proposed solution.. although I cna only guess that this is pretty much
what getimagesize() does too.. although it may be faster to jkust read the header compared to whatever other tests getimagesize() performs too.
fread() is way that works in any case, but you will need analyze file
signature to identify what type of that file and you should now how to

do that. You should know file structure of various pictures' formats.

Like.. the first 4 bytes of the file (in most cases)? Don't really need to
know much about the actual structure of the rest of the data.. just the
header.

$fp = @fopen('foo.jpg'm 'rb');
if ($fp) {
$fh = @fread($fp, 4);
@fclose($fp);
}

switch ($fh) {
'JPEG': /* File is a JPEG image */; break;
'GIF.': /* File is a GIF image */; break;
[...]
default: /* File == unknown / invalid type */
}

This example is _very_ crude and I haven't double checked to see exactly
how many bytes of the header would need to be read in (I think it
differs between 2 and 4.. but maybe wrong).. but should work just fine and
possible quicker than getimagesize().. although I haven't tested any of
this =)

Regards,

Ian

--
Ian.H
digiServ Network
London, UK
http://digiserv.net/


Yes, in common, first several bytes, but you should analyze it. By, the way,
JPEG some time has JFIF signature :). Anyway, I agree that your version will
work in any case.

Regards,
Dennis
Jul 17 '05 #8

P: n/a
ebobnar wrote:
Can anyone think of a different way to tell if a remote file is an
image? And also, has anyone else experienced this kind of behavior
with getimagesize when running php4.2.2?


If you're willing to trust the remote server to correctly report the
Content-Type, it'd be a lot more efficient than retrieving the whole thing
just to check it out.

Perhaps something along the general lines of:

$fh = fsockopen($host,80);
if ($fh)
{
fputs($fh,"HEAD $url HTTP/1.0\n\n");
$resp = fgets($fh,2048);
if (preg_match("/Content-Type:(.+)/",$resp,$match))
{
print "Content type is : " . $match[1];
}
fclose($fh);
}

Of course you'd have to parse the URL they've entered to get the hostname
and path correct, but that shouldn't be too hard.

Cheers

Dave P
--
David Precious
http://www.preshweb.co.uk/

Jul 17 '05 #9

P: n/a
On Fri, 02 Apr 2004 14:00:25 GMT, "Ian.H" <ia*@WINDOZEdigiserv.net> wrote:
On Fri, 02 Apr 2004 16:50:07 +0300, Dennis Biletsky wrote:
Can anyone think of a different way to tell if a remote file is an
image? And also, has anyone else experienced this kind of behavior
with getimagesize when running php4.2.2?


Perhaps, this function will work better.
http://www.php.net/manual/en/functio...-imagetype.php

If the image hasn't been optiomised (ie: had the thumbnail (exif image)
removed).


Actually, despite being a part of the EXIF extension, this function doesn't
actually have anything to do with EXIF. If you look at the source, it's just a
wrapper that calls back into php_getimagetype in standard/image.c, which does a
read of the first few bytes pretty much as you posted elsewhere in this thread.

The php_getimagetype C function is also used by the PHP function getimagesize.

--
Andy Hassall <an**@andyh.co.uk> / Space: disk usage analysis tool
http://www.andyh.co.uk / http://www.andyhsoftware.co.uk/space
Jul 17 '05 #10

P: n/a
Thank you to everyone who replied to my question.

I haven't solved it yet. Apparently exif_imagetype only works on php
= php 4.3.0, and I am working with php 4.2.2. I tried the reading the

header for image identifiers, like so:

$fp = @fopen("$redirect_to", 'rb');
if ($fp) {
$fh = @fread($fp, 12);
@fclose($fp);
}

if (preg_match("/GIF87|GIF88|GIF89|JFIF|hsi1|MM|II|IIN1|PNG|BM|P1|P 4|P2|P5|P3|P6/i",
$fh)) {
include("$redirect_to");
} else {
header("Location: $redirect_to");
}

This improved things somewhat, execution time dropped from about 160
sec to about 80 sec, but still takes much too long to be practical.

I appreciate everyones feedback, and I am continuing to look for a way
to solve this problem.

Thanks,

Esoos
Jul 17 '05 #11

P: n/a
"David Precious" <pi******@preshweb.co.uk> wrote in message
news:10****************@iris.uk.clara.net...
If you're willing to trust the remote server to correctly report the
Content-Type, it'd be a lot more efficient than retrieving the whole thing
just to check it out.


getimagesize() at most reads 12 bytes from the stream, so I don't think file
size is an issue here. The problem, it appears, is that the PHP isn't timing
out quickly when the server doesn't respond or if the domain name is
invalid.

Reduce default_socket_time so that getimagesize fails quickly, instead of
160 seconds that this customer has set:

$dst = ini_set('default_socket_timeout', 5);
getimagesize($redirect_to);
ini_set('default_socket_timeout', $dst);
Jul 17 '05 #12

P: n/a
"ebobnar" <eb*******@yahoo.com> wrote in message
news:c9**************************@posting.google.c om...
I've written a link aliasing script that allows users to rewrite urls
on their web pages. The crux of the script is the following:

if(getimagesize($redirect_to) == 0)
header("Location: $redirect_to");
else
include("$redirect_to");


BTW: You've actually written a script that allows users to take over your
server. Use readfile(), not include(), to print the content of a remote
page.
Jul 17 '05 #13

P: n/a
Thanks again to everyone who responded.

I have tried everyones suggestions, but still have not been completely
sucessful.
If you're willing to trust the remote server to correctly report the
Content-Type, it'd be a lot more efficient than retrieving the whole thingjust to check it out.
I wrote a function, similar to the one in this post:

function display_content_type($hostname, $file) {

$ip = gethostbyname($hostname);
$fp = fsockopen($ip, 80, &$errno, &$errstr);

if ($fp)
{
fputs($fp, "GET " . $file . " HTTP/1.0\r\n" .
"Host: $hostname\r\n" .
"Accept: text/html\r\n" .
"Accept: text/plain\r\n\r\n" );

$src = '';
while (!feof ($fp)) {
$src .= fgets($fp, 4096);
if (preg_match("/Content-Type:(.+)/", $src, $match))
{
print "Content type is : " . $match[1];
fclose ($fp);
exit;
}
}
}
}

This works well with when called with arguments like:

display_content_type("http://www.yahoo.com", "/index.html");

but fails completely when called like:

display_content_type("http://www.qksrv.net",
"/click-1469122-7154067");

Also, runs extremely slow under php 4.2.2.
getimagesize() at most reads 12 bytes from the stream, so I don't think filesize is an issue here. The problem, it appears, is that the PHP isn't timingout quickly when the server doesn't respond or if the domain name is
invalid.


I profiled the code very closely, and was able to tell that it was
precisely the getimagesize() function that was taking 180 seconds to
complete. I don't think that the program is failing to retrieve the
images, because if I wait 180 seconds for getimagesize() to complete,
then the images are downloaded and displayed normally.

I also tried just using:

header("Location: $redirect_to");

for both images and web pages, and it works pretty well, but fails
when the link to the image is redirected to another site (I imagine
for server load balancing, but I digress...)

I am thinking that the problem is php 4.2.2. It seems that any file
manipulation functions that access remote files run really slow. I'm
not sure if this is the case but that's my guess.

The question now stands: if I just use the header("Location:
$redirect_to");
statement, is there a way to determine if the link is being redirected
(that would run quickly on php 4.2.2?) Does php have a function that
does this?

I would like to do something like the following pseudocode:

header("Location: $redirect_to");
if ($status_code == "3.x.x") {
header("Location: $redirect_to_whateverpage_is specified in the
redirect header");
}
also, thanks to Chung Leong for the security heads up.
Jul 17 '05 #14

This discussion thread is closed

Replies have been disabled for this discussion.