Remove periods from url using .htaccess - apache

I've seen variations of this question around, but I couldnt make it work for me.
My problem is: I have many urls indexed at google where the address has one ore more periods. Ex: http://partiturapara.com.br/15-sheets/809-some-music-enc.4.5
Of course the URL does not work, because Apache thinks it is a extension, so I have to strip them, to leave something like this:
http://partiturapara.com.br/15-sheets/809-some-music-enc45
I have a few .htacces lines that make things work (I use joomla) that I will show them bellow.
I´ve tried the following:
RewriteRule ^([^/]*)\.([^/]*)\.$ /$1$2 [L,R=301] - But it just keep loading for ever
and also tried:
RewriteRule ^([^/]*)\.$ /$1 [NC] - This almost works, but gets terrible slow and url will not finish loading.
If you could at least point me in the right direction it would be amazing, cause I already spent lots and lots of hours trying to figure out how all these lines works together and its been very frustrating.
My actual rewrite at the .htaccess file:
RewriteEngine On
RewriteCond %{QUERY_STRING} base64_encode[^(]*\([^)]*\) [OR]
RewriteCond %{QUERY_STRING} (|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
RewriteRule .* index.php [F]
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{REQUEST_URI} !^/index\.php
RewriteCond %{REQUEST_URI} /component/|(/[^.]*|\.(php|html?|feed|pdf|vcf|raw))$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# ----- The line I inserted ------
RewriteRule ^([^/]*)\.$ /$1 [NC]
#-------My edit end --------------
RewriteRule .* index.php [L]
EDIT 1
----------------- UPDATE AFTER JON´S SUGGESTION (it didnt work)----------------------
Hi,
After Jon suggestion, I am trying to figure out yet how my htaccess files works. This way I removed all lines in a way the website still works. The Line Jon suggested seems to be ignored. This is minimum .htaccess I got:
RewriteEngine On
------ this is the line Jon suggested me -----
RewriteRule ^(.*)\.([^/]*)\.$ /$1$2 [L,R=301]
------ end line Jon sugested -----------------
RewriteCond %{REQUEST_URI} /component/|(/[^.]*|\.(php|html?|feed|pdf|vcf|raw))$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php [L]
As I said, the website navigates normally, except when it finds the "dot" in the URL, so it returns the error:
Not Found
The requested URL /15-partituras/1046-sentimental-o.d.m-v-choro was not found on this server.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.
Perhaps I misunderstood something?
Thanks again!

You don't want to insert that rule there. You've completely usurped the very necessary conditions that need to be applied to the index.php routing rule. RewriteCond's only apply to the immediately following rule.
Try adding this right below RewriteEngine On:
RewriteRule ^(.*)\.([^/]*)\.$ /$1$2 [L,R=301]

Related

RewriteRules in htaccess for clean URL resolution and redirect from full URL to clean URL

I'm working on a website project, www.experimonkey.com. In the root directory, I have directories for experiments, games, etc., that I've been serving dynamically with php. I want to clean up the URLs so that instead of /experiments?eid=homemade-lava-lamp, for example, a user can go to /experiments/homemade-lava-lamp. I'd also like to have a redirect so that if a user goes to the old link, /experiments?eid=homemade-lava-lamp, they will be redirected to the clean link.
I thought I had figured out the first part of the problem with the following code in /experiments/.htaccess:
RewriteEngine On
RewriteRule ^([a-zA-Z0-9\-]+)/?$ index.php?eid=$1 [L]
This works for the dynamic pages; however, I later realized that this would screw up the other, real directories in the /experiments folder. For example, the address /experiments/submit (which is actually /experiments/submit/index.php) redirects to /experiments/submit?eid=submit--why, I have no idea.
But also, no matter what combinations of the following code I tried (and all of the other threads and documentation I've read), I could not get the old URL to redirect to the clean URL:
RewriteCond %{QUERY_STRING} eid=(.+)
RewriteRule .+ https://www.experimonkey.com/experiments/%1 [R=301]
RewriteEngine On
Edit (almost working)
I've worked it out this far. Everything is now mostly working, except the last two parts create an infinite loop and I'm not sure how to fix it.
#Ignore existing directories and files unless has query string
RewriteCond %{QUERY_STRING} !eid=(.*)
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule ^ - [L]
#Redirect and remove query string
RewriteCond %{QUERY_STRING} /?eid=(.*)
RewriteRule (.*) https://www.experimonkey.com/experiments/%1? [R=301,L]
#Rewrite internally to actual URL
RewriteRule ^([a-zA-Z0-9\-]+)/?$ index.php?eid=$1 [L]
I finally figured it out--I hope this can help someone somewhere along the way (I honestly can't believe how long this took me to figure out).
#Ignore existing directories and files unless has query string
RewriteCond %{QUERY_STRING} !eid=(.*)
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule ^ - [L]
#Redirect and remove query string.
#First line was the crucial condition to stop loop by checking for internal redirect first.
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} /?eid=(.*)
RewriteRule (.*) https://www.experimonkey.com/experiments/%1? [R=301,L]
#Rewrite internally to actual URL
RewriteRule ^([a-zA-Z0-9\-]+)/?$ index.php?eid=$1 [L]

How to add/ignore a subfolder in htaccess file?

I have build an app at http://url/sdf19/
I have a .htaccess placed in /sdf19/ containing RewriteRule for clean urls.
But I have built a PDF generating tool, which is in a subfolder /inc/tools.
I need to link to it direct to run before headers.
Despite a few hours of searching, trying snippets, generators, etc. I cannot get any request to http://url/sdf19/inc/tools to be allowed, without the existing RewriteRule set taking over
Here is my starting file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-z]+)\/?$ index.php?page=$1 [NC]
RewriteRule ^([a-z]+)\/([0-9]+)\/?$ index.php?page=$1&id=$2 [NC]
RewriteRule ^([a-z]+)\/([a-z]+)\/?$ index.php?page=$1&action=$2 [NC]
RewriteRule ^([a-z]+)\/([a-z]+)\/([0-9]+)\/?$ index.php?page=$1&action=$2&id=$3 [NC]
I've tried to add this on line 4;
RewriteCond %{REQUEST_URI} !^ inc/tools/ [NC]
This gave RewriteCond: bad argument line error
I've tried to add this to line 2;
RewriteCond %{REQUEST_URI} ^/inc/tools/(.*)$
RewriteRule ^.*$ - [L]
Desired result is that I can allow direct access to http://url/sdf19/inc/tools > everything I have tried so far i get redirected to base http://url/sdf19/
Maybe, we could step by step solve this problem. First step, we might just want to make something work with as less as boundaries that'd be possible.
Let's design a low boundary expression, maybe something similar to:
(.+)(\/inc\/tools)
From here, we can just add \/inc\/tools to the RewriteCond, just for testing. Later, we can modify that.
RegEx
If this wasn't a desired expression, you can modify/change your expressions in regex101.com.
RegEx Circuit
You can also visualize your expressions in jex.im:
RewriteRule Test
You can test your RewriteRules in htaccess.madewithlove.be.
I'm not so sure about the rest of RewriteRules, but I'm assuming they are working fine and not conflicting with the new one. Maybe, this or something similar would work:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} \/inc\/tools [NC]
RewriteRule ^(.*)$ $1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-z]+)\/?$ index.php?page=$1 [NC]
RewriteRule ^([a-z]+)\/([0-9]+)\/?$ index.php?page=$1&id=$2 [NC]
RewriteRule ^([a-z]+)\/([a-z]+)\/?$ index.php?page=$1&action=$2 [NC]
RewriteRule ^([a-z]+)\/([a-z]+)\/([0-9]+)\/?$ index.php?page=$1&action=$2&id=$3 [NC]
</IfModule>

