.htaccess rules being overriden - php

I am currently having an issue with a website I am working on. I am forwarding one URL to another URL.
In my root folder, I have the following code:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www.domaina.com
RewriteRule ^(.*) http://www.domainb.com/$1 [R=301,L]
It's redirecting traffic as it is supposed to, except in one directory on the website > /shop
In the /shop directory, there is also an .htaccess file and it seems to be cancelling out what I have set in the root. Here are the contents of the .htaccess in the /shop directory:
RewriteEngine On
RewriteBase /shop/
RewriteRule ^enclosures-enclosure-guidelines-c-229_675.html$
/resources#nema-guidelines [L,R=301,NE]
#RewriteRule ^category/(.*)$ index.php?$cPath=$2
RewriteRule ^mc/(.*)$ mc.php?keywords=$1
RewriteRule ^(.*)-c-(.*)-p-(.*)$ product_info.php?cPath=$2&products_id=$3&%{QUERY_STRING}
RewriteRule ^(.*)-p-(.*)$ product_info.php?products_id=$2&%{QUERY_STRING}
RewriteRule ^(.*)-c-(.*)$ index.php?cPath=$2&%{QUERY_STRING}
RewriteRule ^(.*)-c2-(.*)$ index2.php?cPath=$2&%{QUERY_STRING}
RewriteRule ^(.*)-c-(.*)-p-(.*).html$ product_info.php?cPath=$2&products_id=$3&%{QUERY_STRING}
RewriteRule ^(.*)-p-(.*).html$ product_info.php?products_id=$2&%{QUERY_STRING}
RewriteRule ^(.*)-c-(.*).html$ index.php?cPath=$2&%{QUERY_STRING}
RewriteRule ^(.*)-m-(.*).html$ index.php?manufacturers_id=$2&%{QUERY_STRING}
RewriteRule ^(.*)-pi-(.*).html$ popup_image.php?pID=$2&%{QUERY_STRING}
RewriteRule ^(.*)-t-(.*).html$ articles.php?tPath=$2&%{QUERY_STRING}
RewriteRule ^(.*)-a-(.*).html$ article_info.php?articles_id=$2&%{QUERY_STRING}
RewriteRule ^(.*)-pr-(.*).html$ product_reviews.php?products_id=$2&%{QUERY_STRING}
RewriteRule ^(.*)-pri-(.*).html$ product_reviews_info.php?products_id=$2&%{QUERY_STRING}
RewriteRule ^(.*)-i-(.*).html$ information.php?info_id=$2&%{QUERY_STRING}
RewriteRule ^(.*)-links-(.*).html$ links.php?lPath=$2&%{QUERY_STRING}
Any help would be appreciated.

it seems to be cancelling out what I have set in the root"
That's how .htaccess files work. From the docs:
The configuration directives found in a .htaccess file are applied to
the directory in which the .htaccess file is found, and to all
subdirectories thereof. However, it is important to also remember that
there may have been .htaccess files in directories higher up.
Directives are applied in the order that they are found. Therefore, a
.htaccess file in a particular directory may override directives found
in .htaccess files found higher up in the directory tree. And those,
in turn, may have overridden directives found yet higher up, or in the
main server configuration file itself.

Inside shop/.htaccess you can use this directive at the top:
RewriteOptions InheritBefore
This forces the current configuration to inherit the configuration of the parent and applies parent rules before current .htaccess rules.
If you are on older Apache i.e. < 2.4 then use:
RewriteOptions Inherit
though remember that parent config will be applied after current set.
Check official doc for more details

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.

URL prefix for Apache's RewriteRule patterns

I was wondering if there is any Apache directive to automatically add a given prefix to all RewriteRule patterns (and possibly also RewriteCond patterns), similar to RewriteBase for substitutions of relative urls.
To put this into a context - I want to run my php application under a url sub-folder, say we http://example.com/my-app/. In the Apache virtual host I set
Alias /myapp "<path-to-my-app-source-dir>"
as I want to run a different app under http://example.com. In the .htaccess under the my-app source folder, I added RewriteBase /my-app so I don't have to explicitly put my-app in RewriteRule substitutions. I haven't found any similar directive to specify prefix for patterns, so the following rules
RewriteRule ^my-app/foo/(.+)$ foo.php?x=$1
RewriteRule ^my-app/.*$ index.php [L]
could be specified as
RewriteRule ^foo/(.+)$ foo.php?x=$1
RewriteRule ^.*$ index.php [L]
Is there one? Or is there overall a better solution for this set up?
Thanks!

