Connecting Tech Pros Worldwide Forums | Help | Site Map

how can I tell if a remote file is an image

ebobnar
Guest
 
Posts: n/a
#1: Jul 17 '05
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

Dennis Biletsky
Guest
 
Posts: n/a
#2: Jul 17 '05

re: how can I tell if a remote file is an image


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" <ebobnar74@yahoo.com> ???????/???????? ? ???????? ?????????:
news:c903769f.0404020053.3eadbfea@posting.google.c om...[color=blue]
> 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[/color]


Ian.H
Guest
 
Posts: n/a
#3: Jul 17 '05

re: how can I tell if a remote file is an image


Please learn to post correctly...

[ http://tk.digiserv.net/tofu.txt ]


On Fri, 02 Apr 2004 12:03:30 +0300, Dennis Biletsky wrote:
[color=blue]
> 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[/color]


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/

Dennis Biletsky
Guest
 
Posts: n/a
#4: Jul 17 '05

re: how can I tell if a remote file is an image



"ebobnar" <ebobnar74@yahoo.com> ???????/???????? ? ???????? ?????????:
news:c903769f.0404020053.3eadbfea@posting.google.c om...[color=blue]
> 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[/color]

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


Ian.H
Guest
 
Posts: n/a
#5: Jul 17 '05

re: how can I tell if a remote file is an image


On Fri, 02 Apr 2004 16:50:07 +0300, Dennis Biletsky wrote:


[ snip ]

[color=blue][color=green]
>> 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[/color]
>
> Perhaps, this function will work better.
> http://www.php.net/manual/en/functio...-imagetype.php[/color]


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/

Dennis Biletsky
Guest
 
Posts: n/a
#6: Jul 17 '05

re: how can I tell if a remote file is an image


"Ian.H" <ian@WINDOZEdigiserv.net> ???????/???????? ? ???????? ?????????:
news:pan.2004.04.02.13.02.05.468000@bubbleboy.digi serv.net...[color=blue]
> Please learn to post correctly...
>
> [ http://tk.digiserv.net/tofu.txt ]
>
>
> On Fri, 02 Apr 2004 12:03:30 +0300, Dennis Biletsky wrote:
>[color=green]
> > Try to look on extension of $redirect_to. If it will image extension[/color][/color]
(.jpg,[color=blue][color=green]
> > .gif, .png, etc), so that is picture, otherwise other file type[/color]
>
>
> 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/
>[/color]

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.


Ian.H
Guest
 
Posts: n/a
#7: Jul 17 '05

re: how can I tell if a remote file is an image


On Fri, 02 Apr 2004 17:45:05 +0300, Dennis Biletsky wrote:
[color=blue]
> "Ian.H" <ian@WINDOZEdigiserv.net> ???????/???????? ? ???????? ?????????:
> news:pan.2004.04.02.13.02.05.468000@bubbleboy.digi serv.net...[color=green]
>> Please learn to post correctly...
>>
>> [ http://tk.digiserv.net/tofu.txt ]
>>
>>
>> On Fri, 02 Apr 2004 12:03:30 +0300, Dennis Biletsky wrote:
>>[color=darkred]
>> > Try to look on extension of $redirect_to. If it will image extension[/color][/color]
> (.jpg,[color=green][color=darkred]
>> > .gif, .png, etc), so that is picture, otherwise other file type[/color]
>>
>>
>> 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.[/color][/color]

[color=blue]
> 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.[/color]


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/

Dennis Biletsky
Guest
 
Posts: n/a
#8: Jul 17 '05

re: how can I tell if a remote file is an image



"Ian.H" <ian@WINDOZEdigiserv.net> ???????/???????? ? ???????? ?????????:
news:pan.2004.04.02.15.43.49.469000@bubbleboy.digi serv.net...[color=blue]
> On Fri, 02 Apr 2004 17:45:05 +0300, Dennis Biletsky wrote:
>[color=green]
> > "Ian.H" <ian@WINDOZEdigiserv.net> ???????/???????? ? ???????? ?????????:
> > news:pan.2004.04.02.13.02.05.468000@bubbleboy.digi serv.net...[color=darkred]
> >> 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[/color]
> > (.jpg,[color=darkred]
> >> > .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[/color][/color][/color]
this[color=blue][color=green][color=darkred]
> >> proposed solution.. although I cna only guess that this is pretty much
> >> what getimagesize() does too.. although it may be faster to jkust read[/color][/color][/color]
the[color=blue][color=green][color=darkred]
> >> header compared to whatever other tests getimagesize() performs too.[/color][/color]
>
>[color=green]
> > 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[/color][/color]
do[color=blue][color=green]
> > that. You should know file structure of various pictures' formats.[/color]
>
>
> 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/
>[/color]

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


David Precious
Guest
 
Posts: n/a
#9: Jul 17 '05

re: how can I tell if a remote file is an image


ebobnar wrote:
[color=blue]
> 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?[/color]

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/

Andy Hassall
Guest
 
Posts: n/a
#10: Jul 17 '05

re: how can I tell if a remote file is an image


On Fri, 02 Apr 2004 14:00:25 GMT, "Ian.H" <ian@WINDOZEdigiserv.net> wrote:
[color=blue]
>On Fri, 02 Apr 2004 16:50:07 +0300, Dennis Biletsky wrote:
>[color=green][color=darkred]
>>> 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?[/color]
>>
>> Perhaps, this function will work better.
>> http://www.php.net/manual/en/functio...-imagetype.php[/color]
>
>
>If the image hasn't been optiomised (ie: had the thumbnail (exif image)
>removed).[/color]

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 <andy@andyh.co.uk> / Space: disk usage analysis tool
http://www.andyh.co.uk / http://www.andyhsoftware.co.uk/space
ebobnar
Guest
 
Posts: n/a
#11: Jul 17 '05

re: how can I tell if a remote file is an image


Thank you to everyone who replied to my question.

I haven't solved it yet. Apparently exif_imagetype only works on php[color=blue]
>= php 4.3.0, and I am working with php 4.2.2. I tried the reading the[/color]
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
Chung Leong
Guest
 
Posts: n/a
#12: Jul 17 '05

re: how can I tell if a remote file is an image


"David Precious" <pinkmeat@preshweb.co.uk> wrote in message
news:1080942326.74016.0@iris.uk.clara.net...[color=blue]
> 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.[/color]

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);


Chung Leong
Guest
 
Posts: n/a
#13: Jul 17 '05

re: how can I tell if a remote file is an image


"ebobnar" <ebobnar74@yahoo.com> wrote in message
news:c903769f.0404020053.3eadbfea@posting.google.c om...[color=blue]
> 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");[/color]

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.


ebobnar
Guest
 
Posts: n/a
#14: Jul 17 '05

re: how can I tell if a remote file is an image


Thanks again to everyone who responded.

I have tried everyones suggestions, but still have not been completely
sucessful.
[color=blue]
>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[/color]
thing[color=blue]
>just to check it out.[/color]

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.
[color=blue]
>getimagesize() at most reads 12 bytes from the stream, so I don't[/color]
think file[color=blue]
>size is an issue here. The problem, it appears, is that the PHP isn't[/color]
timing[color=blue]
>out quickly when the server doesn't respond or if the domain name is
>invalid.[/color]

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.
Closed Thread


Similar PHP bytes