Написание модуля 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
определение.