Jump to content

WHMCS in subdomain & wildcard SSL results in host name duplicated in links


wescleveland

Recommended Posts

I have WHMCS installed in a subdomain (clients.example.com) on a shared hosting account using cPanel and am using a wildcard SSL which (under cPanal) always ends up serving the page from the main directory. Consequently, I have a .htaccess rewrite rule redirecting *.example.com to the appropriate directory (in this example, clients.example.com):

 

RewriteCond %{HTTPS} =on
RewriteCond %{REQUEST_URI} !^/.+\.example.com/
RewriteCond %{HTTP_HOST} ^([0-9a-zA-Z]+.example.com)
RewriteRule ^(.*)$ /%1/$1 [NC,L,NS]

 

Many of the templates generate links using "{$smarty.server.PHP_SELF}" which, I assume, comes from _SERVER["PHP_SELF"]. Herein lies my problem. The value for _SERVER["PHP_SELF"] is different for the non-redirected (http:) vs. the redirected (https:) executions. For https:, _SERVER["PHP_SELF"] contains the subdomain's host name at the beginning while the http: version does not.

 

As an example, to add a product, I go to "http(s)://clients.example.com/cart.php?...". The shopping cart form is created with

action="{$smarty.server.PHP_SELF}?a=confproduct&i={$i}"

. The end result is the http: version of the form contains "action='/cart.php?...'" while the https: version of the form contains "action='/clients.example.com/cart.php?...'". When the client clicks on "Add to cart", the http: version correctly maps to "http://clients.example.com/cart.php?...". But, the https: version maps to "https://clients.example.com/clients.example.com/cart.php?..." instead of "https://clients.example.com/cart.php?...".

 

I know the different values in _SERVER["PHP_SELF"] are a result of the .htaccess rewrite (which I know of no way around in this shared hosting environment). So, my dilemma is how do I correct these links?

 

I was thinking if there was an exit that would allow me to change the output html before it was sent, I could replace all occurrences of "/clients.example.com/" with "/" (or further restrict it to replace "action='/clients.example.com/" with "action='/"). But, I have no clue how I might intercept WHMCS html output before it gets served back to the client.

 

Another approach might be to find a way to change the value of "{$smarty.server.PHP_SELF}" to not include the subdomain's host name. Again, I have no idea how I might do this globally.

 

Does anyone have any thoughts on how I might correct this without rewriting all of the templates?

 

Thanks in advance.

Link to comment
Share on other sites

In case anyone's interested or runs into a similar problem, here's my solution (appears to be working so far):

 

First, I created the following script called _https.php and put it in the root WHMCS directory (clients.example.com):

 

<?php
if ( 'on' != $_SERVER[ 'HTTPS' ] ) die();

$sub_DOCUMENT_ROOT = $_SERVER[ 'DOCUMENT_ROOT' ] . DIRECTORY_SEPARATOR . $_SERVER[ 'HTTP_HOST' ];
$sub_SCRIPT_NAME = $_SERVER["REDIRECT_URL"];
$sub_SCRIPT_FILE_NAME = $sub_DOCUMENT_ROOT . $sub_SCRIPT_NAME;
$sub_PHP_SELF = $sub_SCRIPT_NAME;
$sub_SERVER_ADMIN = substr( $_SERVER["SERVER_ADMIN"], 0, strpos( $_SERVER["SERVER_ADMIN"], '@' ) + 1 ) . $_SERVER["SERVER_NAME"];

//	Determine desired scriptname
if ( file_exists( $sub_SCRIPT_FILE_NAME ) )
{
$_SERVER["DOCUMENT_ROOT"] = $sub_DOCUMENT_ROOT;
$_SERVER["SCRIPT_FILENAME"] = $sub_SCRIPT_FILE_NAME;
$_SERVER["SCRIPT_NAME"] = $sub_SCRIPT_NAME;
$_SERVER["PHP_SELF"] = $sub_PHP_SELF;
$_SERVER["SERVER_ADMIN"] = $sub_SERVER_ADMIN;
$_ENV["DOCUMENT_ROOT"] = $sub_DOCUMENT_ROOT;
$_ENV["SCRIPT_FILENAME"] = $sub_SCRIPT_FILE_NAME;
$_ENV["SCRIPT_NAME"] = $sub_SCRIPT_NAME;
$_ENV["SERVER_ADMIN"] = $sub_SERVER_ADMIN;
include( $sub_SCRIPT_FILE_NAME );
exit;
}
else exit( header( 'Location: http'.('on'==$_SERVER['HTTPS'] ? 's': '').'://'.$_SERVER[ 'HTTP_HOST' ].'/') );
?>

 

Then I modified .htaccess to execute this script for any clients.example.com/*.php request:

 

RewriteCond %{HTTPS} =on
RewriteCond %{REQUEST_URI} !^/clients.example.com/
RewriteCond %{HTTP_HOST} ^clients.example.com
RewriteCond %{REQUEST_URI} ^/([0-9a-zA-Z_\-\.]*/)*[0-9a-zA-Z_\-\.]+\.php
RewriteRule ^(.*)$ /clients.example.com/_https.php [NC,L,NS]

 

I tried doing this with _https.php in the account's root directory instead of in clients.example.com, but some of the WHMCS admin functions were failing - I think because the php DOCUMENT_ROOT global variable was still pointing to the account's root.

 

That's it.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use & Guidelines and understand your posts will initially be pre-moderated