.htaccess how to substitute urls - apache

How can I substitute URLs of a web application in a sub folder as installed on root.
e.g. need to map
example.com/index.php
to
example.com/new/index.php
I do not want redirection but url rewrite to exempt folder name.
Help me to learn and define rules.

You can use the following rule to rewrite any request that’s URL path (without path prefix) does not start with new/:
RewriteCond $1 !^new/
RewriteRule ^(.*)$ new/$1
This will also work in .htaccess files other than in the document root directory.
But as you want to use this rule in the .htaccess file in the document root directory, you could also use REQUEST_URI:
RewriteRule !^new/ new%{REQUEST_URI}

The first line matches all requests not matching /new/... and prefixes it with a new before it.
RewriteCond %{REQUEST_URI} !^/new/
RewriteRule ^(.*)$ new/$1
Request: http://example.com/index.php
Maps to: [document root]/new/index.php

Related

how do I rewrite a URL and maintain the file name

I have a rewrite written in my .htaccess file. I am trying to redirect the following
https://olddomain.com/folder/file.pdf to https://newdomain.com/folder/file.pdf. file.pdf can change so I need to change the domain but leave the folder and file name needs to stay what ever it is. it could be file.pdf or file1.pdf etc
I have this code in my .htaccess file
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/folder/(.*)$
RewriteRule ^(.*) https://newdomain.com/folder/%1 [R=301,NC]
If the file.pdf exists on the old server then the redirect works but if the file does not exist on the old server the redirect does not work.
Any help fixing this would be appreciated.
If the file.pdf exists on the old server then the redirect works but if the file does not exist on the old server the redirect does not work.
That sounds like you've put the rule/redirect in the wrong place. If you have other directives before this redirect that implement a front-controller pattern then you will experience this same behaviour since any request for a non-existent file would be routed to the front-controller (and request for an existing file is ignored) before your redirect is triggered - so no redirect occurs.
If this is the case then you need to move your rule to the top of the file, before any existing rewrites.
RewriteCond %{REQUEST_URI} ^/folder/(.*)$
RewriteRule ^(.*) https://newdomain.com/folder/%1 [R=301,NC]
However, your existing rule is not quite correct. Importantly, you are missing the L flag on the RewriteRule directive and the preceding RewriteCond directive is not required. For example, try the following instead:
RewriteRule ^folder/.* https://newdomain.com/$0 [NC,R=301,L]
This does assume your .htaccess file is located in the document root of the site.
Alternatively, you create an additional .htaccess file inside the /folder with the following:
RewriteEngine On
RewriteRule ^ https://newdomain.com%{REQUEST_URI} [R=301,L]
The REQUEST_URI server variable contains the full URL-path of the request (including the slash prefix).
By default, the mod_rewrite directives in the /folder/.htaccess file will completely override any directives in the parent (root) .htaccess file (the mod_rewrite directives in the parent are not even processed).

htaccess redirect subdirectory (folder) to single page in same subdirectory

I am having another issue with .htaccess where I can't seem to find the right solution for it. What I am trying to accomplish is to redirect from a subdirectory to a specific html document within that same directory when you copy/paste the url displayed below
For example:
http://example.com/staging/test/ to http://example.com/staging/test/page.html
My (almost) working method:
Options -Indexes -MultiViews
RewriteEngine on
RewriteRule ^test/(.*)$ test/page.html [L]
The problem with this code is that it does basically redirect to the correct page.html but if you want to click on any link on page.html it just redirects to page.html again instead of going to a particular link within subdirectory /test/ let's say /test/page-2.html
Important: This redirect should only affect the subdirectory "staging". All other sub-directories including root can not be affected.
Other info:
This code is also in my .htaccess file to remove the .html extension for the directory "staging"
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^(.*)$ $1.html [L]
The directory "staging" is not connected to any CMS and only consists of .html files.
I am on a shared hosting environment (Hostgator/cPanel).
Thank you.
Use below rule, you are using only L flag but I am modifying it for redirect as you mentioned.
Options -Indexes -MultiViews
RewriteEngine on
RewriteRule ^test/$ /staging/test/page.html [R=301,L]
You want to redirect only the directoy, but not the files in it. The pattern in the rule says match the directory test/ followed by anything .*, including any files.
To match the directory alone, the pattern must stop at test, which is accomplished by an end of string anchor
RewriteRule ^test/$ /staging/test/page.html [R,L]
Instead of an absolute path, you can keep the relative path and add a RewriteBase directive
RewriteBase /staging
RewriteRule ^test/$ test/page.html [R,L]
If you want to rewrite only, leave out the R flag.

.htaccess and rewrite from subdirectories inside unknown parent directory

So I have an htaccess file in a subdirectory and whenever I try to rewrite the url, it redirects to the document_root and not the subdirectory where the htaccess resides. Now, under normal circumstances, I'd rewrite it with the path to the subdirectory with path/to/subdirectory, but I won't know what the exact path will be. Is there a way either, through an Apache environment variable or something else, to write out that path?
Edit:
Here's the .htaccess file so far.
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
#RewriteRule (.*-file) a/b/c/$1.file
RewriteRule (.*-file) $1.file
So, I'm trying to, if the request contains the word file, I want to match the entire request prior to the word file and redirect there. This is so that if a request is to
example.com/a/b/c/file[any characters here].file
the request will be redirected to the right file. To reiterate, the problem is that I am trying to redirect within the subdirectory. So when I say Rewrite $1, I want that to include the entire request and not just what matched in the REQUEST_FILENAME. And the reason I need it to do that is because I can't simply put a/b/c/$1.file since I won't know for absolute certainty the a/b/c part.
Edit 2: Examples:
So, an example is that I'd send a request like:
example.com/a/b/c/fileacs.file
And want to redirect to:
example.com/a/b/c/file.file
Where I do not know a/b/c/. I have an actual regex and set of rules for the real-world use of this redirect, so don't mind the ridiculous nature of this example.
But currently it's redirecting to:
example.com/file.file
Which does not exist and even if it did, I do not want to redirect there. I've read about Rewrite Context, but can't find out anything substantial about it nor if it's the cause for this. Thank you, in advance.
You can use this rule to capture any path before fileacs.file and use that as bach-reference in RewriteRule:
RewriteEngine On
RewriteCond ^(.*)/file[^.]+\.file$ [NC]
RewriteRule ^ %1/file.file [L,R=302]
The solution is to use the a RewriteCond on the %{REQUEST_URI} (thanks anubhava!) that checks matches the entire request except for the %{REQUEST_FILENAME} without capturing it, using a lookahead. Write out this with the %1 followed by the desired filename. See the following:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} (.*)-file(?!\.file) [NC]
RewriteRule ^ %1.file [L,R=301]
The %1 now holds the path up to the directory that the .htaccess is stored, plus any prefix to the filename. This doesn't match the remainder of the request, but rather looksahead to ensure you're not actually requesting the file you would like to redirect to (causing a loop).

Apache choose folder based on url parameter and keep url

I'd like to have a way to access folders on my server based on the name given in the url as a parameter.
Let's say my website is www.site.com
I'd like to access custom folders under the main directory by sending a parameter on the url but without having a redirect changing the url.
So I'd provide the folder in the parameter: www.site.com/dev1
This way people wouldn't have to remember the full url be aware of it.
my base folder as per the vhost is /var/www/developers
the subfolders are dev1, dev2, dev3 and so on.
Under dev1/2/3 there is a folder called Portal.
-/var/www/developers
--/var/www/developers/dev1
----/var/www/developers/dev1/Portal
------/var/www/developers/dev1/website/Portal
my current .htaccess is:
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}/$1/website/Portal -f
RewriteRule ^([^/]*)/?$ /$1/website/Portal [L]
Whilst it is working, it keeps changing my url to www.site.com/dev1/Portal
That is happening because mod_dir is adding a trailing slash after directory portal.
Have your rule like this by having a trailing slash in your rule:
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}/$1/website/Portal -d
RewriteRule ^([^/]+)/?$ /$1/website/Portal/ [L]

How do I set up RewriteRule for urls that all start with the same folder and then some but not all subfolders

I am trying to write a rule to redirect some but not all of the content of a certain folder:
^folder1/ any .html files
^folder1/blackberry
^folder1/content
^folder1/data
^folder1/images
^folder1/docs
I need to use RewriteRule to send everything except ^folder1/blackberry to another site (eg, http://somedomain.com/main.html) and I'm sure there must a way to do this with regular expressions but I don't (yet) know how :-)
Use a rule to catch everything and exclude the exceptions with a RewriteCond directive:
RewriteCond %{REQUEST_URI} !^/folder1/blackberry$
RewriteRule ^folder1/ http://sub.example.com/main.html [L,R=301]
This rule redirects every request with a URL path that starts with /folder1/ except /folder1/blackberry externally to http://sub.example.com/main.html.