Location matching

I’ve just had to move subversion onto a server that’s already serving
network wordpress via nginx. Most things work via /svn in a subversion
client but I can’t for the life of me figure out how to stop /svn.*.php
hitting the fastcgi_pass.

I’m sure it’s simple and I’m just not seeing the wood for the trees.

Here’s the nginx access_log entry:
1.1.1.1 - - [12/May/2013:14:16:01 +0000] “OPTIONS /svn/live/s.php
HTTP/1.1” 404 47 “-” “SVN/1.7.8/TortoiseSVN-1.7.11.23600 neon/0.29.6”

server block:
server {
listen 80 default; ## listen for ipv4
listen 443 default ssl; ## listen for ipv4
listen [::]:80 default; ## listen for ipv6
listen [::]:443 default ssl; ## listen for ipv6
server_name abc.xyz.com;
server_name def.xyz.com;
root /srv/sites/docroot;
ssl_certificate /etc/ssl/STAR.xyz.com.pem;
ssl_certificate_key /etc/ssl/STAR.xyz.com.pem;
index index.php index.php5 index.html index.htm;
client_max_body_size 300M;
location ~ /svn {
proxy_pass http://apache;
proxy_set_header X-Real-IP $remote_addr;
}
location ~ .(php|php5) {
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
include /etc/nginx/fastcgi_params;
fastcgi_pass unix:/var/run/php/wp-sites;
}
# multi site rule
location / {
try_files $uri $uri/ /index.php?$args;
}
rewrite /wp-admin$ $scheme://$host$uri/ permanent;
location ~* .(js|css|png|jpg|jpeg|gif|ico)$ {
expires 24h;
log_not_found off;
}
rewrite /files/$ /index.php last;
set $cachetest
“$document_root/wp-content/cache/ms-filemap/${host}${uri}”;
if ($uri ~ /$) {
set $cachetest “”;
}
if (-f $cachetest) {
rewrite ^ /wp-content/cache/ms-filemap/${host}${uri} break;
}
if ($uri !~ wp-content/plugins) {
rewrite /files/(.+)$ /wp-includes/ms-files.php?file=$1 last;
}
if (!-e $request_filename) {
rewrite ^/[_0-9a-zA-Z-]+(/wp-.) $1 last;
rewrite ^/[_0-9a-zA-Z-]+.
(/wp-admin/..php)$ $1 last;
rewrite ^/[_0-9a-zA-Z-]+(/.
.php)$ $1 last;
}
}

nginx -v:
nginx version: nginx/1.4.1
TLS SNI support enabled
configure arguments: --prefix=/usr/share/nginx
–conf-path=/etc/nginx/nginx.conf
–error-log-path=/var/log/nginx/error.log
–http-client-body-temp-path=/var/lib/nginx/body
–http-fastcgi-temp-path=/var/lib/nginx/fastcgi
–http-log-path=/var/log/nginx/access.log
–http-proxy-temp-path=/var/lib/nginx/proxy
–http-scgi-temp-path=/var/lib/nginx/scgi
–http-uwsgi-temp-path=/var/lib/nginx/uwsgi
–lock-path=/var/lock/nginx.lock --pid-path=/var/run/nginx.pid
–with-pcre-jit --with-debug --with-file-aio --with-http_addition_module
–with-http_dav_module --with-http_geoip_module
–with-http_gzip_static_module --with-http_image_filter_module
–with-http_realip_module --with-http_secure_link_module
–with-http_stub_status_module --with-http_ssl_module
–with-http_sub_module --with-http_xslt_module --with-ipv6 --with-mail
–with-mail_ssl_module
–add-module=/usr/src/nginx/source/nginx-1.4.1/debian/modules/nginx-auth-pam
–add-module=/usr/src/nginx/source/nginx-1.4.1/debian/modules/nginx-dav-ext-module
–add-module=/usr/src/nginx/source/nginx-1.4.1/debian/modules/nginx-echo
–add-module=/usr/src/nginx/source/nginx-1.4.1/debian/modules/nginx-upstream-fair
–add-module=/usr/src/nginx/source/nginx-1.4.1/debian/modules/nginx-syslog
–add-module=/usr/src/nginx/source/nginx-1.4.1/debian/modules/nginx-cache-purge
–add-module=/usr/src/nginx/source/nginx-1.4.1/debian/modules/ngx_http_pinba_module
–add-module=/usr/src/nginx/source/nginx-1.4.1/debian/modules/ngx_http_substitutions_filter_module
–add-module=/usr/src/nginx/source/nginx-1.4.1/debian/modules/nginx-x-rid-header
–with-ld-opt=-lossp-uuid

Regards
Steve.

Have you looked at the ^~ prefix mentioned in
http://wiki.nginx.org/HttpCoreModule#location ?

It looks like what you need …


Jonathan M. // Oxford, London, UK
http://www.jpluscplusm.com/contact.html

On 12/05/2013 15:55, Jonathan M. wrote:

Have you looked at the ^~ prefix mentioned in
http://wiki.nginx.org/HttpCoreModule#location ?

