URL Encoded text not matching htaccess QUERY_STRING - regex

My website uses a comma to separate some coordinates in a parameter, like ?coords=38.88,-77.03. I'm now finding issues as , is a url reserved character. The issue seems limited to when the links are shared with Facebook and Facebook changing it to ?coords=38.88%2C-77.03.
Long term I'd like to fix it but I need to make a temporary fix for existing links that have been shared. If people were to click the link from Facebook I'd like an .htaccess rule to change it to using the comma.
I already have a similar rule for when there's a space after the comma:
RewriteCond %{QUERY_STRING} (.*coords=-?\d{1,2}(?:\.\d+)?),(?:\s+|\%20|\+)(-?\d{1,3}(?:\.\d+)?,?.*) [NC]
RewriteRule ^ %{REQUEST_URI}?%1,%2 [L,NE,R=301]
I tried changing it to:
RewriteCond %{QUERY_STRING} (.*coords=-?\d{1,2}(?:\.\d+)?)(,|\%2C)(?:\s+|\%20|\+)(-?\d{1,3}(?:\.\d+)?,?.*) [NC]
RewriteRule ^ %{REQUEST_URI}?%1,%3 [L,NE,R=301]
I cleared my cache and even tried changing the coordinate numbers to new ones, but I can't get it to redirect. What am I doing wrong and how can I fix it?

Your earlier non-capture group is not optional thus it is trying to match 1+ spaces after matching %2C and failing. You may use this rule:
RewriteCond %{QUERY_STRING} (.*coords=-?\d{1,2}(?:\.\d+)?)(?:[+\s]+|\%2C|\%20)+(-?\d{1,3}(?:\.\d+)?,?.*) [NC]
RewriteRule ^ %{REQUEST_URI}?%1,%2 [L,NE,R=301]

Related

RewriteRule to handle one domain two folders to two domains no folder

I am attempting to create rewrite rules to handle some specific website redirections:
I would like domain1.ca/folder1/xyz to go to domain2.ca/xyz and domain1.ca/folder2/xyz to go to domain3.ca/xyz
Right now my attempts are as following:
RewriteCond %{HTTP_HOST} ^domain1.ca$ [OR]
RewriteCond %{HTTP_HOST} ^www.domain1.ca$
RewriteRule ^(\/folder1\/)(.*)$ "https://domain2.ca/$1" [R=301,L]
RewriteCond %{HTTP_HOST} ^domain1.ca$ [OR]
RewriteCond %{HTTP_HOST} ^www.domain1.ca$
RewriteRule ^(\/folder2\/)(.*)$ "https://domain3.ca/$1" [R=301,L]
Any help would be greatly appreciated :) Thx.
A couple of problems with your existsing rules:
In .htaccess the URL-path matched by the RewriteRule pattern does not start with a slash. So, the URL-path starts folder1/xyz, not /folder1/xyz.
You are unnecessarily capturing "folder1" in the first parenthesised subpattern and using this in the substitution string (ie. $1). You should be using $2, or don't capture the first path segment.
The directives could also be tidied up a bit (eg. no need to backslash-escape slashes in the regex and the conditions can be combined).
Try the following instead:
RewriteCond %{HTTP_HOST} ^(www\.)?domain1\.ca [NC]
RewriteRule ^folder1/(.*) https://domain2.ca/$1 [R=301,L]
RewriteCond %{HTTP_HOST} ^(www\.)?domain1\.ca [NC]
RewriteRule ^folder2/(.*) https://domain3.ca/$1 [R=301,L]
Additional notes:
The end-of-string anchor ($) following (.*)$ in the RewriteRule pattern is not required since regex is greedy by default.
You only need to surround the argument in double quotes if it contains spaces.
I removed the end-of-string anchor ($) from the end of the CondPattern to also match fully qualified domain names that end in a dot.
I added the NC flag to the condition. It's technically possible that some bots can send a mixed/uppercase Host header.
Test first with 302 (temporary) redirects to avoid potential caching issues.

htaccess - rewrite URL ending with specific string and capturing the unique part

