У меня странная проблема с Nginx. Это минимальный конфиг, воспроизводящий ошибку:
server {
server_name mydomain.com;
listen 111.111.111.111:80;
root /some/path;
set $some_var $sent_http_content_type;
add_header "X-Debug" $sent_http_content_type;
}
В таком случае X-Debug
заголовок никогда не отображается в ответе. Но, если я прокомментирую эту строку:
set $some_var $sent_http_content_type;
все работает. Мне это кажется очень странным, потому что эта строка не переназначает $sent_http_content_type
var, но только читает.
Похоже, это принадлежит $sent_http_
только переменные.
Я тоже пробовал "${sent_http_content_type}"
вместо того $sent_http_content_type
с тем же результатом.
more_set_headers
директива не исправляет этого.
Почему Nginx так себя ведет? Это ошибка?
Редактировать:
Приведенный мной пример - это простейший случай, когда $sent_http_
вары исчезают. На самом деле я хочу сделать что-то вроде этого:
if ($sent_http_access_control_allow_origin ~ "^(https?)://([^/]+)") {
set $new_cors http://$1.$2.proxy.mydomain.com;
}
more_set_headers "Access-Control-Allow-Origin: $new_cors";
Я пишу прокси-сервер и мне нужно заменить Access-Control-Allow-Origin
заголовок ответа, потому что в противном случае прокси-сайты не будут работать должным образом.
В приведенном выше примере if
состояние (в server
раздел) никогда не уступает true
, даже если такой заголовок есть и он подходит моему регулярному выражению.
Это можно исправить? Ценю вашу помощь!
Nginx's rewrite
модуль (где переменные и set
директива принадлежит) довольно неинтуитивно и хрупко. Но на самом деле
set $some_var $sent_http_content_type;
в любом случае бессмысленно, потому что set
директива выполняется в начале запроса и нет $sent_http_*
переменные, доступные на данный момент.
Что вы могли бы сделать (если действительно хотите использовать $sent_http_*
переменные каким-то образом) заключается в использовании map
директива.
map $sent_http_content_type $some_var {
default $sent_http_content_type;
}
...
server {
...
add_header "X-Debug" $sent_http_content_type;
add_header "X-Debug2" $some_var;
}
РЕДАКТИРОВАТЬ: Ваша проблема может быть решена с помощью еще map
s, но было бы намного проще, если бы вы могли использовать модуль Lua.
Вот как это можно сделать с map
s: (совершенно нечитаемый и не поддерживаемый)
map $sent_http_access_control_allow_origin $__proto {
default "NONE";
"~^(?<_>https?):" "$_";
}
map $sent_http_access_control_allow_origin $__host {
default "";
"~^https?://(?<_>[^/]+)" "$_";
}
map "http://$__proto.$__host.proxy.mydomain.com" $new_cors {
default "";
"~^http://NONE" "";
"~^(?<_>.+)$" "$_";
}