diff options
author | 2016-03-12 12:31:13 +0100 | |
---|---|---|
committer | 2016-03-12 12:31:13 +0100 | |
commit | a026a582f1a0ea8c1ede3acaddacef506ef3f3b0 (patch) | |
tree | e31573822f2359677de519f9f3b600d98e8764cd /plugins/coro-http/init.lua | |
parent | 477d2abd43984f076b7e45f5527591fa8fd0d241 (diff) | |
parent | dcab55bf53b94713a6f72e9633f5101c8dd6c08c (diff) |
Merge pull request #15 from mamedev/master
Sync to base master
Diffstat (limited to 'plugins/coro-http/init.lua')
-rw-r--r-- | plugins/coro-http/init.lua | 187 |
1 files changed, 0 insertions, 187 deletions
diff --git a/plugins/coro-http/init.lua b/plugins/coro-http/init.lua deleted file mode 100644 index 49613403eaf..00000000000 --- a/plugins/coro-http/init.lua +++ /dev/null @@ -1,187 +0,0 @@ -local exports = {} -exports.name = "creationix/coro-http" -exports.version = "1.2.1-1" -exports.dependencies = { - "creationix/coro-net@1.1.1", - "creationix/coro-tls@1.2.1", - "creationix/coro-wrapper@1.0.0", - "luvit/http-codec@1.0.0" -} -exports.homepage = "https://github.com/luvit/lit/blob/master/deps/coro-http.lua" -exports.description = "An coro style http(s) client and server helper." -exports.tags = {"coro", "http"} -exports.license = "MIT" -exports.author = { name = "Tim Caswell" } - -local httpCodec = require('http-codec') -local net = require('coro-net') -local connect = net.connect -local createServer = net.createServer ---local tlsWrap = require('coro-tls').wrap -local wrapper = require('coro-wrapper') - -function exports.createServer(options, onConnect) - createServer(options, function (rawRead, rawWrite, socket) - local read = wrapper.reader(rawRead, httpCodec.decoder()) - local write = wrapper.writer(rawWrite, httpCodec.encoder()) - for head in read do - local parts = {} - for part in read do - if #part > 0 then - parts[#parts + 1] = part - else - break - end - end - local body = table.concat(parts) - head, body = onConnect(head, body, socket) - write(head) - if body then write(body) end - write("") - if not head.keepAlive then break end - end - end) -end - -local function parseUrl(url) - local protocol, host, hostname, port, path = url:match("^(https?:)//(([^/:]+):?([0-9]*))(/?.*)$") - if not protocol then error("Not a valid http url: " .. url) end - local tls = protocol == "https:" - port = port and tonumber(port) or (tls and 443 or 80) - if path == "" then path = "/" end - return { - tls = tls, - host = host, - hostname = hostname, - port = port, - path = path - } -end -exports.parseUrl = parseUrl - -local connections = {} - -local function getConnection(host, port, tls) - for i = #connections, 1, -1 do - local connection = connections[i] - if connection.host == host and connection.port == port and connection.tls == tls then - table.remove(connections, i) - -- Make sure the connection is still alive before reusing it. - if not connection.socket:is_closing() then - connection.reused = true - connection.socket:ref() - return connection - end - end - end - local read, write, socket = assert(connect({host=host,port=port})) - --if tls then - --read, write = tlsWrap(read, write) - --end - local httpRead, updateRead = wrapper.reader(read, httpCodec.decoder()) - return { - socket = socket, - host = host, - port = port, - tls = tls, - read = httpRead, - write = wrapper.writer(write, httpCodec.encoder()), - reset = function () - -- This is called after parsing the response head from a HEAD request. - -- If you forget, the codec might hang waiting for a body that doesn't exist. - updateRead(httpCodec.decoder()) - end - } -end -exports.getConnection = getConnection - -local function saveConnection(connection) - if connection.socket:is_closing() then return end - connections[#connections + 1] = connection - connection.socket:unref() -end -exports.saveConnection = saveConnection - -function exports.request(method, url, headers, body) - local uri = parseUrl(url) - local connection = getConnection(uri.hostname, uri.port, uri.tls) - local read = connection.read - local write = connection.write - - local req = { - method = method, - path = uri.path, - {"Host", uri.host} - } - local contentLength - local chunked - if headers then - for i = 1, #headers do - local key, value = unpack(headers[i]) - key = key:lower() - if key == "content-length" then - contentLength = value - elseif key == "content-encoding" and value:lower() == "chunked" then - chunked = true - end - req[#req + 1] = headers[i] - end - end - - if type(body) == "string" then - if not chunked and not contentLength then - req[#req + 1] = {"Content-Length", #body} - end - end - - write(req) - if body then write(body) end - local res = read() - if not res then - write() - -- If we get an immediate close on a reused socket, try again with a new socket. - -- TODO: think about if this could resend requests with side effects and cause - -- them to double execute in the remote server. - if connection.reused then - return exports.request(method, url, headers, body) - end - error("Connection closed") - end - - body = {} - if req.method == "HEAD" then - connection.reset() - else - while true do - local item = read() - if not item then - res.keepAlive = false - break - end - if #item == 0 then - break - end - body[#body + 1] = item - end - end - - if res.keepAlive then - saveConnection(connection) - else - write() - end - - -- Follow redirects - if method == "GET" and (res.code == 302 or res.code == 307) then - for i = 1, #res do - local key, location = unpack(res[i]) - if key:lower() == "location" then - return exports.request(method, location, headers) - end - end - end - - return res, table.concat(body) -end - -return exports |