Servez des images plus grandes que la taille de fichier minimale dans Nginx (et lua)

J’essaie de vérifier si le fichier demandé est supérieur à une certaine taille (disons 250 octets) et, si tel est le cas, servez le fichier, sinon diffusez une image par défaut.

Cependant, je reçois des résultats inattendus. La ligne vérifiant la longueur du corps ne semble pas être respectée et no_image_small.png est servi. res.status == 200 semble fonctionner, cependant:

  • Taille de l’image demandée: 17 octets
  • taille no_image_small.png: 3030 octets

journal des erreurs nginx:

2014/12/01 11:52:57 [error] 6033#0: *1 subrequests cycle while processing "/images/blue_image_small.jpg", client: 127.0.0.1, server: images.dev, request: "GET /images/blue_image_small.jpg HTTP/1.1", subrequest: "/images/blue_image_small.jpg", host: "images.dev:8080" 2014/12/01 11:52:57 [error] 6033#0: *1 lua entry thread aborted: runtime error: rewrite_by_lua:2: failed to issue subrequest: -1 stack traceback: coroutine 0: [C]: in function 'capture' rewrite_by_lua:2: in function , client: 127.0.0.1, server: images.dev, request: "GET /images/blue_image_small.jpg HTTP/1.1", subrequest: "/images/blue_image_small.jpg", host: "images.dev:8080" 

Mon nginx config:

 server { listen 8080; server_name images.dev www.images.dev; root /home/syz/dev/images/; location ~* ^/images/(.*_small.) { rewrite_by_lua ' local res = ngx.location.capture(ngx.var.uri) if res.status == 200 then local blength = ssortingng.len(res.body) if blength > 250 then ngx.say(res.body) ngx.exit(ngx.OK) else ngx.redirect("/images/no_image.small.png") end else ngx.redirect("/images/no_image_small.png") end '; } } 

Au lieu de capturer et de lire la longueur du corps de la réponse, vous pouvez lire l’en tête Content-Length lors de votre validation (il est plus rapide).

J’ai une validation similaire en production, certains aiment:

 location ~*/img/.*\.(png|jpg|jpeg) { set $max_image_size 15000; # default redirect if requested image too big error_page 412 = @default_image_loc; #serving the content root /local_server/root/; #validating response header_filter_by_lua ' local image_size = tonumber(ngx.header.content_length) if image_size > tonumber(ngx.var.max_image_size) then ngx.log(ngx.NOTICE, ssortingng.format("invalid image size <%s>" , image_size)) ngx.exit(412) end '; } location @default_image_loc { try_files "/img/default_image.png" @none; } 

Le journal d’access restra propre car le saut 412 est interne.