Forum Moderators: phranque

Message Too Old, No Replies

Understanding the most recent (library) .htaccess hotlinking example

jdMorgan scores again!

         

zollerwagner

7:33 am on Dec 2, 2005 (gmt 0)

10+ Year Member



I'm revising my .htaccess file and have been studying the example jdMorgan posted here:
[webmasterworld.com...]

I really appreciate jdMorgan sharing these examples with us!

I'd like to understand several changes made from previous versions.

First...
jdMorgan is now using:
RewriteCond %{HTTP_REFERER} .

instead of:
RewriteCond %{HTTP_REFERER}!^$

I assume that the old version "!^$" means "not empty"
and that the new version "." means "any character".
So is the new one simply a more efficient way of saying the same thing?

Second...
Does this part ([^.]+\.) of this line:
RewriteCond ${HTTP_REFERER}!^http://([^.]+\.)?example\.com
say "match at least one character which is not a period (.) and which is followed by one period"?

I assume that this form allows for any subdomain without having to list them all?

Third...
Am I right that this line covers a number of search engines and translation services?
RewriteCond %{HTTP_REFERER}!^http://.*(search¦cache¦translate).+example\.com

Is that why you no longer have Comet Systems in the list? It's line was something like:
RewriteCond %{HTTP_REFERER}!^http://search.*\.cometsystems\.com/search.*www\.example\.com

Fourth...
Your line for Ask Jeeves has periods that aren't escaped between web, ask, and com:
RewriteCond %{HTTP_REFERER}!^http://web.ask.com/redir.*example\.com

Is that a mistake or do they mean "any character"?

And finally...
I noticed that you changed some of the RewriteConds to URLs from IP addresses. Was that to make it easier to read the code?

Thanks for keeping us up-to-date, jdMorgan!

jdMorgan

4:51 pm on Dec 2, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I assume that the old version "!^$" means "not empty"
and that the new version "." means "any character".
So is the new one simply a more efficient way of saying the same thing?

Yes, one is the logical equivalent of the other, but "." is two characters shorter and one logical-inversion operation faster.

Does this part ([^.]+\.) of this line:
RewriteCond %{HTTP_REFERER} !^http://([^.]+\.)?example\.com
say "match at least one character which is not a period (.) and which is followed by one period"?

I assume that this form allows for any subdomain without having to list them all?

Yes, it matches any subdomain, but only one subdomain-level. That is, "www.sub.example.com" would not match. It's also much, much more efficient than using, for example, "(.+\.)?example\.com" or "(.*\.)?example\.com" because those patterns are effectively unanchored and ambiguous, requiring the regex parser to attempt many "best-fit" trials, looking for a "best match."

Am I right that this line covers a number of search engines and translation services?
RewriteCond %{HTTP_REFERER} !^http://.*(search¦cache¦translate).+example\.com

Is that why you no longer have Comet Systems in the list? It's line was something like:
RewriteCond %{HTTP_REFERER} !^http://search.*\.cometsystems\.com/search.*www\.example\.com

Yes, shorter code is better...

Your line for Ask Jeeves has periods that aren't escaped between web, ask, and com:
RewriteCond %{HTTP_REFERER}!^http://web.ask.com/redir.*example\.com

Is that a mistake or do they mean "any character"?

It's an error of omission. The pattern still works, but it would be better to escape the literal periods, yes. I certainly do make mistakes - many examples are posted in this forum... ;)

I noticed that you changed some of the RewriteConds to URLs from IP addresses. Was that to make it easier to read the code?

I'm not sure what you mean by "changed" because I'm not sure what other code you're comparing to. The exclusion RewriteConds should include the URL and/or domain of any sites you want to allow. Sometimes this referer is a URL, and sometimes it's an IP address, so check your logs and add whatever you need.

Bear in mind that my goal here is not to provide "the one true path" to .htaccess nirvana; Rather, it's to demonstrate techniques that you can use to accomplish certain tasks or to improve your code's efficiency. Each end every Webmaster should analyze the code, decide whether it will work for his or her particular site, and then modify it to suit.

Jim

[edit] Fixed typo from original post to prevent anyone else having problems from copying this code -- See post 4 below. [/edit]

[edited by: jdMorgan at 1:04 am (utc) on Dec. 4, 2005]

zollerwagner

7:42 am on Dec 3, 2005 (gmt 0)

10+ Year Member



Thanks, Jim, that helps my understanding.

But I'm still stumped on one problem.

If I use this line:

RewriteCond ${HTTP_REFERER}!^http://([^.]+\.)?example\.com

(and that's the only line that allows files from my site to be used on my site) I don't get any images or css (which is also controlled by this code).

If I add this below the line above, then my images and css are available:

RewriteCond %{HTTP_REFERER}!^http://(www¦testing)\.example\.com

Do you have any idea of what is causing that?

(Oops. You can ignore the last question I asked yesterday. I thought there were more IP addresses in the a version from a couple of years ago, but I'm not seeing that now.)

zollerwagner

8:26 am on Dec 3, 2005 (gmt 0)

10+ Year Member



Nevermind...I got it. It was the "$" instead of "%" in this line:

RewriteCond ${HTTP_REFERER} !^http://([^.]+\.)?example\.com

The little stuff matters!

[edited by: jdMorgan at 1:00 am (utc) on Dec. 4, 2005]
[edit reason] Fixed typo/character-code problem [/edit]