homepage Welcome to WebmasterWorld Guest from 54.198.139.141
register, free tools, login, search, subscribe, help, library, announcements, recent posts, open posts,
Accredited PayPal World Seller

Visit PubCon.com
Home / Forums Index / Code, Content, and Presentation / Apache Web Server
Forum Library, Charter, Moderators: Ocean10000 & incrediBILL & phranque

Apache Web Server Forum

This 43 message thread spans 2 pages: 43 ( [1] 2 > >     
Rewrite image for specific referrer
batface




msg:4515654
 8:07 pm on Nov 4, 2012 (gmt 0)

I'm hoping someone can help with this. I have a background image I want to rewrite to a different image if a specific referrer is used. The following does not trigger the rewrite.

RewriteEngine On
RewriteCond %{HTTP_REFERER} .
RewriteCond %{HTTP_REFERER} ^http://(www\.)?thereferrer\.com [NC]
RewriteRule ^images/image\.png$ http://www.example.com/directory/images/new-image.png [R=302,L]

The rewrite rule works by itself but the following condition and rewrite works, so where am I going wrong?

RewriteEngine On
RewriteCond %{HTTP_REFERER} .
RewriteCond %{HTTP_REFERER} ^http://(www\.)?thereferrer\.com [NC]
RewriteRule .* - [F]

 

g1smd




msg:4515658
 8:47 pm on Nov 4, 2012 (gmt 0)

Images and redirect responses are cached. Are you clearing the cache before each test?

You say you want a rewrite, but your code is for a redirect. Which do you want?

Usually a rewrite is better, as it serves the alternative image at the originally requested URL. There's no guarantee that having served the redirect the requester will actually follow it.

batface




msg:4515662
 8:57 pm on Nov 4, 2012 (gmt 0)

yes the cache is cleared at each test.

I want to rewrite.

phranque




msg:4515671
 11:01 pm on Nov 4, 2012 (gmt 0)

if you specify the protocol/hostname in the target and/or the R flag it is a redirect, not a rewrite.

batface




msg:4515768
 6:37 am on Nov 5, 2012 (gmt 0)

Ok, I see my mistake, thanks.

This gives me a rewrite to the desired image so the landing page the referrer lands on dishes up the desired background image:

RewriteRule ^images/image\.png$ http://www.example.com/directory/images/new-image.png [L]

I was thinking that the condition is incorrect, so to test created this rule:
RewriteEngine On
RewriteCond %{HTTP_REFERER} .
RewriteCond %{HTTP_REFERER} ^http://(www\.)?thereferrer\.com [NC]
RewriteRule .* - [F]

which works in that I am served a 403 page at the referrer.

So how come the two parts do not work?
RewriteEngine On
RewriteCond %{HTTP_REFERER} .
RewriteCond %{HTTP_REFERER} ^http://(www\.)?thereferrer\.com [NC]
RewriteRule ^images/image\.png$ http://www.example.com/directory/images/new-image.png [L]

confused?!?

phranque




msg:4515772
 6:49 am on Nov 5, 2012 (gmt 0)

RewriteRule ^images/image\.png$ http://www.example.com/directory/images/new-image.png [L]


if you specify the protocol/hostname in the target and/or the R flag it is a redirect, not a rewrite.

wilderness




msg:4515773
 6:53 am on Nov 5, 2012 (gmt 0)

Try the following, as per the explanations that g1smd and phranque have offered.

The shortened version of the refer is my own addition. You really don't need all that other stuff (protocol).

# Refer CONTAINS domain name and requests Specific image
RewriteEngine On
RewriteCond %{HTTP_REFERER} thereferrer
RewriteRule ^images/image\.png$ /directory/images/new-image.png [L]

batface




msg:4515784
 7:24 am on Nov 5, 2012 (gmt 0)

ok but with this amendment I still dont get the rewrite image:

RewriteEngine On
RewriteCond %{HTTP_REFERER} .
RewriteCond %{HTTP_REFERER} ^http://(www\.)?thereferrer\.com [NC]
RewriteRule ^images/image\.png$ /directory/images/new-image.png [L]

or

RewriteEngine On
RewriteCond %{HTTP_REFERER} .
RewriteCond %{HTTP_REFERER} thereferrer
RewriteRule ^images/image\.png$ /directory/images/new-image.png [L]

neither work.

wilderness




msg:4515788
 7:35 am on Nov 5, 2012 (gmt 0)

Remove this line (it is NOT what I provided previously)
RewriteCond %{HTTP_REFERER} .

". (a dot) matches any single character, except the ending of a line. "

Which is in conflict with your domain name refer, and as a result implies any refer.

Clear your cache before testing.

If your not getting the replacement image, you likely have a sytax error or a path error.

What do your error logs say?

Additionally mod_rewrite only requires ON, once per file. If you have it turned on previously, than don't try turning on again.

lucy24




msg:4515789
 7:45 am on Nov 5, 2012 (gmt 0)

RewriteCond %{HTTP_REFERER} ^http://(www\.)?thereferrer\.com [NC]
RewriteRule .* - [F]

You do not need (www\.)? here, unless you are personally acquained with the referring site and you know for a fact that they don't canonicalize. Otherwise it's either with or without; the wrong way would be a forged referer. Look closely at your logs and you'll find fake referers from your own site getting caught this way. Give the referring site name in its exact, full form. If it's a specific page, name it.

So how come the two parts do not work?
RewriteEngine On
RewriteCond %{HTTP_REFERER} .
RewriteCond %{HTTP_REFERER} ^http://(www\.)?thereferrer\.com [NC]
RewriteRule ^images/image\.png$ http://www.example.com/directory/images/new-image.png[L]

Even though it's mis-coded as a redirect instead of the intended rewrite note lower case it should still work. Have you tried it with a different browser? One whose cache has never seen the page in any form.

Is it serving up the originally requested image, or no image at all?

For testing purposes, set the "expires" header for new-image.png (NOT the requested image.png but the one that is actually served) to "right away". You can look up the exact terminology yourself ;) It will save you having to empty your browser cache every time you test the rule.

