Last active
December 21, 2015 13:09
-
-
Save suzumura-ss/a3a479b57c061c090caf to your computer and use it in GitHub Desktop.
nginx-lua: upload request-body to other service with LuaSocket
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- 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