To handle large response bodies without high memory usage, use the streamed request pattern. This involves three distinct steps:
- Connect: Establish a connection using
connect. - Request: Send the request using
request (providing path and Host header instead of a full URI). - Stream: Use the
body_reader iterator from the response object to read the body in chunks.
Finally, use set_keepalive() to return the connection to the pool or close it. This pattern is essential for predictable memory usage and allows for request pipelining.
local httpc = require("resty.http").new()
-- First establish a connection
local ok, err, ssl_session = httpc:connect({
scheme = "https",
host = "127.0.0.1",
port = 8080,
})
if not ok then
ngx.log(ngx.ERR, "connection failed: ", err)
return
end
-- Then send using `request`, supplying a path and `Host` header instead of a
-- full URI.
local res, err = httpc:request({
path = "/helloworld",
headers = {
["Host"] = "example.com",
},
})
if not res then
ngx.log(ngx.ERR, "request failed: ", err)
return
end
-- We can use the `body_reader` iterator, to stream the body according to our
-- desired buffer size.
local reader = res.body_reader
local buffer_size = 8192
repeat
local buffer, err = reader(buffer_size)
if err then
ngx.log(ngx.ERR, err)
break
end
if buffer then
-- process
end
until not buffer
local ok, err = httpc:set_keepalive()
if not ok then
ngx.say("failed to set keepalive: ", err)
return
end