g1smd




msg:4515816
 10:51 am on Nov 5, 2012 (gmt 0)

RewriteCond %{HTTP_REFERER} . -- means "and referrer is not blank".

This allows requests with blank referrer to view the site.

wilderness




msg:4515839
 12:56 pm on Nov 5, 2012 (gmt 0)

g1smd,
The use is still redundant in this instance.
Obviously the refer is not blank, it contains a domain name.

FWIW, the solitary use of that line in my very large htaccess in within the image-hot-link section, which results in a denial (not a rewrite or redirect), with specific domain exceptions by use of leading-!

lucy24




msg:4515924
 4:52 pm on Nov 5, 2012 (gmt 0)

RewriteCond %{HTTP_REFERER} . -- means "and referrer is not blank".

This allows requests with blank referrer to view the site.

? Blank or not blank?

The condition pair is default-coded as AND, so the rule is redundant. "The request has a referer AND the referer is specifically so-and-so." Basic tenet of philosophy: A thing that does not exist cannot have properties.

But it's a good idea for the OP to stop and ask which way he wants to go for requests that don't come with a referer. That includes both robots and humans. Since we're talking about a background image, robots aren't important and we're only looking at Preview. Or specifically at Bing Preview; Google sends a referer. Not worth making a rule for them alone, so that leaves referer-less humans. Whichever way you go, some of them will...

:: grind to a screeching halt as wording of original post sinks in ::

You said background image. That means the referer will never be some outside site. It will be your own CSS, either free-standing or on the page itself.

:: OK, let's start over from the very beginning ::

Can you backtrack and explain what you're doing? In English, not in Apache.

batface




msg:4515996
 6:15 pm on Nov 5, 2012 (gmt 0)

hehe, ok Lucy here goes.

Some landing page has a background image, so somewhere in the code is images/image.png. Using the following rewrite the page serves up the new background image - this works a treat, just what i'm looking for.
RewriteRule ^images/image\.png$ http://www.example.com/directory/images/new-image.png[L]

What we want is a rule that if a specific external domain visits that page with the background image the alternative background image is used.

I am confused because the rewrite to set the URL to forbidden (whether I need the www or not)works with the referer set.

g1smd




msg:4515997
 6:18 pm on Nov 5, 2012 (gmt 0)

The problem is that the referrer for the page will be the referring domain, but the referrer for the image will be the site that the page is on, not the site the visitor came from.

Since it appears that you're interested in the visitor IP and not the site they just came from, shouldn't you be looking at REMOTE_HOST instead and not at HTTP_REFERER?

batface




msg:4516004
 6:35 pm on Nov 5, 2012 (gmt 0)

The problem is that the referrer for the page will be the referring domain, but the referrer for the image will be the site that the page is on, not the site the visitor came from.


Are you saying this is not possible?

wilderness




msg:4516089
 11:39 pm on Nov 5, 2012 (gmt 0)

Are you saying this is not possible?


g1smd did mot say that at all.
He suggests that you may have focused upon the wrong method to reach your goal.

REMOTE_HOST
1) Explore Apache Docs
2) Forum Library
3) Webmaster World search

I am confused because the rewrite to set the URL to forbidden (whether I need the www or not)works with the referer set.


