.htaccess rewriting URLs that don't exist - apache

Currently, I'm working with some guys that love short URLs for marketing purposes when posting to social media.
They have https://www.example.com/folder/subfolder
For their marketing, they would like https://www.example.com/mysuperbuzzword which would point to the first URL but in the browser, you would still see the shorter URL.
My first thought was "I'll just add a rewrite rule in the .htaccess"
Something like Redirect 301 /mysuperbuzzword /folder/subfolder/ which would work but then the URL changes.
I did some reading and discovered the [P] flag. Then I tried this:
RewriteCond %{REQUEST_URI} ^/vanityurl
RewriteRule ^(.*)$ /folder/subfolder [P]
The issue I have now is that because /vanityurl doesn't exist, instead of rewriting, I just get a 404 error.
I've been testing my rule using a .htaccess rule checking tool and the URL it spits out looks correct, but again, I just get a 404.
Also, if you use the flag [PT] the resource is found but the URL is changed in the address bar.

You tested with a permanent redirect. Never do that. It is cached by the browser, and the browser will no longer do requests to the server. This is possible, because such a redirect is supposed to be... well... permanent. If you must test redirects, test them with a temporary redirect (302) and change them later if everything turns out to be fine.
With mod_rewrite you can do three things:
Do an internal rewrite. If you internally rewrite url a to url b, then the user sees url a, but url b is being executed on the server.
Do an external redirect. If you externally redirect url a to url b you send back a response: "Please request url b instead.". The browser then sends another request to the server with url b and changes the url in the address bar accordingly.
Do a proxy request. If you proxy url a to url b, the user requests url a. The server then opens a http connection and requests url b. It then waits for the response and channels that back to the client. It is very expensive to do such a thing via mod_rewrite.
What you simply want to do is:
RewriteRule ^vanityurl$ /folder/subfolder [L]
It as a simple internal rewrite.

Related

POST information getting lost in .htaccess redirect

