2015-07-07 3 views
5

У меня есть директива nginx location, целью которой является «удалить» префикс локализации из URI для директивы proxy_pass.Nginx - кодировка (нормализующая) часть URI

Например, чтобы сделать URI http://example.com/en/lalala использование proxy_pass http://example.com/lalala

location ~ '^/(?<locale>[\w]{2})(/(?<rest>.*))?$' { 
     ... 
     proxy_pass http://example/$rest; 
     ... 
} 

Таким образом, переменная rest будет декодироваться, когда передается proxy_pass directeve. Кажется, ожидается behavior.

Проблема заключается в том, когда мой URI содержит закодированное пространство %20 передается от клиента

http://example.com/lala%20lala 

Nginx декодирует URI для

http://example.com/lala lala 

Я могу видеть это в моем error.log.

Вопрос в том, можно ли использовать кодировку rest переменную как-то, поскольку она передается от клиента? Если я делаю что-то совершенно неправильное, пожалуйста, предложите правильный путь.

спасибо.

ответ

6

Да, такое поведение, как ожидается, хотя документы также говорят:

Если proxy_pass указан без URI, запрос URI передается на сервер в той же форме, отправленного клиентом, когда первоначальный запрос обрабатывается или полный нормированный запрос передается URI будет при обработке измененной URI:

location /some/path/ { 
    proxy_pass http://127.0.0.1; 
} 

инженеров Nginx сказать то же самое: https://serverfault.com/questions/459369/disabling-url-decoding-in-nginx-proxy

Однако если вы добавляете $ REQUEST_URI к proxy_pass (и полосы локаль заранее может работать как said инженером Nginx):

set $modified_uri $request_uri; 

if ($modified_uri ~ "^/([\w]{2})(/.*)") { 
set $modified_uri $1; 
} 

proxy_pass http://example$modified_uri; 
+0

большое спасибо. Я знал о $ request_uri, но мои текущие знания nginx не позволяли мне правильно изменять URI. –

+0

Имейте в виду, что если вы используете $ request_uri, тогда IT НЕ ИЗМЕНИТЬ, если сделано внутреннее перенаправление, например, когда выполняется переписывание, или применяя директиву error_page. В этих случаях изменяется только $ uri, но $ uri уже декодируется, поэтому его нельзя использовать в качестве общей замены для $ request_uri. –

4

Я имел некоторый успех, используя следующие с Confluence и других приложений Atlassian за Nginx, где специальные символы, такие как() <> [] были причиной проблем.

location /path { 
    # [... other proxy options ...] 

    # set proxy path with regex 
    if ($request_uri ~* "/path(/.*)") { 
    proxy_pass http://server:port/path$1; 
    break; 
    } 

    # fallback (probably not needed) 
    proxy_pass http://server:port/path; 
} 
+0

Большое спасибо. Это закончилось 2 днями вздоха :) –

Смежные вопросы