вторник, 8 ноября 2011 г.

Теперь постом можно поделиться в социальных сетях

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

Mojlicious: Использование роутов в javascript

Мне нравится, как реализованы роуты в Mojolicious и особенно мне нравится то, что их можно именовать. Именую я роуты всегда в соответствии с именем контроллера и метода.
Например,
$r->get('/messages/:id')->to('messages#show')->name('messages_show');
$r->post('/messages/:id/delete')->to('messages#delete')->name('messages_delete');
И затем в контроллере:
$self->redirect_to('messages_show', id =>123);
Такой подход позволяет изменять роуты с меньшим влиянием на остальной код. И все бы хорошо, но часто приходится использовать роуты не только на стороне сервера, но и на стороне клиента. Например,
var some_id = 123;
$.getJSON('/messages/' + some_id, function(data){ ... });
$.post('/messages/' + some_id + '/delete', function(data){ ... });
Хотелось бы иметь возможность использовать имена роутов и на клиентской стороне. Для этой задачи и был написан плагин "Mojolicious::Plugin::JSUrlFor". Достаточно добавить в основной ваш лейаут:
<%= js_url_for %>
и в клиентском javascript-е будет доступна функция "url_for"( аналогична хелперу "url_for" с "Mojolicious::Plugin::DefaultHelpers"):
var some_id = 123;
$.getJSON( url_for('messages_show', {id:some_id}), function(data){  } );
$.post( url_for('messages_delete', {id:some_id}), function(data){  } );
Модуль "Mojolicious::Plugin::JSUrlFor" пока еще только на Github, но заброшу на CPAN сразу, как покрою тестами.

вторник, 1 ноября 2011 г.

Mojolicious и защита от Cross Site Request Forgery (CSRF)

Немного теории
Я полагаю многие знают, что такое CSRF. Но для новичков озвучу. CSRF (Cross Site Request Forgery) - это межсайтовая подделка запросов. И происходит она следующим образом.

Допустим, на вашем сайте, назовем его "mysite.com", есть ссылка, которая удаляет сообщение. Ссылка вида - "http://mysite.com/myprofile/delete?message=123".

Злоумышленник может вставить эту ссылку на свой сайт "attackerssite.com", например,  в виде картинки -
<img src="http://mysite.com/delete?message=123" />
И если Вы зайдете на "attackerssite.com", то будет отправлен запрос на загрузку картинки с вашего сайта, но вместо загрузки картинки будет удалено сообщение. Проблем с авторизацией не будет, так как будет отправлена ваша кука, запрос же отправляется с вашего браузера.

Таким образом возможно подделать абсолютно любой запрос.
Есть разные методы борьбы с этим, но реально работает только один - необходимо с каждым запросом,  который изменяет данные, посылать секретную строку.
Эта строка должны быть уникальна для каждой сессии.

среда, 26 октября 2011 г.

Интересности Perl

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

Приступим.

Приватные методы
В Perl возможно реализовать приватные методы и делается это следующим образом:

Недостаток такого подхода в том, что caller будет нам возвращать "__ANON__" в качестве имени нашего метода. И stack trace будет нечитабельным.


вторник, 9 августа 2011 г.

IGAL - создаем фотогалерею за 5 минут

У меня стояла задача раздать всем фотки после праздника. Логичнее всего раздать их через интернет. Следовательно возникли следующие требования:

  1. Фотографии должны быть доступны для скачивание только определенному кругу людей.
  2. Фотографии должны быть доступны в полном размере( не ужатые )
  3. Должна быть возможность предварительного просмотра фотографий.
  4. Должна быть возможность пакетного скачивания фотографий.

Фотографий всего было где-то около 10 гб. Подходящего веб-сервиса я не нашел и решил создать самому веб-галерею и залить ее на свой сервак. После недолгих поисков я нашел очень удобный скрипт (написан на Perl) для генерации статической фото-галереи из папки с фотками.

Скрипт называется igal ( http://igal.trexler.at/ ). Все что нужно - это просто запустить его в нужной папке. Результат будет выглядеть примерно так - http://igal.trexler.at/igal2-sample/.

Я использовал опцию "-s make no HTML slides, link thumbnails to images", чтобы превьюшки ссылались сразу на JPG файлы.

Для ограничения доступа настроил аутентификацию в nginx, а для пакетного скачивания можно использовать менеджер закачек типа DownloadMaster( умеет скачивать все линки со страницы).

пятница, 1 июля 2011 г.

Тест на понимание Perl: Вопрос 5

Вопрос
Что выведет следующий код?
$MODE = 'debug';

sub is_debug { $MODE =~ /debug/gi ? 1:0 }

print 5 if is_debug();
print 6 if is_debug();
print 7 if is_debug();
Ответ: 57


Пояснение
Вызов функции is_debug будет нам по очереди возвращать то 1, то 0. Это связано с тем, что мы используем регексп с модификатором "g" в скалярном контексте. В такой ситуации при удачном совпадении Perl запоминает позицию на которой остановился и в следующий раз продолжает поиск с нее.

Нужно такое поведение, для таких вот ситуаций:
$x = "cat dog house";
while ($x =~ /(\w+)/g) {
    print "Word is $1, ends at position ", pos $x, "\n";
}

Детали в perldoc perlretut

среда, 29 июня 2011 г.

Ищем Perl-программистов в Киеве и Чернигове (Украина)

Для Perl программистов есть 2 вакансии - одна в Киеве и одна в Чернигове.

Компания Portaone.
Описание киевской вакансии -  http://www.portaone.com/company/careers/developer/
Описание черниговской вакансии -  http://www.portaone.com/company/careers/web-developer/

Работать будете в команде профессионалов, начинающих программистов в компании практически нет.

Если что-то интересует - спрашивайте, постараюсь ответить на все вопросы.

четверг, 23 июня 2011 г.

Запускаем Mojolicious/PSGI приложение: мини-тест производительности.

Решил провести небольшое тестирование производительности Mojolicious  в разных режимах:
  1. Mojo::Server::Daemon (Epoll/Poll)
  2. Mojo::Server::Hypnotoad (Epoll/Poll)
  3. Mojo::Server::PSGI + Corona
  4. Mojo::Server::PSGI + Starman
  5. Mojo::Server::PSGI + Starlet
  6. Mojo::Server::PSGI + Plack::FCGI::Handler
Хотелось еще протестировать nginx+uwsgi, но не сложилось. Возможно в следующий раз.


Как проводилось тестирование 
Тестировалось приложение, которое просто возвращает строку "OK". Также, в тех же условиях, тестировалось минимальное PSGI приложение. Основной задачей было узнать наиболее производительный режим запуска. 
Все запросы к приложению проксировались через nginx - 4 воркера по 1024 конекшенов максимум. Тестировалось при помощи утилиты "ab". Результат считался как среднее арифметическое по 3 запускам теста. 10000 запросов на тест.

понедельник, 6 июня 2011 г.

Наконец-то исправлена обработка исключений в Perl 5.14

Все уже знают про выход Perl 5.14, но почему везде пишут лишь про новые плюшки?! Но то что была наконец-то решена древняя проблема с обработкой исключений, никто и не вспоминает.

В Perl мы используем die для генерации исключения и блочный eval для перехвата. Конструкция, думаю, знакома всем:
eval { 
  # some code 
  die "error"; 
  # some code  
}; 

if ($@) { 
    print "Error [$@] occured!"; 
}

Так вот, кроме того, что это выглядит коряво, так это еще и работает(до версии 5.14) не всегда хорошо. Проблема описана в моем посте "Чем плох eval?!"

В perl 5.14 произошли изменения в поведении die, warn и $@, что решило проблемы описанные в вышеупомянутом посте. Теперь можно не боятся, что деструктор затрет исключение.  Также  local $@ не испортит нам жизнь.

Более детально читайте в perldoc perldelta => Exception Handling.

Можно было бы отказаться и от Try::Tiny, но есть еще эстетические соображения :)

пятница, 27 мая 2011 г.

Развертываем Perl приложение на DotCloud

Немного про PSGI
Спецификация PSGI стала очень важным(переломным) моментом в мире разработки Perl веб-приложений. По сути, произошло отделение протокола взаимодействия с веб-сервером от API фреймворка, что позволило запускать PSGI приложения в любом окружении(возможно стоит про это написать отдельный пост :) ). Все современные фреймворки поддерживают PSGI.

