local Http = require('coro-http') local HTTPRequest = Http.request local json = require('json') local METHODS = { GET = true, POST = true } local function QueryParams(Params) -- {Name = Value, ...} if not Params then return "" end local QueryString = "?" for ParamName, ParamValue in next, Params do if ParamValue ~= nil then QueryString = QueryString .. tostring(ParamName) .. "=" .. tostring(ParamValue) .. "&" end end return string.sub(QueryString, 1, -2) -- Remove last character (will always be a "&") end local function CreateHeaders(Headers) -- {Name = Value, ...} if not Headers then return {} end local RequestHeaders = {} for HeaderName, HeaderValue in next, Headers do RequestHeaders[#RequestHeaders + 1] = { tostring(HeaderName), tostring(HeaderValue) } end return RequestHeaders end local function TryDecodeJson(Body) local Success, Result = pcall(json.decode, Body) if not Success then return Body end return Result end local function NormalizeHeaders(Response) for Index, Header in next, Response do if type(Header) == "table" and #Header == 2 then local HeaderName, HeaderValue = table.unpack(Header) Response[HeaderName] = HeaderValue Response[Index] = nil end end end local function Request(Method, Url, Params, RequestHeaders, RequestBody, Callback) if not METHODS[Method] then error("[HTTP] Method " .. Method .. " is not supported.") end if type(Url) ~= "string" then error("[HTTP] Url is not a string") end if type(RequestBody) == "table" then RequestBody = json.encode(RequestBody) end local QueryString = QueryParams(Params) -- at worse (I think), this is an empty string (which cannot mess up the request) local FormattedHeaders = CreateHeaders(RequestHeaders) -- At worse, this will just be an empty table (which cannot mess up the request) local RequestUrl = Url .. QueryString print(RequestUrl) if Callback and type(Callback) == "function" then return coroutine.wrap(function() local Headers, Body = HTTPRequest(Method, RequestUrl, FormattedHeaders, RequestBody) NormalizeHeaders(Headers) Callback(Headers, TryDecodeJson(Body)) end) else local Headers, Body = HTTPRequest(Method, RequestUrl, FormattedHeaders, RequestBody) NormalizeHeaders(Headers) return Headers, TryDecodeJson(Body) end end return { Request = Request }