Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!


Nginx rewrite rules help needed
New on LowEndTalk? Please Register and read our Community Rules.

All new Registrations are manually reviewed and approved, so a short delay after registration may occur before your account becomes active.

Nginx rewrite rules help needed

DudeistDudeist Member
edited December 2012 in General

Greetings!

Trying to test my new site on nginx and have one last rewrite rule to fix. Everything else is working
fine except for images, namely this:

RewriteRule ^file/([0-9]+)?/([0-9]+)x([0-9]+)/([^/\.]+) image.php?id=$1&width=$2&height=$3&cropratio=$4 [L]

So far I've tried the following rules:

rewrite ^/file/([0-9]+)?/([0-9]+)x([0-9]+)/([^/.]+) /image.php?id=$1&width=$2&height=$3&cropratio=$4 last;

and this one:

rewrite ^/file/([0-9]+)?/([0-9]+)x([0-9]+)/([^/\.]+) /image.php?id=$1&width=$2&height=$3&cropratio=$4 last;

but it still doesn't generate any images. I'm pulling my hair out and hope someone will know the trick. Maybe even a more elegant way to do this?

Thanks

Comments

  • location /file {
    rewrite ^/file/([0-9]+)?/([0-9]+)x([0-9]+)/([^/.]+) /image.php?> id=$1&width=$2&height=$3&cropratio=$4 break;
    }

    Try this, not totally sure.

  • @Patrick said: Try this, not totally sure.

    Unfortunately it doesn't, but thanks anyway.

  • It might be worth visiting #nginx on irc.freenode.net.

    Generally speaking, the people on there know their stuff, and are very helpful when asked politely :)

  • nginx mailing list is the best nginx reference

  • @ElliotJ said: It might be worth visiting #nginx on irc.freenode.net.

    No one's there atm, but I'll hang around just in case someone shows up. Thanks.

  • Really try the nginx mailing list/forum! Great helpful people there!

    http://forum.nginx.org/

  • @Dudeist - are you running WordPress with Nginx? If not, what software is it? What are you trying to accomplish with your rules? This might be helpful info to provide so that we can help you. I do build custom Nginx 1.2 and 1.3 packages for CentOS 6, and I have pretty good experience with this software, so I'd be more than happy to help!

  • @marcm said: @Dudeist - are you running WordPress with Nginx? If not, what software is it? What are you trying to accomplish with your rules? This might be helpful info to provide so that we can help you. I do build custom Nginx 1.2 and 1.3 packages for CentOS 6, and I have pretty good experience with this software, so I'd be more than happy to help!

    No, this is not wordpress. It's a custom/customized script someone has build for me, so I'm left with it on my own. This rule is for making neat looking thumbnail URL's, because the thumbnails are generated on the flight and stored in a cache without touching the original image. In the above example, the path to the image should be like this:

    http://domain.com/file/36/225x150/crop/some-image.jpg

    If you need any more details, please let me know.

    Thanks

  • EllimistEllimist Member
    edited December 2012
        location /file/ {
                rewrite ^\/file\/([0-9]+\/)?([0-9]+)x([0-9]+)\/([^\/\.]+)\/[^\/]+$ /image.php?id=$1&width=$2&height=$3&cropratio=$4 last;
        }
    

    Your regex was not matching the whole URL.

    I also included the slash inside the first, optional backreference, otherwise if the backreference is absent, it will only match URLs with two slashes after /file.

  • @Ellimist said: location /file/ { rewrite ^\/file\/([0-9]+\/)?([0-9]+)x([0-9]+)\/([^\/.]+)\/[^\/]+$ /image.php?id=$1&width=$2&height=$3&cropratio=$4 last; }

    Unfortunately this doesn't work either. Also tried the above without the location directive, but no luck. Before you ask, yes, I'm restarting the server on every change.

    Thanks for taking a shot at it. I'm starting to lose my mind over this.

  • It should work unless something else is interfering. (worked on v0.7.67, v1.1.19 and v1.2.1) Can you post your full config file here or on Pastebin?

  • @Ellimist said: It should work unless something else is interfering. (worked on v0.7.67, v1.1.19 and v1.2.1) Can you post your full config file here or on Pastebin?

    Happy New Year!

    Here are the nginx files:

    Main Nginx Configuration
    vhost File
    custom.conf

    I think this should be it.

  • Hmm, nothing seems out of place. Can you check the error logs and see if it's a 404 generated for the pretty URL or image.php?

  • seikanseikan Member
    edited January 2013

    @Dudeist said: rewrite ^/file/([0-9]+)?/([0-9]+)x([0-9]+)/([^/.]+) /image.php?id=$1&width=$2&height=$3&cropratio=$4 last;

    If I remember correctly, you will need to quote your regular expression.

    rewrite "^/file/([0-9]+)?/([0-9]+)x([0-9]+)/([^/.]+)" /image.php?id=$1&width=$2&height=$3&cropratio=$4 last;
  • kevin78kevin78 Member
    edited January 2013

    It looks to me that your location blocks are preventing the rewrite from taking effect.

    This is a rough paraphrasing of your current configuration:

    location /
    { rewrite ^/file/([0-9]+)?/([0-9]+)x([0-9]+)/([^/\.]+) /image.php?id=$1&width=$2&height=$3&cropratio=$4 last;
      ... }
    location ~ \.jpg$ { ... }
    

    Now, if you visit the site URL http://domain.com/file/36/225x150/crop/some-image.jpg in your browser, it will match your second location -- the one that matches against images. Your other location is only a fallback when nothing matches the regex location. Because the rewrite is in the fallback, it won't take effect with URLs that end in image file extensions.

    I think you can fix this with creative use of try_files.

    location @FileNoteFound {
        rewrite ^/file/([0-9]+)?/([0-9]+)x([0-9]+)/([^/\.]+) /image.php?id=$1&width=$2&height=$3&cropratio=$4 last;
    }
    location ~ \.jpg$ {
        try_files $uri @FileNotFound;
        expires 30d;
    }
    

    Note that you must have the try_files entry in the deepest nested location that your URLs can actually reach. This is because you are using a regex location, and these are selected over any partial matching location and try_files statements.

    PS. Hi everyone. I'm new here.

  • @kevin78 said: It looks to me that your location blocks are preventing the rewrite from taking effect.

    You're right about the location block preventing the rewrite from taking effect. The only thing that needed to be done was to place the original rewrite above the location / directive, so on first line, and boom - it works! Here's the final custom.conf if you want to see it. No need for try_files.

    Thanks for the great suggestion! BTW, did you just register to comment on my problem?

    Also big thanks to everyone for giving it a shot. Problem solved.

  • @Dudeist Yes, I registered when I saw you needed help.

    Moving the rewrite is a good solution, but it does have some problems that you might not like.

    The first problem is that your expires 30d; will no longer be taking effect. This is because the rewritten URL does not match the location block that sets the expiration date.

    The second problem is more of an opinion I have, in that a simple rewrite does not always do what is best. I think it is more useful to have the rewrites only take effect if the underlying file is actually missing. That's what the try_files solution ensures.

    The try_files solution might give you more long-term options. For example, you could decide to do static caching of the most frequent thumbnails at their associated URLs. NginX will then serve the direct version if it exists, and fall back to your script if it doesn't. The cost of the flexibility is a file existance check, which should be cheap.

    That's just something to keep in mind. Right now, the expires header might be a real problem. Maybe you should use web-sniffer.net to see if the expires header is being set correctly.

  • @kevin78

    Oh, I see. You're right about the images not being cached client-side in the current configuration.

    As to your second point, and forgive me if I'm not understanding this correctly (I'm not a developer), the cached thumbnails are currently stored in the script's folder as a hash, with a set memory limit of 100MB, so I would assume that the nginx rewrite has to take place every time the file is requested. Either way, I'm still not sure where to place the try_files solution to make it work. It can't go in the custom.conf as I'm getting the following error:

    nginx: [emerg] named location "@FileNoteFound" can be on the server level only in /usr/local/nginx/conf/custom.conf

    Placing it in the vhost file either spits out various errors or is ineffective.

    In the meantime, as a temporary workaround I've palced expires 30d; just below the first line in the custom.conf and it's working correctly. Like this:

    `rewrite ^/file/([0-9]+)?/([0-9]+)x([0-9]+)/([^/.]+) /image.php?id=$1&width=$2&height=$3&cropratio=$4 last;
    expires 30d;

    location / {
    ...`

    May not be ideal but at least it works.

  • @Dudeist Oh, sorry, I made a typo that might be tripping you up. The location block should be spelled @FileNotFound rather than @FileNoteFound. Try the following:

    location @FileNotFound {
        rewrite ^/file/([0-9]+)?/([0-9]+)x([0-9]+)/([^/\.]+) /image.php?id=$1&width=$2&height=$3&cropratio=$4 last;
    }
    location ~ \.jpg$ {
        try_files $uri @FileNotFound;
        expires 30d;
    }
    

    You can put the expires header where you now have it, but it might then be applying that header to almost everything. Perhaps you should check if it is being applied to non-images, which would be undesirable.

  • @kevin78

    Oh, silly me, how did I not notice this. Anyway, I got this working. I've put the above code in the vhost file, just above include custom.conf;. The expires 30d; was left one the first line in the custom.conf as suggested otherwise the expires are being called from the main nginx.conf. Just double checked and the expires are correctly applying to the thumbnails only.

    What can I say, thank you so much for your help with this. You certainly spared me a lot of headache.

  • @Dudeist You are welcome. I'm glad to have been able to help.

Sign In or Register to comment.