Как выглядит PSGI приложение?
PSGI приложение это просто ссылка на функцию. Эта функция принимает ссылку на хеш с описанием окружения и возращает ссылку на массив с трех элементов(статус, хидеры, боди)
sub app {
    my $env = shift;
    return [
        '200', 
        [ 'Content-Type' => 'text/plain' ],
        [ "Hello World" ], # or IO::Handle-like object
    ];
}

Если хотите попробовать, то установите себе Plack c cpan и запустите:
plackup  -e 'sub {my $env=shift; return [200, [Content-Type => "text/plain"], ["Welcome home, $env->{QUERY_STRING}"]] }'
Затем откройте в браузере http://localhost:5000/?Dude

Приложения на базе Mojolicious и Dancer  умеют работают в режиме PSGI.

Теперь ближе к сабжу - разворачиваем наше приложение
Dotcloud - это платформа для развертывания ваших приложений. C Dotcloud Вы можете забыть про настройку веб-сервера. Просто выполняем "dotcloud deploy myapp" и приложение готово к использованию :). Для примера,  возьмем приложение c поста - "Пример приложения на Mojolicious ( не Lite )". ( Предварительно необходимо завести себе аккаунт на dotcloud.com и установить клиент - sudo easy_install dotcloud. )

четверг, 26 мая 2011 г.

Mojo::JSON для сессий в Mojolicious

Сейчас Mojolicious использует Storable для сериализации сессий, но Себастьян решил перейти на Mojo::JSON и мне нравится эта идея :). Я приверженец формата JSON и уже упоминал его преимущества в посте "Как устроены сессии в Mojolicious?!". Проблемы могут возникнуть только у пользователей, которые хранят в сессии блесснутые(blessed) ссылки.

Тикет с обсуждением на гитхабе.

вторник, 17 мая 2011 г.

Конвертируем HTML в PDF

Предыстория
Есть некое веб-приложение(на Perl), в котором нужно было добавить определенный набор отчетов. Отчеты должны иметь два представления - HTML и PDF.

Для решения этой задачи, естественно, можно было бы воспользоваться модулями типа PDF::Reuse, PDF::API2, PDF::API2::Simple, но:
1. Это лишние временные затраты (изучение API, написания дополнительного кода)
2. Это усложнение сопровождения отчетов. Необходимо дублировать логику HTML-шаблонов в PDF и постоянно поддерживать это в актуальном состоянии.

Поэтому, было выбрано другое решение - использовать конвертор HTML в PDF. Сразу оговорюсь, что было это года 3-4 назад. Для PHP, вроде как, на то время уже существовал dompdf(рендеринг написан на php), а для Perl ничего такого не было.

Провал HTMLDOC
После долгих поисков нашел такую тулзень как HTMLDOC. Но она была далеко не идеальна:
1. В HTMLDOC нет поддержки Unicode, поэтому приходилось предварительно перекодировать HTML в cp1251.
2. Шрифты, которые идут с HTMLDOC не поддерживают кириллических символов. Но в интернетах был найдет комплект шрифтов с поддержкой кириллицы. Главное после установки HTMLDOC не забыть заменить шрифты :)
3. Поддержка только базового HTML(про CSS забудьте). Пришлось довольствоваться чем было.

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

Первой попыткой было использовать  HTMLDOC 1.9 (нестабильный релиз),  там добавили базовую поддержку Unicode. После 8-го segfault с 10 попыток конвертации, было решено вернуться к предыдущей версии(без поддержки  Unicode)

Вторая попытка была заменять не CP1251 символы на escape-последовательности вида "&#xxxx;", но после 3-4 последовательностей в файле, HTMLDOC их просто переставал преобразовывать в нужные символы.

Триумф WKHTMLTOPDF
Я начал искать новый конвертор. И каково было ж мое удивление, когда я нашел такого зверя, как  WKHTMLTOPDF :)

WKHTMLTOPDF - это консольный конвертор, который использует Webkit для рендеринга HTML, следовательно PDF документы будут максимально приближены к оригинальному HTML. И это реально так, можете смело использовать CSS-стили. WKHTMLTOPDF сконвертит HTML практически любой сложности!!!

пятница, 15 апреля 2011 г.

Mojolicious 1.16: Экстренный релиз, Всем обновляться!!!

Час назад стало известно про серьезную уязвимость в Mojolicious, которая позволяет вычитать любой файл с файловой системы.
Баг уже исправлен, к сожалению баг был опубликовал в твиттере перед тем как передан Себастьяну.
Все срочно обновляемся!!!! Но учтите, что новый релиз не сразу попадет на все зеркала CPAN, лучше качайте прямо с официального сайта.

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

Дополнительная информация:

понедельник, 28 марта 2011 г.

Mojoliciuos - Производительность Mojo::JSON

Mojo::JSON VS JSON::PP
Решил проверить производительность Mojo::JSON
Интересовала, естественно, производительность в сравнении с JSON::PP.
Колоссальная производительность JSON::XS лишает смысла сравнивать его с перловыми реализациями.

Результаты
Тестирование показало, что Mojo::JSON в 1.5 раза быстрее чем JSON::PP при сериализации и в почти в 3 раза быстрее при десериализации. Очень даже неплохо.
Естественно, JSON::XS вне конкуренции, он в 40 раз быстрее чем Mojo::JSON при сериализации и в 30 раз быстрее при десериализации.

Если мы посмотрим на абсолютные цифры производительности Mojo::JSON, то 3-5 тыс вызовов в секунду хватит для большинства проектов. Кроме того, в тесте использовалась достаточно сложная структура данных.  Ну и всегда можно переключится на JSON::XS

вторник, 22 марта 2011 г.

Guttman-Rosler Transform. Часть 1: Описание преобразования.

Уже наверное больше года хочу написать про GRT(Guttman-Rosler Transform) и наконец-то дошли руки. Вернее, наткнулся на Sort::External::Cookbook, который и взял за основу своего поста. Повествование решил разбить на две части. Первая с описанием, вторая с результатами тестирования.

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

Perl имеет очень удобную в использовании функцию sort. Когда мы хотим нестандартный порядок сортировки, то мы использует колбек, который передаем в функцию sort.
Например, sort {$b <=> $a } @array;

Идея GRT заключается в том, чтобы преобразовать входные данные так, чтобы мы могли сортировать без использования дополнительного колбека( "sort @transformed_array;" )

Тогда вся сортировка будет происходить на уровне C, что даст нам выигрышь в скорости.

воскресенье, 27 февраля 2011 г.

Встречайте Mojolicious::Plugin::Gravatar

Написал небольшой плагин для Mojolicious - Mojolicious::Plugin::Gravatar . Добавляет хелперы для работы с Gravatar.com.  Думаю многие знакомы с этим сервисом( его используют cpan и github ), но кто не знаком - обратите внимание.

Для отображения аватарки  - <%= gravatar $email %>
Для получения url аватарки - <%= gravatar_url $email %>

Плагин уже на GitHub и на CPAN 

понедельник, 21 февраля 2011 г.

Mojolicious - интервью с Себастьяном Риделем( Sebastian Riedel )

Мой перевод интервью ActiveState с Себастьяном Риделем( Sebastian Riedel ), создателем веб-фреймворка Mojolicious. Это достаточно свободный перевод, но я старался не потерять суть.

14.02.2011 Себаcтьян зарелизил Mojolicious 1.1 - Perl веб-фреймворк следующего поколения. В связи с этим и состоялось интервью.

Tara: Почему ты занялся созданием Mojolicious?

Sebastian: По большому счету это случилось случайно. Стартовал Mojolicious в конце 2008 под названием Mojo, как фреймворк для  разработчиков веб-фреймворков. Он должен был решить многие проблемы архитектуры Catalyst и подразумевался как замена для его устаревающих внутренностей. Но когда текущие мейнтейнеры Catalyst отказались от использования Mojo, то я решил показать его ценность, создав но его основе пример  веб-фреймворка.
Затем этот пример под названием Mojolicious превысил все ожидания, и я никогда не пожалел о случившемся.

Tara: Какие уроки приобретенные во время работы над Catalyst, оказались полезными при создании Mojolicious?

Sebastian: Я полагаю, что наиболее важным уроком, который я выучил, было искусство построения сообщества. Активное сообщество является наиболее ценным активом для любого фреймворка и является основной его популярности. И хотя  Mojolicious очень молодой проект, но у нас уже второе по размеру сообщество среди всех веб-фреймворков на Perl, мы идем сразу за Catalyst.

