.htaccess mask original url - apache

I have this URL:
localhost:1001/project/index.html
And if I write this URL:
localhost:1001/project/index.html.twig
I want it to be masked to the first one (localhost:1001/project.index.html) but the URL processed must be the second one (don't know if it is possible).
I have tried all of this but I think all is wrong in my .htaccess in project folder root, because nothing worked as I want:
a)
RedirectMatch 302 /project/index.html.twig /project/index.html
b)
RedirectMatch 301 /project/index.html.twig /project/index.html
c)
RewriteCond %{HTTP_HOST} ^/project/index.html.twig$ [NC]
RewriteRule /project/index.html [R=301,L]
COMMENTS
Process I want to obtain:
I write in the browser: localhost:1001/project/index.html.twig
Somehow I want my .htaccess to convert that URL in the browser to localhost:1001/project/index.html and see that URL in the browser
Internally after that I want to process the original URL: localhost:1001/project/index.html.twig

This probably is what you are looking for if you want an external redirection:
RewriteEngine on
RewriteRule ^/?project/index\.html$ /project/index.html.trig [R=301]
RewriteRule ^/?project/index\.html\.twig$ /project/index.html [END]
In case you want an internal rewrite use that variant:
RewriteEngine on
RewriteRule ^/?project/index\.html\.twig$ /project/index.html [R=301]
RewriteRule ^/?project/index\.html$ /project/index.html.trig [END]
These rules should work likewise, in the http servers host configuration or in a dynamic configuration file (".htaccess" style file). You should definitely prefer the first option if you have access to it. If you need to use a dynamic configuration file then take care that it's interpretation is enabled at all and that it is located in the host's DOCUMENT_ROOT folder.
In case you receive a server internal error (http status 500) using that rule chances are that you operate an old version of the apache http server. You will find a definite hint on an unknown [END] flag in the http servers error log file in that case. Try using the older [L] flag in that case, it will probably work the same here, though that depends on your setup.

Related

301 url redirect .htaccess in Apache server

How can i direct the search engines from one domain to other domain for better SEO optimization. I want to make 301 redirect from domain.uk to language directory of another domain domain.com/gr
How can to change last line code? Thanks!
RewriteEngine on
RewriteCond %{HTTP_HOST} ^example-old\.uk$ [NC]
RewriteRule ^(.*)$ http://example-new.com/gr [R=301,L]
RewriteCond %{HTTP_HOST} ^example-old\.uk$ [NC]
RewriteRule ^(.*)$ http://example-new.com/gr [R=301,L]
You've not actually stated the problem you are having. However, if you want to redirect to the same URL-path, but with a /gr/ path segment prefix (language code) then you are missing a backreference to the captured URL path (otherwise there's no reason to have the capturing group in the RewriteRule pattern to begin with).
For example:
RewriteRule (.*) http://example-new.com/gr/$1 [R=301,L]
The $1 backreference contains the value captured by the preceding (.*) pattern.
I assume that is what you are looking for:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^example-old\.uk$ [NC]
RewriteRule ^ http://example-new.com/gr%{REQUEST_URI} [R=301,END]
It is a good idea to start out with a 302 temporary redirection and only change that to a 301 permanent redirection later, once you are certain everything is correctly set up. That prevents caching issues while trying things out...
In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, it probably will work the same in this situation, though that depends a bit on your setup.
This implementation will work likewise in the http servers host configuration or inside a distributed configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a distributed configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.
And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using distributed configuration files (".htaccess"). Those distributed configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).

Redirect Loop, Faraway so Close

