How to remove a subfolder from URL using htaccess - apache

We have those kinds of URL:
https://www.example.com/public/something/something
I need to get rid of the /public/ subfolder so every duplicate URL with this subfolder would be redirected using 301 redirect to the same URL but without the subfolder. The example above would be redirected to:
https://www.example.com/something/something
I have tried this:
RewriteRule ^public/(.*)$ /$1 [L,NC,R=301]
The example still returns 200. How to redirect every URL with /public/ to the same URL without the subfolder? And if It possible, could you explain the .htacces code which handles it briefly?
EDIT: We have discovered another hidden .htaccess file on the server which appears to be the one we need to set up. Here is its content: https://gist.github.com/zatkoma/6425eb2f93c3c6affd46828de044e95b.
We have added the line here but still nothing happens. Where exactly should we put the line?
Thanks

There are two problems in your config: the first is that when in subfolder .htaccess, RewriteRule pattern will strip the path to that subfolder
so ^public/ is never matched.
The second is little tougher: your requirement that your site is in located in /public subfolder, so when user enters URL without /public, you (in root htaccess) rewrite that to /public/...
But at the same time you want, if someone writes URL starting with /public/, you want it to be removed.
This can be achieved by checking if Original request (as typed in browser) contained /public.
So now the flow is:
Check if request has /public, if not then add it internally, and go
to /public (done by htaccess in root)
When in /public (thus having subfolder .htaccess in effect), don't check if request begins with /public (because it always does), but check if original request (before step 1). had /public, and only if it had, do the rewrite to URL without /public
RewriteCond %{THE_REQUEST} \s/public/
RewriteRule (.*) /$1 [L,NC,R=301]

Related

Redirect subfolder to another subfolder without appending parametres

I need to redirect a subfolder to another subfolder, but I don't want to carry over what comes after the trailing slash or any URL parametres.
For example:
www.mysite.com/this-is-the-old/ -> www.mysite.com/this-is-the-new/
But I would like this redirect to fire no matter what the user adds to the end of the old URL. No matter what I try (in either RedirectMatch or RewriteRule) it's always adding the trailing characters to the new URL.
You can use this rewrite rule in your site root .htaccess:
RewriteEngine On
RewriteRule ^this-is-the-old(/.*)?$ /this-is-the-new/? [L,NC,R=301]
Make sure to clear your browser cache completely before you test this new rule.

Wildcard redirect from subdomain root folder to subdomain subfolder

So I recently sorted all my files on a subdomain into different folders, let's just call it upload.example.org. One of the new folders is titled "img" (public_html/upload/img), where I now automatically upload any pictures I take for easy sharing. Previously all images were in the document root folder "upload" and that's where I used to share the URLs from, so a redirect to the new URL is needed to avoid breaking anything.
Now what I've been trying to do is create a .htaccess that redirects people from upload.example.org/image.jpg to upload.example.org/img/image.jpg. image.jpg can be replaced with any other file name in the img folder.
Looking for answers, I found this:
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
Using this line of code with my subdomain results in a loop, in the end redirecting me to http://upload.example.org/img/img/img/img/img/img/img/img/img/img/image.jpg.
After searching and trying out different .htaccess variants, I couldn't come across the correct solution.
Any help that you can give would be much appreciated! :)
The reason for the loop is because after the redirect, the client requests the new URL and this new URL is redirected again, causing a new request from the client and again a redirect, and so on ...
To avoid this, you must prefix the rule with a stop condition, e.g.
RewriteRule ^img/ - [L]
This causes an exit to the rewrite chain, if the requested URL already starts with img/.
Another approach would be to test first if an appropriate file exists in the img folder, and only redirect if there is one.
RewriteCond /img/$1 -f
RewriteRule ^(.*)$ ^img/$1 [R,L]
If you want to exclude a folder from any rewrite, use a stop condition rule as in the above example
RewriteRule ^path/to/some/folder - [L]
This ensures, that any request beginning with the given URL path is ever rewritten or redirected.
If you want an exception from only the img rule, you could add another condition to the rule, which checks if the resulting path would be in this other folder, e.g.
RewriteCond /img/$1 -f
RewriteCond /img/excluded/folder/$1 !-f
RewriteRule ^(.*)$ ^img/$1 [R,L]
These conditions check first, if the image exists somewhere in the img subfolder, and then make sure it is not a file in the img/excluded/folder.
Unrelated, but never test with R=301! When everything works as it should, you may replace R with R=301.

htaccess - rewrite rule not working when requested URL is a folder on my system

