Can htaccess redirect to parent folder? - regex

My domain is in my user folder. I would like to serve a file from another folder down a level, under the same user. I tried this:
RewriteRule ^test$ ../testfolder/test.txt [L]
But Apache serves a 400 Bad Request. Is htaccess capable of dropping down a level like this?

You may use this code to dynamically figure out PARENT directory and then rewrite to that:
RewriteEngine On
# dynamically figure out parent directory using composite RewriteCond
RewriteCond $0#%{REQUEST_URI} ^([^#]*)#(.*)/[^/]+/\1$
RewriteRule .* - [E=PARENT:%2]
RewriteRule ^test$ %{ENV:PARENT}/test.txt [L,NC]
RegEx Demo

Related

Serving static subpages in drupal 8 via htaccess

We have drupal 8 site with a folder in docroot. Lets say its in a folder called micrositefolder. It contains a single index.html file.
Now let's say micrositefolder lives on fullsite.com. I dont want someone to access the microsite via fullsite.com/micrositefolder, but instead only accessible via mymicrosite.com
I have already achieved that with the following:
# Prevent access to the static site from non-static site hosts.
RewriteCond %{REQUEST_URI} ^/micrositefolder [NC]
RewriteCond %{HTTP_HOST} !^mymiscrosite
RewriteRule .* /index.php [L,R=301]
# Only serve the static site if host begins with mymiscrosite.
RewriteCond %{HTTP_HOST} ^mymiscrosite
# Don't loop anything targeting the actual mask directory, to allow
# for linked scripts, stylesheets etc in the static HTML
RewriteCond %{REQUEST_URI} !^/micrositefolder/
#Any requests that made it this far are served from the /micrositefolder/ directory
RewriteRule ^(.*)$ /micrositefolder/$1 [PT]
That works great. I can now visit mymicrosite.com and it serves me that index.html in that folder.
I now have to include another page on that microsite. The url would be mymicrosite.com/ronnie. I created a folder inside of micrositefolder called ronnie with another index.html in it.
When I try to go to that url (mymicrosite.com/ronnie) it is being rewritten to mymicrosite.com/micrositefolder/ronnie/ and I cannot figure out why. I am pretty sure it has to do with that last line in my code snippet, but I cannot figure out how to make it just be mymicrosite.com/ronnie
One thing to note is if I view the url via mymicrosite.com/ronnie/ it works, but if I dont include the slash at the end it redirects to mymicrosite.com/micrositefolder/ronnie
You can add this rule below your existing rules in site root .htacess:
# add a trailing slash to directories
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule [^/]$ %{REQUEST_URI}/ [L]
This will add a trailing slash if current request is pointing to a directory.
Problem with your proposed approach (in the answer) is that:
It will perform a trailing slash 301 redirect even if it is an invalid URI such as mymicrosite.com/qwerty111
For cases like mymicrosite.com/ronnie where /micrositefolder/ronnie is an actual directory, it will perform an extra 301 redirect before showing index.html
Adding an .htaccess inside the micrositefolder with the below seems to have solved my issue
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*[^/])$ /$1/ [L,R=301]
</IfModule>

redirect from subfolder to main folder and multiple pages to one page

