Перейти к контенту

Докачка файлов и ограничение скорости.


Рекомендуемые сообщения

Очередная модификация / улучшение.

 

post-84588-0-89005800-1289482016_thumb.pngpost-84588-0-86255700-1289482017_thumb.pngpost-84588-0-78349200-1289482018_thumb.png

 

При остановки закачки файла или обрыве связи с интернетом приходилось скачивать файл с самого начала.

А если файлик весит не мало?

 

Некоторые улучшения. :)

 

Поправим один файлик, admin/applications/core/sources/classes/attach/class_attach.php

А именно, функцию showAttachment() (замените...)

 

 

	public function showAttachment( $attach_id )
{
	/* INIT */
	$sql_data = array();

	/* Get attach data... */
	$attachment = $this->DB->buildAndFetch( array( 'select' => '*', 'from' => 'attachments', 'where' => 'attach_id='.intval( $attach_id ) ) );

	if( ! $attachment['attach_id'] )
	{
		$this->registry->getClass('output')->showError( 'attach_no_attachment', 10170 );
	}

	/* Load correct plug in... */
	$this->type = $attachment['attach_rel_module'];
	$this->loadAttachmentPlugin();

	/* Get SQL data from plugin */
	$attach = $this->plugin->getAttachmentData( $attach_id );

	/* Got a reply? */
	if( $attach === FALSE OR ! is_array( $attach ) )
	{
		$this->registry->getClass('output')->showError( 'no_permission_to_download', 10171, null, null, 403 );
	}

	/* Got a rel id? */
	if( ! $attach['attach_rel_id'] AND $attach['attach_member_id'] != $this->memberData['member_id'] )
	{
		$this->registry->getClass('output')->showError( 'err_attach_not_attached', 10172, null, null, 403 );
	}

	//-----------------------------------------
	// Reset timeout for large attachments
	//-----------------------------------------

	if ( @function_exists("set_time_limit") == 1 and SAFE_MODE_ON == 0 )
	{
		@set_time_limit( 0 );
	}

	if( is_array( $attach ) AND count( $attach ) )
	{
		/* Got attachment types? */
		if ( ! is_array( $this->registry->cache()->getCache('attachtypes') ) )
		{
			$attachtypes = array();

			$this->DB->build( array( 'select' => 'atype_extension,atype_mimetype', 'from' => 'attachments_type' ) );
			$this->DB->execute();

			while( $r = $this->DB->fetch() )
			{
				$attachtypes[ $r['atype_extension'] ] = $r;
			}

			$this->registry->cache()->updateCacheWithoutSaving( 'attachtypes', $attachtypes );
		}

		/* Show attachment */
		$attach_cache       = $this->registry->cache()->getCache('attachtypes');
		$this->_upload_path = ( isset( $this->plugin->mysettings[ 'upload_dir' ] ) ) ? $this->plugin->mysettings[ 'upload_dir' ] : $this->attach_settings[ 'upload_dir' ];

        $file = $this->_upload_path . "/" . $attach['attach_location'];

		if( file_exists( $file ) and ( $attach_cache[ $attach['attach_ext'] ]['atype_mimetype'] != "" ) )
		{
			$this->settings['download_resume'] = 1;
			$this->settings['download_max_speed'] = 50;

			$propsize = filesize( $file );

			if( $this->settings['download_resume'] ) {		
				if( isset( $_SERVER['HTTP_RANGE'] ) ) {			
					$range = $_SERVER['HTTP_RANGE'];
					$range = str_replace( "bytes=", "", $range );
					$range = str_replace( "-", "", $range );			
				} else {			
					$range = 0;			
				}	
				if( $range > $propsize ) $range = 0;		
			} else {			
				$range = 0;		
			}	

			if( $range ) {
				header( $_SERVER['SERVER_PROTOCOL'] . " 206 Partial Content" );
			} else {
				header( $_SERVER['SERVER_PROTOCOL'] . " 200 OK" );
			}		

			header( "Pragma: public" );
			header( "Expires: 0" );
			header( "Cache-Control:" );
			header( "Cache-Control: public" );
			header( "Content-Description: File Transfer" );
			header( "Content-Type: {$attach_cache[ $attach['attach_ext'] ]['atype_mimetype']}" );

			if( $this->settings['download_resume'] ) header( "Accept-Ranges: bytes" );				

			@ini_set( 'max_execution_time', 0 );
			@set_time_limit();
			@ob_end_clean();				

			if( $this->settings['download_max_speed'] > 0 ) $sleep_time = (8 / $this->settings['download_max_speed']) * 1e6;
			else $sleep_time = 0;		


			/* Update the "hits".. */
			$this->DB->buildAndFetch( array( 'update' => 'attachments', 'set' => "attach_hits=attach_hits+1", 'where' => "attach_id={$attach_id}" ) );

			// 	header( "Content-Type: {$attach_cache[ $attach['attach_ext'] ]['atype_mimetype']}" );
			/* Open and display the file.. */				
			if( $attach['attach_is_image'] )
			{
				header( "Content-Disposition: inline; filename=\"{$attach['attach_file']}\"" );
			}
			else
			{
				header( "Content-Disposition: attachment; filename=\"{$attach['attach_file']}\"" );
				header( "Content-Transfer-Encoding: binary" );	# Fix
			}

			if( !ini_get('zlib.output_compression') OR ini_get('zlib.output_compression') == 'off' )
			{
				//	header( 'Content-Length: ' . (string) ( $propsize ) );
				if( $range ) {					
					header( "Content-Range: bytes {$range}-" . ($propsize - 1) . "/" . $propsize );
					header( "Content-Length: " . ($propsize - $range) );
				} else {					
					header( "Content-Length: " . $propsize );				
				}
			}

			/** @link	http://community.invisionpower.com/tracker/issue-22011-wrong-way-to-handle-attachments-transfer/ */
			if ( function_exists('ob_end_clean') )
			{
				@ob_end_clean();
			}		
			if( function_exists('readfile') && ( (!$this->settings['download_resume']&&!$this->settings['download_max_speed']) OR $attach['attach_is_image'] ) )
			{
				readfile( $file );
			}
			else
			{
				if( $fh = fopen( $file, 'rb' ) )
				{
					fseek( $fh, $range );
					while( ! feof( $fh ) )
					{
						echo fread( $fh, 4096 );
						if ( function_exists('ob_get_length') AND function_exists('ob_flush') AND @ob_get_length() )
						{
							@ob_flush();
						}
						else
						{
							@flush();
						}
						usleep( $sleep_time ); # Fix NEO
					}
					@fclose( $fh );
				}
			}
			exit();
		}
		else
		{
			/* File does not exist.. */
			$this->registry->getClass('output')->showError( 'attach_file_missing', 10173 );
		}
	}
	else
	{
		/*  No permission? */
		$this->registry->getClass('output')->showError( 'no_permission_to_download', 10174, null, null, 403 );
	}
}

 

 