It depends on the clarity you desire and the lesser possibility of application to innocent visitors.

# Referer MUST begin with www.example.com (note leading anchor)
RewriteCond %{HTTP_REFERER} ^www\.example\.com

# refer contains "example" (note absence of begins with or ends with anchor)
RewriteCond %{HTTP_REFERER} example

In the latter, the referring URL could be two blocks long and "example" could be used in other portions (rather than just the domain name) of the referring link, which you never intended.
EX.
Let us suppose the domain was "red" (i. e., example) and the referring URL also contained a phrase of "red cars" beyond the domain name, than the visitor would be denied innocently when using the "contains method"

lucy24




msg:4516113
 12:53 am on Nov 6, 2012 (gmt 0)

# Referer MUST begin with www.example.com (note leading anchor)
RewriteCond %{HTTP_REFERER} ^www\.example\.com

And when you say "must begin with www.example.com" you mean "must begin with http://" because that too is part of the referer ;)

Are you saying this is not possible?

With the situation as you originally described it, it isn't possible in htaccess alone. You'd need a cookie or possibly a bit of scripting or other code to hold the page referer in memory. But then it turns out you're not talking about the referer at all:
What we want is a rule that if a specific external domain visits that page

which means, as wilderness says, that you need to look at REMOTE_HOST and not at REFERER. This in fact makes it much easier, because you can hide or fake an referer or a user agent, but so far it isn't possible to fudge your IP address.

And NOW we go back to the drawing board :)



Oh yes and...
Using the following rewrite the page serves up the new background image - this works a treat, just what i'm looking for.
RewriteRule ^images/image\.png$ http://www.example.com/directory/images/new-image.png[L]

It's STILL a ### redirect!

phranque




msg:4516156
 4:38 am on Nov 6, 2012 (gmt 0)

Using the following rewrite the page serves up the new background image - this works a treat, just what i'm looking for.
RewriteRule ^images/image\.png$ http://www.example.com/directory/images/new-image.png[L]

please reread both of my posts in this thread.

batface




msg:4516412
 6:35 pm on Nov 6, 2012 (gmt 0)

sorry I copied the redirect, got the rewrite in my version.

I tried with REMOTE_HOST but cannot get the new image. I have:

RewriteEngine On
RewriteBase /
RewriteCond %{REMOTE_HOST} ^1\.1\.1\.1
RewriteCond %{REQUEST_URI} /Landingpage/index\.html$ (tried with this)
RewriteRule ^images/image\.png$ /directory/images/new-image.png[L]

lucy24




msg:4516542
 9:56 pm on Nov 6, 2012 (gmt 0)

RewriteCond %{REQUEST_URI} /Landingpage/index\.html$ (tried with this)


REQUEST_URI is not the page that "owns" the image; it's the image itself. Each request is an island. In fact I've got a strong impression that several previous people in this thread have pointed out that you don't need to say anything about REQUEST_URI at all, since that's going to be in the body of the Rule.

Unless -- further horrid thought -- you use the same background image on more than one page, but you only want to rewrite it in one place? If so, that's where you would need a Referer line. It would be your own page-- or your own stylesheet, if it's a separate file-- not the visitor's previous location. But then you're back to the question of UAs that don't send a referer. (Or is that what the REMOTE_ADDR option does? Someone else will know.)

batface




msg:4516871
 8:32 pm on Nov 7, 2012 (gmt 0)

What I can't get my head around (and I shouldn't be doing this in the middle of study :-) )is that if I amend the condition to a not IP, then the alternative image always displays - 1.1.1.1 or from anywhere.

RewriteCond %{REMOTE_HOST} !^1\.1\.1\.1
RewriteRule ^images/image\.png$ /directory/images/new-image.png[L]

In my simple mind this means "hey, if the visitor does not come from 1.1.1.1 use the alternative image." but the alternative image is now used from this visitor or anywhere.

What is it about !^1\.1\.1\.1 that is now allowing the rewrite rule to work, although incorrectly across the board? I am using the correct IP address.

g1smd




msg:4516873
 8:47 pm on Nov 7, 2012 (gmt 0)

Once the image has been requested once, it's then cached in your browser and irrespective of what condition does or does not match in the htaccess file next time, if you change your IP or change the conditions in the htaccess file, your next request will continue to show the image cached in your browser. This makes it look like the htaccess rules are failing.

This means that the rules will not work if the user has previously seen the image loaded in a legitimite way. You'll need to set the image properties (both the real and the replacement) so that it is not cached - because to the user it's always the same URL and browsers only know URLs and not anything about the server internals.

batface




