lighttpd forum lighty > Redirecting hotlinked images to a descriptive Web page

Posted by Ian Evans
on 19.07.2006 00:29
I'm trying to wrap my head around converting Tom Sherman's method of 
redirecting hotlinked images to a descriptive web page from Apache rules 
to lighty rule. His method allows you to give context to the image, run 
ads, etc. This is based on his entry at: 
http://underscorebleach.net/jotsheet/2004/11/stop-image-hotlinking-tutorial-htaccess-apache

I'm not sure of the most efficient way to do this. If one of the 
mod_rewrite experts in this forum wants to take a run at it, I think 
it'd make a great addition to the hotlinking examples in the lighttpd 
wiki.

Anyway here's the Apache code:

RewriteCond %{REQUEST_FILENAME} \.(gif|jpe?g|png)$ [NC]
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !yoursite\.com [NC]
RewriteCond %{HTTP_REFERER} !anothersite\.com [NC]
RewriteCond %{HTTP_REFERER} !google\. [NC]
RewriteCond %{HTTP_REFERER} !search\?q=cache [NC]
RewriteRule (.*) /view_image.shtml?/$1 [R,NC,L]

Thanks in advance for your help!
Posted by Ian Evans
on 21.07.2006 07:50
I thought something like this would work, but it doesn't seem to do 
anything. Please keep in mind that my forte is comedy, not regex. ;-)

$HTTP["url"] =~ "\.(gif|jpe?g|png)$" {
$HTTP["referer"] !~ "^($|http://[^/]*mysite\.com|search\?q=cache)" {
url.redirect = ("\.(gif|jpe?g|png)$" => 
"http://www.mysite.com/image_handler.php")
}
}

Also in Apache, the image_handler file gets passed the requested 
filename so you can do db lookups etc.

Any advice on why the above isn't working?
Posted by Ingo Fabbri
on 21.07.2006 10:32
Ian Evans wrote:
> I thought something like this would work, but it doesn't seem to do 
> anything. Please keep in mind that my forte is comedy, not regex. ;-)
> 
> $HTTP["url"] =~ "\.(gif|jpe?g|png)$" {
> $HTTP["referer"] !~ "^($|http://[^/]*mysite\.com|search\?q=cache)" {
> url.redirect = ("\.(gif|jpe?g|png)$" => 
> "http://www.mysite.com/image_handler.php")
> }
> }
> 
> Also in Apache, the image_handler file gets passed the requested 
> filename so you can do db lookups etc.
> 
> Any advice on why the above isn't working?

image_handler.php needs some GET arguments to know what image should be 
displayed.

so now you have to extract (via regex) the image filename from the url 
and put it as argument to image_handler.php

e.g. something like that

url.redirect = ("(/.*\.(gif|jpe?g|png))$" =>
> "http://www.mysite.com/image_handler.php$1" )
Posted by Ian Evans
on 21.07.2006 17:35
> url.redirect = ("(/.*\.(gif|jpe?g|png))$" =>
>> "http://www.mysite.com/image_handler.php$1" )

Now that I think about it, I should probaly be using url.rewrite. In the 
Tom Sherman Apache method, the address bar still shows the image url.

-=BUT=- I'm still not getting the rules to trigger. Is there anything 
wrong in my initial $HTTP["url"] or $HTTP["referer"] regex's?
on 21.07.2006 20:00
> image_handler.php needs some GET arguments to know what image should be 
> displayed.

image_handler.php may need nothing, because of $_SERVER['REQUEST_URI'] 
;)
Posted by Ian Evans
on 21.07.2006 21:07
Vyacheslav Chernousov wrote:
> image_handler.php may need nothing, because of $_SERVER['REQUEST_URI'] 
> ;)

It doesn't need it right now in the Apache version I'm currently using. 
In fact, under Apache I'm not currently using the Apache mod_rewrite 
I've detailed above since I just use a custom 403 handler.

I'm trying to translate the version I've detailed in the initial message 
since lighty doesn't have a dynamic 403 handler.
on 21.07.2006 21:37
> since lighty doesn't have a dynamic 403 handler.

Try to do next thing. It's very stupid, but I hope it will work.

server.errorfile-prefix =  "/some/dir/for/errors/"

and in /some/dir/for/errors/ upload files with your own content, but 
with names:

400.html
401.html
403.html
404.html
500.html
...

