Click Fraud Protection
PHP related blog, freelancer to hire!

Magento downloadable are not supporting https (SSL) links

Google right now is pushing for websites to delivered over SSL, so no surprise that Magento merchants who sell digital goods, want to deliver files over HTTPS as well.

Looks like a simple task – make file available then in your downloadables section – put https:// links – Magento accepts it – so no issues there.

What a surprise – when customer already paid and he is ready to download your precious content – he get’s error

“An error occurred while getting the requested content. Please contact the store owner.” – what? File is available, link is ok in magento – so why?

You can try to google for it – http://magento.stackexchange.com/questions/5013/why-only-http-links-are-supported-as-source-for-downloadable-products

Answer is in poor coding in Mage_Downloadable_Helper_Download

protected function _getHandle()
{
if (!$this->_resourceFile) {
Mage::throwException(Mage::helper('downloadable')->__('Please set resource file and link type.'));
}
if (is_null($this->_handle)) {
if ($this->_linkType == self::LINK_TYPE_URL) {
$port = 80;
/**
* Validate URL
*/
$urlProp = parse_url($this->_resourceFile);
if (!isset($urlProp['scheme']) || strtolower($urlProp['scheme'] != 'http')) {
Mage::throwException(Mage::helper('downloadable')->__('Invalid download URL scheme.'));
}
if (!isset($urlProp['host'])) {
Mage::throwException(Mage::helper('downloadable')->__('Invalid download URL host.'));
}
$hostname = $urlProp['host'];

port 80 hardcoded, scheme allows only http, also actual implementation of sockets further does not support SSL. So why poor customer has to be notified about all that when he already paid and he is trying to download the file? If magento didn’t want to support SSL, they should not allow those links in admin first place.

 

Don’t panic – this is all fixable – create a override class and fix it.

 

/**
* Retrieve Resource file handle (socket, file pointer etc)
*
* @return resource
*/
protected function _getHandle()
{
if (!$this->_resourceFile) {
Mage::throwException(Mage::helper('downloadable')->__('Please set resource file and link type.'));
}
if (is_null($this->_handle)) {
if ($this->_linkType == self::LINK_TYPE_URL) {
/**
* Validate URL
*/
$urlProp = parse_url($this->_resourceFile);
if (!isset($urlProp['scheme'])
|| (strtolower($urlProp['scheme']) != 'http' && strtolower($urlProp['scheme']) != 'https')
) {
Mage::throwException(Mage::helper('downloadable')->__('Invalid download URL scheme.'));
}
if (!isset($urlProp['host'])) {
Mage::throwException(Mage::helper('downloadable')->__('Invalid download URL host.'));
}
switch ($urlProp['scheme']) {
case 'https':
$scheme = 'ssl://';
$port = 443;
break;
case 'http':
default:
$scheme = '';
$port = 80;
}
$hostname = $scheme . $urlProp['host'];
if (isset($urlProp['port'])) {
$port = (int)$urlProp['port'];
}
$path = '/';
if (isset($urlProp['path'])) {
$path = $urlProp['path'];
}
$query = '';
if (isset($urlProp['query'])) {
$query = '?' . $urlProp['query'];
}
try {
$this->_handle = fsockopen($hostname, $port, $errno, $errstr);
}
catch (Exception $e) {
throw $e;
}
if ($this->_handle === false) {
Mage::throwException(Mage::helper('downloadable')->__('Cannot connect to remote host, error: %s.', $errstr));
}
$headers = 'GET ' . $path . $query . ' HTTP/1.1' . "\r\n"
. 'Host: ' . $urlProp['host'] . "\r\n"
. 'User-Agent: Magento ver/' . Mage::getVersion() . "\r\n"
. 'Connection: close' . "\r\n"
. "\r\n";
fwrite($this->_handle, $headers);
while (!feof($this->_handle)) {
$str = fgets($this->_handle, 1024);
var_dump($str);
if ($str == "\r\n") {
break;
}
$match = array();
if (preg_match('#^([^:]+): (.*)\s+$#', $str, $match)) {
$k = strtolower($match[1]);
if ($k == 'set-cookie') {
continue;
}
else {
$this->_urlHeaders[$k] = trim($match[2]);
}
}
elseif (preg_match('#^HTTP/[0-9\.]+ (\d+) (.*)\s$#', $str, $match)) {
$this->_urlHeaders['code'] = $match[1];
$this->_urlHeaders['code-string'] = trim($match[2]);
}
}
if (!isset($this->_urlHeaders['code']) || $this->_urlHeaders['code'] != 200) {
Mage::throwException(Mage::helper('downloadable')->__('An error occurred while getting the requested content. Please contact the store owner.'));
}
}
elseif ($this->_linkType == self::LINK_TYPE_FILE) {
$this->_handle = new Varien_Io_File();
if (!is_file($this->_resourceFile)) {
Mage::helper('core/file_storage_database')->saveFileToFilesystem($this->_resourceFile);
}
$this->_handle->open(array('path'=>Mage::getBaseDir('var')));
if (!$this->_handle->fileExists($this->_resourceFile, true)) {
Mage::throwException(Mage::helper('downloadable')->__('The file does not exist.'));
}
$this->_handle->streamOpen($this->_resourceFile, 'r');
}
else {
Mage::throwException(Mage::helper('downloadable')->__('Invalid download link type.'));
}
}
return $this->_handle;
}

Leave a Reply