Basically I need to let through requests to a specific path:
https://domainfoo.com/my-app?param1=ABC&paramY=123
Anything else, let's say,
https://domainfoo.com/aboutus
I need it redirected to
https://moodomain.io/aboutus
I need this last part to be generic.
So Far I have this two rules:
To address the first requirement:
RewriteCond %{HTTP_HOST} ^domainfoo.com$
RewriteCond %{REQUEST_URI} ^/my\-app
RewriteRule ^(my\-app)$ https://domainfoo.com/$1 [L,R=301]
Then as a second rule (if first rule is matched (the L) should redirect and stop right? The thing is apparently it doesn't and then goes into the second rule:
RewriteCond %{HTTP_HOST} ^domainfoo.com$ [OR]
RewriteCond %{HTTP_HOST} ^www.domainfoo.com$
RewriteCond %{REQUEST_URI} !^/my\-app$
RewriteRule (.*)$ https://moodomain.io/$1 [R=301,L]
But I have been dealing for hours with a looped redirect.
Ideas?
You first rule codes the rewriting loop, since you implemented an external redirection where none is required at all. Here is a simplified version:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^domainfoo\.com$
RewriteRule ^/?my-app$ - [END]
RewriteCond %{HTTP_HOST} ^domainfoo\.com$
RewriteRule ^/?(.*)$ https://moodomain.io/$1 [R=301]
It is a good idea to start out with a 302 temporary redirection and only change that to a 301 permanent redirection later, once you are certain everything is correctly set up. That prevents caching issues while trying things out...
In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, it probably will work the same in this situation, though that depends a bit on your setup.
This rule will work likewise in the http servers host configuration or inside a dynamic configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a dynamic configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.
And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using dynamic configuration files (".htaccess"). Those dynamic configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).
And if you need to redirect clients "back" to the first domain, as you later stated in the comments to the question, then add an explicit redirection for that:
RewriteCond %{HTTP_HOST} !^domainfoo\.com$
RewriteRule ^/?my-app$ https://domainfoo.com/my-app [R=301]

.htaccess rewrite returning Error 404

RewriteEngine on
RewriteCond %{QUERY_STRING} (^|&)public_url=([^&]+)($|&)
RewriteRule ^process\.php$ /api/%2/? [L,R=301]
Where domain.tld/app/process.php?public_url=abcd1234 is the actual location of the script.
But I am trying to get .htaccess to make the URL like this: domain.tld/app/api/acbd1234.
Essentially hides the process.php script and the get query ?public_url.
However the script above is returning error 404 not found.
I think this is what you are actually looking for:
RewriteEngine on
RewriteCond %{QUERY_STRING} (?:^|&)public_url=([^&]+)(?:$|&)
RewriteRule ^/?app/process\.php$ /app/api/%1 [R=301,QSD]
RewriteRule ^/?app/api/([^/]+)/?$ /app/process.php?public_url=$1 [END]
If you receive an internal server error (http status 500) for that then check your http servers error log file. Chances are that you operate a very old version of the apache http server, you may have to replace the [END] flag with the [L] flag which probably will work just fine in this scenario.
And a general hint: you should always prefer to place such rules inside the http servers (virtual) host configuration instead of using dynamic configuration files (.htaccess style files). Those files are notoriously error prone, hard to debug and they really slow down the server. They are only supported as a last option for situations where you do not have control over the host configuration (read: really cheap hosting service providers) or if you have an application that relies on writing its own rewrite rules (which is an obvious security nightmare).
UPDATE:
Based on your many questions in the comments below (we see again how important it is to be precise in the question itself ;-) ) I add this variant implementing a different handling of path components:
RewriteEngine on
RewriteCond %{QUERY_STRING} (?:^|&)public_url=([^&]+)(?:$|&)
RewriteRule ^/?app/process\.php$ /api/%1 [R=301,QSD]
RewriteRule ^/?api/([^/]+)/?$ /app/process.php?public_url=$1 [END]
I am trying to get .htaccess to make the URL like this: example.com/app/api/acbd1234.
You don't do this in .htaccess. You change the URL in your application and then rewrite the new URL to the actual/old URL. (You only need to redirect this, if the old URLs have been indexed by search engines - but you need to watch for redirect loops.)
So, change the URL in your application to /app/api/acbd1234 and then rewrite this in .htaccess (which I assume in in your /app subdirectory). For example:
RewriteEngine On
# Rewrite new URL back to old
RewriteRule ^api/([^/]+)$ process.php?public_url=$1 [L]
You included a trailing slash in your earlier directive, but you omitted this in your example URL, so I've omitted it here also.
If you then need to also redirect the old URL for the sake of SEO, then you can implement a redirect before the internal rewrite:
RewriteEngine On
# Redirect old URL to new (if request by search engines or external links)
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} (?:^|&)public_url=([^&]+)(?:$|&)
RewriteRule ^process\.php$ /app/api/%1? [R=302,L]
# Rewrite new URL back to old
RewriteRule ^api/([^/]+)$ process.php?public_url=$1 [L]
The check against REDIRECT_STATUS is to avoid a rewrite loop. ?: inside the parenthesised subpattern avoids the group being captured as a backreference.
Change the 302 (temporary) to 301 (permanent) only when you are sure it's working OK, to avoid erroneous redirects being cached by the browser.