In your 403.html make a javascript which sets some cookie to browser 
(like 'loc='+window.location) and after that it redirects to /403.php, 
where you can get cookie "loc" with information about url where 403 
really happens.

Baahh... very stupid? Yeah :) But seems there are no another way.
on 21.07.2006 21:39
> Baahh... very stupid? Yeah :) But seems there are no another way.

Hmmmm... not sure it will work in IE when "Show friendly HTTP error 
messages" is checked.
Posted by Ian Evans
on 21.07.2006 22:52
Vyacheslav Chernousov wrote:

> Try to do next thing. It's very stupid, but I hope it will work.
> server.errorfile-prefix =  "/some/dir/for/errors/"

But, with the correct regex, shouldn't the $HTTP["url"] and 
$HTTP["referer"] coding I've got above work? I'm just not sure why it's 
not working unless there's an error in my regex.
on 21.07.2006 23:05
> shouldn't the $HTTP["url"] and 
> $HTTP["referer"] coding I've got above work?

Aren't both these conditions INSIDE one more condition like 
$HTTP["host"]?
Seems lighty has bug with deep nested conditions, check my post about 
it: http://forum.lighttpd.net/topic/189
May be it's the same error. I'm not sure it's fixed. Try to simplify 
your conditions as much as possible and test it.
Posted by Ian Evans
on 22.07.2006 07:43
Vyacheslav Chernousov wrote:

> Seems lighty has bug with deep nested conditions, check my post about 
> it: http://forum.lighttpd.net/topic/189

That'd be a problem, eh?
on 22.07.2006 10:03
Ian Evans wrote:
> That'd be a problem, eh?

Did you test it on latest lighttpd version from svn? If yes and problem 
is still not fixed, let's write a ticket to jan. Let me know please.
Posted by Ian Evans
on 22.07.2006 16:05
Vyacheslav Chernousov wrote:
> Did you test it on latest lighttpd version from svn? If yes and problem 
> is still not fixed, let's write a ticket to jan. Let me know please.

Hopefully I can grab the code Sunday night.
Posted by Ian Evans
on 24.07.2006 06:59
Vyacheslav Chernousov wrote:
> Did you test it on latest lighttpd version from svn? If yes and problem 

I tested the following under the latest code and the rule was not 
followed:

$HTTP["url"] =~ "\.(JPG|jpe?g|png)$" {
$HTTP["referer"] !~ "^($|http://[^/]*digitalhit\.com)" {
url.rewrite = ("(/.*\.(JPG|jpe?g|png))$" => 
"http://www.digitalhit.com/dhe403.shtml" )
}
}
Posted by Jan Kneschke
on 24.07.2006 08:18
1. url.rewrite doesn't work inside a HTTP["url"] conditional.
2. you want to use a redirect as you leave the the host
3. (?i) switch to case-insensitive mode.
4. http://trac.lighttpd.net/trac/wiki/HowToFightDeepLinking

$HTTP["referer"] !~ "^($|http://[^/]*digitalhit\.com)" {
  url.redirect = ("(?i)(/.*\.(jpe?g|png))$" =>
    "http://www.digitalhit.com/dhe403.shtml" )
}


Jan
Posted by Ian Evans
on 24.07.2006 09:53
Jan Kneschke wrote:

> 2. you want to use a redirect as you leave the the host

Unless I'm misunderstanding, I'm not sure what you mean that we "leave
the host" as we're staying on our site.

> 3. (?i) switch to case-insensitive mode.

Thanks.

The only problem with the redirect is that issues a 301 Permanently
Moved (and we haven't moved the image) and the PHP environment isn't 
getting the requested filename.

In the method we use under apache we use a custom 403 error handler. PHP
gets the filename requested, looks it up in our photo database, and
presents a link to the image within the context of our site.

Tom Sherman's Apache method, detailed in the first message, does
basically the same thing.

Is there any reason why lighty can't have a dynamic 403 handler like it
has a dynamic 404?
Posted by Ian Evans
on 24.07.2006 21:14
UPDATE:

I used the following rule:

$HTTP["referer"] !~ "^($|http://[^/]*mysite\.com)" {
  url.rewrite = ("(?i)(/.*\.(jpe?g|png))$" => "/image_handler.php" )
}

As a quick test I tossed phpinfo() into the file, and the 
_SERVER["REQUEST_URI"] variable will allow me to strip out the filename 
and create the descriptive 403 handler I'm looking for.