homepage Welcome to WebmasterWorld Guest from 54.205.144.54
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member
Visit PubCon.com
Home / Forums Index / Code, Content, and Presentation / Apache Web Server
Forum Library, Charter, Moderators: Ocean10000 & incrediBILL & phranque

Apache Web Server Forum

    
Redirect all URLs on Mobile Devices Except one Page
CrashNet




msg:4541889
 2:20 am on Feb 3, 2013 (gmt 0)

Good day,

In my endeavor to building .htaccess files I have tasked myself with learning how to redirect sites to others. I am utilizing the Drupal CMS and would like to add rules to .htaccess that when when accessed from a mobile device, will redirect to a completely different mobile website on a different domain. This code (and hopefully it is respectable) works. My struggle is the following: I would like to add a RewriteCond that ensures a single page will not redirect to the other site on a mobile device and instead go to the full site page. In my rules below:

  • www.mysite.com is the site I am redirecting from on mobile devices
  • www.theothersite.com is the site I am redirecting to
  • www.mysite.com/content/do-not-redirect-if-this-page-is-requested is the page I would like to access if accessed directly on mobile devices. The URL format is exactly as shown with no trailing slash or extension (php, html, etc)


RewriteEngine on

#urls to exclude
RewriteCond %{REQUEST_URI} !^www.mysite.com/content/do-not-redirect-if-this-page-is-requested

#are you mobile
RewriteCond %{HTTP:x-wap-profile} !^$ [OR]
RewriteCond %{HTTP:Profile} !^$ [OR]
RewriteCond %{HTTP_USER_AGENT} "acs|alav|alca|amoi|audi|aste|avan|benq|bird|blac|blaz|brew|cell|cldc|cmd-" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "dang|doco|eric|hipt|inno|ipaq|java|jigs|kddi|keji|leno|lg-c|lg-d|lg-g|lge-" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "maui|maxo|midp|mits|mmef|mobi|mot-|moto|mwbp|nec-|newt|noki|opwv" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "palm|pana|pant|pdxg|phil|play|pluc|port|prox|qtek|qwap|sage|sams|sany" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "sch-|sec-|send|seri|sgh-|shar|sie-|siem|smal|smar|sony|sph-|symb|t-mo" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "teli|tim-|tosh|tsm-|upg1|upsi|vk-v|voda|w3cs|wap-|wapa|wapi" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "wapp|wapr|webc|winw|winw|xda|xda-" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "up.browser|up.link|windowssce|iemobile|mini|mmp" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "symbian|midp|wap|phone|pocket|mobile|pda|psp" [NC]
RewriteCond %{HTTP_USER_AGENT} !macintosh [NC]

#redirect me
RewriteRule (.*) http://www.theothersite.com$1 [R,L]


Fortunately this is not an active site, but merely a learning opportunity on my part. I welcome any feedback or correction to the above code. Please keep in mind these rules would be embedded in Drupal's existing htaccess file. I would imagine there would be precedence to rule order.

Thanks and regards,

 

g1smd




msg:4541947
 8:36 am on Feb 3, 2013 (gmt 0)

Since all of the above code is a single ruleset, remove the blank lines. You need a blank line after each RewriteRule for clarity.

The first line should be
RewriteCond %{REQUEST_URI} !^content/do-not-redirect-if-this-page-is-requested

lucy24




msg:4541984
 9:37 am on Feb 3, 2013 (gmt 0)

%{REQUEST_URI} !^www.mysite.com/ {et cetera}

This condition will never fail, because the domain name is-- by definition-- not part of the REQUEST_URI.

That's an appallingly long UA list. Throw in [NC] and you've got a good chance that one of the conditions will succeed, just by finding some random four-letter sequence in the UA. Especially if it's one of those MSIE things where the browser thinks your server has nothing better to do than sit around reading User-Agent strings that go on for miles. Quite a few robots as well.

Are there really that many smartphones in existence?

