Пример #1
0
 public static function download($fileData, $downloadId, $currentLink, $type = 0)
 {
     $app = JFactory::getApplication();
     $params = $app->getParams();
     $directLink = $fileData['directlink'];
     // Direct Link 0 or 1
     $externalLink = $fileData['externallink'];
     $absOrRelFile = $fileData['file'];
     // Relative Path or Absolute Path
     // Type = 1 - Token - unique download link - cannot be direct
     if ($type == 1) {
         $directLink = 0;
     }
     // NO FILES FOUND (abs file)
     $error = false;
     $error = preg_match("/COM_PHOCADOWNLOAD_ERROR/i", $absOrRelFile);
     if ($error) {
         $msg = JText::_('COM_PHOCADOWNLOAD_ERROR_WHILE_DOWNLOADING_FILE') . ' ' . JText::_($absOrRelFile);
         $app->redirect(JRoute::_($currentLink), $msg);
     } else {
         // Get extensions
         $extension = JFile::getExt(strtolower($absOrRelFile));
         $aft = $params->get('allowed_file_types_download', PhocaDownloadSettings::getDefaultAllowedMimeTypesDownload());
         $dft = $params->get('disallowed_file_types_download', '');
         // Get Mime from params ( ext --> mime)
         $allowedMimeType = PhocaDownloadFile::getMimeType($extension, $aft);
         $disallowedMimeType = PhocaDownloadFile::getMimeType($extension, $dft);
         // NO MIME FOUND
         $errorAllowed = false;
         // !!! IF YES - Disallow Downloading
         $errorDisallowed = false;
         // !!! IF YES - Allow Downloading
         $errorAllowed = preg_match("/PhocaError/i", $allowedMimeType);
         $errorDisallowed = preg_match("/PhocaError/i", $disallowedMimeType);
         $ignoreDownloadCheck = $params->get('ignore_file_types_check', 2);
         if ($ignoreDownloadCheck == 3 || $ignoreDownloadCheck == 4 || $ignoreDownloadCheck == 5) {
             $errorAllowed = false;
             $errorDisallowed = true;
         }
         if ($errorAllowed) {
             $msg = JText::_('COM_PHOCADOWNLOAD_WARNFILETYPE_DOWNLOAD');
             $app->redirect(JRoute::_($currentLink), $msg);
         } else {
             if (!$errorDisallowed) {
                 $msg = JText::_('COM_PHOCADOWNLOAD_WARNFILETYPE_DISALLOWED_DOWNLOAD');
                 $app->redirect(JRoute::_($currentLink), $msg);
             } else {
                 if ($directLink == 1) {
                     // Direct Link on the same server
                     $fileWithoutPath = basename($absOrRelFile);
                     $addHit = self::hit($downloadId);
                     if ($type == 1) {
                         self::hitToken($downloadId);
                     }
                     if ((int) $params->get('send_mail_download', 0) > 0) {
                         PhocaDownloadMail::sendMail((int) $params->get('send_mail_download', 0), $fileWithoutPath, 1);
                     }
                     // USER Statistics
                     if ((int) $params->get('enable_user_statistics', 1) == 1) {
                         $addUserStat = PhocaDownloadStat::createUserStatEntry($downloadId);
                     }
                     PhocaDownloadLog::log($downloadId, 1);
                     $app->redirect($absOrRelFile);
                     exit;
                 } else {
                     if ($directLink == 0 && $externalLink != '') {
                         // External Link but with redirect
                         // In case there is directLink the external Link does not go this way but directly to the external URL
                         $addHit = self::hit($downloadId);
                         if ($type == 1) {
                             self::hitToken($downloadId);
                         }
                         if ((int) $params->get('send_mail_download', 0) > 0) {
                             PhocaDownloadMail::sendMail((int) $params->get('send_mail_download', 0), $externalLink, 1);
                         }
                         // USER Statistics
                         if ((int) $params->get('enable_user_statistics', 1) == 1) {
                             $addUserStat = PhocaDownloadStat::createUserStatEntry($downloadId);
                         }
                         PhocaDownloadLog::log($downloadId, 1);
                         $app->redirect($externalLink);
                         exit;
                     } else {
                         // Clears file status cache
                         clearstatcache();
                         $fileWithoutPath = basename($absOrRelFile);
                         $fileSize = filesize($absOrRelFile);
                         $mimeType = '';
                         $mimeType = $allowedMimeType;
                         // HIT Statistics
                         $addHit = self::hit($downloadId);
                         if ($type == 1) {
                             self::hitToken($downloadId);
                         }
                         if ((int) $params->get('send_mail_download', 0) > 0) {
                             PhocaDownloadMail::sendMail((int) $params->get('send_mail_download', 0), $fileWithoutPath, 1);
                         }
                         // USER Statistics
                         if ((int) $params->get('enable_user_statistics', 1) == 1) {
                             $addUserStat = PhocaDownloadStat::createUserStatEntry($downloadId);
                         }
                         PhocaDownloadLog::log($downloadId, 1);
                         if ($fileSize == 0) {
                             die(JText::_('COM_PHOCADOWNLOAD_FILE_SIZE_EMPTY'));
                             exit;
                         }
                         // Clean the output buffer
                         ob_end_clean();
                         // test for protocol and set the appropriate headers
                         jimport('joomla.environment.uri');
                         $_tmp_uri = JURI::getInstance(JURI::current());
                         $_tmp_protocol = $_tmp_uri->getScheme();
                         if ($_tmp_protocol == "https") {
                             // SSL Support
                             header('Cache-Control: private, max-age=0, must-revalidate, no-store');
                         } else {
                             header("Cache-Control: public, must-revalidate");
                             header('Cache-Control: pre-check=0, post-check=0, max-age=0');
                             header("Pragma: no-cache");
                             header("Expires: 0");
                         }
                         /* end if protocol https */
                         header("Content-Description: File Transfer");
                         header("Expires: Sat, 30 Dec 1990 07:07:07 GMT");
                         header("Accept-Ranges: bytes");
                         // HTTP Range
                         /*	$httpRange = 0;
                         			if(isset($_SERVER['HTTP_RANGE'])) {
                         				list($a, $httpRange) = explode('=', $_SERVER['HTTP_RANGE']);
                         				str_replace($httpRange, '-', $httpRange);
                         				$newFileSize	= $fileSize - 1;
                         				$newFileSizeHR	= $fileSize - $httpRange;
                         				header("HTTP/1.1 206 Partial Content");
                         				header("Content-Length: ".(string)$newFileSizeHR);
                         				header("Content-Range: bytes ".$httpRange . $newFileSize .'/'. $fileSize);
                         			} else {
                         				$newFileSize	= $fileSize - 1;
                         				header("Content-Length: ".(string)$fileSize);
                         				header("Content-Range: bytes 0-".$newFileSize . '/'.$fileSize);
                         			}
                         			header("Content-Type: " . (string)$mimeType);
                         			header('Content-Disposition: attachment; filename="'.$fileWithoutPath.'"');
                         			header("Content-Transfer-Encoding: binary\n");*/
                         // Modified by Rene
                         // HTTP Range - see RFC2616 for more informations (http://www.ietf.org/rfc/rfc2616.txt)
                         $httpRange = 0;
                         $newFileSize = $fileSize - 1;
                         // Default values! Will be overridden if a valid range header field was detected!
                         $resultLenght = (string) $fileSize;
                         $resultRange = "0-" . $newFileSize;
                         // We support requests for a single range only.
                         // So we check if we have a range field. If yes ensure that it is a valid one.
                         // If it is not valid we ignore it and sending the whole file.
                         if (isset($_SERVER['HTTP_RANGE']) && preg_match('%^bytes=\\d*\\-\\d*$%', $_SERVER['HTTP_RANGE'])) {
                             // Let's take the right side
                             list($a, $httpRange) = explode('=', $_SERVER['HTTP_RANGE']);
                             // and get the two values (as strings!)
                             $httpRange = explode('-', $httpRange);
                             // Check if we have values! If not we have nothing to do!
                             if (!empty($httpRange[0]) || !empty($httpRange[1])) {
                                 // We need the new content length ...
                                 $resultLenght = $fileSize - $httpRange[0] - $httpRange[1];
                                 // ... and we can add the 206 Status.
                                 header("HTTP/1.1 206 Partial Content");
                                 // Now we need the content-range, so we have to build it depending on the given range!
                                 // ex.: -500 -> the last 500 bytes
                                 if (empty($httpRange[0])) {
                                     $resultRange = $resultLenght . '-' . $newFileSize;
                                 } elseif (empty($httpRange[1])) {
                                     $resultRange = $httpRange[0] . '-' . $newFileSize;
                                 } else {
                                     $resultRange = $httpRange[0] . '-' . $httpRange[1];
                                 }
                                 //header("Content-Range: bytes ".$httpRange . $newFileSize .'/'. $fileSize);
                             }
                         }
                         header("Content-Length: " . $resultLenght);
                         header("Content-Range: bytes " . $resultRange . '/' . $fileSize);
                         header("Content-Type: " . (string) $mimeType);
                         header('Content-Disposition: attachment; filename="' . $fileWithoutPath . '"');
                         header("Content-Transfer-Encoding: binary\n");
                         // TEST TEMP SOLUTION
                         ob_end_clean();
                         //@readfile($absOrRelFile);
                         // Try to deliver in chunks
                         @set_time_limit(0);
                         $fp = @fopen($absOrRelFile, 'rb');
                         if ($fp !== false) {
                             while (!feof($fp)) {
                                 echo fread($fp, 8192);
                             }
                             fclose($fp);
                         } else {
                             @readfile($absOrRelFile);
                         }
                         flush();
                         exit;
                         /*
                         http://www.phoca.cz/forum/viewtopic.php?f=31&t=11811
                         
                         $fp = @fopen($absOrRelFile, 'rb');
                         // HTTP Range - see RFC2616 for more informations (http://www.ietf.org/rfc/rfc2616.txt)
                         $newFileSize = $fileSize - 1;
                         // Default values! Will be overridden if a valid range header field was detected!
                         $rangeStart = 0;
                         $rangeEnd = 0;
                         $resultLength = $fileSize;
                         // We support requests for a single range only.
                         // So we check if we have a range field. If yes ensure that it is a valid one.
                         // If it is not valid we ignore it and sending the whole file.
                         if ($fp && isset($_SERVER['HTTP_RANGE']) && preg_match('%^bytes=\d*\-\d*$%', $_SERVER['HTTP_RANGE'])) {
                         	// Let's take the right side
                         	list($a, $httpRange) = explode('=', $_SERVER['HTTP_RANGE']);
                         	// and get the two values (as strings!)
                         	$httpRange = explode('-', $httpRange);
                         	// Check if we have values! If not we have nothing to do!
                         	if (sizeof($httpRange) == 2) {
                         		// Explictly convert to int
                         		$rangeStart = intval($httpRange[0]);
                         		$rangeEnd = intval($httpRange[1]); // Allowed to be empty == 0
                         		if (($rangeStart || $rangeEnd) // something actually set?
                         		&& $rangeStart < $fileSize // must be smaller
                         		&& $rangeEnd < $fileSize // must be smaller
                         		&& (!$rangeEnd || $rangeEnd > $rangeStart) // end > start, if end is set
                         		) {
                         			header("HTTP/1.1 206 Partial Content");
                         			if (!$rangeEnd) {
                         				$resultLength = $fileSize - $rangeStart;
                         				$range = $rangeStart . "-" . ($fileSize - 1) . "/" . $fileSize;
                         			} else {
                         				$resultLength = ($rangeEnd - $rangeStart 1);
                         				$range = $rangeStart . "-" . $rangeEnd . "/" . $fileSize;
                         			}
                         			header("Content-Range: bytes " . $range);
                         		} else {
                         			// Didn't validate: kill
                         			$rangeStart = 0;
                         			$rangeEnd = 0;
                         		}
                         	}
                         }
                         
                         header("Content-Length: ". $resultLength);
                         header("Content-Type: " . (string)$mimeType);
                         header('Content-Disposition: attachment; filename="'.$fileWithoutPath.'"');
                         header("Content-Transfer-Encoding: binary\n");
                         @@ -211,13 +198,25 @@ class PhocaDownloadAccessFront
                         
                         // Try to deliver in chunks
                         @set_time_limit(0);
                         if ($fp !== false) {
                         	if ($rangeStart) {
                         		// Need to pass only part of the file, starting at $rangeStart
                         		fseek($fp, $rangeStart, SEEK_SET);
                         	}
                         	// If $rangeEnd is open ended (0, whole file from $rangeStart) try fpassthru,
                         	// else send in small chunks
                         	if ($rangeEnd || @!fpassthru($fp)) {
                         		while ($resultLength > 0 && !feof($fp)) {
                         			// 4 * 1460 (default MSS with ethernet 1500 MTU)
                         			// This is optimized for network packets, not disk access
                         			$bytes = min(5840, $resultLength);
                         			echo fread($fp, $bytes);
                         			$resultLength = $resultLength - $bytes;
                         		}
                         	}
                         	fclose($fp);
                         } else {
                         	// Ranges are disabled at this point and were never set up
                         	@readfile($absOrRelFile);
                         }
                         flush();
                         exit;
                         */
                     }
                 }
             }
         }
     }
     return false;
 }
Пример #2
0
	public static function canUpload( $file, &$err, $manager = '', $frontEnd = 0, $chunkEnabled = 0, $realSize = 0) {
		
		$paramsC 	= JComponentHelper::getParams( 'com_phocadownload' );
		
		if ($frontEnd == 1) {
			$aft = $paramsC->get( 'allowed_file_types_upload', PhocaDownloadSettings::getDefaultAllowedMimeTypesUpload() );
			$dft = $paramsC->get( 'disallowed_file_types_upload', '' );
			$allowedMimeType 	= PhocaDownloadFile::getMimeTypeString($aft);
			$disallowedMimeType = PhocaDownloadFile::getMimeTypeString($dft);
			
			$ignoreUploadCh = 0;
			$ignoreUploadCheck = $params->get( 'ignore_file_types_check', 2 );
			if ($ignoreUploadCheck == 1 || $ignoreUploadCheck == 4 ) {
				$ignoreUploadCh = 1;
			}
			
		} else {
		
			$aft = $paramsC->get( 'allowed_file_types_download', PhocaDownloadSettings::getDefaultAllowedMimeTypesDownload() );
			$dft = $paramsC->get( 'disallowed_file_types_download', '' );
			$allowedMimeType 	= PhocaDownloadFile::getMimeTypeString($aft);
			$disallowedMimeType = PhocaDownloadFile::getMimeTypeString($dft);
			
			$ignoreUploadCh = 0;
			$ignoreUploadCheck = $paramsC->get( 'ignore_file_types_check', 2 );
			if ($ignoreUploadCheck == 5 || $ignoreUploadCheck == 5 ) {
				$ignoreUploadCh = 1;
			}
		}
		
		
		
		$paramsL = array();
		$group = PhocaDownloadSettings::getManagerGroup($manager);
		if ($group['f'] == 2) {
			$paramsL['upload_extensions'] 	= 'gif,jpg,png,jpeg';
			$paramsL['image_extensions'] 	= 'gif,jpg,png,jpeg';
			$paramsL['upload_mime']			= 'image/jpeg,image/gif,image/png';
			$paramsL['upload_mime_illegal']	='application/x-shockwave-flash,application/msword,application/excel,application/pdf,application/powerpoint,text/plain,application/x-zip,text/html';
			$paramsL['upload_ext_illegal']	= $disallowedMimeType['ext'];
		} else {
			$paramsL['upload_extensions'] 	= $allowedMimeType['ext'];
			$paramsL['image_extensions'] 	= 'bmp,gif,jpg,png,jpeg';
			$paramsL['upload_mime']			= $allowedMimeType['mime'];
			$paramsL['upload_mime_illegal']	= $disallowedMimeType['mime'];
			$paramsL['upload_ext_illegal']	= $disallowedMimeType['ext'];
		}
		

		// The file doesn't exist
		if(empty($file['name'])) {
			$err = 'COM_PHOCADOWNLOAD_WARNING_INPUT_FILE_UPLOAD';
			return false;
		}
		// Not safe file
		jimport('joomla.filesystem.file');
		if ($file['name'] !== JFile::makesafe($file['name'])) {
			$err = 'COM_PHOCADOWNLOAD_WARNFILENAME';
			return false;
		}

		$format 		= strtolower(JFile::getExt($file['name']));
		if ($ignoreUploadCh == 1) {
		
		} else {
		
			$allowable 		= explode( ',', $paramsL['upload_extensions']);
			$notAllowable 	= explode( ',', $paramsL['upload_ext_illegal']);
			if(in_array($format, $notAllowable)) {
				$err = 'COM_PHOCADOWNLOAD_WARNFILETYPE_DISALLOWED';
				return false;
			}
			
			
			//if (!in_array($format, $allowable)) {
			if ($format == '' || $format == false || (!in_array($format, $allowable))) {
				$err = 'COM_PHOCADOWNLOAD_WARNFILETYPE_NOT_ALLOWED';
				return false;
			}
		}

		
		// Max size of image
		// If chunk method is used, we need to get computed size
		$maxSize = $paramsC->get( 'upload_maxsize', 3145728 );
		if ((int)$frontEnd > 0) {
			$maxSize = $paramsC->get( 'user_file_upload_size', 3145728 );
		} else {
			$maxSize = $paramsC->get( 'upload_maxsize', 3145728 );
		}
		
		if ($chunkEnabled == 1) {
			if ((int)$maxSize > 0 && (int)$realSize > (int)$maxSize) {
				$err = 'COM_PHOCADOWNLOAD_WARNFILETOOLARGE';
				
				return false;
			}
		} else {
			if ((int)$maxSize > 0 && (int)$file['size'] > (int)$maxSize) {
				$err = 'COM_PHOCADOWNLOAD_WARNFILETOOLARGE';
				
				return false;
			}
		}
		
		
		// User (only in ucp) - Check the size of all files by users
		if ($frontEnd == 2) {
			$user 				= JFactory::getUser();
			$maxUserUploadSize 	= (int)$paramsC->get( 'user_files_max_size', 20971520 );
			$maxUserUploadCount	= (int)$paramsC->get( 'user_files_max_count', 5 );
			$allFile	= PhocaDownloadUser:: getUserFileInfo($file, $user->id);
			
			if ($chunkEnabled == 1) {
				$fileSize = $realSize;
			} else {
				$fileSize = $file['size'];
			}
			
			if ((int)$maxUserUploadSize > 0 && (int) $allFile['size'] > $maxUserUploadSize) {
				$err = JText::_('COM_PHOCADOWNLOAD_WARNUSERFILESTOOLARGE');	
				return false;
			}
				
			if ((int) $allFile['count'] > $maxUserUploadCount) {
				$err = JText::_('COM_PHOCADOWNLOAD_WARNUSERFILESTOOMUCH');	
				return false;
			}
		}
		
		
		

		// Image check
		$imginfo	= null;
		$images		= explode( ',', $paramsL['image_extensions']);
		
		if(in_array($format, $images)) { // if its an image run it through getimagesize
			
			$group = PhocaDownloadSettings::getManagerGroup($manager);
			if($group['i'] == 1) {
				if ($chunkEnabled != 1) {
					if(($imginfo = getimagesize($file['tmp_name'])) === FALSE) {
						$err = 'COM_PHOCADOWNLOAD_WARNINVALIDIMG';
						$err = $imginfo[0];
						return false;
					}
				}
			}
		} else if(!in_array($format, $images)) { // if its not an image...and we're not ignoring it
			$allowed_mime = explode(',', $paramsL['upload_mime']);
			$illegal_mime = explode(',', $paramsL['upload_mime_illegal']);
			if(function_exists('finfo_open')) {// We have fileinfo
				$finfo	= finfo_open(FILEINFO_MIME);
				$type	= finfo_file($finfo, $file['tmp_name']);
				if(strlen($type) && !in_array($type, $allowed_mime) && in_array($type, $illegal_mime)) {
					$err = 'COM_PHOCADOWNLOAD_WARNINVALIDMIME';
					return false;
				}
				finfo_close($finfo);
			} else if(function_exists('mime_content_type')) { // we have mime magic
				$type = mime_content_type($file['tmp_name']);
				if(strlen($type) && !in_array($type, $allowed_mime) && in_array($type, $illegal_mime)) {
					$err = 'COM_PHOCADOWNLOAD_WARNINVALIDMIME';
					return false;
				}
			}
		}
			
		// XSS Check
		$xss_check =  JFile::read($file['tmp_name'],false,256);
		$html_tags = PhocaDownloadSettings::getHTMLTagsUpload();
		foreach($html_tags as $tag) { // A tag is '<tagname ', so we need to add < and a space or '<tagname>'
			if(stristr($xss_check, '<'.$tag.' ') || stristr($xss_check, '<'.$tag.'>')) {
				$err = 'COM_PHOCADOWNLOAD_WARNIEXSS';
				return false;
			}
		}
		
		return true;
	}