Stop image hotlinking with whitelist htaccess

2019-08-30 01:16发布

A big image galerie need a hotlinking script with a whitelist for google, bing, yahoo etc. On the web I found many examples but they have all a different syntax.

Example 1:

RewriteCond %{HTTP_REFERER} !^http://(.+\.)?google/.*$ [NC]

Example 2:

RewriteCond %{HTTP_REFERER} !google\. [NC]

Example 3:

RewriteCond %{HTTP_REFERER} !google. [NC] 

Example 4:

SetEnvIfNoCase Referer "^(http|https)://.*google.*" whitelist

Example 5:

RewriteCond %{HTTP_REFERER} !^http://(.+\.)?google/.*$ [NC]

Question 1: Which one is the fastest and correct with a domain wildcard?
Question 2: Why is on example 5 a http:// infront when its not needed?

What I did:

RewriteCond %{HTTP_REFERER}  !my-domain\.                   [NC]
RewriteCond %{HTTP_REFERER}  !search\?q=cache               [NC]
RewriteCond %{HTTP_REFERER}  !google\.                      [NC]
RewriteCond %{HTTP_REFERER}  !twitter\.                     [NC]
RewriteCond %{HTTP_REFERER}  !facebook\.                    [NC]
RewriteCond %{HTTP_REFERER}  !googleusercontent\.           [NC]
RewriteCond %{HTTP_REFERER}  !bing\.                        [NC]
RewriteCond %{HTTP_REFERER}  !pinterest\.                   [NC]
RewriteCond %{HTTP_REFERER}  !yahoo\.                       [NC]
RewriteCond %{REQUEST_URI}   !^/hotlink\.jpg$               [NC]

RewriteRule \.(gif|jpg|png)$ http://domain.tld/hotlink.jpg  [R,NC,L]

Questions 3: Is it faster to have only 1 line? How can I write it such as this:

google|facebook|bing|etc

What I did:

RewriteCond %{HTTP_REFERER}  !my-domain\. [NC]
RewriteCond %{HTTP_REFERER} !(google|googleusercontent|yahoo|bing|facebook|pinterest|etc.) [NC]
RewriteCond %{REQUEST_URI}   !^/hotlink\.jpg$               [NC]
RewriteRule \.(gif|jpg|png)$ http://my-domain.tld/hotlink.jpg  [R,NC,L]

1条回答
forever°为你锁心
2楼-- · 2019-08-30 01:42

Well not really scientific but my guess is the ored option would be longest.

I did a try on http://www.regex101.com with this regex: (google|googleusercontent|yahoo|bing|facebook|pinterest) to match http://www.yahoo.com

It took 87 steps (you can see it in regex debugger on the site) where it tooks only 7 steps to match with a regex which is yahoo

So roughly 7 by 9 (number of RewriteCond) give 63 steps where the ored regex took 87 steps, so I think it would be faster in any case using simple regex and multiple RewriteCond until the steps cross (the regex will took a predictable number of steps, try it with the full ored and the last match to know the maximum steps).

Once again: nothing scientific there and myabe it would take more time calling 9 test than a complex one, maybe a apache in debug mode could tell the time taken but I'm unsure.

It's still a matter of choice to prefer one over the other, as I'm quite sure it won't do a noticable difference before the serer has stalled anyway by the number of requests.


For the match the domain\. is enought, no need to use something more complex in my opinion, maybe you may got some edge cases where there's domain. elsewhere in the referer...

The \ before the dot is important to match a litteral dot and not any char after domain in the regex.

查看更多
登录 后发表回答