Skip to content

Instantly share code, notes, and snippets.

@suzumura-ss
Last active December 21, 2015 13:09
Show Gist options
  • Save suzumura-ss/a3a479b57c061c090caf to your computer and use it in GitHub Desktop.
Save suzumura-ss/a3a479b57c061c090caf to your computer and use it in GitHub Desktop.
nginx-lua: upload request-body to other service with LuaSocket
2015/12/21 20:31:38 [error] 7922#0: *70 lua entry thread aborted: runtime error: attempt to yield across C-call boundary
stack traceback:
coroutine 0:
[C]: in function 'request'
/opt/nginx/scripts/upload4.lua:45: in function </opt/nginx/scripts/upload4.lua:1>, client: 127.0.0.1, server: localhost, request: "POST /upload4 HTTP/1.0", host: "localhost"
see:
http://stackoverflow.com/questions/30111808/luasocket-nginx-error-lua-entry-thread-aborted-runtime-error-attempt-to-yi
-- using https://github.com/diegonehab/luasocket
local HTTP = require("socket.http")
local LTN12 = require("ltn12")
-- source for ngx.req.socket()
function source_tcpsock(handle, bytes)
bytes = tonumber(bytes)
if handle then
return function()
if bytes <= 0 then
return nil
end
local rsize = 2048
if bytes < rsize then
rsize = bytes
end
local chunk, err, partial = handle:receive(rsize)
if err then
ngx.log(ngx.ERR, 'failed to receive request body - ' .. err)
ngx.exit(500)
end
if not chunk then
chunk = partial
end
if chunk then
bytes = bytes - #chunk
end
return chunk
end
else
return nil
end
end
-- upload uri
local post_uri = 'http://localhost:9292/teapot'
-- copy headers
local headers = ngx.req.get_headers()
local reqtype = headers['content-type'] or 'application/json'
local reqsize = headers['content-length'] or '0'
-- upload
local resbody = {}
local result, rescode, resheaders, resstatus = HTTP.request {
method = 'POST',
url = post_uri,
source = source_tcpsock(ngx.req.socket(), reqsize),
headers = {
['Content-Type'] = reqtype,
['Content-Length'] = reqsize
},
sink = LTN12.sink.table(resbody)
}
-- make response
if result then
ngx.status = rescode
ngx.header.content_type = resheaders['content-type']
ngx.say(table.concat(resbody))
else
ngx.exit(500)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment