What is the most efficient code to detect and redirect SNI supported browsers?

Say, I have a website mywebsite.com , hosted using Apache Httpd. Now what I want is that whenever any user types mywebsite.com or www.mywebsite.com and if the browser supports SNI then it should redirect to https://www.mywebsite.com else redirect to http://www.mywebsite.com .

So, what is the most efficient way to achieve it ?


The below code should work

Options -Indexes +FollowSymLinks
RewriteEngine on

RewriteCond %{HTTP_HOST} ^mywebsite.com$
RewriteCond %{HTTPS} (on|off)
RewriteRule ^(.*)$ http://www.mywebsite.com/$1 [R=302,L]

RewriteCond %{HTTPS} off
RewriteCond %{HTTP_USER_AGENT} !MSIEs6
RewriteCond %{HTTP_USER_AGENT} !WindowssNTs5
RewriteCond %{HTTP_USER_AGENT} !^(.*.symbian.*) [NC]
RewriteCond %{HTTP_USER_AGENT} !^(.*.blackberry.*) [NC]
RewriteRule ^(.*)$ https://www.mywebsite.com/$1 [R=302,L]

Here we are neglecting most of the browsers which does not support SNI and hence for them only the http version would be loaded.


A better solution would be

  #Test if new browser and if so redirect to https
  #new browser is not MSIE 5-8, not Android 0-3,
  #not any symbian and not any blackbery
  RewriteCond %{HTTPS} off
  RewriteCond %{HTTP_USER_AGENT} !MSIE [5-8] [NC]
  RewriteCond %{HTTP_USER_AGENT} !Android.*(Mobile)? [0-3] [NC]
  RewriteCond %{HTTP_USER_AGENT} !^(.*.symbian.*) [NC]
  RewriteCond %{HTTP_USER_AGENT} !^(.*.blackberry.*) [NC]
  RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

This ignores MSIE 5-8 which excludes all IE on XP, plus some on VISTA that would work. But allows XP with chrome, firefox, opera, all of which support SNI on XP. That at least allows XP users to use https. Likewise it assumes all symbian, blackbery don't have sni. And that android 3 does (which tablets do I'm told, phones need 4).

For a different solution you could have

  #Could use this to set $_SERVER['SSL_TLS_SNI'] for php
  SetEnv SSL_TLS_SNI %{SSL:SSL_TLS_SNI}

This would set $_SERVER['SSL_TLS_SNI'] to either %{SSL:SSL_TLS_SNI} (yeah could be better code), or the domain name. If you know what is the default cert that apache returns and have access to that domain then in the other domains you could get php to do a test https to the default domain and then check $_SERVER['SSL_TLS_SNI'] to test for SNI before going to https.

Note there is no way to avoid an error message if a non-sni browser does https to a site which needs sni. The best you can do is

  # Test if SNI will work and if not redirect to too old browser page
  RewriteCond %{HTTPS} on
  RewriteCond %{SSL:SSL_TLS_SNI} =""
  RewriteRule ^ http://www.example.com/too-old-browser [L,R=307]

The user needs to accept the browser error and continue to website, after which he gets redirected to http and the error page.


This is what I used based on the answers above.

RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI} [R=302]

RewriteCond %{HTTP_USER_AGENT} !MSIEs7
RewriteCond %{HTTP_USER_AGENT} !WindowssNTs5
RewriteCond %{HTTP_USER_AGENT} !Android.*(Mobile)? [0-3] [NC]
RewriteCond %{HTTP_USER_AGENT} !^(.*.symbian.*) [NC]
RewriteCond %{HTTP_USER_AGENT} !^(.*.blackberry.*) [NC]
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

RewriteCond %{HTTP_HOST} !^$
RewriteCond %{HTTP_HOST} !^www. [NC]
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

This rewrites to http first and then rewrites to https if useragent is not listed. I dont know if this is bad having two rewrites but I am sure google and other relevant bots prefer indexing https. This way achieves that (I Think :)

My backwards way of doing it but it seems to work. I am sure your better blacklisting browsers and navigating them to HTTP rather than whitelisting browsers as there is way too many to add.

Every site is different and depending on security the above could be an option.

Please let me know your thoughts.

链接地址: http://www.djcxy.com/p/79470.html

上一篇: 在文档中显示knitr代码块源

下一篇: 什么是检测和重定向SNI支持的浏览器的最有效的代码?