I've been trying to get a wikipedia style language thing to work. So that the url will be en.example.com for English, fr.example.com for French, etc... This is working fine however I would like the admin area to always default to base language, i.e. not set the LANGUAGE environment variable. I've tried adding RewriteCond %{REQUEST_URI} !^admin [NC] but it seems to have no effect.
My mod_rewrite code is as follows:
# Handle languages
# Picks up the language code from the browser accept-language parameter
RewriteCond %{HTTP:Accept-Language} ^([a-z]{2}).*$ [NC]
RewriteCond %{HTTP_HOST} !^[a-z]{2}\.[a-z]{2,}\. [NC]
RewriteRule ^(.*)$ http://%1.%{HTTP_HOST}/$1 [R=301]
RewriteCond %{REQUEST_URI} !^admin [NC]
RewriteCond %{HTTP_HOST} ^([a-z]{2})\.[a-z]{2,}\. [NC]
RewriteRule ^(.*)$ - [ENV=LANGUAGE:%1,QSA]
# Redirecting all requests to one script
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([\+a-zA-Z0-9,%\(\)\_\ -/]+)$ /index.php [NC,L,QSA]
Thanks for any help, I'm sure it's something really stupid that is wrong, as usual.
Your problem is that REQUEST_URI doesn't start with admin, its going to have a slash in front... it might start with /admin if you have no rewrite base... so you can change it to !^/admin or just !admin or !admin/ if all your code is in foo.com/admin/*
REQUEST_URI is going to be the entire GET like "/foo/bar.html"
Related
I am moving most pages from a site and I want to redirect all requests to a 404 error page except all/any pages in a certain cname on the site, all/any pages in a certain sub-directory on the site and a certain page in a certain directory on the site.
Here is what I have so far:
Options +FollowSymlinks
RewriteEngine On
RewriteCond %{HTTP_HOST} !^blogs.example.com [NC]
RewriteCond %{REQUEST_URI} !^/private [NC]
RewriteCond %{REQUEST_URI} !^/public/special-form.php [NC]
RewriteCond %{REQUEST_URI} !^/public/special-form_submitted.php [NC]
RewriteCond %{REQUEST_URI} !^/error404.php [NC]
RewriteRule ^(.*) http://example.com/error404.php [R=301,L]
Your issue is mainly the / at the start of your RewriteRule, why?
Because you're using it with an .htaccess so the RewriteRule path starts without the / at the begin.
If it was inside the VirtualHost then that would have worked just fine.
Basically this is what your rule is telling the server to do after our comments conversation and your update:
Options +FollowSymlinks
RewriteEngine On
# if domain is not blogs.example.com
RewriteCond %{HTTP_HOST} !^blogs.example.com [NC]
# and if address does not start with /private
RewriteCond %{REQUEST_URI} !^/private [NC]
# and if the file is not /public/special-form.php
RewriteCond %{REQUEST_URI} !^/public/special-form.php [NC]
# and if the file is not /public/special-form_submitted.php
RewriteCond %{REQUEST_URI} !^/public/special-form_submitted.php [NC]
# and if the file is not /error404.php
RewriteCond %{REQUEST_URI} !^/error404.php [NC]
# then redirect to http://example.com/error404.php
RewriteRule ^ http://example.com/error404.php [R=301,L]
So anything else including images or css or not listed on the conditions would be redirected, in order to avoid that you would have to verify all the needed files within those 2 php pages and white list it, for example with a condition like this:
RewriteCond %{REQUEST_URI} !^/public/[^.]+\.(css|pdf|jpg|doc)$ [NC]
Basically the above means anything within the public folder that ends with .css or .pdf or .doc or .jpg should be displayed.
NOTE: Keep in mind that if your images and documents and whatever else you need to show to your users from those 2 PHP pages are not within the public folder the above will not work, that was merely an example to illustrate an easy way to couple multiple types of files into it.
You could also resume this 2 conditions:
RewriteCond %{REQUEST_URI} !^/public/special-form.php [NC]
RewriteCond %{REQUEST_URI} !^/public/special-form_submitted.php [NC]
as follow:
RewriteCond %{REQUEST_URI} !^/public/(special-form_submitted|special-form)\.php [NC]
You would end with:
Options +FollowSymlinks
RewriteEngine On
RewriteCond %{HTTP_HOST} !^blogs.example.com [NC]
RewriteCond %{REQUEST_URI} !^/private [NC]
RewriteCond %{REQUEST_URI} !^/public/(special-form_submitted|special-form)\.php [NC]
RewriteCond %{REQUEST_URI} !^/public/[^.]+\.(css|pdf|jpg|doc)$ [NC]
RewriteCond %{REQUEST_URI} !^/error404.php [NC]
RewriteRule ^ http://example.com/error404.php [R=301,L]
Just a side information, since you're redirecting anything that does not match the conditions and you're not passing along anything to the redirect, you don't need the (.*), merely using ^ alone will do the job.
I have the following configuration,
RewriteCond %{HTTPS} !^on$ [nocase,ornext]
RewriteCond %{HTTP_HOST} !^www\. [nocase,ornext]
RewriteCond %{HTTP_HOST} !\.com$ [nocase]
RewriteRule ^(.*)$ https://www.acme.com/$1 [redirect=301,last]
the purpose is to redirect to a canonical URL if the request is either not HTTPS, nor begins with www. or ends with .com.
For being seamlessly compatible with developer engines, I want to exclude all these directives if %{HTTP_HOST} includes, for example, dev.internal or so. In this case the RewriteRule should be skipped immediately. Since the three ORs are evaluated with the higher precedence than an (implicit) AND, I wonder how and where to place my dev.internal exception...
Thanks for any advice!
//edit: hmm... if OR has the higher precendence, shouldn't
RewriteCond %{HTTP_HOST} !internal\. [nocase]
RewriteCond %{HTTP:X-Forwarded-Proto} !^https$ [nocase,ornext]
RewriteCond %{HTTP_HOST} !^www\. [nocase,ornext]
RewriteCond %{HTTP_HOST} !\.com$ [nocase]
RewriteRule ^(.*)$ https://www.acme.com/$1 [redirect=301,last]
work then?
If my understanding of ornext is correct then yes, your way should work (can someone else confirm it?).
Here's another way, if you don't want to rely on that:
RewriteCond %{HTTP_HOST} internal\. [nocase] # If it's an internal host...
RewriteRule .* - [skip=1] # ... skip the next rule (and leave the URL unchanged)
RewriteCond %{HTTP:X-Forwarded-Proto} !^https$ [nocase,ornext]
RewriteCond %{HTTP_HOST} !^www\. [nocase,ornext]
RewriteCond %{HTTP_HOST} !\.com$ [nocase]
RewriteRule ^(.*)$ https://www.acme.com/$1 [redirect=301,last]
I am trying to redirect all requests coming in to the web server as http://portal.company.com/legacy to http://portal.company.com/wps/portal/public/legacy/legacyportlet with the following rule, but it is not working as expected.
RewriteEngine on
RewriteCond %{HTTP_HOST} ^portal\.company\.com$ [NC]
RewriteCond %{REQUEST_URI} ^/legacy$ [NC]
RewriteRule ^(.*)$ /wps/portal/public/legacy/legacyportlet$1 [NC,L,PT]
I have also tried
RewriteCond %{HTTP_HOST} ^portal\.company\.com$ [NC]
RewriteRule ^/legacy /wps/portal/public/legacy/legacyportlet [NC,L,PT]
Any help would be greatly appreciated!
Thanks
It doesn't look like your source or target URLs change in any way, so possibly you're better off using Apache's basic Redirect directive which just redirects one URL to another.
Use this rule:
RewriteCond %{HTTP_HOST} ^portal\.company\.com$ [NC]
RewriteRule ^legacy/?$ /wps/portal/public/legacy/legacyportlet [NC,L]
Remember that in .htaccess RewriteRule doesn't match leading slash of URI.
Please suggest me what to put into .htaccess file.
I have PNG, GIF, JPG images on server http://domain.tld/images/anyimage.anyextension
Want to make URLs more friendly like a http://domain.tld/anyimage.anyextension
This I have now. First two strings change links as described. But last string doesn't change it back for server.
RewriteCond %{REQUEST_URI} ^/images/(.+)(\.gif|\.jpg|\.png)$ [NC]
RewriteRule ^image/(.+)$ /$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/(.+)$ /images/$1 [L]
If I add
RewriteCond %{REQUEST_URI} ^/([^/.]+\.(png|gif|jpg))$ [NC]
RewriteCond %{DOCUMENT_ROOT}/image/%1 -f
RewriteRule ^([^/.]+\.(png|gif|jpg))$ /image/$1 [L,NC]
Right after previous query string rule then images don't open. If before there's no problem. What it could be? Do you have an idea how to fix it? The last string RewriteRule ^/?(.+)$ /?$1 [L] cause this conflict
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /\?([^\ ]+) [NC]
RewriteRule ^$ /%1? [R=301,L]
RewriteCond %{QUERY_STRING} ^$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?(.+)$ /?$1 [L]
Not sure how that makes it more friendly, aside from it being shorter. You can try adding this to the htaccess file in your document root:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/([^/.]+\.(png|gif|jpg))$ [NC]
RewriteCond %{DOCUMENT_ROOT}/images/%1 -f
RewriteRule ^([^/.]+\.(png|gif|jpg))$ /images/$1 [L,NC]
Then you can change all of your links from http://domain.tld/images/anyimage.anyextension to http://domain.tld/anyimage.anyextension
The first condition checks to make sure the request is for anyimage.anyextension, as long as the extension is a case-insensitive png, gif, or jpg.
The second condition checks to make sure the requested image actually exists in the /images/ directory.
RewriteEngine On
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /images/(.+)(\.gif|\.jpg|\.png) [NC]
RewriteRule ^image/(.+)$ /$1 [R=301,L]
This redirects the browser to the non-/image/ URL. There's 2 completely different things going on here. One deals with the browser and the other deals with content on the server. See the top part of this answer that explains how they are different.
The rules that you have won't work. First:
RewriteRule ^/(.+)$ /images/$1 [L]
will never match. URI's used to match against the regex of a RewriteRule in htaccess files have the leading slash removed, so no URI is going to start with a /. You need to get rid of it.
Secondly, once you do, you'll get a 500 internal server error because your rules will cause an internal infinite loop. You need to match against %{THE_REQUEST} to ensure that a browser is actually requesting a URL with the /images/ path in it, not what has been internally rewritten.
The Problem:
Been spinning my wheels and reading up on this one for awhile and looking for some help now. I'm looking to take a group of non-friendly URLs (there are actually more "groups" but this should me for an example):
domainname.com/?section=zebras
domainname.com/?section=monkeys&id=555
and turn them into friendly URLs, as well as do a 301 on the old versions, so that any old bookmarks (and search engines) will still resolve them. The new format I'm looking for would be:
domainname.com/zebras/
domainname.com/monkeys/555
I'm fully intending to write separate RewriteCond/RewriteRule combinations for each of those scenarios, so I don't necessarily need a super-rule that catches all my scenarios. Oh and this is all in .htaccess.
My Progress:
I was originally getting into a redirect loop because I was just doing two RewriteRules back to back - one for the friendly URL and one for the 301 redirect. Came across my favorite way (so far) around the redirect loop which works (for my scenario #1 at least):
RewriteCond %{ENV:REDIRECT_STATUS} !200
RewriteCond %{QUERY_STRING} ^section=zebras$ [NC]
RewriteRule ^.*$ http://www.domainname.com/zebras/? [R=301,NC,L]
RewriteRule ^zebras/$ /index\.php?section=zebras [NC,L]
However, I'd like to have something that works for more than just "zebras" (for instance, I'd like it to work for "lions" as well), so I'm trying to make that more generic. What I am trying now looks like this:
RewriteCond %{ENV:REDIRECT_STATUS} !200
RewriteCond %{QUERY_STRING} ^section=([a-z]+)$ [NC]
RewriteRule ^section=([a-z]+)$ http://www.domainname.com/$1/? [R=301,NC,L]
RewriteRule ^([a-z]+)/$ /index\.php?section=$1 [NC,L]
However, this doesn't work. I think I have something "not quite right", I just can't tell what it is - there's something I'm missing or formatting incorrectly somewhere. Sorry in advance for the lengthy description, just wanted to be clear.
Do this:
RewriteEngine on
RewriteBase /
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(\.\w+|/)$
RewriteRule (.*) /$1/ [R,L]
RewriteCond %{QUERY_STRING} ^section=([a-z]+)$ [NC]
RewriteRule ^ /%1/? [R=301,NC,L]
RewriteRule ^([a-z]+)/$ /index\.php?section=$1 [NC,L]
RewriteCond %{QUERY_STRING} ^section=([a-z]+)&id=(\d+)$ [NC]
RewriteRule ^ /%1/%2/? [R=302,NC,L]
RewriteRule ^([a-z]+)/(\d+)/$ /index\.php?section=$1&id=$2 [NC,L]
Description
Prevents looping:
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]
Prevents trailing slash problem:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(\.\w+|/)$
RewriteRule (.*) /$1/ [R,L]
Handles rewrites with only section=([a-z]+) in them:
RewriteCond %{QUERY_STRING} ^section=([a-z]+)$ [NC]
RewriteRule ^ /%1/? [R=302,NC,L]
RewriteRule ^([a-z]+)/$ /index\.php?section=$1 [NC,L]
Handles rewrites with only section=([a-z]+)&id=(\d+) in them:
RewriteCond %{QUERY_STRING} ^section=([a-z]+)&id=(\d+)$ [NC]
RewriteRule ^ /%1/%2/? [R=302,NC,L]
RewriteRule ^([a-z]+)/(\d+)/$ /index\.php?section=$1&id=$2 [NC,L]
mistake in your rules:
section=([a-z]+) is not available in the URI part. So, RewriteRule ^section=([a-z]+)$ never matched.