Preventing a double redirect with htaccess - apache

I'm trying to create a redirect in-between page of sorts, because the URL that I'm redirecting TO includes more information than the URL I'm redirecting FROM. I'm using a short domain (hrci.me) with an htaccess file to redirect to the full domain (currently reachchallenges.infectionist.com). An example would be:
hrci.me/ch123
The path, ch123, includes the identifier that lets me know it's a challenge link (ch), and the 123 is the challenge ID. Each challenge has a title that I like to append to the end of the URL for SEO purposes. This example URL would redirect to:
reachchallenges.infectionist.com/challenge/123/Challenge+Title
The "Challenge+Title" part is stored in the database and needs to be retrieved by the challenge id, so I wrote a simple PHP script that does just that and then handles the redirect itself. My htaccess rule looks like this:
RewriteRule ^ch([0-9]{1,4})(/)?$ redirhandler.php?chid=$1 [L]
So the request to /ch123 should redirect to redirhandler.php?chid=123, which would get the title then redirect to the other domain at /challenge/123/Challenge+Title. The problem is, the short domain is set up to forward all incoming requests to the long domain, maintaining the original path (so hrci.me/something would redirect to reachchallenges.infectionist.com/something), and I'm finding that after the htaccess handles the rewrite to redirhandler.php, it then redirects that to reachchallenges.infectionist.com/redirhandler.php...
Basically, I need it to ignore any further redirects if the path is redirhandler.php, allowing the php script to handle the rest o the redirect. I'm thinking a RewriteCond is how I might do this, but I can't figure it out.

It sounds like your rule that forwards all incoming requests to the long domain is higher up in the .htaccess file than the more specific rule for /ch* requests. Try putting the more specific rule before the more general one.

Related

Rewriting dynamic url's using apache rewrite

I have a anchor tag in my html content like this class="list-content" href="/abcd/test.html".
and this is in a lot of places in my html for a list of some results.
I need to append all these URLs that are in "href" by appending a prefix.
For example: /abcd/test.html should be dynamically changed as newprefix/abcd/test.html
If i have another one like /xyz/some.html then this should be changed as newprefix/xyz/some.html
I have explored different solutions over the internet and I have not found something that would fit my problem.
To implement an external redirect to prepend /newprefix to these requests you could do something like the following near the top of the root .htaccess (or server config).
For example:
RewriteEngine On
RewriteRule ^[^/]+/[^./]+\.html$ /newprefix/$0 [R=302,L]
The above will redirect requests for /abcd/test.html or /xyz/some.html to /newprefix/abcd/test.html and /newprefix/xyz/some.html respectively. Anything that matches the pattern /<something>/<file>.html.
$0 is a backreference that contains the URL-path that is matched by the RewriteRule pattern.
Note that this is not "url-rewriting" since you stated in comments that you do not want to "hide" the /newprefix part of the URL from your users. An external redirect is therefore the only solution if you are intending to use Apache / mod_rewrite (as tagged).
Aside: This is not particularly good for SEO, your users or your server since the user is externally redirected everytime they click one of your links, potentially doubling the number of requests that hit your server and slowing your users.

Redirect Rewrite for Joomla Root Domain Only?

I recently migrated an existing site between two domain names. I created 301 rewrite rules for all existing pages to their new, corresponding links and that appears to be functioning correctly.
Since I individually mapped the link rewrites I didn't have the need to apply a broad redirect all visitors. The issue I am experiencing is that I have not been able to successfully 301 redirect the root (home/index) only. I have tried redirecting / as well as /index.php, but those rules appear to interfere with my other rewrite rules. I'm guessing this has something to do with Joomla's core SEF rewrite rules, but I'm not sure.
Example:
Let's assume this is one of my redirects:
Redirect 301 /oldlink http://www.example.net/newlink
But someone somehow visits /oldlink25 (which doesn't exist and never has). The current setup where I am redirecting /index.php, which is my attempt to redirect the root only, will still redirect this visitor to the new site root. I'd prefer to 404 that visitor, and the old link, at the old domain instead.
Long story short, unless someone visits a link that has an individually declared 301 in the htaccess, how can I redirect visitors that hit the root only and not every visitor that hits any random link without a corresponding rewrite rule?

A .htaccess trick to allow only one page from sub-domain to be opened

here is the situation and I need a little help with it:
I have a domain xxxxx.com and a sub-domain upload.xxxxx.com both lead to directory /www/xxxxx.com/, but I am using the 2nd domain for file uploading since I am using Cloudflare's services and with the 2nd domain there are no performance optimization and troubles with the upload (I've created cookies that are valid for both domains).
But my point is because I am using only 1 file for that 2nd domain and it upload.xxxxx.com/upload.php the same file exist under xxxxx.com/upload.php - I am not really good in .htaccess, so how can I make the only page that could be opened from this subdomain to be upload.php and all other to redirect to the main domain ?
You can use this rule as first rule in your DOCUMENT_ROOT/.htaccess file:
RewriteEngine On
RewriteCond %{HTTP_HOST} !^upload\. [NC]
RewriteRule ^upload\.php$ /? [NC,L,R]
What I did in the end I think it's good for the users who are interested to know:
I added a cross domain support for the cookies and added additional domain, upload.*
I left the upload.* domain only on redirect rules via Cloudflare (no optimization)
Redirected the uploading form to the upload.xxxxx.com/upload.php
Made the cookie cross domain based on login so when you login on the main site you're logged in on the upload.* one too.
When you submit the form it uploads really fast via upload.* and redirects back to the preview page on the original domain.
It handles the errors via cookies from the upload.* to the normal domain
Hope this helps :)

Multiple Domains to Display Content from Landing Pages on Another Domain

We have created a bunch of landing pages on a Joomla CMS system, such that the URL for each landing page is www.domain.com/page1.html and www.domain.com/page2.html, and so on. Of course the page1.html isn't really an HTML file it is a dynamic CMS page, just rewritten with htaccess.
The goal is to have one of our other domains, something like www.uniquedomain1.com show the content of www.domain.com/page1.html. Or, another domain like www.uniquedomain2.html show the content of www.domain.com/page2.html.
This needs to be search engine friendly so we can't use URL masking. Also we can't use HTACCESS redirects as this actually changes the URL in the browser bar. Need to keep the www.uniquedomain1.com URL in the browser bar.
Tried Apache VirtualHost options without any luck. You can park in a directory but not from a URL.
Ended up parking the domains on one folder, and then creating a PHP script to detect the domain host and then use CURL to query the correct url and deliver content. This whole thing seems ridiculously over complicated, and of course CURL isn't the best option, but it is all we could get to work.
Any thoughts on how to do this, or a better solution?
You can use HTACCESS redirect rules to do it without performing a redirect.
Change the html file names to be the domain name of the desired domain like domain.tld and do something like this in an .htaccess file
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(?:www\.)?([a-z0-9\.-]+\.[a-z]+) [NC]
RewriteRule ^$ /%1.html [L]
A quick test of this worked for two of my test (sub)domains test.domain.tld and test2.domain.tld. Both properly redirected to files with the names test.domain.tld.html and test2.domain.tld.html without modifying the URL.
You could also just use your PHP wrapper script to grab the content of each of the miscellaneous html files and output them.
If you renamed all of your HTML files (as in my previous suggested answer) to be domain.tld.html you could do it fairly easily. Something might look like:
<?php
require($_SERVER['SERVER_NAME'] .'.html');

Understanding difference between redirect and rewrite .htaccess

I'd like to understand the difference between redirecting and rewriting a URL using .htaccess.
So here's an example: Say I have a link like www.abc.com/ index.php?page=product_types&cat=88 (call this the "original" url)
But when the user types in abc.com/shoes (let's call this the "desired" url), they need to see the contents of the above link. To accomplish this, I would do this:
Options +FollowSymLinks
RewriteEngine on
RewriteBase /
RewriteRule ^(.*)shoes(.*)$ index.php?page=product_types&cat=88
Nothing wrong with this code and it does the trick. However, if I type in the original url in the address bar, the content comes up, but the url does not change. So it remains as www.abc.com/index.php?page=product_types&cat=88
But what if I wanted the desired url (/shoes) to show up in the address bar if I typed in www.abc.com/ index.php?page=product_types&cat=88? How would this be accomplished using .htaccess? Am I running into a potential loop?
Some of the explanation can be found here: https://stackoverflow.com/a/11711948/851273
The gist is that a rewrite happens solely on the server, the client (browser) is blind to it. The browser sends a request and gets content, it is none the wiser to what happened on the server in order to serve the request.
A redirect is a server response to a request, that tells the client (browser) to submit a new request. The browser asks for a url, this url is what's in the location bar, the server gets that request and responds with a redirect, the browser gets the response and loads the URL in the server's response. The URL in the location bar is now the new URL and the browser sends a request for the new URL.
Simply rewriting internally on the server does absolutely nothing to URLs in the wild. If google or reddit or whatever site has a link to www.abc.com/index.php?page=product_types&cat=88, your internal server rewrite rule does absolutely nothing to that, nor to anyone who clicks on that link, or any client that happens to request that URL for any reason whatsoever. All the rewrite rule does is internally change something that contains shoes to /index.php?page=product_types&cat=88 within the server.
If you want make it so a request is made for the index.php page with all of the query strings, you can tell the client (browser) to redirect to the nicer looking URL. You need to be careful because rewrite rules loop and your redirect will be internally rewritten which will cause a redirect which will be internally rewritten, etc.. causing a loop and will throw a 500 Server Error. So you can match specifically to the request itself:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php\?page=product_types&cat=88
RewriteRule ^/?index.php$ /shoes [L,R=301]
This should only be used to make it so links in the wild get pointed to the right place. You must ensure that your content is generating the correct links. That means everything on your site is using the /shoes link instead of the /index.php?page=product_types&cat=88 link.