Rewrite rule in htaccess is not working - .htaccess

Here are the .htaccess rules:
RewriteEngine On
RewriteRule ^([^/]*)$ content.php?seourl=$1 [L]
RewriteRule ^pdf/([^/]*)$ content-single.php?seourl=$1 [L]
RewriteRule ^browsepdf$ browse.php [L]
RewriteRule ^browsepdf-([^/]*)$ browse.php?page=$1 [L]
RewriteRule ^download/([^/]*)$ download.php?pdf=$1 [L]
RewriteRule ^sitemap.xml$ xmlsitemap.php [L]
Options -Indexes
Here every URL is pointing to content.php?seourl=$1, even css, js and image files.
Here are some example URLs I need,
http://example.com/sjskjfsk21
http://example.com/asfasfasf43sf
http://example.com/pdf/fhfdhdh3432aaf
http://example.com/pdf/aisfyiahm2faf3
http://example.com/browsepdf
http://example.com/browsepdf-1
http://example.com/browsepdf-2
http://example.com/download/fjaskfjalsk3rs
http://example.com/download/usaydiy7aisydi
http://example.com/sitemap.xml
Can anyone please fix the .htaccess file.

Here every url is pointing to "content.php?seourl=$1"
Because your first (generic) rule catches all the requests. You need to change the order so you have the most specific rules first, and the most generic (catch-all) rules at the end. In your case you just need to move the first rule to the end. For example:
RewriteRule ^pdf/([^/]*)$ content-single.php?seourl=$1 [L]
RewriteRule ^browsepdf$ browse.php [L]
RewriteRule ^browsepdf-([^/]*)$ browse.php?page=$1 [L]
RewriteRule ^download/([^/]*)$ download.php?pdf=$1 [L]
RewriteRule ^sitemap\.xml$ xmlsitemap.php [L]
RewriteRule ^([^/]*)$ content.php?seourl=$1 [L]
NB: I backslash-escaped the dot in sitemap.xml to match a literal dot, otherwise it matches any character.
even css, js and image files.
You can make an exception for these static resources at the beginning of your file, before the existing directives. For example:
RewriteRule \.(js|css|png|jpg|gif)$ - [L]
For any URL that ends in any of the stated file extensions then stop processing the current mod_rewrite rules.
Alternatively (although perhaps marginally less efficient), you can prevent processing of requests for files that exist. Again, this goes before your existing mod_rewrite directives. For example:
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
However, this must now check every request for the existence of a file on the filesystem that maps to the request. (It could also be combined with the above rule if required.)
UPDATE: Bringing this together, we have:
# Exclude any existing files from being rewritten
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# Specific rewrites
RewriteRule ^pdf/([^/]*)$ content-single.php?seourl=$1 [L]
RewriteRule ^browsepdf$ browse.php [L]
RewriteRule ^browsepdf-([^/]*)$ browse.php?page=$1 [L]
RewriteRule ^download/([^/]*)$ download.php?pdf=$1 [L]
RewriteRule ^sitemap\.xml$ xmlsitemap.php [L]
# Any other requests for the form "/<anything>"
RewriteRule ^([^/]*)$ content.php?seourl=$1 [L]

Related

Apache Rewrite module, complex rules

I basically want to redirect all requests to index.php doesn't matter what, except those with certain REQUEST_URI. Those requests that look like image files, so have an ending like: .jpg or .png should be examined and if they are under the public/ folder (or any subfolders in any depth) and if they are they should be served and the rewriting process should stop here! If not, I want to redirect to a default image at public/errors/image-not-found.png and terminate rewriting process. The other exceptions are files that end with .js, .css, .html or .swf. They also should only be served if they are located under the public/ folder or any other subfolders. If not, a simple 404-Not found should be sent back. In either case of the last to the rewriting process need to stop of course.
Any other request should be redirected to index.php and appended as a query string. (even if the request points to a directory or to a file that is not under the conditions aforesaid, but exists, e.g: www.xyz.com/library/Database.php -> www.xyz.com/index.php?url=library/Database.php)
I have half-measure solution:This is how I redirect everything to index.php:
RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]
I append a visual explanation of what I want. Maybe this is clearer:
Basically, you don't want to do anything if the requested file exists in public/ or any of its subfolders. So, first we deal with those:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/public/.*\.(html|css|js|swf|jpe?g|png|gif|bmp|ico)$ [NC]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
Now, that is over with. We now check whether an image was requested:
RewriteCond %{REQUEST_URI} \.(jpe?g|png|gif|bmp|ico)$ [NC]
RewriteRule ^ /public/errors/image-not-found.png [R,L]
Similarly for other static files:
RewriteCond %{REQUEST_URI} \.(html|css|js|swf)$ [NC]
RewriteRule ^ - [R=404,L]
Redirect everything now to index.php:
RewriteCond %{REQUEST_URI} !/index\.php$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f [NC]
RewriteCond %{REQUEST_FILENAME} !-d [NC]
RewriteRule ^.*$ /index.php?url=$0 [R,L]
Following series of rules should probably mimic the flow-chart:
# for public folder pass through
RewriteRule ^public/.+?\.(?:jpe?g|ico|png|bmp|css|js|html|swf)$ - [L,NC]
# for other images
RewriteRule ^.+?\.(?:jpe?g|ico|png|bmp)$ /public/errors/img-not-found.jpg [L,NC,R=302]
# for other css|js|html|swf URIs
RewriteRule ^.+?\.(?:css|js|html|swf)$ - [L,NC,R=404]
# everything else, route to index.php
RewriteRule ^((?!index\.php).+)$ index.php?url=$1 [NC,QSA,L]

htaccess similar file names goes to same page

Most of the RewriteRules are working fine but there are a couple that have the same word in them and aren't going to the correct page.
Here is my full htaccess
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
# Rewrites for main pages
RewriteRule home index.php
RewriteRule about-us about-us.php
RewriteRule business-advice business-advice.php
RewriteRule associates associates.php
RewriteRule become-an-associate associates-sign-up.php
RewriteRule blog blog.php
RewriteRule contact-us contact-us.php
RewriteRule log-in log-in.php
RewriteRule sign-up sign-up.php
The problem resides within the two associated links. When I go to [MYURL]/associates it works fine but if I go to [MYURL]/become-an-associate it takes me to the correct URL but shows content from [MYURL]/associates
Anybody got any ideas?
Thanks,
The pattern for RewriteRule's are regular expressions and the rules all loop until the URI stops changing. That means the first time around, when you request /become-an-associate, it matches and is rewritten to /associates-sign-up.php. Then, the second time around, the rule with the pattern associates matches because of "/associates-sign-up.php". You need to add boundary checks (e.g. ^ and $) as well as the [L] flag:
# Rewrites for main pages
RewriteRule ^home/?$ index.php [L]
RewriteRule ^about-us/?$ about-us.php [L]
RewriteRule ^business-advice/?$ business-advice.php [L]
RewriteRule ^associates/?$ associates.php [L]
RewriteRule ^become-an-associate/?$ associates-sign-up.php [L]
RewriteRule ^blog/?$ blog.php [L]
RewriteRule ^contact-us/?$ contact-us.php [L]
RewriteRule ^log-in/?$ log-in.php [L]
RewriteRule ^sign-up/?$ sign-up.php [L]

301redirect to remove folder from URL

I have:
mydomain.com/folder-name/segment1/segment2
I want to change it to:
mydomain.com/segment1/segment2
using a 301 redirect.
I've tried:
RewriteCond %{REQUEST_URI} !^/test/.*$
RewriteRule ^(.*)$ /test/$1 [L]
but its not working
here is my htacess file:
# #AddHandler application/x-httpd-php53 .php .php5 .php4 .php3
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_URI} ^/b1/.*$
RewriteRule ^(.*)$ /b1/$1 [R=301,L]
The answer for the first part of the question should be like this:
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/? $2/$3 [R=301,L]
The second code that you've tried is the opposite of what you're asking for initially. This line matches anything not starting with /test/:
RewriteCond %{REQUEST_URI} !^/test/.*$
This line says take everything and rewrite it to the /test/ directory:
RewriteRule ^(.*)$ /test/$1 [L]
So together anything that's not in the test directory is being rewritten to the test directory.
If you're trying to specifically remove the word test then you would remove the ! symbol in your attempt to create a match. Since you already know it's called test there's no need to even make Apache perform this look for 'test' because Apache handles the RewriteCond statement after the RewriteRule (rather unintuitively).
RewriteCond %{REQUEST_URI} ^/?test
You can specialize the rewrite rule like this (I've added [QSA] to catch any query strings:
RewriteRule ^test/([^/]+)/([^/]+)/? $1/$2/ [R=301,L,QSA]
Simply change your code to:
RewriteRule ^test/(.*)$ /$1 [R=301,L,NC]

.htaccess: mod_rewrite

Here is what I'm trying to accomplish:
(this .htaccess file is located in mysite.com/test/):
http://mysite.com/test/admin go to http://mysite.com/test/admin/index.php
http://mysite.com/test/contact go to http://mysite.com/test/contact.php
http://mysite.com/test/salt-lake-city/ go to http://mysite.com/test/index.php/city=salt-lake-city
http://mysite.com/test/salt-lake-city/deals/ go to http://mysite.com/test/deals.php?city=salt-lake-city
To start, I have:
RewriteRule ^(.*)/(.*)\.php$ $2.php?city=$1 [L]
(this handles the last 2). But, when I try to add the admin clause:
RewriteRule ^admin/ admin/index.php [L]
RewriteRule ^(.*)/(.*)\.php$ $2.php?city=$1 [L]
It messes up (the css is out of whack) etc.
Any thoughts?
Well .. if I had to do these rewrite rules, I would do them like this:
Options +FollowSymLinks -MultiViews
RewriteEngine On
# do not do anything for already existing files
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .+ - [L]
# admin rewrite
RewriteRule ^admin$ admin/index.php [L]
# rewrite /contact --> /contact.php (and similar)
# add .php extension if such file does exist
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.+)$ $1.php [L]
# OR
# alternatively specify their names directly
# plus it is more precise for the example you have provided
# (that's if you need to rewrite only specific pages)
RewriteRule ^(contact|about|something)$ $1.php [L]
# /salt-lake-city/ --> /index.php?city=salt-lake-city
RewriteRule ^([^/]+)/$ index.php?city=$1 [QSA,L]
# /salt-lake-city/deals/ --> /deals.php?city=salt-lake-city
RewriteRule ^([^/]+)/deals/$ deals.php?city=$1 [QSA,L]
To start, I have:
RewriteRule ^(.*)/(.*)\.php$ $2.php?city=$1 [L]
(this handles the last 2).
Sorry, but I do not see how "it will handle the last 2". I see no .php in the last two URL examples you have provided.
It messes up (the css is out of whack) etc.
Well -- let's see how it will work with my rules. In any case -- it may also depends how you wrote links to css/images/js.

Logical AND in htaccess modrewrite?

This is my htaccess file
RewriteBase /
RewriteCond %{HTTP_HOST} ^example.com [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [L,R=301]
RewriteCond %{REQUEST_URI} !^/chat/
RewriteCond %{REQUEST_URI} !^/m/
RewriteCond %{REQUEST_URI} !^/__admin/
RewriteCond %{REQUEST_URI} !^/gzip_headers.php
RewriteCond %{REQUEST_URI} !^/phpfreechat/
RewriteCond %{REQUEST_URI} !^/_temp/
RewriteRule ^.+\.php$ index.php [L]
RewriteRule ^.*\.css gzip_headers.php [L]
RewriteRule ^.*\.js gzip_headers.php [L]
RewriteRule ^classifieds/ /index.php [L]
RewriteCond %{REQUEST_URI} !^/movies/.
RewriteRule ^movies/ /index.php [L]
RewriteCond %{REQUEST_URI} !^/games/.
RewriteRule ^games/ /index.php [L]
RewriteRule ^jntu/ /index.php [L]
RewriteRule ^news/ /index.php [L]
My idea behind this basically is,
forward everything to public_html/index.php (except some directories)
forward all js and css to gzip file, ( i am doing this basically because im not jsut gzipping them but also compressing in tha phpfile)
the problem is when I load images from subdirectories the are redirected to index.php as well, so just creating conditions for those directories and storing images in them like RewriteCond %{REQUEST_URI} !^/games/.
I would like to make it simple to do stuff like this
forward everything to index.php (except some conditions on top)
forward css and js to gzip file
load images and flash and some other mime types straight away only if they exists. (jpg|gif|png|swf|flv|mp4|3gp|mp3|zip|rar|exe)
Something like logical AND REQUEST_URI and -f flag I guess
Try these rules:
RewriteCond %{HTTP_HOST} =example.com [NC]
RewriteRule ^ http://www.example.com%{REQUEST_URI} [L,R=301]
RewriteRule .*\.(js|css)$ gzip_headers.php [L]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .+\.(jpg|gif|png|swf|flv|mp4|3gp|mp3|zip|rar|exe)$ - [L]
RewriteCond %{REQUEST_URI} !^/(gzip_headers|index)\.php$
RewriteCond %{REQUEST_URI} !^/(chat|m|__admin|phpfreechat|_temp)/
RewriteRule ^.+\.php$ index.php [L]
I'm not sure why your images are being redirected if your rule only redirects URIs ending with '.php'. That should exclude all other file extensions from the rule.
I'm also not sure what you mean by needing 'logical and'. When you have a number of RewriteCond lines before a RewriteRule those conditions are ANDed together and the rule is only applied if they all are true.
You can't use modrewrite to check for the existance of files and say "if the file exists, don't apply any rules, just serve up the file".
I think the best solution would be to either use a single top-level directory called 'static' or 'images' where you put all your files and exclude it from the rules, or have a wider-matching rule.
So for example you could make 'static' or 'images' a special directory name and exclude any url that contains .*/images/.* from the rules. Then /something/images/image.jpg and /something/else/images/image.jpg would both be excluded and the file would be served up.
Another hacky way would be to serve the files up from PHP. So in PHP you would translate $_SERVER['REQUEST_URI'] into a filename and see if it exists. If it does, you can write the file contents to the PHP output stream, although this won't be as efficient as leaving it up to Apache, and actually I really would not recommend it.
But like I said before, if your rule is only matching files that end with .php then your images should not be getting redirected. I would figure out why this is happening first. There is a way to turn on debug logging for mod_rewrite but you'll have to Google that.

Resources