@XEHKOK

Как сделать поддержку PCRE2 для Apache 2.4?

Доброго времени суток всем.
Вопрос следующий пытаюсь перевести Apache 2.4.41 на PCRE2 10.33, тк в последней версии все еще отсутствует поддержка PCRE2 из-за обратной совместимости с PCRE.

Скачал исходники Apache 2.4.41, редактирую исходный файл для работы с PCRE: util_pcre.c
Я поправил некоторые функции/константы такие как: PCRE2_INFO_NAMECOUNT, PCRE2_INFO_NAMEENTRYSIZE, PCRE2_INFO_NAMETABLE, то есть с PCRE_DEFINE на PCRE2_DEFINE и тд.

Так же вместо pcre.h я подключил исходник от PCRE2: pcre2.h
spoiler
#include "pcre2.h"

Ошибка где-то в этом куске кода util_pcre.c :
#include "httpd.h"
#include "apr_strings.h"
#include "apr_tables.h"
#define PCRE2_CODE_UNIT_WIDTH (0)
#include "pcre2.h"

#define APR_WANT_STRFUNC
#include "apr_want.h"

#ifndef POSIX_MALLOC_THRESHOLD
#define POSIX_MALLOC_THRESHOLD (10)
#endif

/* Table of error strings corresponding to POSIX error codes; must be
 * kept in synch with include/ap_regex.h's AP_REG_E* definitions.
 */

static const char *const pstring[] = {
    "",                         /* Dummy for value 0 */
    "internal error",           /* AP_REG_ASSERT */
    "failed to get memory",     /* AP_REG_ESPACE */
    "bad argument",             /* AP_REG_INVARG */
    "match failed"              /* AP_REG_NOMATCH */
};

AP_DECLARE(apr_size_t) ap_regerror(int errcode, const ap_regex_t *preg,
                                   char *errbuf, apr_size_t errbuf_size)
{
    const char *message, *addmessage;
    apr_size_t length, addlength;

    message = (errcode >= (int)(sizeof(pstring) / sizeof(char *))) ?
              "unknown error code" : pstring[errcode];
    length = strlen(message) + 1;

    addmessage = " at offset ";
    addlength = (preg != NULL && (int)preg->re_erroffset != -1) ?
                strlen(addmessage) + 6 : 0;

    if (errbuf_size > 0) {
        if (addlength > 0 && errbuf_size >= length + addlength)
            apr_snprintf(errbuf, errbuf_size, "%s%s%-6d", message, addmessage,
                         (int)preg->re_erroffset);
        else
            apr_cpystrn(errbuf, message, errbuf_size);
    }

    return length + addlength;
}




/*************************************************
 *           Free store held by a regex          *
 *************************************************/

AP_DECLARE(void) ap_regfree(ap_regex_t *preg)
{
    (pcre2_code_free)(preg->re_pcre);
}




/*************************************************
 *            Compile a regular expression       *
 *************************************************/

static int default_cflags = AP_REG_DOTALL |
                            AP_REG_DOLLAR_ENDONLY;

AP_DECLARE(int) ap_regcomp_get_default_cflags(void)
{
    return default_cflags;
}

AP_DECLARE(void) ap_regcomp_set_default_cflags(int cflags)
{
    default_cflags = cflags;
}

AP_DECLARE(int) ap_regcomp_default_cflag_by_name(const char *name)
{
    int cflag = 0;

    if (ap_cstr_casecmp(name, "ICASE") == 0) {
        cflag = AP_REG_ICASE;
    }
    else if (ap_cstr_casecmp(name, "DOTALL") == 0) {
        cflag = AP_REG_DOTALL;
    }
    else if (ap_cstr_casecmp(name, "DOLLAR_ENDONLY") == 0) {
        cflag = AP_REG_DOLLAR_ENDONLY;
    }
    else if (ap_cstr_casecmp(name, "EXTENDED") == 0) {
        cflag = AP_REG_EXTENDED;
    }

    return cflag;
}

/*
 * Arguments:
 *  preg        points to a structure for recording the compiled expression
 *  pattern     the pattern to compile
 *  cflags      compilation flags
 *
 * Returns:      0 on success
 *               various non-zero codes on failure
*/
AP_DECLARE(int) ap_regcomp(ap_regex_t * preg, const char *pattern, int cflags)
{
    const char *errorptr;
    int erroffset;
    int errcode = 0;
    int options = PCRE2_DUPNAMES;

    cflags |= default_cflags;
    if ((cflags & AP_REG_ICASE) != 0)
        options |= PCRE2_CASELESS;
    if ((cflags & AP_REG_NEWLINE) != 0)
        options |= PCRE2_MULTILINE;
    if ((cflags & AP_REG_DOTALL) != 0)
        options |= PCRE2_DOTALL;
    if ((cflags & AP_REG_DOLLAR_ENDONLY) != 0)
        options |= PCRE2_DOLLAR_ENDONLY;

    preg->re_pcre =
        pcre2_compile(pattern, options, &errcode, &errorptr, &erroffset, NULL);
    preg->re_erroffset = erroffset;

    if (preg->re_pcre == NULL) {
        /*
         * There doesn't seem to be constants defined for compile time error
         * codes. 21 is "failed to get memory" according to pcreapi(3).
         */
        if (errcode == 21)
            return AP_REG_ESPACE;
        return AP_REG_INVARG;
    }

    pcre_fullinfo((const pcre *)preg->re_pcre, NULL,
                   PCRE2_INFO_CAPTURECOUNT, &(preg->re_nsub));
    return 0;
}


