Jump to content

Стандартный Антиспам-сервис IPB: "зависает" php-команда fgets()


cyrax_02
 Share

Recommended Posts

Что имеем:

1) Срок активности лицензии истёк и как следствие, антиспам-фильтр от IP.Board не работает (не должен работать)

2) В настройках IP.Board включаем антиспам-фильтр (почему-то IP.Board разрешает это сделать при истёкшей лицензии)

 

Что получаем:

При попытке регистрации нового пользователя на странице регистрации (шаг 1) нажимаем кнопку "Регистрация" и... ждём 3 мин, после чего получаем от сервера ошибку "Internal Server Error"

Первое, что пришло в голову - бесконечный цикл где-то в глубинах исходных кодов IP.Board

 

Локализация причины

1) /admin/sources/base/ipsController.php => ipsController::init():

protected function init()
{
   $this->registry = ipsRegistry::instance();
   $this->registry->init();
}

2) /admin/sources/base/ipsController.php => ipsController::handleRequest():

self::$cmd->execute( $this->registry )

3) /admin/applications/core/modules_public/global/register.php => public_core_global_register::_completeRegistrationSave():

//-----------------------------------------
// Pass twitter/facebook via spam service
//-----------------------------------------
...
/* Query the service */
$spamCode = IPSMember::querySpamService( $member['email'] );

4) /admin/sources/base/ipsMember.php => IPSMember::querySpamService():

/* Query the service */
$response = $query->postFileContents( "https://remoteservices.invisionpower.com/spam/{$type}", array( 'email' => $email, 'ip' => $ip ), $key, $key );

5) /kernel/classFileManagement.php => classFileManagement::postFileContents():

//-------------------------------
// Is URL, try curl and then fall back
//-------------------------------
...			
$contents = $this->_getContentsWithSocket( $file_location );

6) /kernel/classFileManagement.php => classFileManagement::_getContentsWithSocket():

while( ! feof($fp) && ! $status['timed_out'] )		
{
   $data .= fgets( $fp, 8192 );
   $status = stream_get_meta_data($fp);
}

Вот здесь команда fgets "зависает". При этом поток $fp проинициализирован:

print_r($fp) = "Resource id #35"

 

По каким-то причинам IP.Board'овский сервер не отдаёт ни EOF, ни EOL ?

Link to comment
Share on other sites

Удаленный сервер не отвечает или недоступен.

 

По умолчанию установлен таймаут в 15 сек. Если превышен этот лимит при чтение функцией fgets, $status['timed_out'] принимает значение TRUE и цикл завершается.

 

Когда время работы потока истекает, ключ 'timed_out' массива, возвращаемого функцией stream_get_meta_data(), устанавливается в значение TRUE, хотя ошибка или предупреждение не генерируется.

Link to comment
Share on other sites

Удаленный сервер не отвечает или недоступен.

 

По умолчанию установлен таймаут в 15 сек. Если превышен этот лимит при чтение функцией fgets, $status['timed_out'] принимает значение TRUE и цикл завершается.

У меня для php-скриптов установлен лимит 3 минуты. Следовательно, через 15 сек цикл должен был завершиться. Но он не завершается. Команда fgets() работает все 3 мин. О чём это говорит ?

 

При загрузке страницы

без каких-либо post/get-данных получаем от сервера 400 Bad Request. Что из этого следует ?

Edited by cyrax_02
Link to comment
Share on other sites

без каких-либо post/get-данных получаем от сервера 400 Bad Request. Что из этого следует ?

Из этого следует, что без ключа сервер не принимает запросы, для php нужно устанавливать curl и нехрен отправлять запросы на IPS с истекшей лицензией. У вас вообще-то копирайт IBR, насколько я знаю они юзают другой антиспам сервис.

 

Команда fgets() работает все 3 мин.

Настройки -> Пользователи -> Защита от Спама -> Лимит времени соединения с сервисом

 

Какое значение стоит?

 

По крайней мере у меня, по истечению таймаута, функция fgets прекращает читать из сокета и завершает работу. Посмотрите выше есть вызов функции stream_set_timeout. Продебажте var_dump'ом что она возвращает.

Link to comment
Share on other sites

Настройки -> Пользователи -> Защита от Спама -> Лимит времени соединения с сервисом

Какое значение стоит?

15 сек

 

Посмотрите выше есть вызов функции stream_set_timeout. Продебажте var_dump'ом что она возвращает.

var_dump('timeout = '.$this->timeout); var_dump(stream_set_timeout( $fp, $this->timeout )); die();