.htaccess RewriteRule conflict across different directories

On my Ubuntu development machine(s) I run a LAMP stack. For each website I work on, I create a new directory off root:
/var/www/somesite.com
/var/www/anothersite.com
The problem I have is that apache wont allow duplicate rewrite rules across these folders. For instance, If I set up this:
RewriteRule ^track/(.*)$ /somesite.com/order_track.php [nc,L]
http://localhost/somesite.com/track/abc123 - works as intented
This same declaration wont work on anothersite.com
RewriteRule ^track/(.*)$ /anothersite.com/order_track.php [nc,L]
http://localhost/anothersite.com/track/abc123 - Apache returns a 404.
Clearing browser cache and restarting Apache have no effect. Apache seems to "remember" the first like rewriterule used. This happens on all of my computers(Home, work, laptop)
Edit: I should have mentioned that I have an htaccess file in each directory. The root /var/www does not contain an htaccess file. Each directory's htaccess should operate independently. But they do not.
You can have this in /somesite.com/.htaccess:
RewriteEngine On
RewriteBase /somesite.com/
RewriteRule ^track/(.*)$ order_track.php [NC,L]
Then this in /anothersite.com/.htaccess:
RewriteEngine On
RewriteBase /anothersite.com/
RewriteRule ^track/(.*)$ order_track.php [NC,L]
RewriteCond %{HTTP_HOST} ^(?:www\.)?(somesite\.com|anothersite\.com)$
RewriteRule ^track/ /%1/order_track.php [NC,L]
you don't need (.*) if not needed to catch this.

php mod rewrite .htaccess ignore directory

What rule should i set, to make the mod_rewrite ignore the directory "public" completely?
By that, I mean, the files should be accessible within it, but if the file does not exist, a server error page should come up with something like, FORBIDDEN, or FILE NOT FOUND what ever. I do not need custom error pages or stuff like that. I simply want the "public" to behave like there is no mod_rewrite at all.
Here is my .htaccess file:
RewriteEngine on
RewriteCond $1 !^(index\.php|robots\.txt)
RewriteRule ^(.*)$ index.php/$1 [L,QSA]
My file structure is
/system/
/application/
/public/
I want the folder public to behave, like there are no rewrite rules set at all, completely ignore it.
edit
That's my .htaccess file:
RewriteEngine on
RewriteRule ^(public)($|/) - [L,NC]
RewriteCond $1 !^(index\.php|robots\.txt)
RewriteRule ^(.*)$ index.php/$1 [L,QSA]
I already had this .htaccess in the /public/ folder:
RewriteEngine off
I've tried all the different answers above (and a ton from google). I've tried to mix 'em up what so ever.
My folders:
/system/
/application/
/public/
/public/.htaccess #RewriteEngine off
/public/favicon.ico
/index.php
Below are the url with results I'm getting:
/public/favicon.ico -> I get the favicon
/public/faviDon.ico -> I get the index.php (without mod rewrite you would get "not found")
/public/ -> I get the index.php (without mod rewrite "forbidden")
So it still does rewrite urls, if the file was not found, or upon accessing a folder directly.
Can you se it?
Thank you very much for effort guys! I really appreciate it!
EDIT
I completely setup your files on my machine
// /.htaccess
RewriteEngine on
RewriteRule ^(public)($|/) - [L,NC]
RewriteCond $1 !^(index\.php|robots\.txt)
RewriteRule ^(.*)$ index.php/$1 [L,QSA]
.htaccess in the public folder:
// /public/.htaccess
Options -Indexes
RewriteEngine off
This disables rewriting like you wanted.
/public/ -> 403 Forbidden
/public/favicon.ico -> 200 File found
/public/not-existing.ext -> 404 File not found
Do you have a index.php in you public folder?
Maybe you could remove that one..
What kind of machine your testing on?
I tested it on Linux + Apache 2 + PHP5.3
I can give you more support in the afternoon (my time +2 GMT)
EDIT 2
When I remove this line from /.htaccess is still works
RewriteRule ^(public)($|/) - [L,NC]
Everything is handled by the .htaccess in the public folder.
Maybe it's a caching problem in your browser. Try a different browser/clean up history/install app to remove cache.. (depending on what browser you're using)

URL rewrite not working when another htaccess is in a subfolder

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.

Categories