RewriteCond %{HTTP_USER_AGENT} !macintosh [NC]
Put this one second (after the REQUEST_URI one). Whenever possible, list conditions in most-likely-to-fail order.

CrashNet




msg:4542138
 11:16 pm on Feb 3, 2013 (gmt 0)

g1sdm and lucy24,

Thank for taking the time to respond. I have followed your steps and tested. Then, for the sake of argument and to limit possible errors, I reduced the user agents down to the "majority catch" list. Here is my new code:

#Check for Mobile Device
RewriteEngine on
# Urls to exclude
RewriteCond %{REQUEST_URI} !^content/do-not-direct-if-this-page-is-requested
# Are you mobile
RewriteCond %{HTTP_USER_AGENT} "android|blackberry|ipad|iphone|ipod|iemobile|opera mobile|palmos|webos|googlebot-mobile" [NC]
# Send to root
RewriteRule (.*) http://www.theothersite.com/m/companyname/index.html$1 [R,L]


Unfortunately, I did not have success. So there is no stone left unturned, I have included the full URL structure listed in the redirect.

As listed above, the code returns the following:

http://www.theothersite.com/m/companyname/index.htmlcontent/do-not-direct-if-this-page-is-requested


If I remove the $1, as expected, I am still redirected to the mobile site. The goal of this redirect exclusion is to allow this link to be accessed anywhere, on any site, including the mobile site and direct access. I imagine I am missing something.

As this is a CMS (Drupal) and the link above represents an cleanURL generated by the CMS, is there a possibility there are other rules which may be preventing the condition to fail? If there is additional information I may provide to assist, please do not hesitate to ask.

Best,

lucy24




msg:4542156
 1:45 am on Feb 4, 2013 (gmt 0)

Before anything else:

Where is this new rule located in relation to the existing htaccess rules created by your CMS?

It is especially important to get redirects ([R=301] flag) and rewrites (no R of any kind) in the right order.

RewriteRule (.*)

is way too generic. For starters, you only want to redirect requests for pages. That means requests ending in pagename.html (or whatever format you use) or / (directory slash) or nothing-at-all in the case of requests for your front page. Something like:

^((?:[^/.]+/)*(?:[^/.]+\.html)?)$

CrashNet




msg:4542255
 1:54 pm on Feb 4, 2013 (gmt 0)

Wow...it is certainly amazing how a second brain can point out the simple things you overlook.

It dawned on me when you asked where the rule was located that there is a special section for rewrite rules in the Drupal htaccess file. I moved the code to the top of the section (there are other URL rewrite rules) and it works!

Additionally, I did add your suggestions as well, but I would like to better understand the logic behind the long list of characters you recommended I add to the rewrite rule. So that I am not taking any more of your time, would you happen to have a reference off the top of your head to which I can further read about the additional code you provided?

Thank you again for all of your help!

lucy24




msg:4542305
 5:31 pm on Feb 4, 2013 (gmt 0)

The only reference is the past couple years of posts in this forum :) but I can pick it apart.

^((?:[^/.]+/)*(?:[^/.]+\.html)?)$

=
^((?:aaa)*(?:bbb)?)$

=
the "path" part of the request consists of zero or more iterations of aaa followed by a single optional bbb. The aaa and bbb pieces have to be in parentheses so the * and ? can apply to the whole group. But they do not need to be captured separately, so the ?: saves the server a nano-minim of resources.

In the first element
[^/.]+/
each piece is a directory: one or more non-slash non-periods followed by a single slash

The second element
[^/.]+\.html
is a filename-- one or more non-slash non-periods followed by a period plus extension-- where "\.html" would be replaced by whatever extension you really use.

If you use extensionless URLs, all pages can be expressed even more simply as
^([^.]*)$
without the [^./]+/ component. Anchors are crucial. Inside grouping brackets, . is a literal period.

Using this formulation, the server will only have to backtrack once, if at all: when it captures a [^./]+ group and then runs into a . dot instead of a / slash.

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.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved