Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Apache :: mod_rewrite :: RewriteMap : о программных картах.  (Прочитано 20283 раз)
0 Пользователей и 1 Гость смотрят эту тему.
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« : 23-04-2008 16:02 » 

Знаю, что мои редкие вопросы часто остаются без ответов. Но все же надеюсь, что найдется знающий человек: чай, Апач - не редкость.



Прощу не считать мои вопросы ленью проверить, а считать недостатком времени.



http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewritemap

Если кто не понял из заголовка темы, речь об модуле Апача - rewrite. Меня интересует особенность работы директивы RewriteMap, а именно - программные карты (prg:...). Ограниченные знание языка мне не позволяют понять некоторые вещи.

Вопросы опытным админам:

1. Нужно ли завершать возвращаемое значение \n ?

Меня смутило следующее предложение:
Цитата
It then has to give back the looked-up value as a newline-terminated string on stdout or the four-character string ``NULL'' if it fails (i.e., there is no corresponding value for the given key).
Я понял так: я должен вернут или произольнюю строку с \n на конце, или строку "NULL" без терминатора.

2. Такое работает?

Код:
    RewriteMap china prg:/....../bin/check-china-networks.pl
    RewriteRule ^(.*$) %{china:${REMOTE_ADDR}|http://other-place.ru/path/} [R]

Скрипт возвращает либо "-", либо "NULL".
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 23-04-2008 16:36 » 

1.
я так и понял

Затем эта программа должна вернуть значение найденной величины в stdout в виде строки оканчивающейся символом перевода строки (\n)  либо строкой из четырёх символов «NULL» если поиск неудачен (т.е., для соответствующего значения ключа не найдено никакого значения).
Думаю что NULL должен быть с терминатором.

И как я понимаю, для того чтоб правило вступило в силу нужно рестартануть апач
This program is started once, when the Apache server is started,
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #2 : 23-04-2008 17:05 » 

вот только непонятно что он делает с NULL
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 23-04-2008 19:00 » 

Sla, NULL, по идее, полже заменяться дефолтным значением: ${map_name:input_value|default_value}

Ссмущает именно "the four-character string". Про терминатор ни слова. Завтра ппробую проверить.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #4 : 24-04-2008 09:44 » 

RXL, по идее когда апач стартует с RewriteMap prg, он запускает модуль слушающий (liisten) stdout и видимо ожидает \n, что и говорит ему о конце обработки правила, отсюда можно сделать вывод, что NULL\n
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 24-04-2008 10:18 » new

вот даже нашел Улыбаюсь в исходниках
Код:
    apr_file_read(fpout, &c, &nbytes);
    do {
        i = 0;
        while (nbytes == 1 && (i < REWRITE_PRG_MAP_BUF)) {
            if (c == eol[eolc]) {
                if (!eol[++eolc]) {
                    /* remove eol from the buffer */
                    --eolc;
....

затем...
Код:
    /* catch the "failed" case */
    if (i == 4 && !strcasecmp(buf, "NULL")) {
        return NULL;
    }
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #6 : 24-04-2008 16:35 » 

Столкнулся с непонятной траблой: карты работают в RewriteRule, но отказываются работать в RewriteCond, хотя в доке указывается, что TestString может быть и картой. Вообще, карты очень жидко освещены в документации.
Крайне удивительно, что в инете есть примеры, использующие карты с RewriteCond...

Апач у меня 2.2.

Не работает:
Код:
RewriteMap test prg:/..../test.pl
RewriteCond ${test:${REMOTE_HOST}|none} !=none
RewriteRule ^.*$ http://other-place.ru/ [L]

А это работает:
Код:
RewriteMap test prg:/..../test.pl
RewriteRule ^(.*)$ ${test:${REMOTE_ADDR}/http://other-place.ru/|$1} [L]

Включил лог и поднял уровень до 9 (достаточно 4).
В первом случае в логе говорится, что input='', во втором - map lookup test .....
« Последнее редактирование: 24-04-2008 17:12 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #7 : 25-04-2008 07:46 » 

RXL, а разве
RewriteCond ${test:${REMOTE_HOST}|none} !=none
правильная запись?
а если так
RewriteCond ${test:${REMOTE_HOST}|"none"} !="none"
или
RewriteCond ${test:${REMOTE_HOST}} !=""
учитывая что что "NULL" превращается в NULL
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #8 : 25-04-2008 08:20 » 

Sla, по всякому пробовал. Кавычки в первом аргументе не нужны - они транслируются как обычный plain text.
Скажу точно и проверенно: здесь конструкция не рассматривается как карта. Если поставить просто $(REMOTE_ADDR}, то в логе появляется input='1.2.3.4', а с картой - input=''. В код карты встроил ведение лога, но в лог ничего не попадает. Если же использовать карту в RewriteRule, то и работает и в лог пишет.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #9 : 25-04-2008 08:55 » 

RXL, да ты прав
Код:
typedef struct {
    const char *datafile;          /* filename for map data files         */
    const char *dbmtype;           /* dbm type for dbm map data files     */
    const char *checkfile;         /* filename to check for map existence */
    const char *cachename;         /* for cached maps (txt/rnd/dbm)       */
    int   type;                    /* the type of the map                 */
    apr_file_t *fpin;              /* in  file pointer for program maps   */
    apr_file_t *fpout;             /* out file pointer for program maps   */
    apr_file_t *fperr;             /* err file pointer for program maps   */
    char *(*func)(request_rec *,   /* function pointer for internal maps  */
                  char *);
    char **argv;                   /* argv of the external rewrite map    */
} rewritemap_entry;
а вот
Код:
typedef struct {
    apr_array_header_t *rewriteconds;/* the corresponding RewriteCond entries */
    char      *pattern;              /* the RegExp pattern string             */
    ap_regex_t *regexp;              /* the RegExp pattern compilation        */
    char      *output;               /* the Substitution string               */
    int        flags;                /* Flags which control the substitution  */
    char      *forced_mimetype;      /* forced MIME type of substitution      */
    char      *forced_handler;       /* forced content handler of subst.      */
    int        forced_responsecode;  /* forced HTTP response status           */
    data_item *env;                  /* added environment variables           */
    data_item *cookie;               /* added cookies                         */
    int        skip;                 /* number of next rules to skip          */
} rewriterule_entry;

это из исходников mod_rewrite.c apache.2.2
« Последнее редактирование: 25-04-2008 08:57 от Sla » Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #10 : 25-04-2008 09:14 » 

Sla, ты хочешь сказать, что для cond нет такой структуры?

Кстати, еще недокументированная фича: объявив карту в главном конфиге нельзя ее использовать в виртуальном хосте. Надо использовать там, где объявляется.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #11 : 25-04-2008 09:39 » 

RXL, не совсем это
структура под rewritecond есть вот она
Код:
typedef struct {
    char        *input;   /* Input string of RewriteCond   */
    char        *pattern; /* the RegExp pattern string     */
    ap_regex_t  *regexp;  /* the precompiled regexp        */
    int          flags;   /* Flags which control the match */
    pattern_type ptype;   /* pattern type                  */
} rewritecond_entry;

но в в структуре rewritemap она не присутсвует, и что интересно, структура rewritemap, описана раньше структуры rewritecond.
т.е. по сути происходит следующее
apach при просмотре conf, как бы игнорирует rewritecond, а начинает его воспринимать уже при обработке rules
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #12 : 25-04-2008 09:42 » 

Цитата
Кстати, еще недокументированная фича: объявив карту в главном конфиге нельзя ее использовать в виртуальном хосте. Надо использовать там, где объявляется.
что вполне логично, он же должен понимать с какого output он получил данные
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #13 : 25-04-2008 12:13 » 

Слав, я тебя не понимаю что-то...
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #14 : 25-04-2008 13:10 » 

в какой точке ты стал меня не понимать? Улыбаюсь


зы... я еще трезвый
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #15 : 25-04-2008 15:53 » 

Улыбаюсь
С поста №9
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #16 : 25-04-2008 18:25 » 

ок.
порядок описания структур
rewritemap_entry
rewritecond_cond
rewriterule_entry
та еще есть...

rewriterule_entry содержит поле  - ссылка на rewriteconds
rewritemap_entry такого поля не содержит

в функции обработки rewritemap нет даже никакой попытки обращения к rewritecond

в функции обработки rewriterule чуть ли не впервой строке анализируется rewriteconds

Могу ли я сделать вывод что в apache 2.2. rewritecond для rewritemap не имеет смысла?
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #17 : 28-04-2008 07:58 » 

Так все логично: правила выстраиваются в цепочку и любое из них может предваряться любым числом правил.
В обеих структурах ссылок на карту нет - видимо ссылка по имени идет.
Просто в условии в
Код: (C)
    char        *input;   /* Input string of RewriteCond   */
не обрабатываются конструкции с картами.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines