How can I rewrite all requests except for one specific URI - apache

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]

Related

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

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.

Mod_rewrite redirect not working as intended (working in htaccess checker)

I'm trying to redirect users accessing https://www.mywebsite.com/index.php?p=home to https://www.mywebsite.com/. I have already added the code below to my public_html's .htaccess file and have tested it on an htaccess checker.
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_URI} ^/index\.php$ [NC]
RewriteCond %{QUERY_STRING} ^p=home$ [NC]
RewriteRule .* https://%{HTTP_HOST}/ [R=301,L,QSD]
Based on my code, do you have any idea why the redirect is not working even though the htaccess checker says it should be working.
You could try following Rules in your htaccess rules file. Please don't trust htaccess checker sites they don't give correct results. Have your htaccess file with following rules and make sure you clear your browser cache before testing your URLs.
RewriteEngine ON
##Redirection external rules here.
RewriteCond %{THE_REQUEST} \s/index\.php\?p=home\s [NC]
RewriteRule ^ https://%{HTTP_HOST} [R=301,L]
##Rewrite internal rule here.
RewriteRule ^/?$ index.php?p=home [L]

htaccess rewrite not working for multiple files in main directory

The title does not fully describe the issue, but I have rewrite rules setup to go to three different files which exist in the main directory: api.php, admin.php, and index.php
Here is my .htaccess
RewriteEngine on
RewriteCond $1 ^(api)
RewriteRule ^(.*)$ /api.php/$1 [L]
RewriteCond $1 ^(admin)
RewriteRule ^(.*)$ /admin.php/$1 [L]
RewriteCond $1 !^(index\.php|admin\.php|api\.php|admin|api|_|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]
For /admin and /api I get a 500 Internal Server Error. I am not sure why that happens, yet if I put those php files within a folder like /_ and edit the .htaccess to match it then it rewrites without an error. Am I limited on the number of main directory file redirects I can do? Or did I am I missing something?
My main goal is:
Redirect all /api requests to /api.php/whatever/is/after/here
Redirect all /admin requests to /admin.php/whatever/is/after/here
Redirect all other requests apart from the exceptions to /index.php/whatever/is/here
Try with:
RewriteEngine on
# skip all files and directories from rewrite rules below
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
RewriteRule ^(api.*)$ /api.php/$1 [L]
RewriteRule ^(admin.*)$ /admin.php/$1 [L]
RewriteCond $1 !^(index\.php|admin\.php|api\.php|admin|api|_|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]
I found that I simply had to be more specific in my regex match. Previously I was matching anything that started with "admin" or "api" (eg. admins-at-the-new-school) which actually I was unaware of and would cause problems in the future anyways. I changed my regex and now it only matches if it's the end of a line, a pound sign, slash, or question mark. (based on testing)
Here is my final code:
RewriteEngine on
RewriteRule ^(api(?=$|[/?#]).*)$ /api.php/$1 [L]
RewriteRule ^(admin(?=$|[/?#]).*)$ /admin.php/$1 [L]
RewriteCond $1 !^(index\.php|admin\.php|api\.php|_|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]
I appreciate Croises answer, and it did help give me an idea of what might be going wrong that his solution would work. However, this is what I was looking for as I did not want to open up access to files and directories simply because they existed.

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.