string(12) "timeout = 15" bool(true)

 

для php нужно устанавливать curl

IP.Board должен корректно работать и без curl'а. Curl не входит в число обязательных требований к php:

 

/kernel/classFileManagement.php => classFileManagement::postFileContents():

if( ( $contents = $this->_getContentsWithCurl( $file_location, $post_array ) ) === false )
{
   $contents = $this->_getContentsWithSocket( $file_location, $post_array );
}

 

У вас вообще-то копирайт IBR, насколько я знаю они юзают другой антиспам сервис.

http://forums.ibresource.ru/topic/58637-antispam-servis/

 

Да, но сейчас у меня этот сервис отключен из-за истёкшей активности лицензии. Плюс не установлен curl.

Почему-то не могут найти в настройках "Сервис мониторинга спама". Когда он отключен, так и должно быть ? В любом случае должны быть, как минимум, видимый раздел/настройки, касающиеся этого сервиса...

Link to comment
Share on other sites

Registration / Spam service timing out on 3.4.7

Вот это другое дело. Патч сабжевую проблему полностью устраняет.

Сейчас ответ от сервера fgets получает сразу (без всяких 15-секундных таймаутов). При этом в журнале появляются записи типа "0: Ошибка сервиса" (т.к. ключ истёк).

 

В любом случае, вернул исходный classFileManagement.php на место, т.к. патч - для версии 3.4.7, а у меня - 3.4.5 (могут быть глюки). Всё равно спам-сервис не работает.

 

newbie, вы знали про этот патч или нашли на invisionpower.com поиском ?

Link to comment
Share on other sites

Вот по этому и надо юзать curl, а не низкоуровневые сокеты где малейший баг и они отваливаются.

 

В любом случае, вернул исходный classFileManagement.php на место, т.к. патч - для версии 3.4.7, а у меня - 3.4.5 (могут быть глюки).

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

Link to comment
Share on other sites

Вот по этому и надо юзать curl, а не низкоуровневые сокеты где малейший баг и они отвалятся.

В данном случае баг имеет место не в механизме сокетов, а в коде IP.Board.

 

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

Особенности реализации (с точностью до строки кода) той же самой логики могут менять от версии к версии...

Link to comment
Share on other sites

Особенности реализации (с точностью до строки кода) той же самой логики могут менять от версии к версии...

Если говорят что его можно применять для всех версий (3.4) это значит, что все изменения которые там есть не затрагивают основную логику скрипта. 3.4.7 в данном случае указано потому, что это финальная версия, и разработчики поддерживают только финальные версии линейки, а не выпускают отдельные патчи для 3.4.0, 3.4.1 и тд

Link to comment
Share on other sites

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

Баг исправлен в php-коде файла classFileManagement.php версии 3.4.7. При этом патч, помимо, собственное нового кода, содержит прочий (неизменённый) код версии 3.4.7. Следовательно, при замене файла версии 3.4.5 файлом патча версии 3.4.7 мы, помимо исправления бага, обновляем на новую версию весь прочий код этого файла.

Link to comment
Share on other sites

3.4.7 в данном случае указано потому что, это финальная версия, и разработчики поддерживают только финальные версии линейки, а не выпускают отдельные патчи для 3.4.0, 3.4.1 и тд.

Вашей логике противоречит патч 3_4_x_patch_nov_14, в документации к которому указывается не только последняя версия, а все версии движка, с которыми совместим патч

Link to comment
Share on other sites

помимо исправления бага, обновляем на новую версию весь прочий код этого файла.

Если говорят что его можно применять для всех версий (3.4) это подразумевает, что все изменения которые там есть не затрагивают основную логику скрипта.

Вы снова не хотите слушать.

 

@newbie, попробуйте вы объяснить ТС'у почему именно 3.4.7, у меня больше нет сил.)

Link to comment
Share on other sites

Вашей логике противоречит патч 3_4_x_patch_nov_14

Как раз наоборот. Потому что все патчи содержат код последних версий этой подверсии 3.x.x. Ставя патч на 3.4.5 вы обновляете файлом из последней версии 3.4.x.

Когда говорят что можно, значит можно. Версионные изменения которые там есть не затрагивают основную логику. В данном случае можно, хоть и не указан x.

 

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

Link to comment
Share on other sites

У меня только 1 вопрос: "@cyrax_02, каким образом Вы устанавливаете патчи безопасности?". Там же тоже код от 3.4.7. А, учитывая то, что Вы используете локализацию от ибр, то вообще кричи "Караул!".

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

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