I want to feed several URLs into a single php file that will handle the contents of the page, the URLs are like
domain.com/fashion-registration
domain.com/singing-registration
I want to capture URLs ending with -registration and feed fashion or singing into the page but it doesn't seem to be working. This is what I tried
RewriteRule ^(.*)$-registration category.php?link=$1 [NC,L,QSA]
Could you please try following.
RewriteEngine ON
RewriteCond %{REQUEST_URI} ^/(.*)-registration/?$ [NC]
RewriteRule ^(.*)$ /category.php?link=%1 [NE,NC,L]
OR you could try following too, one without RewriteCond.
RewriteEngine ON
RewriteRule ^(.*)-registration/?$ /category.php?link=$1 [NE,NC,L]
Problem in OP's attempt: Since you have used ^(.*)$ and after that you are using -registration in your regex that's why your regex is NEVER going to match -registration

removing multiple groups of slashes everywhere in URL in .htaccess

I currently have a website where guests are able to access each url with any number of slashes to separate folder names. For example, if a URL is supposed to be:
http://example.com/one/two/three/four
Then users could access the same page via any of the following:
http://example.com/one//two///three////four/////
http://example.com/one/two////three/four/////
http://example.com///one///////////two////three/four/
http://example.com///////////one///////////two/three/four
However, I want the above example urls to only redirect users to this URL:
http://example.com/one/two/three/four
This is my .htaccess file to attempt to stop the enormous slashes:
RewriteCond %{ENV:REDIRECT_STATUS} !^$
RewriteRule .* - [L]
RewriteRule ^(.*)/+$ /$1 [R=301,L,NC]
RewriteCond %{REQUEST_URI} ^/+(.*)/+$
RewriteRule .* /%1 [R=301,L]
The third line successfully stops trailing slashes on long URLs. The 4th and 5th lines are my attempt to stop trailing slashes right after the domain name, but that was unsuccessful.
The reason why I ask this question is because I don't want google to catch me for duplicate content and with adsense active on the site, google will likely scan all the URLs that I access.
Is there a RewriteCond/RewriteRule combo I can use to strip the middle slashes or is it more involved?
You can use this rule for removing multiple slashes anywhere in URL except query string:
RewriteCond %{THE_REQUEST} \s[^?]*//
RewriteRule ^.*$ /$0 [R=302,L,NE]
This works for me:
RewriteCond %{REQUEST_URI} ^(.*)//(.*)$
RewriteRule . %1/%2 [R=301,L]

Remove symbol and text from url htaccess

I need to remove some specific text (and all characters after it from a url) - have tried several options, but I can't get any of them to work, a sample url is:
/yacht-sales/yacht/eclipse1?title=http://www.oceanindependence.com/yacht-sales/yacht/daydream&submit=
It's everything from the ?title= - that needs to be removed, so the final url would be:
/yacht-sales/yacht/eclipse1
there is another site on the same server that uses ? in it's url's, so removing everything from the ? onwards did cause problems when I tried it, and I did also try:
RewriteCond %{QUERY_STRING} ^?title=http$ [NC]
RewriteRule ^ %{REQUEST_URI}? [R=301,L,NE]
But this didn't work, sorry am not really good at things like this, if anyone can help at all?
Cheers
%{QUERY_STRING} doesn't contain first ? and since its not ending with http hence don't put $ there.
You can use this rule:
RewriteCond %{QUERY_STRING} (^|&)title=http.+ [NC]
RewriteRule ^ %{REQUEST_URI}? [R=301,L,NE]

rewriting a substring of a filename in RewriteRule