It looks like what you need …

I thought I’d tried that, and even with the change in config it’s still
giving me the 404 errors.

changed config:

    location ^~ /svn {
            proxy_pass http://apache;
            proxy_set_header X-Real-IP $remote_addr;
    }
    location ~* \.(php|php5) {
...

}

Steve.

On 12 May 2013 16:21, Steve W. [email protected] wrote:

On 12/05/2013 15:55, Jonathan M. wrote:

Have you looked at the ^~ prefix mentioned in
http://wiki.nginx.org/HttpCoreModule#location ?

It looks like what you need …

I thought I’d tried that, and even with the change in config it’s still
giving me the 404 errors.

It might just be some unintended rewrite you’re doing at the server
level. Those don’t look very nice, IMHO.

May I strongly suggest that you separate SVN access out by a different
host header? Then you won’t have to deal with an increasingly complex
single server{} where this sort of thing might happen when you make
the slightest change in the future …

Jonathan

Jonathan M. // Oxford, London, UK
http://www.jpluscplusm.com/contact.html

On 12/05/2013 16:34, Jonathan M. wrote:

It might just be some unintended rewrite you’re doing at the server
level. Those don’t look very nice, IMHO.

May I strongly suggest that you separate SVN access out by a different
host header? Then you won’t have to deal with an increasingly complex
single server{} where this sort of thing might happen when you make
the slightest change in the future …

That’s my last option.

Unfortunately I’ve had to move svn from a dedicated server, I’m not sure
if svn clients support SNI but I’ve only 1 IP address available on the
current machine and it’s already doing ssl which is why it’s mixed into
the wordpress junk.

Steve.

The good news is it looks like subversion clients support SNI so I’ve
got a new server block which is now working great.

server {
listen 80; ## listen for ipv4
listen 443; ## listen for ipv4
listen [::]:80; ## listen for ipv6
listen [::]:443; ## listen for ipv6
server_name svn.xyz.com;
ssl_certificate /etc/ssl/STAR.xyz.com.pem;
ssl_certificate_key /etc/ssl/STAR.xyz.com.pem;
client_max_body_size 300M;
access_log /var/log/nginx/svn_access.log;
location ^~ /svn {
proxy_pass http://apache;
proxy_set_header X-Real-IP $remote_addr;
}
location / {
return 200 “There’s nothing at $scheme://$host$uri”;
}
}

Thanks for the help.

Steve.

On Sun, May 12, 2013 at 03:25:56PM +0100, Steve W. wrote:

Hi there,

I see from the end of the thread that you have a working system now by
using separate server{} blocks, so that’s all good.

It might be interesting to see why the original did not do what you
wanted, and to see whether there is a reasonable way of not using two
server{} blocks.

Feel free to ignore this if it’s not interesting to you :slight_smile:

I’ve just had to move subversion onto a server that’s already serving
network wordpress via nginx. Most things work via /svn in a subversion
client but I can’t for the life of me figure out how to stop /svn.*.php
hitting the fastcgi_pass.

The incoming request is for “/svn/live/s.php”.

The only location{} blocks are

    location ~ /svn {
    location ~ \.(php|php5) {
    location / {
    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {

and, of those, this request should be handled in the first one. But you
report that it is actually handled in the second.

As well as the location{} blocks, there are server-level rewrites and
if()
blocks, which will take effect before the location-matching.

    rewrite /wp-admin$ $scheme://$host$uri/ permanent;

That one doesn’t apply here.

    rewrite /files/$ /index.php last;

Neither does that one.

    set $cachetest

“$document_root/wp-content/cache/ms-filemap/${host}${uri}”;
if (-f $cachetest) {

That most likely doesn’t, but it can’t be guaranteed.

    if ($uri !~ wp-content/plugins) {

That “if” does apply, but the following rewrite doesn’t.

    if (!-e $request_filename) {

That “if” most likely does apply, so the next rewrites are tried…

        rewrite ^/[_0-9a-zA-Z-]+(/wp-.*) $1 last;
        rewrite ^/[_0-9a-zA-Z-]+.*(/wp-admin/.*\.php)$ $1 last;
        rewrite ^/[_0-9a-zA-Z-]+(/.*\.php)$ $1 last;

and the third one there matches, so there’s an internal rewrite to
“/live/s.php”, and the location match actually starts with that uri.

Which matches the second location{} block above, and is consistent with
what you report.

It looks like your “wordpress” nginx config (which is similar
to what is currently on both http://wiki.nginx.org/WordPress and
Nginx « WordPress Codex) assumes that wordpress is the only
purpose of this nginx server.

It would probably take quite a bit of testing to safely get rid of the
assumptions made in the server-level “if” and “rewrite” directives
used. It looks like some could probably be replaced with location{}
blocks, but “some” isn’t “all”.

So, unless someone has the time and inclination to re-do and test that
to allow one server{} block share wordpress and anything else, it looks
like the simple change is to use a separate server{} block for
wordpress.

Which is what you did.

Cheers,

f

Francis D. [email protected]