Apache .htaccess subdomain redirect + path proxying (rule chaining?)? - apache

I've got a tricky question, as far as I see it ;)
Currently, I'm in setup of a dynamic branch release pipeline which already takes a branch during pipeline processing and deploys it on our test server in a reserved folder ("branches").
Our wildcard domain points towards it.
Currently working (in the branches folder):
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(?!www\.)([^.]+)\.domain\.com$ [NC]
RewriteRule ^ %1%{REQUEST_URI}/public [L,NC]
But the problem now is, that for example a domain my-new-testbranch-123.domain.com get's the redirect to my-new-testbranch-123.domain.com/my-new-testbranch-123/public/. This is on one side ok (because out data is being found there, but I want to have a proper url such as the app can be routed properly. So I tried to rewrite the url via proxy. But without luck.
Any suggestions?
My goal would be to use the subdomain my-new-testbranch-123.domain.com/ without any additional path in url. The document root is located in my-new-testbranch-123/public/.
I tried via chaining, but both did not work as I thought -.-:
RewriteCond %{HTTP_HOST} ^(?!www\.)([^.]+)\.domain\.com$ [NC]
RewriteRule ^ %1%{REQUEST_URI}/public [NC,N]
RewriteCond %{REQUEST_URI} ([^.]+)/public
RewriteRule ^(.*)$ / [P]
and
RewriteCond %{HTTP_HOST} ^(?!www\.)([^.]+)\.domain\.com$ [NC]
RewriteRule ^ %1%{REQUEST_URI}/public [NC,C]
RewriteCond %{REQUEST_URI} ([^.]+)/public
RewriteRule ^(.*)$ / [P]
(with C and N flags)
Best,
Bent

Issue with your original rule is you don't have / after public and since that is an actual directory, Apache is doing a 301 redirect via mod_dir module.
You can use this rule to fix the issue:
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{HTTP_HOST} ^(?!www\.)([^.]+)\.domain\.com$ [NC]
RewriteRule ^ %1/public%{REQUEST_URI} [L]
Make sure to test in a new browser or via command line curl to avoid old browser cache.

Related

How can I rewrite all requests except for one specific URI

Here is my root path folder content :
/public
/src
/script
/etc
I succesfully managed to rewrite all request to /public folder with following code :
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} /public/([^\s?]*) [NC]
RewriteRule ^ %1 [L,NE,R=302]
RewriteRule ^((?!public/).*)$ public/$1 [L,NC]
My issue is that I need to access /script/script.php from browser, and it is currently returning
NOT FOUND The requested URL was not found on this server.
I tried a lot of things that I founded on stackoverflow but I am really not at ease with Apache 2 .htaccess (but need to use it on a shared hosting)
Anybody know how achieve what I want to do ?
Thanks
Have your .htaccess rules file in following manner. I have added a condition before your last RewriteRule since you want to access script.php so better put a proper condition before last rule.
Also make sure to clear your browser cache before testing your URLs.
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} /public/([^\s?]*) [NC]
RewriteRule ^ %1? [L,NE,R=302]
RewriteCond %{THE_REQUEST} !\s/script/script\.php/?\??\S*\s [NC]
RewriteRule ^((?!public/).*)$ public/$1 [L,NC]

.htaccess doesn't pass arguments to url

I was trying to make my server redirecting to a single page every request the user asks.
The way I am doing it is this:
# Turn rewriting on
Options +FollowSymLinks
RewriteEngine On
# Redirect requests to py-server.php if the request is that page (to avoid loops)
RewriteCond %{REQUEST_URI} !=/py-server.php
# Check if it is not an asset that the page requested needs
RewriteCond %{REQUEST_URI} !.*\.png$ [NC]
RewriteCond %{REQUEST_URI} !.*\.jpg$ [NC]
RewriteCond %{REQUEST_URI} !.*\.css$ [NC]
RewriteCond %{REQUEST_URI} !.*\.gif$ [NC]
RewriteCond %{REQUEST_URI} !.*\.js$ [NC]
# Finally, redirects to the page by adding to the URL the path originally requested
RewriteRule ^(.*)$ /py-server.php?path=$1 [L,QSA]
I added some comments to clarify why I've written those lines.
Now, that code is made by pasting various codeblocks from the internet, but it should work from what I read around.
The fact is that the server redirects correctly to the right page, but without the path in the URL (= there isn't the path argument at all).
Note: the .htaccess file is located at the root directory of the site in localhost (I use XAMPP for the server); the request I'm referring to is, simply, the request of any file of the server like /index.php, /some_dir/, /some_dir/index.php;
Did I forgot something to add? or did I make a mistake anywhere?
Alright, I found the solution searching here and there again:
# Turn rewriting on
Options +FollowSymLinks
RewriteEngine On
# Redirect requests to py-server.php if the request is that page (to avoid loops)
RewriteCond %{REQUEST_URI} !=/py-server.php
# Check if it is not an asset that the page requested needs
RewriteCond %{REQUEST_URI} !.*\.png$ [NC]
RewriteCond %{REQUEST_URI} !.*\.jpg$ [NC]
RewriteCond %{REQUEST_URI} !.*\.css$ [NC]
RewriteCond %{REQUEST_URI} !.*\.gif$ [NC]
RewriteCond %{REQUEST_URI} !.*\.js$ [NC]
# Here, this is the line that does the job!
RewriteRule ^(.*)$ /py-server.php?path=%{REQUEST_URI} [R=302,NC]
I solved by putting %{REQUEST_URI} as an argument for the original path to pass and the R=302 flag between squared brackets.
All this code works perfectly, now: redirects ALL the requests to a file.php EXCEPT FOR the assets (JS files, images, GIFs, CSS files...) and the actual final file to avoid loops.
Edit: as MrWhite wrote in the comments, the only problem seems to have been the R=302 flag, because $1 and %{REQUEST_URI} would work in both cases with just a little difference.

Keep URL request but adjust server path

How can I achieve the following:
I have two domains hosted within the same web root path on the server. Usually php manages my HTTP_Hosts dynamically. Related to my question I am using the directory lisings function of apache. Each Request for /peter/ should point effectively to a different directory.
example.com/peter/ -> /peter_example.com/
xamplee.com/peter/ -> /peter_xamplee.com/
The Url should always contain /peter/ but in effect link to the respective real path which I'd like to have hidden.
Thank you!
Finally, after getting into regex and into mode_rewrite the hard way I can come up with the solution all by myself:
Options -MultiViews
RewriteEngine On
RewriteBase /
# Force adding a trailing Slash
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*[^/])$ /$1/ [L,R=301]
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
RewriteRule ^peter/(.*)$ /peter_example\.com/$1 [NC,L]
RewriteCond %{HTTP_HOST} ^www\.xamplee\.com$ [NC]
RewriteRule ^peter/(.*)$ /peter_xamplee\.com/$1 [NC,L]