Tara: Есть ли какие-то примеры действующий проектов на Mojolicious? Какого рода проекты создаются при помощи Mojolicious?

воскресенье, 20 февраля 2011 г.

Как устроены сессии в Mojolicious?!

В этом посте я не буду рассказывать про API для работы с сессиями, это можно найти в документации к Mojolicious, а постараюсь объяснить как устроены сессии внутри.

Mojolicious использует сookies для хранения сессий. И это достаточно важный момент. Такой подход позволяет нам следовать REST идеологии. Мы можем отказаться от лишних состояний на стороне сервера, нам не нужно обеспечивать общего пространства для доступа к сессиям с разных серверов.

Но имеется несколько важных нюансов:
  1. Старайтесь не делать сессии большими, поскольку эти данные будут передаваться при каждом запросе, а максимально безопасный размер cookie - 4кб.
  2. Вопрос авторства данных.
С первым пунктом все ясно, а относительно второго, то это решается либо шифрованием либо подписью cookies. Mojolicious использует подписанные(signed) cookies.

Что должна обеспечивать подпись?
Начнем с того, что любая подпись (включая подпись ручкой на бумаге) должна обеспечить следующие две вещи:
  1. Идентифицировать автора подписи.
  2. Гарантировать, что после того, как документ подписали, он не изменялся.
Подписанный документ не подразумевает того, что он должен быть зашифрован. Соответственно подписанные cookies не обязаны быть зашифрованными.
Мы оставляем документ в открытом виде и лишь добавляем к нему подпись(цифровую или ручкой на бумаге)

суббота, 5 февраля 2011 г.

Особенности конкурентной записи/чтения файлов в perl + NFS

Рассмотрю буквально парочку малоизвестных нюансов/подводных камней.

Мало кто знает, что для вычитки файла в строку можно использовать такой код:

my $content = do {local (@ARGV, $/) = $filename; <ARGV> };
За объяснениями в perldoc perlvar  и поиск по ARGV.

Такой подход использовался и в File::Slurp. В данной ситуации не просходит flock, это важно учитывать если Вы этот файл еще и пишите другим процессом . Проблему конкурентной записи можно решить и без flock, просто нужно операцию записи сделать атомарной(File::Slurp поддерживает для этих целей флаг "atomic").

Идея заключается в следующем:
  1. Создается уникальный временный файл и в него пишутся данные
  2. Временный файл переименовывается в целевой файл. Операция rename в большинстве ОС - атомарная. 
И казалось бы все отлично, но лишь до того момента когда вы начнете использовать NFS :)

Операция rename в NFS - атомарная, но есть следующий нюанс. Если вы делаете rename и файл назначения уже существует, то сначала удаляется файл назначения, а затем лишь происходит rename. И это ДВЕ  ОТДЕЛЬНЫЕ операции.

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

суббота, 29 января 2011 г.

Perl IDE: Eclipse + Epic

Perl IDE
Посмотрел видео с Perl-воркшопа «Saint Perl — 2» (Санкт-Петербург). Доклад "Perl IDEs" Шафиева Наима.

Я в свое время поигрался почти со всеми перечисленными в докладе IDE и редакторами (кроме Kephra и Emacs) и сделал выбор в пользу Eclipse + Epic.

Сразу немного критики в сторону докладчика, который заявил, что  Epic is deprecated и с 2008 без обновлений. Я пользуюсь Epic и наблюдаю там движение.
Версия 0.6.35 вышла в 2009-07-27. Сейчас у меня установлена версия Epic 0.6.39
Если зайти на сайт проекта, то можно увидеть, что последний коммит был сделан 2011-01-16.

Почему ...
Почему не Vim?
Замарочки с конфигом, а я хочу, чтобы все работало с коробки. Кроме того, меня убивают в Vim некоторые вещи при работе с буферами. В общем моя продуктивность при работе в Vim с большими проектами падает. У меня был очень толковый конфиг и я работал в Vim больше месяца по 8 часов в день, возможно это не так много, но я не готов тратить больше времени лишь для того, чтобы подстроить себя под редактор.

среда, 5 января 2011 г.

Как Perl стал современным(Modern)?!

Смотрим видео про то, как Perl стал современным ;)

Get the Flash Player to see this player.