0

I have a Nginx configuration file that works for everything except one feature. I have installed a Mediawiki, it works pretty well except at showing pictures (loading them works fine).

Whereas (sorry for castrating proper links, the site says I don't have enough rep to write them)

www.domain.tld/wiki/File:Rosa_grande.jpg

results in a 404 error,

www.domain.tld/wiki/index.php?title=File:Rosa_grande.jpg

works OK.

So I started digging in the Nginx configuration and noticed how the "/" location takes precedence to the images location. The 404 comes out because I have not installed an index.php file in the root (yet).

In particular, given a file located in:

/wiki/images/7/78/Rosa_grande.jpg

I have manually created a location that should throw (for debugging purposes only!) an error 500:

location /wiki/images/.*\.(js|css|png|jpg|jpeg|gif|ico)$ {
more_set_headers 'Location 6';

return 500;
}

The regexp parses good at http://www.regexplanet.com/advanced/java/index.html and indeed matches with "jpg".

I also tried putting ^~ /wiki/images/.... but to no result.

Every attempt at getting in this location gets overridden by this other location:

    location / {
            more_set_headers 'Location 10';
            try_files $uri $uri/ /index.php?q=$uri&$args =404;
    }

    location ~ \.php$ {
            more_set_headers 'Location 20';
            try_files $uri =404; # This is not needed if you have cgi.fix_pathinfo = 0 in php.ini (you should!)

            include include/php_fpm_pass.conf;
    }

I must keep said / location including the index.php call because it manages other web apps. As you can see I have also added some useful debugging more_set_headers statements to show the actual location(s) being processed.

Typing:

curl -I http://127.0.0.1:8080/wiki/images/7/78/Rosa_grande.jpg

should show an error 500 (/wiki/images location hit) and the header should display "location 6"

but instead it shows a 404 and location 10.

HTTP/1.1 404 Not Found
Server: nginx
Date: Wed, 31 Jul 2013 09:16:01 GMT
Content-Type: text/html
Content-Length: 162
Connection: keep-alive
Location: 10

If I put the Rosa_grande.jpg file in place, I get a "200 OK" message and still location 10:

HTTP/1.1 200 OK
Server: nginx
Date: Wed, 31 Jul 2013 09:09:02 GMT
Content-Type: image/jpeg
Content-Length: 19735
Last-Modified: Tue, 30 Jul 2013 09:50:15 GMT
Connection: keep-alive
ETag: "51f78c57-4d17"
Location: 10
Accept-Ranges: bytes
Dario Fumagalli
  • 150
  • 2
  • 9
  • Your location gets overwritten because the filename you are trying to match against is part of the query string (follows the ?) and not part of the actual path. Either use short URLs (i.e. pretty URLs, without a query string), or capture the query string and use an if statement. – cyberx86 Jul 31 '13 at 12:56
  • `www.domain.tld/wiki/File:Rosa_grande.jpg` is already the "Pretty" URL. The "ugly" version is `www.domain.tld/wiki/index.php?title=File:Rosa_grande.jpg` – Dario Fumagalli Jul 31 '13 at 13:40
  • Sorry - just skimmed the question - and saw the URL with the query string. You don't appear to have a regex setup - for a regex, you need to prefix the string with `~` or `~*`. In the current setup, therefore, it is matching in string literal mode. See: [Nginx location](http://wiki.nginx.org/HttpCoreModule#location) – cyberx86 Jul 31 '13 at 14:40
  • Yes I found out about the missing tilde. Actually now I have a full working solution, once the 8 hours time out will be over I am going to post it all. I really believe there are a lot of people in a similar situation so it will help them all. I am not just talking about the general Nginx admins but also those who ventured into installing Mediawiki and like me, cannot use a subdomain. I found out how to install Mediawiki in a /wiki subfolder and now also how to let it upload pictures without generating 404 pages. – Dario Fumagalli Jul 31 '13 at 15:14

1 Answers1

1

The answer to the first portion of my issue ended up being easy:

I should not have used:

location /wiki/images/.*\.(js|css|png|jpg|jpeg|gif|ico)$ {

but

location ~* /wiki/images/.*\.(png|jpg|jpeg|gif|ico)$ {

because only the latter is going to actually process the regexp before the "/" "catch all".

Next comes the second phase:

Transform a Mediawiki "pretty URL" like:

www.domain.tld/wiki/File:Rosa_grande.jpg

into a

www.domain.tld/wiki/index.php?title=File:Rosa_grande.jpg

call.

In fact I did not find any "obvious" mapping from the

File:Rosa_grande.jpg

URL to the actual

wiki/images/7/78/Rosa_grande.jpg

as I miss a way to find out that File:Rosa_grande.jpg maps to a file stored in a "/7/78/" subdirectoy.

Needless to say, all the other Mediawiki modules worked flawlessy with "pretty URLs", even those with a "/wiki/Action:Something" URL except for "/wiki/File:Something".

The solution ended up being rather simple: a rewrite to the proper, "ugly" URL:

    location ~* ^/wiki/File:(.*\.(png|jpg|jpeg|gif|ico))$ {
            # more_set_headers 'Location 1.7: /wiki/File';
            rewrite ^/wiki/File:(.*\.(png|jpg|jpeg|gif|ico))$ /wiki/index.php?title=File:$1 last;
    }

I am not sure the rewrite regexp is optimized but it has the awesome property of actually getting the job done.

Dario Fumagalli
  • 150
  • 2
  • 9