Skip to content

Instantly share code, notes, and snippets.

@cyrilis
Created July 11, 2015 17:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cyrilis/2a246ba12536a8f5cb1c to your computer and use it in GitHub Desktop.
Save cyrilis/2a246ba12536a8f5cb1c to your computer and use it in GitHub Desktop.
Superagent like request library for Luvit
--
-- Created by: Cyril.
-- Created at: 15/6/23 下午4:04
-- Email: houshoushuai@gmail.com
--
http = require("http")
https = require("https")
local qs = require('../node_modules/luvit-querystring')
local base64_table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
local sub = string.sub
local gsub = string.gsub
local byte = string.byte
local base64 = function(data)
return ((gsub(data, '.', function(x)
local r, b = '', byte(x)
for i = 8, 1, -1 do
r = r .. (b % 2 ^ i - b % 2 ^ (i - 1) > 0 and '1' or '0')
end
return r
end) .. '0000'):gsub('%d%d%d?%d?%d?%d?', function(x)
if #x < 6 then
return ''
end
local c = 0
for i = 1, 6 do
c = c + (sub(x, i, i) == '1' and 2 ^ (6 - i) or 0)
end
return sub(base64_table, c + 1, c + 1)
end) .. ({
'',
'==',
'='
})[#data % 3 + 1])
end
Emitter = require('core').Emitter
Request = Emitter:extend()
function Request:initialize (options, callback)
self.options = options or {}
self.callback = callback or function() end
local URL = require("url").parse(self.options.url)
local defaultPort = 80
self._request = http.request
if URL.protocol == "https" then
defaultPort = 443
self._request = https.request
end
self.option = {
protocol = URL.protocol or "http",
host = URL.hostname,
port = URL.port or defaultPort,
path = URL.path,
method = self.options.method and self.options.method:upper() or "GET",
headers = self.options.headers or {}
}
table.insert(self.option.headers, {"connection", "keep-alive"})
if URL.auth then
local user, pass = URL.auth:match("([^:]+):([^:]+)")
return self:auth(user, pass)
end
if URL.query then
return self:query(URL.search)
end
return self
end
function Request:on(eventName, eventFunction)
self._EVTS[eventName] = eventFunction
return self
end
function Request:set(key, value)
table.insert(self.option.headers, {key, value})
return self
end
function Request:query(query)
local url = require("url").parse(self.option.path)
p(url)
local oldQuery = url.query
p(oldQuery)
if not(oldQuery) then
oldQuery = ""
else
oldQuery = oldQuery .. "&"
end
self.option.path = url.pathname .. "?" .. oldQuery .. query
p(self.option.path)
return self
end
function Request:send(data)
-- self.option.headers["Content-Type"] = "application/x-www-form-urlencoded"
if self.option.method == "GET" or self.option.method == "HEAD" then
return false
end
self.data = data
self.postData = qs.stringify(self.data)
table.insert(self.option.headers, {"Content-length", #self.postData})
-- if ('HEAD' != options.method) req.setHeader('Accept-Encoding', 'gzip, deflate');
return self
end
function Request:auth(user, pass)
local str = base64(user .. ":" .. pass)
table.insert(self.option.headers, {"Authorization", "Basic "..str})
return self
end
function Request:done(callback)
self.callback = callback
if self._isCalled then return false end
self.client = self._request(self.option, function(res)
p('STATUS: ' .. res.statusCode);
local data = ""
res:on("data", function(chunk)
data = data .. chunk
end)
res:on("end", function(chunk)
chunk = chunk or ""
data = data .. chunk
res.body = data
self.callback(err, res)
self._isCalled = true
end)
end)
self.client:on("error", function(error)
self.callback(error)
self._isCalled = true
self:emit("error", error)
end)
if self.option.method ~= "GET" and self.option.method ~= "HEAD" then
if self.postData then self.client:write(self.postData) end
end
self.client:done();
return self
end
module.exports = {
name = "cyrilis/request",
version = "0.0.1",
get = function(url)
return Request:new({url = url, method = "GET"})
end,
post = function(url)
return Request:new({url = url, method = "POST"})
end,
put = function(url)
return Request:new({url = url, method = "PUT"})
end,
delete = function(url)
return Request:new({url = url, method = "DELETE"})
end
}
@cyrilis
Copy link
Author

cyrilis commented Jul 11, 2015

Usage:

local request  = require("./request")
local config = {
    domain = "example.com",
   api = "XXXXXXXXXXX"
}
request.post("https://api.mailgun.net/v3/"..config.domain.."/messages")
:set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
:send({
    from = "luvit@" .. config.domain,
    to   = "test@test.com",
    subject = "Hello from Luvit.",
    text = "Hello, this is luvit",
    html = "<h1>Hello, here is luvit.</h1>"
})
:auth("api", config.api)
:done(function(err, result)
    if(err) then
        p("Error:", err)
    else
        p("Email has been delivered successfully!")
    end
end)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment