URL rewrite not working when another htaccess is in a subfolder - php

I have an .htaccess file in the root of my site. Inside the file, I have a code that redirects all traffic to add "www." to the beginning of the url:
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{HTTP_HOST} ^website.com [NC]
RewriteRule ^(.*)$ http://www.website.com/$1 [L,R=301]
This works great for 95% of the site. However, I have one subdirectory, website.com/playdate, that has another .htaccess file inside the folder. Inside this .htaccess file is the following code, to redirect the URL to something a little cleaner:
Options +FollowSymLinks
RewriteEngine on
RewriteRule ^page/([0-9]+)/ index.php?page=$1
Options +FollowSymLinks
RewriteEngine on
RewriteRule ^([a-zA-Z0-9_-]+)/ view.php?url_slug=$1
It seems like this code is overriding the www redirect. I have tried to add the initial code,
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{HTTP_HOST} ^website.com [NC]
RewriteRule ^(.*)$ http://www.website.com/$1 [L,R=301]
to the top of the secondary .htaccess, but this does not work.
How do I get the subdirectory to continue to forward to the "www." version of the site, while also keeping the secondary .htaccess rules for this subfolder?

When a request is made, for example /playdate, the first thing that happens is a URL to file mapping is made, then apache checks if that file mapping, which in this case maps to a directory, contains an htaccess file. If it doesn't, then it checks parent directories for htaccess files. If it does, then it simply uses the htaccess file in that directory.
So when a request is made for /playdate, it has an htaccess file in that directory so apache doesn't bother looking for on in any parent directories. Only this one htaccess file is applied, any ones sitting in parent directories are ignored.
If you are using apache 2.2, then you'll just have to copy over the www redirect rules, but you'll need to tweak them because your no longer in the document root. Add these rules to the top of your htaccess file (or at least, above any rules that you already have in there):
RewriteEngine on
RewriteCond %{HTTP_HOST} ^website.com [NC]
RewriteRule ^(.*)$ http://www.website.com/playdate/$1 [L,R=301]
If you are using apache 2.4, there is a specific option you can apply to the htaccess file in the playdate directory:
RewriteOptions InheritBefore
This makes it so any rules in the parent scope are inherited before any rules in the child scope. This is important because you need to make sure the www redirect rules occur before any of your routing rules are applied, otherwise the URI gets mangled. Apache 2.2 has a similar option, Inherit but those are placed after any rules in the child scope.

I think your problem is the L flag you are using when you rewrite the full domain name.
[L,R=301]
The L flag means "Last", as in, "this is the last rewrite directive I want the server to process for this URI request." If the user agent requests "http://website.com/playdate", then the rewrite condition will trigger the line
RewriteRule ^(.*)$ http://www.website.com/$1 [L,R=301]
The server will rewrite the request to http://www.website.com/playdate and stop processing rewrite rules for that URI request because the server comes to the L flag.
At least that is my guess.

Related

.htaccess file is not working in my Server

My site is located in https://itjmovies.com/milan/public/ and I want to rewrite the URL by .htaccess file. From https://itjmovies.com/milan/public/ To https://itjmovies.com/milan/ but it is not working.
And also https://itjmovies.com/milan/public/auth/index.php?page=new To https://itjmovies.com/milan/public/auth/new/ but this is also not working.
I have kept my .httaccess file in /www/wwwroot/itjmovies.com/milan/.htaccess
My .htaccess file:
RewriteEngine On
RewriteRule ^/(.*)$ /public/$1 [R=301,NC,L]
RewriteRule ^public/auth/([a-zA-Z]+) /index.php?page=$1 [QSA,L]
Thank You :)
I'm not sure that your edit made your question any clearer. In your question description the stated rewrites (from/to) appear to be the wrong way round to what I think they are intended (and conflict with the order in which you have written the directives), but anyway...
My assumptions:
/public should not be part of the visible URL. Although your site is located in the /milan/public directory. You are making requests of the form /milan/<anything>.
You need to internally rewrite all requests from /milan/<anything> /to /milan/public/<anything>.
Requests of the form /milan/public/auth/<something>/ (note the trailing slash, as stated in your example) should be internally rewritten to /milan/public/auth/index.php?page=<something>
I would have 2 .htaccess files. One in the /milan subdirectory that simply rewrites/forwards requests to the public subdirectory. And another .htaccess file in /milan/public that handles rewrites that are specific to your application.
For example:
# /milan/.htaccess
RewriteEngine On
# Forward all requests to the "public" subdirectory
RewriteRule (.*) public/$1 [L]
# /milan/public/.htaccess
RewriteEngine On
# Rewrite "auth/<something>/" to "auth/index.php?page=<something>"
RewriteRule ^auth/([^/]+)/$ auth/index.php?page=$1 [QSA,L]
The .htaccess file at /milan/public/.htaccess also serves to prevent a rewrite loop when requests are rewritten to the public subdirectory by the .htaccess file in the parent directory. This is because mod_rewrite directives are not inherited by default.
The QSA flag is only required if you are expecting query strings on the original request.
The RewriteRule pattern (1st argument) matches the URL-path relative to the directory that contains the .htaccess file.
RewriteRule ^/(.*)$ /public/$1 [R=301,NC,L]
RewriteRule ^public/auth/([a-zA-Z]+) /index.php?page=$1 [QSA,L]
A few notes on your attempt - which is close, but has a few crictical errors:
The URL-path matched by the RewriteRule pattern does not start with a slash (when used in .htaccess), so the regex ^/(.*)$ will never match.
The first rule is also an external redirect (ie. exposes the /public subdirectory) which doesn't seem right. Do you really want /public in the visible URL - if so then you should be linking directly to the /public subdirectory, not relying on a redirect?
The first rule is redirecting to /public in the document root, not /milan/public.
Once corrected, the first rule will also result in a rewrite-loop (500 Internal Server Error) as it will repeatedly rewrite the request... public/public/public/<something> etc.
The second rule is also rewriting to /index.php in the document root, not /milan/public/auth/index.php.

User-Friendly Redirect If File Not Exist

I feel like this is a rather common request, but I am too confused about .htaccess and couldn't find a solution by Google.
I have a Laravel instance in a subdirectory of the Apache2 htdocs. Now I would like to invisibly redirect all requests from the root domain to this folder (it should be the "root" website). But the tricky thing is, this is not the only folder, there are other folders directly in the htdocs, which should be reached normally. Just the "root" website is not in the root but also in a subfolder. For example:
https://domainA.com should load https://domainA.com/laravel/public (including possible query string or parameters, but invisibly for the user)
https://domainA.com/websiteB should be served as it is
https://domainA.com/websiteC should be served as it is
...
I assume, part of this solution will be to list all the websiteB, websiteC directories in the .htaccess, would it be possible to automate this?
Thanks in advance!
You can put a .htaccess in the folder you want to custom controle but you have to create some filter condition
<IfModule mod_rewrite.c>
RewriteEngine On
## RewriteBase /foo
## conditions to tell what to redirect ie on URI
## RewriteCond %{REQUEST_URI} ^/a-folder/
## not websiteB or websiteC
RewriteCond %{REQUEST_URI} !^/websiteB/
RewriteCond %{REQUEST_URI} !^/websiteC/
## if the file does not exist call index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ my/path/to/a/script.php [L]
</IfModule>
After you have to do something special in script.php for those HTTP calls
You can also rewrite the URI and pass it again to apache but things can be complicated after...

htaccess RewriteRule redirects to index.php

I am really puzzeld, I want to use htaccess Rewrite to rewrite an url with parameter to one without.
This is my .htaccess file:
RewriteEngine On # Turn on the rewriting engine
RewriteRule ^sitemap.xml$ sitemap.php [NC] # Handle requests for "sitemap"
RewriteRule ^category/([A-Za-z0-9-]+)/$ displaycategory.php?category_name=$1 [NC] # Handle requests for "categories"
RewriteRule ^items/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)$ item.php?category_name=$1&id=$2 [NC] # Handle requests for "single item"
Rule 1 and rule 3 are working fine, but the second url redirects to index.php
If I call this url:
http://example.de/category/test/
it redirects to
http://example.de/category/test/index.php
Your .htaccess rewrite rule is correct, and I assume its not this causing the problem. If you have a directory called test or another file very close to test Apache Multiviews could be the problem. Have you access to server logs? I bet there is something in the server config preventing the rule from working correctly.

htaccess rewrite ".../pages/about.php" to ".../about"

I've searched and found a lot of questions on this site and elsewhere that are very similar, but I've tried implementing and modifying all the suggestions I've found and none of it works. I realize this is a very basic question an I am extremely frustrated because nothing I'm trying is working.
With that having been said... I am trying to organize my content pages within kurtiskronk.com/pages/... (e.g. kurtiskronk.com/pages/about.php)
What I want to do is make it so that I can simply link to kurtiskronk.com/about ... So how do I go about stripping "pages/" and ".php"? I don't have a ton of content pages, so it's not a big deal if I have to specify for each page, though something dynamic would be handy.
NOTES: I am using Rackspace Cloud hosting, and WordPress is installed in /blog. My phpinfo() can be seen at http://kurtiskronk.com/pages/phpinfo.php
This is my existing .htaccess file (in the root)
php_value register_globals "on"
Options +FollowSymLinks
RewriteEngine On
#301 redirect to domain without 'www.'
RewriteCond %{HTTP_HOST} ^www\.kurtiskronk\.com$ [NC]
RewriteRule ^(.*)$ http://kurtiskronk.com/$1 [R=301,NC]
RewriteBase /
RewriteCond %{ENV:PHP_DOCUMENT_ROOT}/pages/$1 -f
RewriteRule ^(.*)$ pages/$1 [L]
RewriteCond %{ENV:PHP_DOCUMENT_ROOT}/pages/$1.php -f
RewriteRule ^(.*)$ pages/$1.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^blog/ blog/index.php [L]
# PHP - MAIL
php_value mail.force_extra_parameters -kurtis#kurtiskronk.com
I tested and the rewrite works with the line below (/about as URL brings up file /pages/about.php), but then the homepage gives a 500 Internal Server Error:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /pages/$1.php [L]
So I'm still sort of in the same boat as before, and as a follow-up, possibly more difficult question, if you go to http://kurtiskronk.com/weddings I am using SlideShowPro (flash) w/ SSP Director (self-hosted) as the back-end for it. When it pulls up a new image, it adds the following after /weddings ... "#id=album-152&num=content-9698"
There are four sections of the portfolio
# Homepage (kurtiskronk.com) id=album-148 ($id is constant for this section)
# Weddings (/weddings) id=album-152 ($id is constant for this section)
# Portraits (/portraits) id=album-151 ($id is constant for this section)
# Commercial (/commercial) id=album-150 ($id is constant for this section)
Assuming we get kurtiskronk.com/weddings to rewrite successfully without breaking anything, how would we make the total URL something cleaner kurtiskronk.com/weddings/9698 since the $num is the only thing that will change within a given section?
Kurtis, thanks for the extra information. It's a lot easier to give a specific answer to this.
My first comment is that you need to separate out in your thinking URI space -- that is what URIs you want your users to type into their browser -- and filesystem space -- what physical files you want to map to. Some of your mappings are URI->URI and some are URI->FS
For example you want to issue a permanent redirect of www.kurtiskronk.com/* to kurtiskronk.com/*. Assuming that you only server the base and www subdomains from this tree, then this cond/rule pair should come first, so that you can assume that all other rules only refer to kurtiskronk.com.
Next, you need to review the RewiteBase documentation. .htaccess files are processed in what Apache calls a Per-Directory context and this directive tells the rewrite engine what to assume as the URI base which got to this directory and .htaccess file. From what I gather, your blog is installed in docroot/blog (in the filesystem, and that you want to get to directory by typing in http://kurtiskronk.com/blog/ but that this .htaccess file is for the root folder -- that is the base should be (this goes before the www mapping rule)
DirectorySlash On
DirectoryIndex index.php
RewriteBase /
#301 redirect to domain without 'www.'
RewriteCond %{HTTP_HOST} ^www\.kurtiskronk\.com$ [NC]
RewriteRule ^(.*)$ http://kurtiskronk.com/$1 [R=301,NC]
You can add some field dumps look for REDIRECT_* in the Server or Environment table in the phpinfo O/P to see if these are sensible. For example:
RewriteWrite ^(.*)$ - \
[E=TESTDR:%{DOCUMENT_ROOT}/pages/$1.php,E=TESTPDR:%{DOCUMENT_ROOT}/pages/$1.php]
Your next rule is that if the file exists in the subdirectory pages then use it:
RewriteCond %{DOCUMENT_ROOT}/pages/$1 -f
RewriteRule ^(.*)$ pages/$1 [NS,L]
[Note that some shared service sites don't set up DOCUMENT_ROOT properly for the rewrite engine so you may need to run a variableinfo script (<?php phpinfo(INFO_ENVIRONMENT | INFO_VARIABLES); to see if it sets up alternatives. On your site you have to use %{ENV:PHP_DOCUMENT_ROOT} instead.]
Your next rule is that if the file exists, but with the extension .php in the subdirectory pages then use it:
RewriteCond %{DOCUMENT_ROOT}/pages/$1.php -f
RewriteRule ^(.*)$ pages/$1.php [NS,L]
Now redirect any blog references to the blog subdirectory unless the URI maps to a real file (e.g. the blog stylesheets and your uploads.)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^blog/ blog/index.php [L]
A complication here is that WP may be using a poorly documented Apache feature call Path Info that is a script can act as a pseudo directory so http://kurtiskronk.com/blog/tag/downtown/ is redirected to docroot/blog/index.php/tag/downtown/ which is then executed by `docroot/blog/index.php using /tag/downtown/ as the PATH_INFO. But this is one for Wordpress experts to comment on. If this last rule doesn't work then try:
RewriteRule ^blog/(.*) blog/index.php/$1 [L]
PS. I like your site. I wish I was that young again :(
Postscript
When you say "it doesn't work", what doesn't with this .htaccess?
http://kurtiskronk.com/phpinfo,
http://kurtiskronk.com/phpinfo.php,
http://kurtiskronk.comblog/tag/downtown/
It's just that these rules work for these tests (with domain swapped) on mine. (One way is to move or copy the above variableinfo.php to the various subdirectories. If necessary temporarily rename the index.php to index.php.keep, say, and copy the variableinfo.php to the index.php file. You can now enter the various URI test patterns and see what is happening. Look for the REDIRECT_* fields in the phpinfo output, and the SCRIPT_NAME will tell you which is being executed. You can add more {E=...] flags to examine the various pattern results. (Remember that these only get assigned if the rule is a match.
Lastly note the changes above especially the additional NS flags. For some reason mod_rewrite was going directly into a subquery which was resulting in redirect: being dumped into the file pattern. I've had a look at the Apache code and this is a internal botch to flag that further redirection needs to take place (which then replaces this or backs out). However this open bug indicates that this backout can be missed in sub-queries and maybe that's what is happening here. Certainly adding the NS flas cured the problem on my test environment.
PS. Note the added explicit DirectoryIndex directive and also that whilst http://kurtiskronk.com will run the root index.php, the explicit /index.php version will run the one in pages, because that's what your rules say.
Here is a simple solution. You can use it apache conf file(s) or in .htaccess (easier to set up when you're trying).
mod_rewrite has to be enabled.
For example, use .htaccess in your DocumentRoot with:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /pages/$1.php [L]
It will redirect /about to /pages/about.php, and any other page.
The "RewriteCond" part is to authorize access to an existing file (eg: if you had an "about" file at the root of your site, then it will be served, instead of redirecting to /pages/about.php).
Options +FollowSymLinks
RewriteEngine On
RewriteRule /([0-9]+)$ /pages/$1.php [L]
Put something like this in your .htaccess file. I guess that is what you want.
Juest a redirect from a simple url to a longer url.

How to use rewriterule to redirect to a php file in the same folder?

I would like to take requests for /somefolder/style.css and handle them with /somefolder/program.php
So, I put the following in my .htaccess file:
rewriteengine on
rewriterule ^style.css$ program.php?css=1 [R=302,L]
The result is that instead of redirecting to /somefolder/program.php, the server tries to redirect to:
/var/www/html/somefolder/program.php?css=1
How can I get rid of the /var/www/html/ in the redirect? I thought that since I just entered program.php in the .htaccess that it would default to the same folder.
Since this is a generic script that I will use in many places, I would like to avoid using rewritebase to specify the folder I'm in -- the .htaccess has to work in any folder without being modified.
Leave the R flag away and you will get an internal redirect:
RewriteRule ^style\.css$ program.php?css=1 [L]
Otherwise specify the full URL path you want to redirect to externally:
RewriteRule ^style\.css$ /program.php?css=1 [R=302,L]
Or for any arbitrary folder:
RewriteCond %{REQUEST_URI} (.*)/style\.css$
RewriteRule ^style\.css$ %1/program.php?css=1 [R=302,L]
I think the problem is that you are missing a ReWrite base statement.
Also the I would put the .htaccess file in the root directory of your site. That way you don't have to copy an .htacess file into every new directory you create. What if you want to change the name of your php file? You'd have to change every .htaccess file.
This is how I would redirect www.mydomain.com/orange/style.css to www.mydomain.com/orange/program.php?css=1 using generic rules:
RewriteEngine On
RewriteBase /
RewriteRule ^(.*)/style\.css$ $1/program.php?css=1 [L]

Categories