Transparent file substitution

Андрей Середенко andrei.seredenko at gmail.com
Tue Sep 2 14:20:00 UTC 2014


Доброго дня всем!

Ребят, подскажите - имеется такой вопрос..

INTRO:

Mono. Есть приложение, на которое nginx проксирует запросы. И есть один
не-совсем-адекватный клиент, который у этого приложения запрашивает wsdl
прежде, чем воспользоваться апишкой.. перед каждым запросом... и делает это
с частотой ~200 запросов в минуту (на каждый полезный запрос - вот этот вот
сорный запрос wsdl'ки, который впустую напрягает приложение)

Возможности повлиять на клиента нет. Время подставлять костыли...


WORKAROUND:

Раз возможности повлиять на клиента нет, было принято решение обмануть его
(нормальная практика, что =) ): вместо постоянной генерации wsdl'ки на
стороне приложения - отдавать nginx'ом статический файл, содержащий её
контент (если в параметрах запроса имеется ?wsdl, если его нет - то
проксировать на приложение). Было сделано что-то вроде следующего:

location = /some/app/url/messenger.asmx {
    if ( $args ~* wsdl ) {
return 301 /some/app/url/static/messengerwsdl.xml;
    }

                    proxy_pass        http://server1:8080;

}

где /some/app/url/static/ - смотрит на папку со статикой, обрабатываемую
nginx'ом, а messengerwsdl.xml - тот самый файл с контентом wsdl'ки.
работало всё просто замечательно, но..

PROBLEMS:

..оказалось, что клиент, запрашивавший wsdl, не умеет работать с редиректом
:(

А т.к. повлиять на клиента возможности нет - пришлось чесать затылок.


GOALS:

Можно ли сделать нечто подобное *без перенаправлений* ?
Что пробовалось: положить файл в папку статики по пути, аналогичным
location и с тем же именем, и поменять $document_root в блоке if'a, но: из
if'a тоже надо как-то выходить - break не годится (обработка пойдет дальше
по локейшену и в результате - запрос будет проксирован), return не годится
(клиент не понимает редиректов), rewrite... а смысл? все равно в итоге
return new location.

В этом смысле, наверное, неплохо вписался бы try_files в блоке if'a... но
он внутри директивы if запрещён.

Может, ещё какие-нибудь варианты? И могут ли они быть в принципе.
Если что-то было не ясно в описании - могу на псевдопримерах пояснить. А
пока - вот:

#$ nginx -V
nginx version: nginx/1.0.15
built by gcc 4.4.6 20110731 (Red Hat 4.4.6-3) (GCC)
TLS SNI support enabled
configure arguments: --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx
--conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log
--http-log-path=/var/log/nginx/access.log
--http-client-body-temp-path=/var/lib/nginx/tmp/client_body
--http-proxy-temp-path=/var/lib/nginx/tmp/proxy
--http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi
--http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi
--http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/var/run/nginx.pid
--lock-path=/var/lock/subsys/nginx --user=nginx --group=nginx
--with-file-aio --with-ipv6 --with-http_ssl_module
--with-http_realip_module --with-http_addition_module
--with-http_xslt_module --with-http_image_filter_module
--with-http_geoip_module --with-http_sub_module --with-http_dav_module
--with-http_flv_module --with-http_mp4_module
--with-http_gzip_static_module --with-http_random_index_module
--with-http_secure_link_module --with-http_degradation_module
--with-http_stub_status_module --with-http_perl_module --with-mail
--with-mail_ssl_module --with-cc-opt='-O2 -g -pipe -Wall
-Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector
--param=ssp-buffer-size=4 -m64 -mtune=generic' --with-ld-opt=-Wl,-E

#$ lsb_release -a
LSB Version:
:core-4.0-amd64:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-noarch
Distributor ID: CentOS
Description: CentOS release 6.2 (Final)
Release: 6.2
Codename: Final



Спасибо!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/nginx-ru/attachments/20140902/a59d7672/attachment.html>


Подробная информация о списке рассылки nginx-ru