I've been trying to figure out how to get this to work for awhile now and it's not making any sense to me. What I've put together so far forces it to reference the lowercase.html file from /BLAH to /blah.html but I can't seem to put together /BLAH.html to /blah.html.
This is only to move SomeCapS.html (or .HTML I guess) to somecaps.html instead.
Any ideas on how to fix this code:
RewriteEngine On
RewriteBase /
# http://www.askapache.com/htaccess/rewrite-uppercase-lowercase.html
# If there are caps, set HASCAPS to true and skip next rule
RewriteRule [A-Z] - [E=HASCAPS:TRUE,S=1]
# Skip this entire section if no uppercase letters in requested URL
RewriteRule ![A-Z] - [S=28]
# Replace single occurance of CAP with cap, then process next Rule.
RewriteRule ^([^A]*)A(.*)$ $1a$2
RewriteRule ^([^B]*)B(.*)$ $1b$2
RewriteRule ^([^C]*)C(.*)$ $1c$2
RewriteRule ^([^D]*)D(.*)$ $1d$2
RewriteRule ^([^E]*)E(.*)$ $1e$2
RewriteRule ^([^F]*)F(.*)$ $1f$2
RewriteRule ^([^G]*)G(.*)$ $1g$2
RewriteRule ^([^H]*)H(.*)$ $1h$2
RewriteRule ^([^I]*)I(.*)$ $1i$2
RewriteRule ^([^J]*)J(.*)$ $1j$2
RewriteRule ^([^K]*)K(.*)$ $1k$2
RewriteRule ^([^L]*)L(.*)$ $1l$2
RewriteRule ^([^M]*)M(.*)$ $1m$2
RewriteRule ^([^N]*)N(.*)$ $1n$2
RewriteRule ^([^O]*)O(.*)$ $1o$2
RewriteRule ^([^P]*)P(.*)$ $1p$2
RewriteRule ^([^Q]*)Q(.*)$ $1q$2
RewriteRule ^([^R]*)R(.*)$ $1r$2
RewriteRule ^([^S]*)S(.*)$ $1s$2
RewriteRule ^([^T]*)T(.*)$ $1t$2
RewriteRule ^([^U]*)U(.*)$ $1u$2
RewriteRule ^([^V]*)V(.*)$ $1v$2
RewriteRule ^([^W]*)W(.*)$ $1w$2
RewriteRule ^([^X]*)X(.*)$ $1x$2
RewriteRule ^([^Y]*)Y(.*)$ $1y$2
RewriteRule ^([^Z]*)Z(.*)$ $1z$2
# If there are any uppercase letters, restart at very first RewriteRule in file.
RewriteRule [A-Z] - [N]
RewriteCond %{ENV:HASCAPS} TRUE
RewriteRule ^/?(.*)$ /$1.html
Thanks a lot
You need to use the built in rewrite map directive, because this has a lot of problems. First, the number of internal redirects is capped at something like 10. This means you can only redirect internally 10 times, and a URI with 11 upper case letters will cause too many internal redirects, resulting in a 500 server error.
The Apache documentation has a page for RewriteMaps.
But the problem is rewrite maps must be declared in the vhost/server config. And not in the htaccess file. If you don't have access, you may need to write a script to do this for you. Something like:
RewriteEngine On
RewriteRule [A-Z] /tolower.php [L]
And in the tolower.php you'd need to look at $_SERVER['REQUEST_URI'], then change all the letters to lower case, then either redirect the browser to the new URL without any upper case letters or, internally load that page and return it on the browser's behalf.
Related
My .htaccess
Options -Indexes
DirectorySlash Off
RewriteEngine On
RewriteRule ^about$ about/about_me.html [L]
Is it possible to do this
Options -Indexes
DirectorySlash Off
RewriteEngine On
RewriteRule ^about$ about/about_me.html [L]
#Using multiple RewriteRules with diffrent names for same url
RewriteRule ^About$ about/about_me.html [L]
RewriteRule ^ABOUT$ about/about_me.html [L]
RewriteRule ^about$ about/about_me.html [L]
#Using multiple RewriteRules with diffrent names for same url
RewriteRule ^About$ about/about_me.html [L]
RewriteRule ^ABOUT$ about/about_me.html [L]
Yes, you can do this, but... you shouldn't.
/about and /ABOUT are strictly speaking different URLs. (URLs are case-sensitive.) Google sees these as different URLs, so if /about and /ABOUT both serve the same content then you are potentially creating a duplicate content issue (whether that is actually going to be a problem or not is another matter).
Aside: You don't need multiple directives to do this, creating another directive for each variation. You can use the NC (nocase) flag on the RewriteRule directive to make it a case-insensitive match. For example:
RewriteRule ^about$ about/about_me.html [NC,L]
This will match about, ABOUT and AbOuT etc. and rewrite the request to about/about_me.html in all cases.
Case-insensitive and avoid duplicate content - Redirect instead
To allow all cased variations of about to be accessible and avoid the duplicate content issue you should externally redirect (not "rewrite") the non-canonical variations (eg. ABOUT and AbOuT etc.) to the canonical about. And only rewrite about to about/about_me.html.
For example, before the above "rewrite" you could implement the following "redirect" to canonicalize ABOUT and AbOuT to about.
# Redirect "ABOUT" and "AbOuT" to "about"
RewriteCond %{REQUEST_URI} ^/about$ [NC]
RewriteRule [A-Z] /about [R=301,L]
However, this rule is specific to one URL - it is not very practical if you have more than a handful of URLs. You might instead choose to simply lowercase all requested URLs. For example:
How to rewrite URLs from UPPERCASE to lowercase in .htaccess
I have found so many examples of URL Rewrite in CI, but not a final and good solution, i have url like this
www.somesite.com/index.php/tehnicki/tekstovi
I want to have url like this
www.somesite.com/about.html
This about is GET Variable, that is going in MySql Query, it will be no number it will be some NAME, how to do that?
And what i have to write in tehnicki controller to take that GET Variable, is there any helper in CI for MySQL Attack, or i have to write it on my own :)
Okay, let's see, it seems messed up and it doesn't make sense but I'll give you what you need.
First we will have to remove the index.php file :
- use this as .htaccess
//.htaccess
RewriteEngine on
RewriteCond $1 !^(index\.php|Skin|robots\.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L,QSA]
next, in your config.php set index_page to an empty string
// application/config/config.php
$config['index_page'] = '';
on the same file, scroll to url_suffix, and set it to .html
// application/config/config.php
$config['url_suffix'] = '.html';
now head to your routes.php and apply a rewrite rule
// application/config/routes.php
$route['about'] = "tehnicki/tekstovi";
I'll quickly explain what I did here so you get how it works:
1- we removed the index.php section of the url in order to clean it
2- we added a url suffix that will be generated on all the pages
3- we applied a rewrite rule that will match /about.html to the controller tehnicki and the action tekstovi (tehnicki/tekskovi)
I want to write htaccess rules where I can rewrite this
www.example.com/Project_Name/1/23 project.html?n=$1&p=$2&i=$3
I have this already, but the problem is that I have a file in /projects/projects.xml which gets rewritten as well when I call it with Ajax.
RewriteRule ^([\._\-a-zA-Z0-9]*)\/([0-9]*)\/([0-9]*)(.?)$ /project.html?n=$1&p=$2&i=$3 [NC]
Try adding RewriteCond %{REQUEST_FILENAME} !-f above the RewriteRule. Assuming projects.xml is an actual file, that should prevent rewriting.
I have a website, with a nice RewriteRule in its root, that redirects all the queries of this kind:
http://domain.com/foo/parameter
into
http://domain.com/index.php?args=parameter
Users can only see the clean URL and everyone is happy.
Now here is the problem: domain.com DNS have an A record for domain.com, pointing to a private server IP, and an A record for mail.domain.com, pointing to the exact same IP.
For some unknown reason, in the last couple of months, Google double indexed all the pages of my site (http://domain.com/foo/par1, http://domain.com/foo/par2 etc.) with another set with the mail subdomain (http://mail.domain.com/foo/par1, http://mail.domain.com/foo/par2 etc).
I thought I could get rid of all of them redirecting any request to mail.domain.com/$whatever to domain.com and eventually Google would understand that all those pages with the 'mail' subdomain redirects to the homepage and are therefore not necessary.
I tried this in .htaccess:
RewriteCond %{HTTP_HOST} ^mail.domain.com$ [NC]
RewriteRule ^(.*)$ http://domain.com [R=301,L]
But this redirects to a visible URL that looks like this: http://domain.com/index.php?args=parameter, while I just want a redirect to the homepage.
What's the correct form, and are there more elegant ways to achieve this, maybe adding something into robots.txt? (Please note that I can't just disallow a subfolder here)
If you just want to redirect to home page by discarding the original REQUEST_URI and QUERY_STRING then use these rules:
RewriteCond %{HTTP_HOST} ^mail.domain.com$ [NC]
RewriteRule ^(.*)$ http://domain.com/? [R=301,L]
By putting ? in the end it will strip out original query string, thus a URL of this type: http://mail.domain.com/index.php?args=parameter will become http://domain.com/
Your rule is correct, but you need to put it before all the other rules (right after RewriteEngine On) or it will pick up the latest state of the internal rewritten URL.
Update: Hmm, you said that your old rule redirects correctly but is using the internal, ugly, URL. That actually shouldn't be the case unless you add $1 to pick out the matched string.
RewriteCond %{HTTP_HOST} ^mail.domain.com$ [NC]
RewriteRule ^(.*)$ http://domain.com/$1 [R=301,L]
I'd like to use mod rewrite in to convert web page addresses like /directory to /directory/index.html, in a standard LAMP hosting situation. What I have works for addresses that end in a slash. I can't find a way to handle addresses that don't end a slash.
What seems like it should work is:
rewriterule ^(.*)/$ $1/index.html [L] /* addresses ending in / */
rewriterule ^(.*(?!html))$ $1/index.html [L] /* where the problem is */
But the second line causes a 500 server error. If I add a single letter x to the second line:
rewriterule ^(.*)/$ $1/index.html [L]
rewriterule ^(.*x(?!html))$ $1/index.html [L]
It starts to work, but only for directory names that end in an x. I have tried replacing the x with many different things. Anything more complicated than real characters (like [^x] or .+) gives a 500 server error.
And, to satisfy my own curiosity, does anyone know why the addition of a single real letter makes the difference between a server error and a perfectly functioning rule?
[Accepted Answer] Thanks to Gumbo I was able to approximate a solution using rewritecond:
rewritecond %{REQUEST_URI} !\.[^/]+$
rewriterule (.+) $1/index.html [L]
This works, but filters more than just .html -- it could block other pages. Unfortunately,
rewritecond %{REQUEST_URI} !\.html$
results in a server error:
Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary.
I'd still like to know why:
rewriterule ^(.*(?!html))$ $1/index.html [L]
results in a loop. The first half is supposed to check if it doesn't end in .html. Since the second half adds .html, it seems like the functional equivalent of:
while(substr($address,-4)!='html') $address.='html'
Obviously I'm missing something.
Use a RewriteCond directive to check whether the URL path does not end with a .html:
RewriteCond %{REQUEST_URI} !\.html$
RewriteRule ^(.*[^/])?/?$ $1/index.html [L]
Edit You’re using a look-ahead assertion ((?!…)). But there isn’t anything after .* (only a $). So try a look-behind assertion instead:
RewriteRule ^.*$(?<!html) $0/index.html [L]
But note that you probably need Apache 2.2 to use these assertions.
Well, for actually making it work, you could just use a negative lookbehind instead of a lookahead:
RewriteRule ^(.*)(?<!html)$ $1/index.html [L]
I'm not sure offhand why adding the 'x' makes it work, I'll edit if I figure it out.
For why adding the x makes it work:
If the replacement will match the regex, the RewriteRule will be applied again. As an example, this causes an error:
RewriteRule ^(.*)$ $1.rb
because it would replace script with script.rb. That matches the regex, so it replaces script.rb with script.rb.rb, again and again...
This is hinted at in the error log:
Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary.
In your example, you add index.html to the end. When there is an x at the end of the regex, then it won't match your replacement, which ends in an l.