same path of url but pointing to different directories - .htaccess

Im trying to redirect this,
www.example.com/about expect to matched with docs/about.html
www.example.com/register expect to matched with mod/register.php
RewriteCond %{REQUEST_URI} !\.+$
RewriteRule ^([^\.][a-z]+)$ docs/$1.html [L]
RewriteRule ^([^\.][a-z]+)$ mod/$1.php [L]
The first rewrite rule works great,
but the second rewrite rule won't work, it keeps showing 404 error.

As long as you don't have the same file in both places (e.g. /docs/foo.html and /mod/foo.php, you can do a check against the destination first before you rewrite:
# check for docs/.html first
RewriteCond %{REQUEST_URI} ^/([a-z]+)$
RewriteCond %{DOCUMENT_ROOT}/docs/%1.html -f
RewriteRule ^ /docs/%1.html [L]
# If not .html, then check for mod/.php
RewriteCond %{REQUEST_URI} ^/([a-z]+)$
RewriteCond %{DOCUMENT_ROOT}/mod/%1.php -f
RewriteRule ^ /mod/%1.php [L]

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.

Rewrite rule in htaccess is not working

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]

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]

Force redirect for certain files (based on referer) and trigger a 404 page otherwise

We distribute different versions of a software product through a single download link. The delivery is based on the referer in conjunction with a default value, which works fine. In addition the user should be redirected to a 404-page, in case the wrong filename was used.
At the moment the .htaccess-file looks like this:
# stop directory listing
Options -Indexes
# turn rewrite engine on
RewriteEngine On
# force 404 if file name is missing or wrong
RewriteCond %{REQUEST_URI} !^(download_mac\.zip|download_pc\.zip)$
RewriteRule (.*) 404/index.html [L]
# an example based on the referer
RewriteCond %{HTTP_REFERER} ^http://([^.]+\.)*domain-a\.com [OR]
RewriteCond %{HTTP_REFERER} ^http://([^.]+\.)*domain-b\.com
RewriteRule ^(download_mac\.zip|download_pc\.zip)$ domain_ab/$1 [L]
# last rule if no referer matches
RewriteRule ^(download_mac\.zip|download_pc\.zip)$ default/$1 [L]
So I have one issue and one additional question with this file:
The first rule, to force 404, is very greedy and gets the error page every time, no matter what URL is called. I also tried single statements like RewriteCond %{REQUEST_URI} !^download_mac\.zip$ without any effect. How can I fix this?
How can I get rid of the filenames in any other rule? I tried things like RewriteRule ^(.*)$ default/$1 [L] but it gives me a hard time and an 500 Internal Server Error.
You can avoid repeating your filenames by using an Env variable like this:
RewriteRule ^(download_mac\.zip|download_pc\.zip)$ - [E=ALLOWED:$1,NC]
RewriteCond %{ENV:ALLOWED} ^$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ /404/index.html [L]
RewriteCond %{ENV:ALLOWED} !^$
RewriteCond %{HTTP_REFERER} ^http://([^.]+\.)*domain-a\.com [OR]
RewriteCond %{HTTP_REFERER} ^http://([^.]+\.)*domain-b\.com
RewriteRule ^ /domain_ab/%{ENV:ALLOWED} [L]
RewriteCond %{ENV:ALLOWED} !^$
RewriteRule ^ /default/%{ENV:ALLOWED} [L]
You can just move the rewrite rule to the end. The other rules handle the valid cases and if none of them matches the last rule applies
# an example based on the referer
RewriteCond %{HTTP_REFERER} ^http://([^.]+\.)*domain-[ab]\.com
RewriteRule ^download_(mac|pc)\.zip$ domain_ab/$0 [L]
# last rule if no referer matches
RewriteRule ^download_(mac|pc)\.zip$ default/$0 [L]
# force 404 if file name is missing or wrong
RewriteRule ^ 404/index.html [L]

Htaccess files and url rewriting

I have 2 questions.
I am currently using wamp server to serve my website.
The homepage is 'localhost/prefix/index.php'
Question 1:
a. I would like it so my home page is:
'localhost/prefix/'
instead of
'localhost/prefix/index.php
b. I would like it so:
'localhost/prefix/admin/profile.php'
is
'localhost/prefix/admin/profile'
How do I go about doing this (I have googled and I am very confused by the syntax)?
Question 2
If I have a url like
'localhost/prefix/games?title=hi'
how can I make it so the url is like this:
'localhost/prefix/games/hi'
Thanks in advance!!
I really have got lost.
EDITED::///
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [R]
Is what I have so far.. It does nothing... But everyone says it should! (the htaccess file is doing something because if I do something random, it throws up errors).
EDITED::///
This seems to remove .php and index.php from the url:
RewriteEngine On
RewriteBase /prefix/
# remove .php; use THE_REQUEST to prevent infinite loops
RewriteCond %{THE_REQUEST} ^GET\ (.*)\.php\ HTTP
RewriteRule (.*)\.php$ $1 [R=301]
# remove index
RewriteRule (.*)/index$ $1/ [R=301]
# remove slash if not directory
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /$
RewriteRule (.*)/ $1 [R=301]
# add .php to access file, but don't redirect
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_URI} !/$
RewriteRule (.*) $1\.php [L]
Problem now is that my prefix base is not working so it ends up going to
localhost/something/something
rather than
localhost/prefix/something/something
Any ideas?
EDITED::///
I have sussed out that the above code actually works perfectly if the page i'm directing to is in a sub folder. so for example.. this will work:
localhost/prefix/admin/dashboard
But this (because the file is in the root directory, doesn't)
localhost/prefix/login.php
it redirects me to
localhost/login
Any ideas?
EDIT::///
If you are having problems getting it to work. close your browser down and restart... I had caching issues.
This code above will remove .php and also remove index.php.

Resources