2008-07-25

PHP: Уменьшаем исходящий трафик (или изобретаем очередной велосипед)

В связи с разработкой мобильной версии сайта столкнулся с проблемой - передается много данных, как следствие на мобильном телефоне тратится много денег, было решено написать несколько функций предназначенных для уменьшения передаваемых данных Во первых было уменьшен размер отдаваемого HTML, с помощью простого класса:

class OutBufferFilter {
function OutBufferFilter() {
if( @ob_start( array(&$this, 'filter') ) ) {
register_shutdown_function( array(&$this, 'shutdown') );
}
}
function filter( $chunk, $mode ) {
return(
str_replace( '> <', '><',
ereg_replace( "[ \t\r\n]{2,}", ' ',
$chunk
)
)
);
}
function shutdown() {
while( @ob_end_flush() );
}
}

Понятное дело, что метод filter не идеален, но на том HTML-коде который есть у меня он работает (в дизайне не используется теги типа pre)

Потом была добавлена компрессия gzip-ом:

class OutBufferFilterGZ extends OutBufferFilter {
var $use_gzhandler = false;

function OutBufferFilterGZ() {
$this->use_gzhandler = function_exists('ob_gzhandler');

if( @ob_start( array(&$this, 'filter') ) ) {
register_shutdown_function( array(&$this, 'shutdown') );
}
}
function filter( $chunk, $mode ) {
return(
$this->use_gzhandler ?
ob_gzhandler( parent::filter( $chunk ), $mode ) :
parent::filter( $chunk )
);
}
}

Потом класс был расширен на предмет того что-бы кешировать полученные страницы в memcached-е, и если в качестве frontend-а используется nginx, то контент отдавался без участия php, а напрямую из memecache

class OutBufferCached extends OutBufferFilterGZ {
var $memcache = false;
var $content = '';
var $timeout = 10;

function key() {
global $_SERVER;

return( ( isset( $_SERVER )
and isset( $_SERVER["REQUEST_METHOD"] )
and $_SERVER["REQUEST_METHOD"] == 'GET'
) ?
( 'pda:html:'
. (isset( $_SERVER["SCRIPT_NAME"] ) ? $_SERVER["SCRIPT_NAME"] : '')
. (isset( $_SERVER["PATH_INFO"] ) ? $_SERVER["PATH_INFO"] : '' )
. '?'
. (isset( $_SERVER["REQUEST_URI"] ) ? $_SERVER["REQUEST_URI"] : '' )
) :
''
);
}
function OutBufferCached( $memcache = false ) {
$key = $this->key();

if( !empty($key) and $memcache and @$memcache->getVersion() !== false ) {
$this->memcache = $memcache;
$this->content = $this->memcache->get( $key );

if( $this->content !== false ) {
$this->shutdown( false );
exit();
}
else {
$this->content = '';
}
}
if( @ob_start( array(&$this, 'filter') ) ) {
register_shutdown_function( array(&$this, 'shutdown') );
}
}
function filter( $chunk, $mode ) {
$this->content .= parent::filter( $chunk, $mode );

return(null);
}
function shutdown( $store = true ) {
parent::shutdown();
$this->output();
if( $store ) {
$key = $this->key();

if( $this->memcache and !empty($key) and $this->timeout ) {
$this->memcache->set(
$key,
$this->content,
MEMCACHE_COMPRESSED,
$this->timeout
);
}
}
$this->content = '';
}
function output() {
echo $this->content;
flush();
}
function timeout( $t = 10 ) {
$this->timeout = $t;
}
function nocache() {
$this->timeout( 0 );
}
}

Все тестировалось на PHP4 и PHP5, в качестве http-сервера использовалось: apache, nginx + php/fastCGI - пока проблем не возникло.
Собственно хотелось-бы узнать насколько интересен изобретенный мною велосипед ?

2005-10-12

Виртуальные домены в Exim + Courier-IMAP + MySQL

Наткнулся тут на данную статью, понравилось.
Правда мне вроде-бы как ни к чему, можно конечно заменить sql-запросы на LDAP...

2005-09-19

Exim4 и все все все (проблема с clamav)

Что-то последнее время начались проблемы с clamd - почему-то рожает зомбей и перестает обрабатывать запросы. То есть соединения на него открываются а вот дальше - висит.
Приходится делать restart.

Буду посмотреть.

2005-09-16

Exim4 и все все все (настройка acl)

Вот тут столкнулся с проблемой - для некоторых e-mail адресов хотелось-бы исключить какую-либо фильтрацию почты, не проверять на вирусы и т.д.
После недолгого чтения документации проблема решилась достаточно просто:
в acl_check_rcpt было добавлено:

accept
recipients = ${if exists{CONFDIR/local_recipients_whitelist} {CONFDIR/local_recipients_whitelist} {}}
set acl_m4 = pass

А в acl_whitelist_local_deny добавить:

accept
condition = ${if eq {$acl_m4}{pass} {yes}{no}}

Теперь можно добавлять e-mail адреса в файл /etc/exim4/local_recipients_whitelist для которых не будут осуществлятся ни какие проверки.

P.S.
Да я в предидущих постах писл про CONFDIR/exiscan_data_acl.conf, так после некоторого переода эксплуатации системы он стал выглядеть:

deny message = This message for $recipients scored $spam_score spam points
spam = Debian-exim:true
condition = ${if >{$spam_score_int} {80} {1}{0} }
!acl = acl_whitelist_local_deny

warn message = X-Spam-Score: $spam_score ($spam_bar)
spam = Debian-exim:true
!acl = acl_whitelist_local_deny

warn message = X-Spam-Report: $spam_report
spam = Debian-exim:true
!acl = acl_whitelist_local_deny
# condition = ${if >{$spam_score_int} {10} {1}{0} }

deny message = Found MIME error ($demime_reason)
demime = *
!acl = acl_whitelist_local_deny
condition = ${if >{$demime_errorlevel} {2} {1}{0} }

deny message = Found blacklisted file attachment (.$found_extension)
demime = vbs:com:bat:pif:scr:prf:lnk
!acl = acl_whitelist_local_deny

deny message = This message contain malware/virus ($malware_name)
malware = *
demime = *
!acl = acl_whitelist_local_deny

Сайты про Debian

Бороздя просторы интернета яя регулярно наталкиваюсь на сайты посвященные Debian. Теперь я решил собирать ссылки не только в закладках моего броузера но и здесь.
Первым оказался свежеоткрытый сайт: DebCentral , вот на него я и разместил первую ссылку.
Дальше будет больше, добавлю что накопилось - обе планеты debian, про администрирование и русскоязычный ресурс про debian.

2005-08-18

devfs vs. udev

Вот тут решил попробывать udev.
Перебирался я на него с devfs. Возникли некоторые затруднения - после обновления udev было сказано что он работает с ядром 2.6.12 и выше, а у меня 2.6.11, так что после перезагрузки возникли некоторые проблемы - пришлось разбиратся, что слазу после отпуска напряжно.
Сейчас сижу компилю 2.6.12 - посмотрим что получится. А то первая попытка не удалась - что-то не совсем стабильно работало в коде xfs, как следствие файловые системы не монтировались

2005-08-17

Я вернулся из отпуска

Ну вот, я наконец вернулся из отпуска.
Буду выкладывать свои наблюдения и замечаения.

P.S. Отдохнул хорошо.

2005-07-13

Exim4 мероприятия по антиспаму (spamassassin -r)

Достаточно полезно использовать e-mail адреса:
  • info
  • mail
  • sale
Как ловушки для spam-сообщений. Если конечно вы их не используете для каких-либо других целей. Просто прописываем в /etc/aliases

info: "|/usr/bin/spamassassin -r"
mail: "|/usr/bin/spamassassin -r"
sale: "|/usr/bin/spamassassin -r"

И почта попадающая на эти адреса будет автоматически считатся спамом, и baes-овские фильтры тренированы на свежайший спам.

2005-07-12

OpenSSH - решение (PermitEmptyPassword)

После долгих и мучительных разборок с исходными текстами самого SSH, pam и глубокой медитацией над ними, была предпринята попытка решить эту проблему с другой стороны - построчным сравниванием конфигов на работающей машине и на неработающей.

Проблема оказалась в одной строчке -

PermitEmptyPassword yes
ее нужно было заменить на

PermitEmptyPassword no
И вся проблема рпзрешилась самим собой. После долгих (несколько недель) мучений.

2005-07-08

OpenSSH - mailing-list обсуждение...

Вот, отправил письмо по поводу OpenSSH и его проблем, но так пока ничего полезного не ответили - буду думать дальше.

Пытался разобратся с PAM и SSH - похоже что проблема в самом SSH - там есть опция UsePAM - собственно видимо это где-то там все мои неприятности.

Буду думать.