All requests to my site should be rewritten to index.php?page=blah, where blah is the page that's requested (except for css, js, jp(e)g, gif and png files).
This is how my .htaccess file looks like:
RewriteEngine On
RewriteCond %{REQUEST_URI} !\.(?:css|js|jpe?g|gif|png)$ [NC]
RewriteRule ^(.*)$ index.php?page=$1 [L,QSA]
The .htaccess is in this directory: localhost:8080/example/, so when I go to localhost:8080/example/abc, it is (internally) rewritten to localhost:8080/example/index.php?page=abc.
However when I go to localhost:8080/example/res, I get redirected to localhost:8080/example/res/?page=res. I found out that this only happens to directories; when I go to localhost:8080/example/core(also a folder on my file system), I get redirected to localhost:8080/example/core/?page=core while it should be internally rewritten to localhost:8080/example/index.php?page=core and the url visible to the user should stay localhost:8080/example/core/
EDIT:
Thanks to #w3dk, who solved the problem stated above. But I found another problem, which may be related to the problem above:
When I go to:
localhost:8080/example/index/a, it's internally rewritten to localhost:8080/example/index.php?page=index.php/a, while it should be rewritten to localhost:8080/example/index.php?page=index/a.
I found out that this happens when index is a file, cause when I go to localhost:8080/example/exampleFile/abc, it's redirected to localhost:8080/example/index.php?page=exampleFile.php/abc, which shouldn't be the case.
The 2 files in my directory are:
index.php (everything should be directed to this file)
example.php
Apache seems to ignore the php file extension, cause this also works for exampleFile.txt
This is probably happening because of a conflict with mod_dir. The default behaviour (DirectorySlash On) is for mod_dir to automatically "fix" the URL when you request a physical directory without a trailing slash. It does this with an external 301 redirect, before your rule is processed. Your rule then fires, which modifies the target URL, a Location header gets returned to the client and the browser redirects.
This won't happen if you include the trailing slash on the original request. eg. localhost:8080/example/core/. mod_dir then does not need to "fix" the URL and issue a redirect. Although this may not be desirable for you?
Since you are wanting to internally rewrite all directories then the simple fix is to disable this behaviour in .htaccess:
DirectorySlash Off
You will need to clear your browser cache before testing, as the earlier 301s by mod_dir will have been cached locally.
Reference (note the security warning):
https://httpd.apache.org/docs/current/mod/mod_dir.html#directoryslash
You can use this
.htaccess file
Note: The directory folder1 must be unique in the URL. It won't work for http://domain.com/folder1/folder1.html. The directory folder1 must exist and have content in it.
RewriteEngine On
RewriteCond %{HTTP_HOST} domain.com$ [NC]
RewriteCond %{HTTP_HOST} !folder1
RewriteRule ^(.*)$ http://domain.com/folder1/$1 [R=301,L]

Setting the HTACCESS file to redirect all .cfm requests to index.php

I have a .htaccess rewrite rule that I wrote, that is supposed to take any requests that container index.cfm and redirect them to the index.php.
http://testsite.com/index.cfm/a/catalog.prodShow/vid/42110/catid/154
However, it is not redirecting this properly. If I just put in index.cfm (no rest of the url) it works fine, however, the moment the /a/... is added to it, it takes me to the 404 page.
How do I adjust my rule so that it works properly for ANY url that has index.cfm anywhere in it?
Here is my rule:
RewriteRule ^index.cfm$ /index.php [L,NC,R]
Thanks.
In your RewriteRule, the ^ and the $ indicate the start and the end of the line. If you wish to match any index.cfm (like /index.cfm/a/... or /sub1/sub2/index.cfm/...) you can try:
RewriteRule ^(.*index.cfm.*)$ /index.php?original_url=$1 [L,NC]
I added the original url as a parameter because you might need it to process the request and I removed the R flag to avoid loops.

.htaccess rewrite rule - change url of any requested jpg to go to another server

I am trying to setup a rewrite rule in .htaccess for a specific folder and its subfolders so that any request for a jpg image file gets redirected to another domain. The problem is the path is also getting redirected which I do not want to happen.
Example - I need
http://www.example.com/test/media/0/1/test.jpg to get directed to
http://www.example1.com/img/gallery/test.jpg
and
http://www.example.com/test/media/5/7/test1.jpg to get directed to
http://www.example1.com/img/gallery/test1.jpg
I have created a .htaccess file in ../test/media folder and in there I have at the moment
RewriteEngine on
RewriteCond %{HTTPS} !on
RewriteRule ([^.]+\.(jpg))$ http://www.example1.com/img/gallery/$1
the request is being redirected but it gets redirected to
http://www.example1.com/img/gallery/0/1/test.jpg
when I need it to be
http://www.example1.com/img/gallery/test.jpg
Could anyone help please?
Modify yor rule this way:
RewriteRule /([^./]+\.(jpg))$ http://www.example1.com/img/gallery/$1
And it will take only filename after last slash.