Можно так же вынести опции в админку...

			$this->settings['download_resume'] = 1;
			$this->settings['download_max_speed'] = 50;

Изменено пользователем mxneo
  • Лайк 1
Ссылка на комментарий
Поделиться на других сайтах

Nginx на это есть.
Ссылка на комментарий
Поделиться на других сайтах

А нефиг отдавать через PHP.
Ссылка на комментарий
Поделиться на других сайтах

Чтобы считать злобных буратин, качающих твои файлы

 

А вообще отдавать большие файлы PHP это да...

Ссылка на комментарий
Поделиться на других сайтах

Да можно хоть права доступа проверять, правда тогда тоже придётся код менять. Если по минимуму, то можно редиректом обойтись.

 

P.S. У меня субъективное разделение всех проектов/админов на тех, кому это совсем не нужно и тех, кто и сам знает, как лучше сделать :)

Ссылка на комментарий
Поделиться на других сайтах

  • 2 недели спустя...

Присоединиться к обсуждению

Вы можете ответить сейчас, а зарегистрироваться позже. Если у вас уже есть аккаунт, войдите, чтобы ответить от своего имени.

Гость
Ответить в этой теме...

×   Вы вставили отформатированный текст.   Удалить форматирование

  Допустимо не более 75 смайлов.

×   Ваша ссылка была автоматически заменена на медиа-контент.   Отображать как ссылку

×   Ваши публикации восстановлены.   Очистить редактор

×   Вы не можете вставить изображения напрямую. Загрузите или вставьте изображения по ссылке.

Зарузка...
×
×
  • Создать...

Важная информация

Находясь на нашем сайте, вы соглашаетесь на использование файлов cookie, а также с нашим положением о конфиденциальности Политика конфиденциальности и пользовательским соглашением Условия использования.