I am trying to use the .htaccess code to have different pages loaded when mobile user-agent recognized.
It doesn't work but I can't figure why, can someone please help?
The below RewriteConds work for me when followed by the RewriteRule for redirecting to subdomain, so I guess there must be a problem with my RewriteRules.
Help appreciated.
RewriteCond %{HTTP_USER_AGENT} android|avantgo|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge\ |maemo|midp|mmp|opera\ m(ob|in)i|palm(\ os)?|phone|p(ixi|re)\/|plucker|pocket|psp|symbian|treo|up\.(browser|link)|vodafone|wap|windows\ (ce|phone)|xda|xiino [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^(1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a\ wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r\ |s\ )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1\ u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp(\ i|ip)|hs\-c|ht(c(\-|\ |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac(\ |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt(\ |\/)|klon|kpt\ |kwc\-|kyo(c|k)|le(no|xi)|lg(\ g|\/(k|l|u)|50|54|e\-|e\/|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(di|rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-|\ |o|v)|zz)|mt(50|p1|v\ )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v\ )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-|\ )|webc|whit|wi(g\ |nc|nw)|wmlb|wonu|x700|xda(\-|2|g)|yas\-|your|zeto|zte\-) [NC]
RewriteRule ^regular.css$ mobi.css
RewriteRule ^view.$ mobile.view.
You writing ^view.$ supposes that you think of a file named "view." (it's the complete filename, ending with a dot). Is that really what you mean?
$ marks the end (of the original string the regex is being matched against). Perhaps, you don't need it.
(Read docs about regexes before you use them in order to understand every symbol you write! Writing code and not understanding what it means is not nice.)
Further problems
I see, after you get rid of the $, you might get further problems, because you might want to construct a complete filename on the right-hand side of the rewrite-rule (like something that eveluates to "mobile.view.mainlayout.php") (or not?).
I don't remember: does Apache's rewrite-rules rewrite only the small matched piece ("view.") in the string and concatenate it with the rest of the requested filename ("mainlayout.php"), or Apache throws away the old requested filename ("view.mainlayout.php") and replaces it with what it finds on the right-hand side of the rewrite-rule (so it must be not a replacing piece like "mobile.view.", but rather evaluate to a complete filename)?
If so, then match the rest of the string with ( ) in the regex on the left-hand side of the rewrite-rule, and insert the matched piece back on the right-hand side.
Main problem is that you cannot have multiple RewriteRules after RewriteConds, so your second RewriteRule will be executed every time.
You have to do a little workaround with the skip flag, see below.
Note: The RewriteConds are 'inverted'.
The second problem is your RegEx: RewriteRule ^view.$ mobile.view. just rewrites the URL view (followed by one random char) to the URL mobile.view..
As I noticed in your comment, you have to do something like this:
RewriteRule ^view\.(.*)$ mobile.view.$1 # files and .htaccess have to be in the same directory
Here the full Rewrite code:
RewriteCond %{HTTP_USER_AGENT} !android|avantgo|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge\ |maemo|midp|mmp|opera\ m(ob|in)i|palm(\ os)?|phone|p(ixi|re)\/|plucker|pocket|psp|symbian|treo|up\.(browser|link)|vodafone|wap|windows\ (ce|phone)|xda|xiino [NC]
RewriteCond %{HTTP_USER_AGENT} !^(1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a\ wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r\ |s\ )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1\ u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp(\ i|ip)|hs\-c|ht(c(\-|\ |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac(\ |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt(\ |\/)|klon|kpt\ |kwc\-|kyo(c|k)|le(no|xi)|lg(\ g|\/(k|l|u)|50|54|e\-|e\/|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(di|rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-|\ |o|v)|zz)|mt(50|p1|v\ )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v\ )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-|\ )|webc|whit|wi(g\ |nc|nw)|wmlb|wonu|x700|xda(\-|2|g)|yas\-|your|zeto|zte\-) [NC]
RewriteRule .* - [S=2] # skip next two RewriteRules if RewriteConds matched (= it's a desktop browser)
RewriteRule ^regular.css$ mobi.css
RewriteRule ^view\.(.*)$ mobile.view.$1
#Freelancer [Edited to fix errors and provide alternative]
You want a [PT] on your RewriteRule statements.
Skipping is probably your best bet:
RewriteCond "%{HTTP_USER_AGENT}" "!(first-condition-regex)" [NC]
RewriteCond "%{HTTP_USER_AGENT}" "!(second-condition-regex)" [NC]
RewriteRule "^" "-" [SKIP=2]
RewriteRule "^regular.css$" "mobi.css" [PT]
RewriteRule "^(view\..*)" "mobile.$1" [PT]
If you want to avoid inverting your conditions it gets a bit messier:
RewriteCond "%{HTTP_USER_AGENT}" "first-condition-regex" [OR,NC]
RewriteCond "%{HTTP_USER_AGENT}" "second-condition-regex" [NC]
RewriteRule "^" "-" [E=MOBILE:TRUE]
RewriteCond "%{ENV:MOBILE}" "!=TRUE"
RewriteRule "^" "-" [SKIP=2]
RewriteRule "^regular.css$" "mobi.css" [PT]
RewriteRule "^(view\..*)" "mobile.$1" [PT]
As pointed out, all these files need to be in the same directory as the .htaccess file.