URLs redirecting to index.php when no protocol

Hoping someone with more htaccess experience can help us with this. We have Drupal 7 site that we have just moved from a dev to the live host (different hosting companies). However, now when someone puts a url with no protocol directly into the address bar (for example: examplesite.com/members), the page redirects to examplesite.com/index.php. I have been muddling around trying to fix this in the htaccess file, but have not been able to find the proper syntax for allowing urls with no protocol, while also forcing https://.
Our code:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^ index.php [L]
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
We have tried moving the RewriteRule ^ index.php [L] line to underneath all rules, or commenting it out. This fixed the initial problem, but breaks the drupal admin functionality on the backend (can't see the admin menu, can't save anything, etc)
Any insight would be helpful, let me know if more info is needed. Thank you in advance.
You need to move the entire block, conditions + rule to the bottom. Drupal routes everything through the index.php script and it requires the previous 3 conditions in order to do that properly. If you simply move the RewriteRule line, then the conditions are all gone.
RewriteEngine On
# this needs to come first
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
# then drupal stuff comes LAST
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^ index.php [L]

Check URL and stop processing using htaccess

I want to check URL using htaccess. Developer might want run special file - specialfile.php. I use htaccess:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /specialfile\.php$
RewriteRule .* [L] #don't change adress
RewriteRule ^$ public/index.html [NC,L]
RewriteRule (.*) public/$1 [NC,L]
My idea was: if rewriteCond %{REQUEST_URI} !/specialfile.php$ true than htaccess should use RewriteRule .* [L] - that should mean that specialfile.php will be run and this all. But it doesn't work because it runs next rule: RewriteRule (.*) public/$1 [NC,L].
I think you are using the RewriteCond not correctly. The conditions only affect the next RewriteRule that follows.
Check out the example on the Apache Homepage. Since your 2nd RewriteRule is evalutated, I think your conditions are not correct. To get a litte bit more information about the rewriting, you should increase the log level. This is also documented here.
Your 2nd rule ^$ matches only an empty request btw. That's why it probably does not work as you expect it to.

