Apache httpd Module: как сохранить исходное «тело ответа» POST при использовании SetHandler? - PullRequest
1 голос
/ 08 мая 2020

ВОПРОС : Как я могу запустить свой код C и установить переменную в заголовке ответа НО по-прежнему сохранять исходное тело ответа, которое сервер генерирует для клиента.

Требование : Написать собственный модуль Apache для чтения тела запроса POST >> Извлечь данные из тела запроса >> Установить конкретный атрибут заголовка ответа с помощью тела запроса >> Отправить ответ обратно клиенту

Подробности : я использую Apache в качестве прокси для моего ElasticSearch. Я успешно разработал модуль Apache в C и добавил его в httpd.conf. Я использовал директиву « SetHandler » для запуска моего пользовательского кода C.

Все работает нормально. Запрос, сгенерированный клиентским браузером, проходит через мой настраиваемый модуль C Apache, и в моем коде C я могу прочитать тело запроса POST из request_re c. Я также могу установить заголовок ответа с тем значением, которое я готовлю из тела запроса.

Проблема : если я вызываю свой модуль / код с помощью SetHandler, когда он появляется, он не имеет любое тело ответа и пустое тело ответа отправляются в браузер клиента. Когда я отключаю свой модуль / код, ответ генерируется и отправляется клиенту. Похоже, что при использовании SetHandler ответ теряется .

Моя конфигурация / код ниже:

1. httpd.conf

LoadModule example_module    /usr/lib64/httpd/modules/mycustommodule.so

<VirtualHost HOSTNAME:80>
  <Location /elasticsearch/_msearch>
    #SetHandler readbody-handler #calling my custom module
  </Location>
  #My KIBANA application is running on 5601 on same machine
  ProxyPass        / http://localhost:5601/ 
  ProxyPassReverse / http://localhost:5601/
</VirtualHost>

2. Мой кастом C модуль

module AP_MODULE_DECLARE_DATA readbody_module = { 
    STANDARD20_MODULE_STUFF,
    NULL, /*Per-directory configuration handler */
    NULL, /*Merge handler for per-directory configurations */
    NULL, /*Per-server configuration handler */
    NULL, /*Merge handler for per-server configurations */
    NULL,
    regiter_hooks /*Our hook registering function */
};

static void register_hooks(apr_pool_t *pool)
{
    ap_hook_handler(readbody_handler, NULL, NULL, -10);
}

static int readbody_handler(request_rec *r)
{
    const char *buffer;

    if (!r->handler || strcmp(r->handler, "readbody-handler")) return (DECLINED);

    if (util_read(r, &buffer) == OK) //reading the body and assigning it into buffer
    {
        char s[2] = ":";
        char s2[2] = "\"";
        char *indexname;
        indexname = strtok(buffer, s);
        indexname = strtok(NULL, s);
        indexname = strtok(indexname, s2);
        indexname = strtok(NULL, s2);
        apr_table_setn(r->headers_out, "IndexPattern", indexname); //setting up response header
    }

    return OK;
}

static int util_read(request_rec *r, const char **rbuf)
{
    int rc;
    if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR)) != OK)
    {
        return rc;
    }
    if (ap_should_client_block(r))
    {
        char argsbuffer[HUGE_STRING_LEN];
        int rsize, len_read, rpos = 0;
        long length = r->remaining;
        *rbuf = apr_pcalloc(r->pool, length + 1);
        while ((len_read = ap_get_client_block(r, argsbuffer, sizeof(argsbuffer))) > 0)
        {
            if ((rpos + len_read) > length)
            {
                rsize = length - rpos;
            }
            else
            {
                rsize = len_read;
            }
            memcpy((char*) *rbuf + rpos, argsbuffer, rsize);
            rpos += rsize;
        }
    }
}
    return rc;
...