msg:4516880
 9:13 pm on Nov 7, 2012 (gmt 0)

I have:
Header unset ETag
FileETag None

<IfModule mod_expires.c>
<FilesMatch "\.png">
Header set Cache-Control: must-revalidate
ExpiresActive On
ExpiresDefault "access plus 0 seconds"
</FilesMatch>
</IfModule>

and I clear the browser cache, so this can't be the problem?

lucy24




msg:4516906
 10:39 pm on Nov 7, 2012 (gmt 0)

You'll need to set the image properties (both the real and the replacement) so that it is not cached

I found out by direct experiment that the only one that matters is the image that is actually displayed. It doesn't matter in the present case, because the image is only sometimes rewritten. But if the image is always rewritten, then only the "real" image's properties matter.

Mine goes

<Files "onedot.gif">
ExpiresActive On
ExpiresByType image/gif "access"
</Files>

Yes, the Files and the "ExpiresByType" are redundant. Belt and suspenders. I put it in its own little htaccess in the small, obscure directory that the image lives in. Belt and suspenders and, um, rivets. No caching at all is pretty strong stuff, so I wanted to be sure no browser wasted its own resources asking for something that hadn't changed.

RewriteRule ^images/image\.png$ /directory/images/new-image.png[L]
I assume that was a typo and there's really a space before the [L].

And I think everyone has been assuming that your rewrite audience has a fixed IP. Otherwise the rule will stop working the next time they restart their modem.

batface




msg:4517186
 3:02 pm on Nov 8, 2012 (gmt 0)

I would like to say it works, but it doesn't. I followed your steps and placed the expires htaccess in the image folder.

I am at the same position -
^1.1.1.1 = no alternative image
!^1.1.1.1 = always alternative image

I also purge the cache with Fiddler in case.

It is a fixed IP.

phranque




msg:4517219
 5:04 pm on Nov 8, 2012 (gmt 0)

you need to find out which IP address the server thinks you are.
have you checked the server access log?
perhaps you are accessing the server through a VPN or local network address.

lucy24




msg:4517340
 12:17 am on Nov 9, 2012 (gmt 0)

I am at the same position -
^1.1.1.1 = no alternative image
!^1.1.1.1 = always alternative image

Double-checking:

Whenever you say . quoting your htaccess you really mean \.
Whenever you say ^1.1.1.1 you really mean your own IP

:: grasping at straws ::

Any difference if you also give a $ closing tag for the IP?

What do your logs say? A rewrite will come through as 200, but the filesize will be different-- assuming the alternative file is a different size. For testing it can be useful to use a redirect instead of a rewrite, because then you can see it clearly in your logs.

batface




msg:4517552
 4:54 pm on Nov 9, 2012 (gmt 0)

Whenever you say . quoting your htaccess you really mean \.
Whenever you say ^1.1.1.1 you really mean your own IP


That is the IP of the website with the link to the URL I want to use the alternative image, not my own IP address.

Any difference if you also give a $ closing tag for the IP?

No

What do your logs say?


One example is:
86.159.xxx.xxx - - [08/Nov/2012:04:43:06 +0100] "GET /Landingpage/index.html HTTP/1.1" 200 630 "http://www.example.com/test.html" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4"

So I see the initial IP address is mine - BT Internet, then the referrer is http://www.example.com/test.html. It was originally making sense to me to use:
RewriteCond %{REMOTE_REFERER} ^http://www\.example\.com.*$ [NC]

but as with either REMOTE_HOST or REMOTE_ADDR using the IP for example.com the alternative image is not displayed.

Ironically and annoyingly setting to 'not' ! always gives me the alternative image. I'm left thinking this works but my condition is wrong. I've tried all these kind of alternatives (also with REMOTE_HOST and REMOTE_ADDR):
RewriteCond %{REMOTE_REFERER} !^http://www\.example\.com.*$ [NC]
#RewriteCond %{REMOTE_REFERER} ^http://1\.1\.1\.1$ [NC]
#RewriteCond %{REMOTE_REFERER} ^http://1\.1\.1\.1.*$ [NC]
#RewriteCond %{REMOTE_REFERER} ^http://1\.1\.1\.1:80.*$ [NC]

I want traffic from http://www.example.com/test.html to get the alternative image.

g1smd




msg:4517557
 5:17 pm on Nov 9, 2012 (gmt 0)

REMOTE_HOST should be looking for the IP of the user that you want to block not set to the IP of your website.

I'm not aware that REMOTE_REFERER is a valid server variable.

This 43 message thread spans 2 pages: 43 ( [1] 2 > >
Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / Apache Web Server
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About
© Webmaster World 1996-2014 all rights reserved