.htaccess rewrite to simultaneously change domain and remove path

My URL structure is currently as follows:
http://domain.com/folder/filename (CURRENT)
I want to change this so that I can use the following URL instead:
http://sub.domain.com/filename (NEW)
So accessing the CURRENT or the NEW url, should load the file located at the CURRENT url, but show the NEW url in the address bar. It should only apply to the "/folder/" path.
sub.domain.com is a mirror of domain.com, ie. they share the same file system and root directory.
This is what I have so far:
Options +FollowSymLinks
RewriteBase /
RewriteCond %{HTTP_HOST} ^(www.)?domain.com$ [NC]
RewriteCond %{REQUEST_URI} ^/folder/?(.*)$ [NC]
RewriteRule ^(.*)$ http://sub.domain.com/$1 [R=301,L]
This is working, but is missing the rule to remove the "/folder/" from the path. I've tried combining multiple RewriteRule's with no luck. Any ideas? Thanks.
UPDATE: Thanks again #Gerben - I understand what your rules are doing now, but the second one isn't working for me. I suspect because it's conflicting with some other rewrite rules, in particular those of WordPress, which are lower down in my .htaccess file:
# BEGIN WordPress
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
Because of this the page ends up in a redirect loop, ie (from Chrome):
"The webpage at http://sub.domain.com/folder/index.php has resulted in too many redirects." - while the url I was originally trying to access was, for example, http://sub.domain.com/page
Any ideas?
Try:
RewriteCond %{HTTP_HOST} ^(www.)?domain.com$ [NC]
RewriteRule ^(folder/)?(.*)$ http://sub.domain.com/$2 [R=301,L]
This will redirect everything to sub.domain.com, and remove the /folder part of the URI if it is there. If not, it redirects and leaves the URI untouched.
RewriteCond %{THE_REQUEST} /folder/
RewriteRule ^folder/(.*)$ http://sub.domain.com/$1 [R=301,L]
RewriteCond %{HTTP_HOST} ^sub\.domain\.com$ [NC]
RewriteCond %{REQUEST_URI} !^/folder/
RewriteRule ^(.*)$ folder/$1 [L]
# WordPress rules here
edit the second R=301 should not have been there
But this won't work, as wordpress has no way of knowing you want folder. You could add the Proxy flag to the rewrite, but then you need to change the rule above to not redirect on this internal proxy request.

How can I change all subdomains to read different content from their respective subdirectories?

I have my DNS configured to accept any subdomain (wildcard *), but I am having trouble feeding back the required content to the browsers.
I would like each subdomain to return the relative content, which resides in subdirectories of the same name within the public_html path of my server.
eg, example.domain.com/picture.jpg would actually request the file at public_html/example/picture.jpg
Currently I have tested the followed .htaccess code, but it is not functional:
RewriteCond %{HTTP_HOST} ^(.*)\.domain\.com$ [NC]
RewriteRule ^(.*)$ %1/$1 [L]
This code, and similar tests, can redirect based on the subdomain (%1) fine, but the request string ($1) seems to be the issue.
Maybe you could take a look at the mod_vhost_alias module :
http://httpd.apache.org/docs/2.0/mod/mod_vhost_alias.html
Try the following:
RewriteCond %{HTTP_HOST} ^([0-9a-z-]+).domain.com [NC]
RewriteRule ^/(.*) http://domain.com/%1/$1 [L]
I didn't test this one but I use similar rules for proxying:
RewriteCond %{HTTP_HOST} !^domain.local [NC]
RewriteCond %{HTTP_HOST} ^([0-9a-z-]+).domain.com [NC]
RewriteRule ^/(.*) http://domain.local/%1/$1 [P]