Перейти к публикации
Дизайн и модификация IPS Community IPBSkinsBETA
Поиск в
  • Дополнительно...
Искать результаты, содержащие...
Искать результаты в...
cyrax_02

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

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

Что имеем:

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 ?

Поделиться сообщением


Ссылка на сообщение

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

 

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

 

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

Поделиться сообщением


Ссылка на сообщение
03/06/15 20:44 (изменено)

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

 

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

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

 

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

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

Изменено пользователем cyrax_02

Поделиться сообщением


Ссылка на сообщение

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

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

 

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

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

 

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

 

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

Поделиться сообщением


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

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

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.

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

Поделиться сообщением


Ссылка на сообщение

Registration / Spam service timing out on 3.4.7

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

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

 

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

 

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

Поделиться сообщением


Ссылка на сообщение

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

 

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

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

Поделиться сообщением


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

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

 

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

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

Поделиться сообщением


Ссылка на сообщение

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

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

Поделиться сообщением


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

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

Поделиться сообщением


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

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

Поделиться сообщением


Ссылка на сообщение

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

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

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

 

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

Поделиться сообщением


Ссылка на сообщение

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

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

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

 

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

Поделиться сообщением


Ссылка на сообщение

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

Поделиться сообщением


Ссылка на сообщение

Создайте аккаунт или войдите в него для комментирования

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

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас

  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу.

×
×
  • Создать...