So, I have a fully working CRUD. The problem is, because of my file structure, my URLs were looking something like https://localhost/myapp/resources/views/add-product.php but that looked too ugly, so after research and another post here, I was able to use a .htaccess file to make the links look like https://localhost/myapp/add-product (removing .php extension and the directories), and I'm also using it to enforce HTTPS. Now, most of the views are working fine, but my Mass Delete view uses POST information from a form on my index. After restructuring the code now that the redirect works, the Mass Delete view is receiving an empty array. If I remove the redirect and use the "ugly URLs" it works fine. Here's how my .htaccess file is looking like:
Options +FollowSymLinks +MultiViews
RewriteEngine On
RewriteBase /myapp/
RewriteRule ^resources/views/(.+)\.php$ $1 [L,NC,R=301]
RewriteCond %{DOCUMENT_ROOT}/myapp/resources/views/$1.php -f
RewriteRule ^(.+?)/?$ resources/views/$1.php [END]
RewriteCond %{HTTPS} off
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
I didn't actually write any of it, it's a mesh between answered questions and research. I did try to change the L flag to a P according to this post: Is it possible to redirect post data?, but that gave me the following error:
Internal Server Error
The server encountered an internal error or misconfiguration and was unable to complete your request.
Please contact the server administrator at admin#example.com to inform them of the time this error occurred, and the actions you performed just before this error.
More information about this error may be available in the server error log.
Apache/2.4.52 (Win64) OpenSSL/1.1.1m PHP/8.1.2 Server at localhost Port 443
POST information getting lost in .htaccess redirect
You shouldn't be redirecting the form submission in the first place. Ideally, you should be linking directly to the "pretty" URL in your form action. If you are unable to change the form action in the HTML then include an exception in your .htaccess redirect to exclude this particular URL from being redirected.
Redirecting the form submission is not really helping anyone here. Users and search engines can still see the "ugly" URL (it's in the HTML source) and you are doubling the form submission that hits your server (and doubling the user's bandwidth).
"Redirects" like this are only for when search engines have already indexed the "ugly" URL and/or is linked to by external third parties that you have no control over. This is in order to preserve SEO, just like when you change any URL structure. All internal "ugly" URLs should have already been converted to the "pretty" version. The "ugly" URLs are then never exposed to users or search engines.
So, using a 307 (temporary) or 308 (permanent) status code to get the browser to preserve the request method across the redirect should not be necessary in the first place. For redirects like this it is common to see an exception for POST requests (because the form submission shouldn't be redirected). Or only target GET requests. For example:
RewriteCond %{REQUEST_METHOD} GET
:
Changing this redirect to a 307/8 is a workaround, not a solution. And if this redirect is for SEO (as it only should be) then this should be a 308 (permanent), not a 307 (temporary).
Aside:
RewriteCond %{HTTPS} off
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Your HTTP to HTTPS redirect is in the wrong place. This needs to go as the first rule, or make sure you are redirecting to HTTPS in the current first rule and include this as the second rule, before the rewrite (to ensure you never get a double redirect).
By placing this rule last then any HTTP requests to /resources/views/<something>.php (or /<something>) will not be upgraded to HTTPS.

Intelligent redirection

I am a newbie using Apache 2.4.18.
I have URLs with the following form that I'd like to redirect.
Current URL: https://www.example.org/page/10/
Desired URL: https://www.example.org/index.php/page/10/
If I use the following rule, I can modify a request, eg for page 2:
Redirect permanent /page/2/ /index.php/page/2/
However, I want to redirect without having to hardcode all the pages on my site. I have tried the following, my browser fails after many redirects:
RedirectMatch /page/(.*)/$ /index.php/page/$1/
And using the following fails, I don't know why:
RedirectMatch "https://www.example.org/page/(.*)/$" "https://www.example.org/index.php/page/$1/"
What am I doing wrong?
In your line
RedirectMatch /page/(.*)/$ /index.php/page/$1/
/page/2/ will in fact redirect to /index.php/page/2/, but this new URL will still match your RedirectMatch’s regex and will produce another redirect. That’s why it redirects endlessly until the browser gives up (see this example).
I’d try with RedirectMatch ^/page/(.*)/$ /index.php/page/$1/, so when redirected, /index.php/page/2/ will no longer match ^/page/(.*)/$ and will not produce the recursive redirects.
As an aftertought, why not use RewriteRule instead? It’d save an additional HTTP request to the client, as redirects are usually used when you need to send the client to a different server.

Rewrite an url get parameter name

I would like to rewrite one parameter in my url and at the same time direct the traffic to another URL. The url should be called with an external program, so it does not actually need to redirect the user.
Original URL:
http://URL1/?parameter1=1234&monkey=12345
Should go into (changing URL1 > URL2 and monkey > abe:
http://URL2/?parameter1=1234&abe=12345
Searched alot of for mod_rewrite examples, but didn't find anything that rewrites the parameter name it self (not the value) and at the same time redirects to a different url.
With mod_rewrite and whithout a client redir you cannot change the host.
If you try the following, you can change the query string:
RewriteCond %{QUERY_STRING} ^parameter1=([0-9]+)&monkey=([0-9]+)$
RewriteRule / /?parameter1=%1&abe=%2
But, in order to change the host, you must do a client redir:
RewriteCond %{QUERY_STRING} ^parameter1=([0-9]+)&monkey=([0-9]+)$
RewriteRule / http://URL2/?parameter1=%1&abe=%2 [R]
Another option without client redir could be using a proxy; this way URL1's apache server, would proxy requests to URL2's web server and return the response to the client

Rewrite URL .htaccess - Apache server

On my website, I would rename the URL on address bar, from
domain.com/economy/article.php?id=00
to
domain.com/economy/id-name-article.html
I wrote this .htaccess file:
RewriteEngine On
RewriteRule ^([0-9]+)-([^\.]*)\.html$ http://domain.com/economy/article.php?id=$1 [L]
I have an anchor with this href: href="economy/id-name-article.html" and when I click on it, the server is redirected on article.php, it runs the script in the correct way and I can view the article, but on the address bar is still written domain.com/economy/article.php?id=00 instead domain.com/economy/id-name-article.html. Why?
This happens only on my online server, while locally it's all right.
The mod_rewrite module is issuing a redirect to your browser rather than transparently rewriting the url, causing you to see the new url in your browser.
Try removing the http://domain.com portion from your RewriteRule to see if it avoids the redirect to your browser by changing the rule to:
RewriteRule ^([0-9]+)-([^\.]*)\.html$ /economy/article.php?id=$1 [L]
If that fails, you could also use the proxy flag [P] to force apache to transparently fetch the page and return it to your users without the redirect. I don't recommend this approach since it can have security implications but it should work if the above doesn't.
EDIT: To clarify, rewriting the url with a fully-qualified domain rather than a relative uri tells apache that the redirect is on a different server, and therefore it doesn't know that the new url is accessible on the same host without redirecting the client.

Apache rewrite rule - prevent rewritten URL appearing in browser URL bar

I have a rewrite rule which is looking for a particular URI. When it matches the particular URL it rewrites it with a proper file path so the required content can be found. It then changes the protocol to HTTPS and allows the request to pass through.
I have two problems;
I don't want the rewritten path to appear in the users browser - i want to maintain the vanity url
I do want the HTTPS protocol to appear indicating to the user that they are accessing the site over a secured conection.
I have tried a couple of options but no success. If i include the [R] flag the URL and protocol remain unchanged but that is not the desired effect
Any suggestions on how i can achieve this?
This is my rule;
RewriteMap redirectsIfSecure txt:/myserver/content/secure_urls.txt
RewriteCond ${lowercase:%{REQUEST_URI}} ^/(.+)$
RewriteCond ${redirectsIfSecure:%1|NOT_FOUND} !NOT_FOUND
RewriteRule ^(.*)$ https://myserver.com${redirectsIfSecure:%1} [PT]
From the mod_rewrite documentation:
If an absolute URL is specified, mod_rewrite checks to see whether the
hostname matches the current host. If it does, the scheme and hostname
are stripped out and the resulting path is treated as a URL-path.
Otherwise, an external redirect is performed for the given URL. To
force an external redirect back to the current host, see the [R] flag
below.
If you rewrite the request to a fully qualified URL (that is, anything starting with http://, https://, etc) that doesn't match your ServerName, then mod_rewrite will issue an HTTP redirect, which will cause the client browser to request the resource from the new location.
If you're not trying to switch between http and https you can use a proxy rule (the P flag) to have Apache make the request on behalf of the client and return the result, thus masking the rewritten URL.
However, if you're trying to upgrade from http to https (or the other way around), this will always require a client redirect.