How to replace escaped slashes via mod_rewrite? - apache

I'm migrating an old web server with an strange php script for directory browsing to an apache httpd server with the standard directory browsing.
The old script required urls like http://myserver/index.php?fm_dir=dir1%2Fsubdir1%2Fsubdir2
This should be replaced now by an url like http://myserver/dir1/subdir1/subdir2
For an easy migration I try to rewrite the url via mod rewrite.
I tried already the following:
RewriteCond %{QUERY_STRING} ^fm\_dir\=(.*)$
RewriteRule index\.php$ /%1? [R]
But the escaped slashes are still escaped and I get and 404 (http://myserver/dir1%2Fsubdir1%2Fsubdir2).
Could someone give me a hint how to fix this.

RewriteCond %{QUERY_STRING} ^fm\_dir\=(.*)$
RewriteRule index\.php$ /%1? [NE,N]
# as long as there are two or more slashes,
# replace only one and keep looping internally
RewriteRule ^(.*)\%2F(.*)\%2F(.*) $1/$2\%2F$3 [NE,N]
# when there is only one left,
# replace that last one and send redirect to the client
RewriteRule ^(.*)\%2F(.*) $1/$2 [L,R=302]

Related

.htaccess redirection not working in ubuntu

To remove multiple slashes I wrote this condition that is working in windows system but not in Ubuntu 18.04 I don't know why..?
RewriteCond %{HTTP_HOST} !=""
RewriteCond %{THE_REQUEST} ^[A-Z]+\s//+(.*)\sHTTP/[0-9.]+$
RewriteRule .* %{HTTP_HOST}/%1 [R=301,L]
I am getting this error in ubuntu system..
Forbidden
You don't have permission to access this resource.
And my URL changed this
http://in.decashop.localhost/p/8489882_500-boys-gym-short-sleeved-t-shirt-grey.html
to this
http://in.decashop.localhost/var/www/html/decashopglobal/www/in.decashop.localhost/p/8489882_500-boys-gym-short-sleeved-t-shirt-grey.html
if I put multiple slashes like
http://in.decashop.localhost///p/8489882_500-boys-gym-short-sleeved-t-shirt-grey.html
At first, you can check apache's log. try to access your website using URL or IP and check your Webserver's log information.
In ubuntu you can try:
sudo tail -f /var/log/apache2/error.log
In most cases wrong permission is the main cause of this problem.
RewriteCond %{HTTP_HOST} !=""
RewriteCond %{THE_REQUEST} ^[A-Z]+\s//+(.*)\sHTTP/[0-9.]+$
RewriteRule .* %{HTTP_HOST}/%1 [R=301,L]
The output you are seeing is consistent with the directives you have posted, as you are missing the scheme (ie. http) on the substitution string in the RewriteRule directive (which presumably should be an absolute URL) - so I don't see how this would have "worked" on the Windows server? Unless you had a very different config (but even then it couldn't have worked the same way).
With the RewriteRule directive as written, the substitution string (ie. %{HTTP_HOST}/%1) would be seen as a relative URL and Apache would then add back the directory-prefix ie. /var/www/html/decashopglobal/www/ prior to issueing the redirect - which naturally results in the malformed redirect you are seeing. If you had set a RewriteBase directive elsewhere in the config file, then this would have overridden this behaviour (although still wouldn't have produced the output you seem to be expecting).
Also note that these directives are intended to remove multiple slashes from the start of the URL-path only, not elsewhere in the URL-path.
So, you would need to change the RewriteRule directive to read:
RewriteRule ^ http://%{HTTP_HOST}/%1 [R=301,L]
OR, remove the HTTP_HOST server variable altogether (to make the substitution string root-relative):
RewriteRule ^ /%1 [R=301,L]
You will need to clear your browser cache before testing, as the erroneosu 301 (permanent) redirects will be cached persistently by the browser. (Test with 302s to avoid caching issues in the future.)
This Rule worked for me..
RewriteBase /
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+(.*?)/+(/[^\s]+) [NC]
RewriteRule ^ %1%2 [R=302,L,NE]
Thanks To All.

Apache mod_rewrite from a folder to a different domain doesn't work with trailing slash

I'm trying to rewrite URLs from old.domain.tld/project to domain.tld/subfolder/project using .htaccess in the project directory on the old server. I think I need to check for the host name so the rule only applies to the old server, even if the .htaccess file is also put on the new server.
I've tried the following .htaccess file:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^old\.domain\.tld$ [NC]
RewriteRule ^(.*)$ https://domain.tld/subfolder/project/$1 [R=301,L]
This works fine for URLs like https://old.domain.tld/project/index.php?p=q (redirects to https://domain.tld/subfolder/project/index.php?p=q) but not for the URL without the trailing slash—https://old.domain.tld/project ends up being redirected to https://domain.tld. Very odd! How do I make this work for both types of URL?
I tried a rather different method to make this a generic redirect, that could be included even if the folder name wasn't project, but this has the same problem:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^old\.domain\.tld$ [NC]
RewriteCond %{REQUEST_URI} ^(.*)$
RewriteRule . https://domain.tld/subfolder/%1 [R=301,L]
In a server-wide configuration, a slash is appended to all requests for index files, e.g. old.domain.tld/project is redirected to old.domain.tld/project/. Could this be causing a problem?

External and internal redirection using htaccess

I want to convert http://mywebsite.com/folder/file.html to http://mywebsite.com/file.
I am not using regular expression as first I am only concerned about this one URL only.
I tried this-
Redirect 301 /folder/file.html http://mywebsite.com/file
Using this I am able to externally redirect this URL to the desired one but since the URL doesn't exist so I am getting 404.
Now, in order to internally redirect the new URL to the old one, I am using below command but it doesn't seem to work-
RewriteRule http://mywebsite.com/file http://mywebsite.com/folder/file.html [L]
Use only mod_rewrite directives and use THE_REQUEST variable for external redirection.
# turn on rewrite engine
RewriteEngine On
# external redirect from actual URL to pretty one
RewriteCond %{THE_REQUEST} \s/+/folder/file\.html[\s?] [NC]
RewriteRule ^ /file [R=301,L,NE]
# internal forward from pretty URL to actual one
RewriteRule ^file/?$ /folder/file.html [L,NC]

301 redirect ?___store=default

I need to make 301 redirection for all urls that have this kind of ending in them:
?___store=default&___from_store=com
For example:
301 FROM URL
https://www.example.com/page.html?___store=default&___from_store=com
TO:
https://www.example.com/page.html?___store=default_migrated&___from_store=com
Server has Apache in it and Magento 2 is the CMS I have running there. If more details are needed I'm happy to provide them.
You could setup a RewriteRule in apache for this. Basically you would just need to check the %{QUERY_STRING} server variable to see if it matches the query string that is exactly "?___store=default&___from_store=com" (you can change it to be a bit less strict in the matching with a regex if needed).
RewriteCond %{QUERY_STRING} ^___store=default&___from_store=com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1?___store=default_migrated&___from_store=com [L,R=301]
You can read more about Apache RewriteRules here.

Apache mod_rewrite redirect, keep sub-directory name

I'm wondering if this is possible.
I have a single page site in which I'd like to incorporate a trailing slash with a file name that anchors to a section on that site. I'm trying to avoid using hash or hash-bangs.
For example; www.example.com/recent
Right now, I'm removing any trailing slash, but I get a 404 with /recent because it's expecting a file.
RewriteRule ^(.*)/$ /$1 [R=301,L]
Is it possible to redirect to www.example.com, but still maintain the /recent without the server thinking it's a file so I can read it client-side (php/js)? More so that I can keep using the back and forward buttons.
Thanks for any help!
TBH it is not 100% clear for me what you want. As I understand you want URL www.example.com/recent to be rewritten (internal redirect, when URL remains unchanged in browser) to www.example.com/index.php?page=recent (or something like that).
DirectorySlash Off
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /
# remove trailing slash if present
RewriteRule ^(.*)/$ /$1 [R=301,L]
# do not do anything for already existing files
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .+ - [L]
# rewrite all non-existing resources to index.php
RewriteRule ^(.+)$ /index.php?page=$1 [L,QSA]
With the above rules (that need to be placed in .htaccess in website root folder) this can be achieved. Request for www.example.com/recent will be rewritten to www.example.com/index.php?page=recent so your single-page server side script knows which URL was requested. The same will be with any other non-existing resource e.g. www.example.com/hello/pink/kitten => www.example.com/index.php?page=hello/pink/kitten.
It may not be necessary to pass originally requested URI as a page parameter as you should be able to access it in PHP via $_SERVER['REQUEST_URI'] anyway.
If I misunderstood you and this is not what you want then you have to clarify your question (update it with more details, make it sound clear).