При компиляции make в консоли я получаю следующие ошибки:
spoiler
In file included from util_pcre.c:59:0:
util_pcre.c: In function ‘ap_regfree’:
/etc/webserver/pcre2-1033/include/pcre2.h:825:60: error: ‘pcre2_code_free_’ undeclared (first use in this function)
 #define pcre2_code_free                       PCRE2_SUFFIX(pcre2_code_free_)
/etc/webserver/pcre2-1033/include/pcre2.h:966:25: note: in definition of macro ‘PCRE2_SUFFIX’
 #define PCRE2_SUFFIX(a) a
util_pcre.c:114:6: note: in expansion of macro ‘pcre2_code_free’
     (pcre2_code_free)(preg->re_pcre);
/etc/webserver/pcre2-1033/include/pcre2.h:825:60: note: each undeclared identifier is reported only once for each function it appears in
 #define pcre2_code_free                       PCRE2_SUFFIX(pcre2_code_free_)
/etc/webserver/pcre2-1033/include/pcre2.h:966:25: note: in definition of macro ‘PCRE2_SUFFIX’
 #define PCRE2_SUFFIX(a) a
util_pcre.c:114:6: note: in expansion of macro ‘pcre2_code_free’
     (pcre2_code_free)(preg->re_pcre);
util_pcre.c: In function ‘ap_regcomp’:
/etc/webserver/pcre2-1033/include/pcre2.h:826:60: warning: implicit declaration of function ‘pcre2_compile_’ [-Wimplicit-function-declaration]
 #define pcre2_compile                         PCRE2_SUFFIX(pcre2_compile_)
/etc/webserver/pcre2-1033/include/pcre2.h:966:25: note: in definition of macro ‘PCRE2_SUFFIX’
 #define PCRE2_SUFFIX(a) a
util_pcre.c:184:9: note: in expansion of macro ‘pcre2_compile’
         pcre2_compile(pattern, options, &errcode, &errorptr, &erroffset, NULL);
util_pcre.c:183:19: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
     preg->re_pcre =
util_pcre.c:197:5: warning: implicit declaration of function ‘pcre_fullinfo’ [-Wimplicit-function-declaration]
     pcre_fullinfo((const pcre *)preg->re_pcre, NULL,
util_pcre.c:197:26: error: unknown type name ‘pcre’
     pcre_fullinfo((const pcre *)preg->re_pcre, NULL,
util_pcre.c: In function ‘ap_regexec_len’:
util_pcre.c:253:10: warning: implicit declaration of function ‘pcre_exec’ [-Wimplicit-function-declaration]
     rc = pcre_exec((const pcre *)preg->re_pcre, NULL, buff, (int)len,
util_pcre.c:253:27: error: unknown type name ‘pcre’
     rc = pcre_exec((const pcre *)preg->re_pcre, NULL, buff, (int)len,
util_pcre.c: In function ‘ap_regname’:
util_pcre.c:315:26: error: unknown type name ‘pcre’
     pcre_fullinfo((const pcre *)preg->re_pcre, NULL,
util_pcre.c:317:26: error: unknown type name ‘pcre’
     pcre_fullinfo((const pcre *)preg->re_pcre, NULL,
util_pcre.c:319:26: error: unknown type name ‘pcre’
     pcre_fullinfo((const pcre *)preg->re_pcre, NULL,
/etc/webserver/srcsrv/httpd-2.4.41/build/rules.mk:206: recipe for target 'util_pcre.lo' failed
make[2]: *** [util_pcre.lo] Error 1
make[2]: Leaving directory '/etc/webserver/srcsrv/httpd-2.4.41/server'
/etc/webserver/srcsrv/httpd-2.4.41/build/rules.mk:75: recipe for target 'all-recursive' failed
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory '/etc/webserver/srcsrv/httpd-2.4.41/server'
/etc/webserver/srcsrv/httpd-2.4.41/build/rules.mk:75: recipe for target 'all-recursive' failed
make: *** [all-recursive] Error 1


Народ подскажите пожалуйста в какую сторону копать, и что я делаю не так, просто я не знаю данный язык и его особенности.
  • Вопрос задан
  • 102 просмотра
Решения вопроса 1
@XEHKOK Автор вопроса
Немного разобрался в данном вопросе нашел обновленные исходники под обратную совместимость PCRE-PCRE2.
Нужно сделать конфигурацию Apache:
./configure --with-apr=/ваш/путь/до библиотеки apr --with-apr-util=/ваш/путь/до библиотеки apr-util --with-pcre=/ваш/путь/до библиотеки pcre2/bin/pcre2-config


Далее необходимо скачать два исходника такие как ap_regex.h и util_pcre.c, ссылки ниже:
ap_regex.h
util_pcre.c
На гите Apache есть уже эти файлы они написаны под PCRE и PCRE2 в зависимости от версии, походу в следующей версии apache нас ждет поддержка PCRE2 Ура товарищи))

После выполнения конфигурации apr-1.7.0 нужно изменить файл apr-1.7.0/build/apr_rules.mk в этом каталоге, и нужно добавить в конец строки где:
EXTRA_LIBS=-lrt -lcrypt -lpthread -ldl
Подключение библиотеки:
-lpcre2-8 -L/ваш/путь/до библиотеки pcre2/lib
После этих изменений нужно скомпилировать apr-1.7.0
make
make install


А потом необходимо тоже из исходников скомпилировать и APR-util.
Так же необходимо найти файл ap_config_auto.h, он находится в каталоге: httpd-2.4.41/include
В самом ap_config_auto.h вставить следующие строки:
/* Load PCRE2 */
#define HAVE_PCRE2 1


После данных действий можно выполнять компиляцию и радоваться:
make
make install
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы