<div dir="ltr">Здравия, друзья! Всех с прошедшими праздниками!<div><br></div><div>В процессе приведения конфигурации своих веб-серверов в более лицеприятный столкнулся с таким моментом: автоматическое добавление слэша не происходит после отрабатывания директивы try_files. Было неожиданно. Немного примеров, чтобы стало понятнее, о чем речь (ниже 2 фрагмента конфигурации - "до" и "после"):</div>

<div><br></div><div><div><span class="" style="white-space:pre">                </span>location /webapp/ {</div><div><span class="" style="white-space:pre">                </span>        proxy_pass         <a href="http://app_upstream">http://app_upstream</a>;</div>

<div><span class="" style="white-space:pre">                    </span>include my-site/proxy_pass_params.conf;</div><div><span class="" style="white-space:pre">            </span>}</div></div><div><br></div><div>Подумалось, что правильнее отдавать статику силами nginx'а, а не напрягать и без того кривое приложение:) В итоге, location принял следующий облик:</div>

<div><br></div><div><div><span class="" style="white-space:pre">                </span>location /webapp/ {</div><div><span class="" style="white-space:pre">                        </span>root<span class="" style="white-space:pre">      </span>/var/www/webapps/nginx-static;</div>

<div><span class="" style="white-space:pre">                    </span>try_files<span class="" style="white-space:pre"> </span>$uri<span class="" style="white-space:pre">      </span>@application-handle;</div><div><span class="" style="white-space:pre">               </span>}</div>

<div><br></div><div><span class="" style="white-space:pre">           </span>location @application-handle {</div><div><span class="" style="white-space:pre">             </span>        proxy_pass         <a href="http://app_upstream">http://app_upstream</a>;</div>

<div><span class="" style="white-space:pre">                    </span>include my-site/proxy_pass_params.conf;</div><div><span class="" style="white-space:pre">            </span>}</div></div><div><br></div><div>В результате, в принципе, получил то, что хотел: запрашиваемые файлы сначала ищутся в /var/www/webapps/nginx-static, и, если ничего не нашли, - проксируем на приложение. Но - перестали обрабатываться запросы вида <a href="http://my.site.com/webapp">http://my.site.com/webapp</a>, хотя запросы <a href="http://my.site.com/webapp/">http://my.site.com/webapp/</a> (со слэшем на конце) обрабатываются корректно.</div>

<div>Оно то, в общем-то, и правильно: в документации сказано:</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

<div><span style="color:rgb(0,0,0);font-family:Georgia,serif;font-size:medium;text-align:justify">Если location задан префиксной строкой со слэшом в конце и запросы обрабатываются при помощи</span><span style="color:rgb(0,0,0);font-family:Georgia,serif;font-size:medium;text-align:justify"> </span><a href="http://nginx.org/ru/docs/http/ngx_http_proxy_module.html#proxy_pass" style="font-family:Georgia,serif;font-size:medium;text-align:justify">proxy_pass</a><span style="color:rgb(0,0,0);font-family:Georgia,serif;font-size:medium;text-align:justify">,</span><span style="color:rgb(0,0,0);font-family:Georgia,serif;font-size:medium;text-align:justify"> </span><a href="http://nginx.org/ru/docs/http/ngx_http_fastcgi_module.html#fastcgi_pass" style="font-family:Georgia,serif;font-size:medium;text-align:justify">fastcgi_pass</a><span style="color:rgb(0,0,0);font-family:Georgia,serif;font-size:medium;text-align:justify">,</span><span style="color:rgb(0,0,0);font-family:Georgia,serif;font-size:medium;text-align:justify"> </span><a href="http://nginx.org/ru/docs/http/ngx_http_scgi_module.html#scgi_pass" style="font-family:Georgia,serif;font-size:medium;text-align:justify">scgi_pass</a><span style="color:rgb(0,0,0);font-family:Georgia,serif;font-size:medium;text-align:justify">,</span><span style="color:rgb(0,0,0);font-family:Georgia,serif;font-size:medium;text-align:justify"> </span><a href="http://nginx.org/ru/docs/http/ngx_http_uwsgi_module.html#uwsgi_pass" style="font-family:Georgia,serif;font-size:medium;text-align:justify">uwsgi_pass</a><span style="color:rgb(0,0,0);font-family:Georgia,serif;font-size:medium;text-align:justify"> </span><span style="color:rgb(0,0,0);font-family:Georgia,serif;font-size:medium;text-align:justify">или</span><span style="color:rgb(0,0,0);font-family:Georgia,serif;font-size:medium;text-align:justify"> </span><a href="http://nginx.org/ru/docs/http/ngx_http_memcached_module.html#memcached_pass" style="font-family:Georgia,serif;font-size:medium;text-align:justify">memcached_pass</a><span style="color:rgb(0,0,0);font-family:Georgia,serif;font-size:medium;text-align:justify">, а в ответ на запрос с URI равным этой строке, но без завершающего слэша, будет возвращено постоянное перенаправление с кодом 301 на URI с добавленным в конец слэшом. Если такое поведение нежелательно, можно задать точное совпадение URI и location, например:</span></div>

<blockquote class="" style="background-color:transparent;border:none;margin:1em;padding:0.5em;color:rgb(0,0,0);font-family:Georgia,serif;font-size:medium"><pre style="padding:0px;margin-top:0px;margin-bottom:0px">location /user/ {
    proxy_pass <a href="http://user.example.com">http://user.example.com</a>;
}

location = /user {
    proxy_pass <a href="http://login.example.com">http://login.example.com</a>;
}</pre><div><br></div></blockquote></blockquote><div>Про try_files тут не сказано ни слова.) Но возник законный вопрос: а как вернуть прежнее поведение? можно ли сделать это "красиво"? или придется городить магию с реврайтами? а если писать реврайты - куда их пихать.. в общем, как-то так. Как-то сходу не получилось самому ответить на эти вопросы, решил поделиться с сообществом. Буду признателен за любые предложения выхода из ситуации.</div>

<div><br></div><div>Немного информации, которая может быть полезной:</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

<div><div>[ root@app1 ~]# nginx -V</div><div>nginx version: nginx/1.0.15</div><div>built by gcc 4.4.6 20110731 (Red Hat 4.4.6-3) (GCC) </div><div>TLS SNI support enabled</div><div>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</div>

</div><div><br></div><div><div>[ root@app1 ~]# lsb_release -a</div><div>LSB Version:<span class="" style="white-space:pre">   </span>:core-4.0-amd64:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-noarch</div>

<div>Distributor ID:<span class="" style="white-space:pre">     </span>CentOS</div><div>Description:<span class="" style="white-space:pre"> </span>CentOS release 6.2 (Final)</div><div>Release:<span class="" style="white-space:pre"> </span>6.2</div>

<div>Codename:<span class="" style="white-space:pre">   </span>Final</div></div><div><br></div><div><div>[ root@app1 ~]# uname -a</div><div>Linux app1 2.6.32-220.23.1.el6.x86_64 #1 SMP Mon Jun 18 18:58:52 BST 2012 x86_64 x86_64 x86_64 GNU/Linux</div>

</div></blockquote><div><br></div><div>Содержимое my-site/proxy_pass_params.conf (роли наверняка не играет, но для полноты картины - надо):</div><div><br></div><div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

<div>proxy_redirect     off;</div><div><br></div><div>proxy_set_header   Host                   $host;</div><div>proxy_set_header   Remote-Addr       $remote_addr;</div><div>proxy_set_header   X-Real-IP            $remote_addr;</div>

<div>proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;</div><div>proxy_set_header   X-Public-Url         http://$host$request_uri;</div><div><br></div><div>client_max_body_size                      40m;</div>

<div>client_body_buffer_size                    128k;</div><div><br></div><div>proxy_connect_timeout                    90;</div><div>proxy_send_timeout                        90;</div><div>proxy_read_timeout                         2600;</div>

<div><br></div><div>proxy_buffer_size                           4k;</div><div>proxy_buffers                                 4 32k;</div><div>proxy_busy_buffers_size                 64k;</div><div>proxy_temp_file_write_size              64k;</div>

</blockquote><div><br></div><div>awaiting.. </div></div></div>