.htaccess rule not excluding existing files when rule has a slash condition - .htaccess

I am redirecting this type of url
http://www.site.com/windows/games/ or http://www.site.com/windows/games
http://www.site.com/windows/software/ or http://www.site.com/windows/software
to
http://www.site.com/windows/ct.php?ct=games
http://www.site.com/windows/ct.php?ct=software
Site structure
wamp/www/Site/windows/ct.php
I am trying this way its redirecting properly but when url has trailing slash at end its rewriting css, js files too.
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^windows/([^/]*)/?$ /Site/windows/ct.php?ct=$1 [L]
i.e
this type of url has css and javascript applied.
http://www.site.com/windows/games
but this type of url has no css and javascript applied. (not working with trailing slash).
http://www.site.com/windows/games/
I have tried several syntax like
RewriteRule ^windows/([^/]+)/?$ /windows/ct.php?ct=$1 [L]
RewriteRule ^windows/(^(.[^/]*)/?)$ /windows/ct.php?ct=$1 [L]
RewriteRule ^windows/([^/]*)/? /windows/ct.php?ct=$1 [L]
RewriteRule ^windows/([^/]+)/? /windows/ct.php?ct=$1 [L]
but it didn't work.
Complete .htaccess
Options +FollowSymlinks -MultiViews
RewriteEngine on
<IfModule mod_rewrite.c>
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^windows/([^/]*)/?$ /Site/windows/ct.php?ct=$1 [L]
RewriteRule ^[^/]*/[^/]*/(.*\.html) /Site/error/400/ [L]
RewriteRule ^(error) - [L]
RewriteRule ^sitemap\.xml$ sitemap.php [L]
RewriteRule ^rss/(.*?)\.xml$ rss/$1.php [L]
</IfModule>
ErrorDocument 404 /Site/error/404/
Please see and suggest any possible way to do it.
Thanks.

The issue here is that your relative paths break when you add a trailing slash as it introduces two-levels of directory structure while the CSS/JS file paths come out only once ... So, your RewriteRule is actually firing for CSS/JS files as well when resolving 404s for paths like /windows/global/js/js.js. But, the scripts still fail to work because they aren't under /Site and that's where your rule is serving the request from.
So, to fix things without touching the relative URLs or resource locations; add another rule as follows:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^windows/([^/]*)/?$ /Site/windows/ct.php?ct=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^windows/(global/.*)$ /$1 [L] # handles css|js files
The rest of your .htaccess (of course) remains the same.

I use the following rule in .htaccess, but this may be too general:
RewriteRule ^q/([^/]+)/([^/]+)(\/?)$ /path/to/q.php?type=$1&q=$2&{QUERY_STRING} [NC]
This may be better for you:
RewriteRule ^windows(\/?)$ /path/to/windows.php?{QUERY_STRING} [NC]
RewriteRule ^windows/([^/]+)(\/?)$ /path/to/windows.php?type=$1&{QUERY_STRING} [NC]
You will have to change this according to your situation. I haven't tested this, but I hope it is good enough for you to get where you want.

Related

Why doesn't url rewriting work for .html extensions?

I am trying to get
/pages/Settings.html
to appear as
/Settings
by using the RewriteRule
RewriteRule ^([A-Za-z_]+)$ pages/$1.html [NC] # Handle pages
in the .htaccess file. This does not work. However,
/pages/ANYOTHERFILE.php
works by using
RewriteRule ^([A-Za-z_]+)$ pages/$1.php [NC] # Handle pages
to be rewritten into
/ANYOTHERPAGE
Why does the former not work and the latter work? How do I get .html extensions to be rewritten like this?
Add this rules to top of your .htaccess file
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /pages/$1.html [L]

Redirecting all requests from a subdirectory to a specific file

