2

I have a program that creates optimized versions of pictures that are uploaded to the /images/ folder on the web server. It traverses subfolders and in each one, creates a .optimized folder that holds the optimized version, if it is at least a certain size smaller than the original. My goal is to check if such an optimized version exists, serve it if it does, and serve the original otherwise (in some sense like how gzip_static serves a .gz version of a file if it exists).

I'm running NGINX as a proxy in front of Apache, so while I'm accustomed to handling issues like this using htaccess, I am trying to do it natively in NGINX to avoid the server having to hand the request over to Apache. In .htaccess, I could do something like this:

RewriteCond %{REQUEST_FILENAME} ^(/images/(?:.*/)?)(.*?)$ [OR]
RewriteCond $1.optimized/$2 -f
RewriteRule .* $1/.optimized/$2 [L]

Is there a good way to handle this directly in NGINX? Most similar use cases I've found kept all the cached/optimized files in a single cached folder, as opposed to the structure I'm describing.

Timothy R. Butler
  • 703
  • 2
  • 11
  • 22
  • `if ($request_filename ~ "^/(.*/)+(.*?)$"){ set $rule_0 1; } if (-f /${fref_0_0}/.optimized/${fref_0_1}){ set $rule_0 1; } if ($rule_0 = "1"){ rewrite /.* /$1/.optimized/$2 last; }` can you test this, if I read your request correctly it may work, else we have to use try files – djdomi Jul 05 '21 at 17:15
  • The files are below the `/images/` folder. Does the URI begin with `/images/` also? – Richard Smith Jul 05 '21 at 17:17
  • @djdomi Thank you! I'll have access to my server in just a bit and will give that a try. – Timothy R. Butler Jul 05 '21 at 17:20
  • @RichardSmith Yes. I erroneously had left that out of the htaccess example. I corrected that now. Thanks! – Timothy R. Butler Jul 05 '21 at 17:20

1 Answers1

3

You can use a regular expression location to extract the first and second parts of the URI. Use a try_files statement to search the file system for each file in order.

For example:

location ~ ^(/images/.*?)([^/]+)$ {
    try_files $1.optimized/$2 $1$2 =404;
}
Richard Smith
  • 12,834
  • 2
  • 21
  • 29
  • I think the order should be `try_files $1.optimized/$2 $1$2 =404`, so that the optimized version is used if it exists. – Tero Kilkanen Jul 05 '21 at 19:22
  • 1
    Oops. Fixed. Thanks @TeroKilkanen – Richard Smith Jul 05 '21 at 19:28
  • Thank you so much! There was a bug in my regex (it assumed there would be at least one subdirectory involved, which can't be assumed), although even when I switch to `^(/images/(?:.*/)?)(.*)$` it doesn't seem to be "activating." I'm trying to figure out why.... – Timothy R. Butler Jul 06 '21 at 04:44
  • Oh! I realized that my proxy_pass was getting in the way of serving static content... I'll have to work on that, but that at least explains why it didn't apply. Thanks again! – Timothy R. Butler Jul 06 '21 at 07:51