Simulating a 2-level If-Else using RewriteCond

I'm trying to get my head around RewriteCond, and want to rewrite any requests either to a static html page (if it exists), or to a specific index.php (so long as the requested file doesn't exist).
To illustrate the logic:
if HTTP_HOST is '(www\.)?mydomain.com'
if file exists: "/default/static/{REQUEST_URI}.html", then
rewrite .* to /default/static/{REQUEST_URI}.html
else if file exists: {REQUEST_FILENAME}, then
do not rewrite
else
rewrite .* to /default/index.php
I don't seem to have much trouble doing it when I don't need to test for the HTTP_HOST. Ultimately, this one .htaccess file will be handling requests for several domains.
I know I could get around this with vhosts, but I'd like to figure out how to do it this way.
I'm not too familiar with some of the other flags, will any of them be of use here (like chain|C, next|N or skip|S)?
Thanks in advance!
UPDATE: I've managed to do it, but would appreciate alternatives:
RewriteCond %{HTTP_HOST} ^(domainA|domainB)\..* [NC]
RewriteCond %{DOCUMENT_ROOT}/%1/static/%{REQUEST_URI}.html -f
RewriteRule (.*)? /%1/static/$1.html [NC,L]
RewriteCond %{HTTP_HOST} ^(domainA|domainB)\..* [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* /%1/index.php [L,QSA]
UPDATE #2: With help from Gumbo's answer, came up with another. I like that this would would require less maintenance in the case of added domains. (Thanks Gumbo!)
Are there any reasons why I shouldn't set ENV variables?
RewriteCond %{HTTP_HOST} ^(domainA|domainB)\..*$ [NC]
RewriteRule ^ - [E=APP:%1]
RewriteCond %{DOCUMENT_ROOT}/%{ENV:APP}/static/%{REQUEST_URI}.html -f
RewriteRule (.*)? /%{ENV:APP}/static/$1.html [NC,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* /%{ENV:APP}/index.php [L,QSA]
I would probably do it like this:
RewriteCond %{HTTP_HOST} !^(www\.)?example\.com$
RewriteRule ^ - [S=2]
RewriteCond %{DOCUMENT_ROOT}/default/static%{REQUEST_URI}.html -f
RewriteRule !^default/static/ default/static%{REQUEST_URI}.html [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule !^default/static/ default/index.php [L]
This is similar to your updated example. Except that the first rule will skip the following two rules if the host is not appropriate. And the RewriteRule patterns exclude any path that starts with /default/static/. But your rules are already pretty good.