I wanted to redirect all requests from a specific subdirectory (/portfolio/*) to a specific file in the root of my website (portfolio.php). This way I want to be able to create project-specific pages within the same file as where the overview is being created.
I tried the following, but it didn't work since it stopped images from loading (images were located in the /images/portfolio/* directory), and it also disables my custom ErrorDocument...
RewriteRule /portfolio/(.*) /$1 [PT]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /portfolio.php [L]
Anyone has an idea on how to fix this?
Try getting rid of the first rule and adding the pattern to your last rule:
RewriteRule ^portfolio.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^portfolio/(.+)$ /portfolio.php [L]
And for good measure, make sure multiviews is turned off:
Options -Multiviews

mod_rewrite: how to enable access to static content and redirect specific url schemes?

My apps' urls are like this: http://domain.com/projects/project-name/
My app's file system is like this:
htdocs/projects/project-name/
L index.html
L img/image1.png
L img/image2.png
L img/...
I need to send requests like http://domain.com/projects/project-name/ to
htdocs/index.php?section=$1&item=$2
But they display the project-name/index.html file instead.
Here is what i tried:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule . - [L]
RewriteRule ^([^/]+)/([^/]+)/?$ index.php?section=$1&item=$2&%{QUERY_STRING} [NC,L]
Obviously, the RewriteCond %{REQUEST_FILENAME} -frule is the culprit. But i need to let the server serve the static img files. How can I tell it to let all file requests but rewrite the project folder's default index.html?
It should work, I am providing a slightly modified version of your rule with complete .htaccess to be placed in DOCUMENT_ROOT/.htaccess:
DirectoryIndex index.php index.html
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
RewriteRule ^([^/]+)/([^/]+)/?$ /index.php?section=$1&item=$2 [L,QSA]
Edit: Misunderstood the question.
You want to rewrite /projects/project-name/ to index.php?... I am also assuming you'll want to be able to request files from within project-name:
RewriteEngine on
RewriteRule ^([^/]+)/([^/]+)(/(index[^/]+)?)?$ /index.php?section=$1&item=$2 [QSA,NC,L]
If being able to request files from the project-name subdir isn't important, just remove (/(index[^/]+)?) and replace it with /. The (/(index[^/]+)?) assumes your DirectoryIndex files start with "index".
Meh.
Consider enabling the mod_rewrite log to analyze how it is applying your conditions and patterns. Within the server or vhost scope (not htaccess) add:
LogLevel warn rewrite:trace6
The LogLevel directive can enable logging for mod_rewrite which will be written to your defined ErrorLog. trace6 is the highest mod_rewrite log level before you get into hex output. Be sure to comment out or remove LogLevel when you're done.
Original, unrelated answer (ignore):
You need to negate files, of which right now you are not, notice the use of !:
RewriteCond %{REQUEST_FILENAME} !-f
Most importantly, your RewriteCond will not affect your second RewriteRule. It is only applied to the first RewriteRule (in your case RewriteRule . - [L]):
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)/([^/]+)/?$ index.php?section=$1&item=$2&%{QUERY_STRING} [NC,L]
And you may also choose to negate directories:
RewriteCond %{REQUEST_FILENAME} !-d
I'd also consider using the QSA (query string append) flag instead of appending QUERY_STRING:
RewriteRule ^([^/]+)/([^/]+)/?$ index.php?section=$1&item=$2 [QSA,NC,L]
In summary:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)/?$ index.php?section=$1&item=$2 [QSA,NC,L]

How to redirect folders to index.php using .htaccess?

Folder structure:
/index/
/upload/
/something/
These folders don't have .htaccess in them(and shouldn't).
When accessing http://site.com/something it redirects to http://site.com/something/url=something, which is not desired.
RewriteEngine on
# RewriteBase /base/ #
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [L,QSA]
Adding another rewrite condition for appending '/' at the end of folders makes an additional(and unnecessary) request, also not nice.
How do I write the rule so that even folders are sent directly to the front controller without any unwanted redirects?
Try adding an additional condition to exclude existing directories:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [L,QSA]
A solution would be.
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.*[^/])$ $1/ [NC,L,R=301]
But this makes an additional redirect(first to something/ and the another to index.php?url...) ... not optimal.
A good solution would be only one redirect, no matter what.

Configure htaccess to load static pages

Im working on a server with the following htaccess:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule .* index.php
RewriteRule ^[^/]*\.html$ index.php
RewriteRule ^/(typo3|typo3temp|typo3conf|t3lib|tslib|fileadmin|uploads|showpic\.php)/ - [L]
RewriteRule ^/(typo3|typo3temp|typo3conf|t3lib|tslib|fileadmin|uploads|showpic\.php)/.*$ - [L]
Now they asked me to prepare a static page inside their server, lets call it http://www.myserver.com/mystaticpage.html
The problem is that when i try to access that url, it redirects to index.php. How could I alter the htacces file to address this problem without messing anything with the installed CMS?
Try this:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond ${REQUEST_URI} !^/(typo3|typo3temp|typo3conf|t3lib|tslib|fileadmin|uploads|showpic\.php)
RewriteRule .* index.php
The rules you used before were redundant: if .* is rewritten to index.php then why also rewrite ^[^/]*\.html$ index.php to it? it already matched previous rule...
They also overlapped - since the three RewriteCond conditions were only applied on the first rule. So the second rule was also applied to static files on disk.
Also, the two rules that were listed last had no effect whatsoever. Either you needed to list them first, or not at all. I converted them to an additional RewriteCond since they were only attempted to avoid rewrite on certain uris

Resources