Алгоритм разбора URL-ов для CMS, у которой не бывает дублей

22.02.2013г. // Рубрики: web, cms
На самом деле, мне неизвестно ни одной популярной CMS с вменяемым механизмом устранения этой проблемы. Обычно все сводится к танцам с бубном вокруг .htaccess и robots.txt.
Однако, выход (для самописов) есть. Все, что изложено далее - вовсе не теоретические абстрактные измышления. Механизм успешно работает, в том числе и на этом самом сайте.
Итак, что мы с будем делать? Приходящий get-запрос, перед отправкой на обработку, фильтруем на предмет выполнения жёстких правил.
Принцип построения правил чем-то сходен с правилами nginx. Вначале проверяется точное совпадение url (с отброшенными параметрами) до первого совпадения. Если нет, то затем - регулярные выражения для url без параметров (до первого совпадения).
Внутри каждого правила присутствует список разрешенных параметров для текущего url, а также указание, какой шаблон отвечает за обработку страницы.
Я реализовал этот механизм с помощью шаблонизатора Template-Toolkit. Примерный кусочек конфигурации выглядит так, сначала управляющий шаблон:
[% engine.config.uri_parser.uri = engine.config.request.uri() %]
[% MACRO macro_check_params_and_run BLOCK %]
[%-
    engine.config.uri_parser.error.param = allow_params.test(engine.params.keys);
    IF (engine.config.uri_parser.error.param.size);
        engine.http_status = default_bad_status || 404;
        RETURN;
    END;
    PROCESS $engine.template;
    RETURN;
-%]
[% END #MACRO %]
[% IF method=='get' %]
    [% PROCESS config.get.tpl %]
    [% RETURN %]
[% END #IF method=='get' %]
[% IF method=='post' %]
    [% PROCESS config.post.tpl %]
    [% RETURN %]
[% END #IF method=='post' %]
Выжимка из обработчика метода GET:
    [% default_bad_status = 404 %]
    [% allow_params = [MAGIC_PARAMETER] %]
    [% SWITCH engine.config.uri_parser.uri %]
        [% CASE '/' %]
            [%
                allow_params = [MAGIC_PARAMETER, 'url', 'err', 'alias'];
                engine.config.uri_parser.label = 'default';
                engine.template = 'index.tpl';
                macro_check_params_and_run;
            %]
    [% END #SWITCH %]
    [% IF (matches = engine.config.uri_parser.uri.match('^\/ajax\/added\/([1-9]\d*)\/)) %]
            [%
                engine.config.uri_parser.label = 'ajax_added';
                engine.template = 'ajax/added.tpl';
                engine.config.uri_parser.var.pagenum = matches.0;
                macro_check_params_and_run;
            %]
    [% END %]
    [% engine.http_status = 404 %]
    [% RETURN %]
Ну и дальше управление передается либо найденному шаблону, отвечающему за прорисовку страницы (напр.  index.tpl), либо возврат в движок с кодом 404.
Таким образом, мы гарантированно избегаем вызова непредусмотренных страниц и реакции на урлы с "левыми" параметрами. По этой причине, на данном  блоге нет и не может быть неожиданных для автора дублей.

Рубрики