Apache rewrite rule that ignores query/parameters, always redirects based on path

I'm trying to create a rewrite rule that will ignore any additional URL query/parameters and just redirect based on the path.
My company has a Wifi Hotspot service that does some DNS routing trick to force people to login before they can use it. Unfortunately when folks get disconnected from the WiFi and dropped back to their normal cell data service sometimes a URL request is still sent to our host, and it shows up as:
www.ourwebsite.com/login?dst=http://www.google.com/m?client=ms-android-verizon&source=android-home
I already wrote a set of rules to take care of base paths of /login and /login/ to redirect to our homepage,
RewriteCond %{THE_REQUEST} ^.*\/login/\ HTTP/
RewriteRule ^(.*)login/?$ "/$1" [R=301,L]
RewriteCond %{THE_REQUEST} ^.*\/login\ HTTP/
RewriteRule ^(.*)login?$ "/$1" [R=301,L]
but I am having trouble coming up with an appropriate string to ALWAYS redirect based souly on the path, and ignore any query parameters that may or may not come after.
Any help would be appreciate! Thanks in advance.
If I understood right, something like this should do it:
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /
RewriteRule ^login /? [R=301,L]
This rule-set will redirect to root as long as the incoming URL is something like:
http://www.ourwebsite.com/login?any_query
From Apache 2.4.0 on you can apply the QSD-flag to the rule.
When the requested URI contains a query string, and the target URI does not, the default behavior of RewriteRule is to copy that query string to the target URI. Using the [QSD] flag causes the query string to be discarded.
-- https://httpd.apache.org/docs/2.4/rewrite/flags.html#flag_qsd
When using this flag for earlier Apache versions you'll cause an 500 Internal Server Error.

RewriteRule and php download counter

(1) I have a site that serves up MP3 files:
http://domain/files/1234567890.mp3
(2) I have a php script that tracks file download counts:
http://domain/modules/download_counter.php?file=/files/1234567890.mp3
After download_counter.php records the download, it redirects to the original file:
Header("Location: $FQDN_url");
(3) I'd like all my public links to be presented as the direct file urls from (1). I'm trying to use Apache to redirect the requests to download_counter.php:
RewriteRule ^files/(.+\.mp3)$ /modules/download_counter.php?file=/files/$1 [L]
I'm currently stuck on (3), as it results in a redirect loop, since download_counter.php simply redirects the request back to the original file (rather than streaming the file contents).
I'm also motivated to use download_counter.php as is (without modifying it's redirect behaviour). This is because the script is part of a larger CMS module, and I'd like to avoid complicating my upgrade path.
Perhaps there is no solution to my problem (other than modifying the download_counter script). WDYT?
If this is not about the strongest protection ever (as I can see, it is not), then just have your script to redirect browser not to the file, but to the
http://domain/files/1234567890.mp3/redirected
Ensure your webserver will still serve such request correctly as a file download. If it will, then just add negative RewriteCond that will ensure, that redirection is done if and only if the link is not ending with /redirected
UPDATED ANSWER
i think you are into a lot of troubles because your pseudo url are actually real urls: they lead to the file. So you should change your pseudo url to something like domain.com/downloads/file.mp3 and then just check whether the requested file does not exist, so that the redirect does not loop.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^downloads/(.+\.mp3)$ /modules/download_counter.php?file=/files/$1 [L]
I first thought something that would use the referer would work:
RewriteCond %{HTTP_REFERER} !download_conter\.php
RewriteCond %{HTTP_REFERER} !=""
RewriteRule ^files/(.+\.mp3)$ /modules/download_counter.php?file=/files/$1 [L]
However, the browser does not cooperate. Let's say you click some link in file.html to something.mp3 and then are forwarded to download_counter.php. When the php script does the forward it sets as referer not download_counter.php but file.html.
The only way I see you could do this would be using an external rewriting program that would keep some state -- the first time the user requested the file it would save that information and make the rewrite, the second time it would know it had made the rewrite in the first place and would pass through the request unmodified. See the documentation of RewriteMap.
Put in http://domain/files/ this .htaccess file...
RewriteEngine On
RewriteOptions Inherit
RewriteRule ^(.*).(mp3)$ /modules/download_counter.php?file=$1.$2 [R,L]
This should do the trick...