We have a new website, build in WordPress. It will be replacing the old website, which was build on a custom CMS.
The old site is using this structure > domain.nl/content/page-title for most of the content pages. On the new site we will be using domain.nl/page-title.
We also combined a couple of very short content pages into 1. e.g. domain.nl/pageaboutsubject1 and domain.nl/pageaboutsubject2 are now on domain.nl/pageboutboth
The issue with the folder I can resolve by using:
RewriteEngine on
RewriteRule ^content/(.*)$ /$1 [R=301,L]
This will get all the urls redirected without /content/ in betweeen the main folder and the page title.
But now I'm stuck on redirecting the other pages to the new ones.
I read somewere that the 'L' in [R=301,L] prevents further redirects, so I tried to remove that. But no luck.
Adding:
RewriteRule ^content/subject1 /subjectboth [R=301]
Will not work, and:
RewriteRule ^/subject1 /subjectboth [R=301]
Will not work as well.
Problem seems to be in your reegx for matching 2nd rule.
This should work for you:
RewriteEngine on
# match /subject1 or /subject2 and redirect them to /subjectboth
RewriteCond %{THE_REQUEST} !/kb [NC]
RewriteRule (^|/)(subject1|subject2) /subjectboth [R=301,L,NC,NE]
# otherwise remove /content/ from start of URLs
RewriteRule ^content/(.*)$ /$1 [R=301,L,NC,NE]
References:
Apache mod_rewrite Introduction
Apache mod_rewrite Technical Details

Redirect all subfolders but keep files accessible?

I have a website with a public folder in which I host some images.
Let's say that the root folder is "public".
In this folder I have another folder called "images".
In the folder called "images" I have a lots of folders called "1"... "92345678".
I want to create a htaccess rule that will redirect the users from the folders:
www.website.com/public/images/
www.website.com/public/images/1
www.website.com/public/images/2
...
www.website.com/public/images/10000001
to
www.website.com/public/
Please give me an option that will work for all sub folders. (Recursive)
I also want to redirect only folders, the images urls should work!
You can use this rule in /public/images/.htaccess file:
RewriteEngine On
RewriteBase /public/images/
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule . /public/ [L,R=302]
You must enable rewrite engine and then use rule to redirect from URI's that starting with /public/image to /public.
RewriteEngine on
RewriteRule ^/public/images.* /public
I found the answer:
#redirect all subfolders to root and exclude images
RewriteCond %{REQUEST_URI} !\.(gif|jpe?g|png)$ [NC]
RewriteRule ^images/(.*)$ / [R=301,NC,L]
Thanks Mark Shevchenko and anubhava for your help!

Redirect to dynamic relative paths with .htaccess?

Is it possible to make .htaccess "understand" dynamic relative paths and redirect to them properly?
My setup goes as follows:
http://domain.com/htroot/aaa/xyz
http://domain.com/htroot/bbb/xyz
http://domain.com/htroot/ccc/xyz
And so on. For the sake of the example, "htroot" contains the .htaccess I need to modify. The following sublevels (aaa, bbb, ccc) can be any a-z0-9 name, and the folders have an index.php (or any other .php to be redirected to). The xyz should work as a parameter of sorts, see next part. The xyz part is nowhere on the filesystem as a "physical" folder or file.
What I need to achieve is the following: When you access with the url
http://domain.com/htroot/aaa/xyz
it gets content from
http://domain.com/htroot/aaa/ (or http://domain.com/htroot/aaa/index.php, either way)
where the index.php kicks in -> I can get the xyz parsed from REQUEST_URI and process it to serve the correct content that it specifies, while the URL of the page stays as http://domain.com/htroot/aaa/xyz, naturally.
So far I have managed to pull this off if every sublevel (aaa etc.) has it's own .htaccess, but I would need one where there is only a single .htaccess located in htroot that handles this. I'm guessing it might have something to do with the $0 parameters in .htaccess, but not sure.
You may want to perform something like this:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/(.*)$ /htroot/$1/index.php?data=$2 [L]
If the first wildcard match (.*) is aaa and the second wildcard match (.*) is xyz (htroot/aaa/xyz) it will get the content from
htroot/aaa/index.php?data=xyz
and you will be able to get the value xyz in index.php with $_GET['data']
OK, there's something I don't understand in the way it works, I guess I still have a lot to learn about mod_rewrite.
But like this in htroot/.htaccess file, it works:
RewriteEngine On
RewriteRule ^aaa/(.*)$ aaa/index.php?$1 [L,QSA]
RewriteRule ^bbb/(.*)$ bbb/index.php?$1 [L,QSA]
RewriteRule ^ccc/(.*)$ ccc/index.php?$1 [L,QSA]
You will be able to access $_GET['xyz'] or whatever you put after / in your index.php scripts. You will also get a bonus 'index_php' entry in the $_GET array, but I guess it's the way the internal redirect works.
This should work as a generic ruleset:
RewriteEngine On
RewriteCond %{REQUEST_URI} !\.php
RewriteRule ^(.*)/(.*) /htroot/$1/index.php?parameters=$2 [L,QSA]

mod_rewrite with nested .htaccess files

I have made an .htaccess to my root directory for creating a subdomain level, assume it is sub.domain.ex that redirect to domain.ex/deb/
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} sub.domain.ex
RewriteCond %{REQUEST_URI} !deb/
RewriteRule ^(.*)$ /deb/$1 [L]
and this works well.
Now, I go to /deb/ and create another .htaccess with the following
RewriteEngine on
RewriteRule ^([^/]+)/ /deb.php?app=$1 [NC]
the deb.php is a file that prints the argument "app".
It works but only if i call http://sub.domain.ex/something/ (note the slash at the end). It only works with a final slash, if I remove it, it doesn't and I want it to work without final slash.
So I change the rule into ^([^/]+) but now I have 500 Apache internal error.
The regex coaches are by my side with the selection, maybe I'm missing something.
Thanks
UPDATE
I'm runinng mad. Mybe is wrong to put one .htaccess in the root for creating se 3th sublevel doman and the .htacces in the other directory? Because I'm ttrying some trick.
I use this rule
RewriteEngine on
RewriteRule ^([^/]+)/ deb.php?app=$1 [NC]
in the .htacces of the /deb directory and made a print_r($_GET); and called index.php. So the redirectory doesn't work at all if it forward me on the index.php of the cydia sublvel and doesn't take the /deb/deb.php!!!
Recap.
my dir structure is this:
/htdocs/ -> the root of the main domain level like www.example.com
---index.php -> home file of www.example.com
/htdocs/deb -> the root directory of the 3th sublevel domain (subdomain.example.com ->
---index.php
---deb.php
So the .htaccess for the 3th level domain is the in /htdocs./htaccess and described as before.
The other .htaccess for "beautify" the link is in the /htdocs/deb/.htaccess. I want that when you go to subdomain.domain.com/someText it transform to deb.php?app=someText
Now i tryed go to subdomain.domain.com/deb.php....WTF!? the deb.php is in /htdocs/deb/deb.php
Home is clear
This works fine for me, at least, assuming I understood everything you wanted.
In /htdocs/.htaccess:
RewriteEngine On
RewriteCond %{HTTP_HOST} =sub.domain.ex
RewriteCond %{REQUEST_URI} !^deb/
RewriteRule ^(.*)$ /deb/$1
In /htdocs/deb/.htaccess:
RewriteEngine On
RewriteBase /deb/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)/?$ deb.php?app=$1
RewriteRule !^deb.php index.php
Edit: I updated the second file's contents to reflect your additional requests. You should remove the /? if you don't want them to be able to go to sub.domain.ex/something/ -> deb.php?app=something.
I could be wrong, but in the second .htaccess you should check that the url wasn't yet rewrited with "/deb.php"
So something like
RewriteCond %{REQUEST_URI} !deb\.php
RewriteRule ^([^/]+) /deb.php?app=$1 [NC]
You rewrite rule should be
RewriteRule ^(.*)$ deb.php?app=$1 [L,QSA]
That's a common pattern used in CMSs like Drupal
I think there is some kind of rescrctions to my host. It's impossible. I tried all kind of goo (for a regexcoach) for matching the correct group and there is nothing else the 500 error apache.
The only way to get this to work is use tu parameters
with this ^app/([^/]+) /deb.php?app=$1 and calling with sub.domain.com/app/nameTest and this is working with or without the end backslash.
Of you get some advice for getting rid of this, please let me know.
bye