openresty / lua-nginx-module

Embed the Power of Lua into NGINX HTTP servers
https://openresty.org/
11.3k stars 2.03k forks source link

image_filter module with ngx.location.capture problem #1063

Open olegabr opened 7 years ago

olegabr commented 7 years ago

I'm trying to get image width and height information. I can do it directly by querying the proxied location with curl, but I can not do it from lua code with ngx.location.capture. it just returns the image without image_filter processing:

The config

load_module "modules/ngx_http_image_filter_module.so";
location /ttt/ {
    proxy_pass_request_headers off;
    proxy_pass https://scontent.xx.fbcdn.net/v/t1.0-1/c50.50.621.621/s50x50/601487_103890943140684_608897883_n.jpg?oh=04ba29ad280bf84ed80029ce8f384ff9&oe=59488366;
    image_filter size;
}

location /test3/ {
    content_by_lua_block {
        local url = "/ttt/"
        res = ngx.location.capture(url)
        ngx.say(res.status)
        ngx.say(res.body)
    }
}

Direct call: success

$ curl -i -X GET 'http://127.0.0.1:82/ttt/'
HTTP/1.1 200 OK
Server: openresty/1.11.2.2
Date: Sun, 07 May 2017 20:00:41 GMT
Content-Type: application/json
Content-Length: 59
Connection: keep-alive

{ "img" : { "width": 50, "height": 50, "type": "jpeg" } }

Indirect call: failure

$ curl -i -X GET 'http://127.0.0.1:82/test3/'
HTTP/1.1 200 OK
Server: openresty/1.11.2.2
Date: Sun, 07 May 2017 20:00:44 GMT
Content-Type: text/plain
Transfer-Encoding: chunked
Connection: keep-alive
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type

200
����JFIF���Photoshop 3.08BIM
a lot of data there also ...

Can you please point me how to make it work from ngx.location.capture?

agentzh commented 7 years ago

@olegabr I guess that image filter module just refuses to work in the context of a subrequest.

olegabr commented 7 years ago

lua-resty-http wins, as always. may be it should be included in the core bundle? in a docker image at least?

location /test3/ {
    content_by_lua_block {
        local url = "http://127.0.0.1/ttt/"

        local http = require "resty.http"
        local httpc = http.new()
        local res, err = httpc:request_uri(url)

        if not res then
          ngx.say("failed to request: ", err)
          return
        end

        ngx.status = res.status

        ngx.say(res.status)
        ngx.say(res.body)
    }
}
agentzh commented 7 years ago

@olegabr subrequests do not incur any TCP (loopback) or socket overhead, unlike the http call in your example. In this particular case, I think it is much more efficient if you call libgd via FFI directly.

spacewander commented 7 years ago

@olegabr Maybe your issue is related to Lua, memc and image_filter, image not resized via lua

This is because the standard ngx_image_filter module's output filter always runs after ngx_lua's subrequest capturing filter and there's no easy way to change this order. The response body of your subrequest is captured by ngx_lua before the ngx_image_filter's filter gets a chance to run.

olegabr commented 7 years ago

@agentzh thank you for the suggestion. I'll take it into account on an optimization phase.