Написание модуля Nginx: как переслать запрос на сервер?

Я использую nginx в качестве обратного прокси-сервера и пытаюсь написать модуль nginx, который будет обрабатывать входящие запросы, и если ему нравятся определенные HTTP-заголовки, присутствующие в запросе, nginx позволит запросу достичь защищенного сервера (за прокси nginx). Теперь я успешно реализовал обработку заголовка, но я застрял в выяснении, как перенаправить запрос на сервер.

До сих пор я изучал подзапросы, но ни один из кодов, которые я пробовал (или скопировал из существующих модулей, таких как ngx_http_addition_filter_module!) похоже на работу. Либо я застреваю в цикле, где запускается более 100 подзапросов, либо ничего не происходит вообще. Код, который я пытался использовать:

static ngx_int_t ngx_http_my_own_handler(ngx_http_request_t *r)
{
    // some request processing here
    // ...


    // now issue the sub-request
    ngx_http_request_t *sr;
    ngx_http_post_subrequest_t *ps;

    ps = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t));
    if (ps == NULL) {
        return NGX_ERROR;
    }

    ps->handler = ngx_http_foo_subrequest_done;
    ps->data = "foo";

    // re-use the request URI to try to forward it
    return ngx_http_subrequest(r, &r->uri, &r->args, &sr, ps, NGX_HTTP_SUBREQUEST_CLONE);
}

И ngx_http_foo_subrequest_done Обработчик выглядит так:

ngx_int_t ngx_http_foo_subrequest_done(ngx_http_request_t *r, void *data, ngx_int_t rc)
{
    char *msg = (char *) data;
    ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "done subrequest r:%p msg:%s rc:%i", r, msg, rc);
    return rc;
}

Посоветуйте пожалуйста что я делаю не так!

1 ответ

Решение

Прокси не работает так, как вы ожидаете... Я тоже был удивлен!

URI необходимо изменить в строке, которая соответствует location /... в вашем конфигурационном файле. Тогда proxy_... определения будут включать в себя реальный полный пункт назначения.

Поскольку путь преобразуется в переменную, вы можете включить имя домена. Так, например, ваш URI может быть:

http://example.com/images/bunny.png

В вашем модуле преобразуйте это в путь, такой как:

/example.com/images/bunny.png

Затем в вашем nginx.conf укажите местоположение:

location /example.com {
    proxy_pass http://example.com;
}

Как я уже говорил, вы можете сделать example.com разделить переменную и использовать ее в своем proxy_pass, что может быть очень полезно, если у вас много целевых доменов. Всего от 1 до 5, вероятно, легче обрабатывать каждый со своим location определение.

Другие вопросы по тегам