htaccess rule is passing innecesary variable - .htaccess

This is the file tree:
/problem/
/problem/index.php
index.php
category.php
somefile.php
I have this 2 rules in the .htaccess that is sitting in the /
RewriteRule ^somedir$ /somefile.php [L]
RewriteRule ^([a-z-]+)$ /category.php?cat=$1 [QSA,L]
So...
http://domain.com/somedir = OK
http://domain.com/ = OK
http://domain.com/problem/ < automatically adds ?cat=problem to the querystring. I want to avoid that extra ?cat=problem
I need to add a rule that doesn't add the cat=$1 when the /dir/ exists.

Just add a RewriteCond before your second rule. Basically, don't run that catch all if it starts with product:
RewriteRule ^somedir$ /somefile.php [L]
RewriteCond %{REQUEST_URI} !^/product [NC]
RewriteRule ^([a-z-]+)$ /category.php?cat=$1 [QSA,L]
To prevent redirecting for a real file or directory, add these two lines before the rule:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

Related

Different .htaccess rewrite rules for new directory

My .htaccess currently has the following behaviour using the rewrite rules below:
https://example.com/abcd?lol=true
if file /abcd.php exists, open https://example.com/abcd.php?lol=true
if directory and file /abcd/index.php exist, open https://example.com/abcd/index.php?lol=true
else open https://example.com/index.php?lol=true
-> in all three cases the address bar must still show https://example.com/abcd?lol=true
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1%{REQUEST_URI} [R=301,QSA,NC,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [END]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ / [END]
Now to my question: I have a new directory /blog/, where the following must happen:
https://example.com/blog/abcd?lol=true
open https://example.com/blog/index.php?lol=true
-> the address bar must still show https://example.com/blog/abcd?lol=true so I can use php to read the abcd part, which could be an article name.
How can I append my .htaccess code to achieve this?
Aside: You're not actually doing anything for #2 (ie. "if directory and file /abcd/index.php exist...") - you are probably relying on default behaviour by mod_dir. However, if you request /abcd?lol=true and /abcd exists as a physical directory, there will be a 301 external redirect to append the trailing slash (ie. /abcd/?lol=true ) which will then result in /abcd/index.php being served. So, this does not strictly show /abcd?lol=true in the address bar as you suggest. Is that what you are seeing?
To implement the /blog/abcd?lol=true to /blog/index.php?lol=true rewrite then replace your last rule with the following:
# Prevent further processing if a file or directory is requested directly
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [END]
# Route requests to blog/index.php
RewriteRule ^blog/. blog/index.php [END]
# Everthing else is routed to "/index.php"
RewriteRule . index.php [END]
This separates out the filesystem checks into their own rule so you aren't doing this twice.
Your previous "last" rule:
RewriteRule ^(.*)$ / [END]
You were only rewriting to / and then relying on mod_dir issuing an internal subrequest for index.php (the DirectoryIndex). You should instead rewrite directly to index.php as required (no need for the slash prefix). The capturing pattern ^(.*)$ is unnecessary here.

how to ignore index.php file from urlrewrite

This is my simple htaccess code:
RewriteRule ^books/([A-Za-z0-9.]+)$ library/search.php?zig=$1 [NC,L]
My code is working fine for the followings:
mydomain/books/math
mydomain/books/english
mydomain/books/physics.applied
as
library/search.php?zig=math
library/search.php?zig=english
library/search.php?zig=physics.applied
But my code is not working only for
mydomain/books/
it is acting as
library/search.php?zig=index.php
There is no subject named index.php. I want to remove this index.php. My search function should not work for mydomain/books/
You can add a RewriteCond to ignore all files and directories from rewrite:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^books/([A-Za-z0-9.]+)$ library/search.php?zig=$1 [NC,L,QSA]

How to add an excluding rewrite (un-rewrite) condition for specific file types?

I have the following simple rewrite, which I am taking a slightly different approach to rewriting site content.
RewriteEngine On
RewriteRule ^(.*)$ controller.php?page=$1 [NC,L,QSA]
The goal, is to rewrite all files and folders, everywhere, except if the file is of a particular type.
Traditionally, the following approaches are taken which are bit too relaxed for this endeavor :
1. Exclude all files/folders that physically exist:
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
2. Exclude specific folders from rewrite
RewriteRule ^somepath - [L]
3. Rewrite only specific file types
RewriteRule ^\.html index.php [NC,L,QSA]
4. Combination of #2 and file types
RewriteCond %{REQUEST_URI} !/images/.*
RewriteRule ^(.*\.(gif|jpg|png))$ images/$1 [QSA,L]
What I am wondering is what rule do I insert to exclude (keeping the sample short): jpg,bmp,png from being rewritten to controller.php regardless of the subfolder they are located in.
Pseudocode
RewriteEngine On
# skip rewriting jpg,bmp,png
RewriteRule ^[..something here..] - [NC,L]
# rewrite everything else
RewriteRule ^(.*)$ controller.php?page=$1 [NC,L,QSA]
RewriteCond %{REQUEST_FILENAME} !.*\.extensiongoeshere

htaccess rewrite / remove parent dir

there's been similar posts about this but I can't quite seem to find what I need.
I want my .htacess to rewrite "up one level".
The Url would be somethign like
http://www.site.com/variable_dir/
or
http://www.site.com/variable_dir/sub_dir
I need that to basically rewrite the request to
http://www.site.com/
or
http://www.site.com/sub_dir
I DO want the URL to still show the original
http://www.site.com/variable_dir/
or
http://www.site.com/variable_dir/sub_dir
I currently have
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php [L]
This redirects to where I want, but this changes the URL to
http://www.site.com/
or
http://www.site.com/sub_dir
which I don't want.
I know it's simple but I just can't seem to get there.
The rule below woule rewrite http://www.site.com/variable_dir/ to http://www.site.com/ and http://www.site.com/variable_dir/sub_dir to http://www.site.com/sub_dir
RewriteEngine on
RewriteBase /
#for a request to /variable_dir
RewriteCond %{REQUEST_URI} ^/variable_dir/(.+)$
#rewrite it to directory without variable_dir
RewriteRule . /%1 [L]
Edit:
If the directory is not literally variable_dir, the rule above will not work. However, if you have a short list of directories, you could enumerate them as below.
RewriteEngine on
RewriteBase /
#only apply if this directory does not exist
RewriteCond %{REQUEST_FILENAME} !-d
#for any direcory enumerated here
RewriteCond %{REQUEST_URI} ^/(variable_dir|dir2|dir3|etc)/(.+)$
#rewrite it to directory without variable_dir
RewriteRule . /%2 [L]
If not, then ideally the directories would all have something in common so you could limit what the rule affects. If you want a completely variable dir, nothing in common, I don't recommend it, but you can try
RewriteEngine on
RewriteBase /
#only apply if this directory does not exist
RewriteCond %{REQUEST_FILENAME} !-d
#skip any top level directory
RewriteCond %{REQUEST_URI} ^/[^/]+/(.+)$
#rewrite it to directory without variable_dir
RewriteRule . /%1 [L]
Edit:
Finally if the trailing slash is optional, as in the example in your comment, change the RewriteCond and rule above to be
#skip any top level directory, optional trailing slash
RewriteCond %{REQUEST_URI} ^/[^/]+(/(.+))?$
#rewrite it to directory without variable_dir
RewriteRule . /%2 [L]

Rewrite rule to hide folder, doesn't work right without trailing slash

i have a strange apache mod_rewrite problem. I need to hide a sub-directory from the user, but redirect every request to that sub-directory. I found several quite similar issues on stackoverflow, but nothing really fits, so i decided to post a new question.
My .htaccess looks like this:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*)?$ foo/$1 [QSA,L]
The document-root only contains the following folder/files:
/foo/bar/index.html
I would now expect that example.com/bar and example.com/bar/ would just show me the contents of index.html.
Instead example.com/bar/ show me the content as expected but example.com/bar redirects me with a 301 to example.com/bar/foo/ an then shows the contents. I really don't get why there is a 301 redirect in this case.
When i put something this
RewriteCond %{REQUEST_URI} !^[^.]*/$
RewriteCond %{REQUEST_URI} !^[^.]*\.html$
RewriteCond %{REQUEST_URI} !^[^.]*\.php$
RewriteRule ^(.*)$ $1/ [QSA,L]
on top of that rule it seems to work, but that would require me to list every used file extension...
Is there any other way i can omit the redirect, the folder "bar" should never be seen by an outside user.
Thanks in advance!
1st rewrite rule is redirect from /foo/(.) to ($1) and second - from (.) to $1.
just idea, this has not been tested.
Better late than never...
Got it working with a simple RewriteRule which append a / to every url that doesn't have on.
# only directories
RewriteCond %{REQUEST_FILENAME} !-f
# exclude there directories
RewriteCond %{REQUEST_URI} !^/excluded-dirs
# exclude these extensions
RewriteCond %{REQUEST_URI} !\.excluded-extension$
# exclude request that already have a /
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ /$1/ [R=301,L]

Resources