diff --git a/source/tools/monitor/unity/beaver/beaver.lua b/source/tools/monitor/unity/beaver/beaver.lua index f8287e1a045f77e25a8c6f3b3aab283d93861a02..15518b92dd2fdbce7f0e5bd01c823976edf10792 100644 --- a/source/tools/monitor/unity/beaver/beaver.lua +++ b/source/tools/monitor/unity/beaver/beaver.lua @@ -17,7 +17,7 @@ local CurlExportRaw = require("beaver.url_export_raw") local CLocalBeaver = require("beaver.localBeaver") local CbaseQuery = require("beaver.query.baseQuery") -local lb = nil +g_lb = nil function init(que, fYaml) fYaml = fYaml or "../collector/plugin.yaml" @@ -35,10 +35,10 @@ function init(que, fYaml) CurlExportHtml.new(web, export) CurlExportRaw.new(web, export) - lb = CLocalBeaver.new(web, fYaml) + g_lb = CLocalBeaver.new(web, fYaml) return 0 end function echo() - return lb:poll() + return g_lb:poll() end diff --git a/source/tools/monitor/unity/beaver/localBeaver.lua b/source/tools/monitor/unity/beaver/localBeaver.lua index 548bd94afa22c5cdd48e165545b0cd1359823102..22d679e88f44942c0f7071341771cc4ae2d6f4c7 100644 --- a/source/tools/monitor/unity/beaver/localBeaver.lua +++ b/source/tools/monitor/unity/beaver/localBeaver.lua @@ -59,6 +59,7 @@ function CLocalBeaver:_installTmo(fd) end function CLocalBeaver:_checkTmo() + local res, msg local now = os.time() if now - self._last >= 30 then -- ! coroutine will del self._tmos cell in loop, so create a mirror table for safety @@ -70,7 +71,8 @@ function CLocalBeaver:_checkTmo() e.fd = fd local co = self._cos[fd] print("close " .. fd) - coroutine.resume(co, e) + res, msg = coroutine.resume(co, e) + assert(res, msg) end end self._last = now @@ -250,31 +252,39 @@ function CLocalBeaver:_proc(fd) end end -function CLocalBeaver:co_add(fd) - local res = self._cffi.add_fd(self._efd, fd) +function CLocalBeaver:co_add(fd, cb) + local res = self._cffi.add_fd(self._efd, fd) -- add to epoll fd assert(res >= 0) - local co = coroutine.create(function(o, fd) self._proc(o, fd) end) + local co = coroutine.create(function(o, fd) cb(o, fd) end) self._cos[fd] = co - local res, msg = coroutine.resume(co, self, fd) - assert(res, msg) + return co end function CLocalBeaver:co_exit(fd) - local res = self._cffi.del_fd(self._efd, fd) + local res = self._cffi.del_fd(self._efd, fd) -- remove from epoll fd assert(res >= 0) self._cos[fd] = nil self._tmos[fd] = nil end +function CLocalBeaver:mod_fd(fd, wr) + local res = self._cffi.mod_fd(self._efd, fd, wr) + assert(res == 0) +end + function CLocalBeaver:accept(fd, e) if e.ev_close > 0 then error("should close bind fd.") else local nfd, err, errno = socket.accept(fd) if nfd then - self:co_add(nfd) + local co = self:co_add(nfd, self._proc) + + local res, msg = coroutine.resume(co, self, nfd) + assert(res, msg) + self:_installTmo(nfd) else system:posixError("accept new socket failed", err, errno) diff --git a/source/tools/monitor/unity/beaver/url_api.lua b/source/tools/monitor/unity/beaver/url_api.lua index c03d824ebec43a6dcb51b4487de6b23e9b448fa2..e54fa5c3d1b8a03b69e7a6b0237edbae0e4c5f9d 100644 --- a/source/tools/monitor/unity/beaver/url_api.lua +++ b/source/tools/monitor/unity/beaver/url_api.lua @@ -10,7 +10,9 @@ local ChttpApp = require("httplib.httpApp") local CfoxTSDB = require("tsdb.foxTSDB") local postQue = require("beeQ.postQue.postQue") local CpushLine = require("beaver.pushLine") - +local CasyncDns = require("httplib.asyncDns") +local CasyncHttp = require("httplib.asyncHttp") +local CasyncOSS = require("httplib.asyncOSS") local CurlApi = class("urlApi", ChttpApp) function CurlApi:_init_(frame, que, fYaml) @@ -21,8 +23,93 @@ function CurlApi:_init_(frame, que, fYaml) self._urlCb["/api/query"] = function(tReq) return self:query(tReq) end self._urlCb["/api/trig"] = function(tReq) return self:trig(tReq) end self._urlCb["/api/line"] = function(tReq) return self:line(tReq) end + self._urlCb["/api/dns"] = function(tReq) return self:dns(tReq) end + self._urlCb["/api/proxy"] = function(tReq) return self:proxy(tReq) end + self:_ossIntall(fYaml) + self:_install(frame) self:_setupQs(fYaml) + self._proxy = CasyncHttp.new() +end + +function CurlApi:_ossIntall(fYaml) + local res = system:parseYaml(fYaml) + if res.oss then + self._oss = CasyncOSS.new(res.oss) + self._urlCb["/api/oss"] = function(tReq) return self:oss(tReq) end + end +end + +local function reqOSS(oss, uuid, stream) + return oss:put(uuid, stream) +end + +function CurlApi:oss(tReq) + local stat, tJson = pcall(self.getJson, self, tReq) + if stat and tJson then + local uuid = tJson.uuid + local stream = tJson.stream + if uuid and stream then + local stat, body = pcall(reqOSS, self._oss, uuid, stream) + if stat then + return body + else + return "bad req dns " .. body, 400 + end + else + return "need uuid and stream arg.", 400 + end + else + return "bad dns " .. tReq.data, 400 + end +end + +local function reqProxy(proxy, host, uri) + return proxy:get(host, uri) +end + +function CurlApi:proxy(tReq) + local stat, tJson = pcall(self.getJson, self, tReq) + if stat and tJson then + local host = tJson.host + local uri = tJson.uri + if host and uri then + local stat, body = pcall(reqProxy, self._proxy, host, uri) + if stat then + return {body = body} + else + return "bad req dns " .. body, 400 + end + else + return "need domain arg.", 400 + end + else + return "bad dns " .. tReq.data, 400 + end +end + +local function reqDns(domain) + local dns = CasyncDns.new() + return dns:dns_lookup(domain) +end + +function CurlApi:dns(tReq) + local stat, tJson = pcall(self.getJson, self, tReq) + if stat and tJson then + local domain = tJson.domain + if domain then + local stat, ip = pcall(reqDns, domain) + if stat then + return {domain = tReq.data, ip = ip} + else + return "bad req dns " .. tReq.data .. ip, 400 + end + else + return "need domain arg.", 400 + end + else + return "bad dns " .. tReq.data, 400 + end end function CurlApi:line(tReq) diff --git a/source/tools/monitor/unity/collector/plugin.yaml b/source/tools/monitor/unity/collector/plugin.yaml index 7e1dc24c762777cd643aa798d5e96e9dd78d30ce..175441db6cf0b863f8b2c4fbebf233cd7da4c670 100644 --- a/source/tools/monitor/unity/collector/plugin.yaml +++ b/source/tools/monitor/unity/collector/plugin.yaml @@ -26,6 +26,12 @@ forkRun: cmd: "/usr/bin/python" args: ["../test/curl/forkRun.py"] +oss: + bucket: "netinfo-shenzhen" + endPoint: "oss-cn-shenzhen.aliyuncs.com" + ak: "ak" + sk: "sk" + diagnose: io_hang: block: 60 diff --git a/source/tools/monitor/unity/httplib/asyncDns.lua b/source/tools/monitor/unity/httplib/asyncDns.lua new file mode 100644 index 0000000000000000000000000000000000000000..d327571cb1144cc174bfcddf9d9f4f768b5a248f --- /dev/null +++ b/source/tools/monitor/unity/httplib/asyncDns.lua @@ -0,0 +1,115 @@ +--- +--- Generated by EmmyLua(https://github.com/EmmyLua) +--- Created by liaozhaoyan. +--- DateTime: 2023/5/24 11:41 +--- + +require("common.class") +local psocket = require("posix.sys.socket") +local unistd = require("posix.unistd") +local pystring = require("common.pystring") +local system = require("common.system") + +local CasyncDns = class("coDns") + +local function lookup_server() + local f = io.open("/etc/resolv.conf") + local server = "" + for line in f:lines() do + if pystring:startswith(line, "nameserver") then + local res = pystring:split(line) + server = res[2] + break + end + end + + f:close() + return server +end + +function CasyncDns:_init_() + self._server = lookup_server() + assert(#self._server > 0) +end + +local function packQuery(domain) + local cnt = 0 + local queries = {} + local head = string.char( + 0x12, 0x34, -- Query ID + 0x01, 0x00, -- Standard query + 0x00, 0x01, -- Number of questions + 0x00, 0x00, -- Number of answers + 0x00, 0x00, -- Number of authority records + 0x00, 0x00 -- Number of additional records + ) + cnt = cnt + 1 + queries[cnt] = head + + local names = pystring:split(domain, ".") + for _, name in ipairs(names) do + cnt = cnt + 1 + queries[cnt] = string.char(string.len(name)) + cnt = cnt + 1 + queries[cnt] = name + end + cnt = cnt + 1 + local tail = string.char( + 0x00, -- End of domain name + 0x00, 0x01, -- Type A record + 0x00, 0x01 -- Class IN + ) + queries[cnt] = tail + + local query = table.concat(queries) + return query +end + +function CasyncDns:waitReq(fd) + local res, msg + local toWake = coroutine.yield() + local e = coroutine.yield() + local ip + if e.ev_close > 0 then + print("force to close socket.") + elseif e.ev_in > 0 then + res = psocket.recvfrom(fd, 512) + if res then + ip = string.format("%d.%d.%d.%d", string.byte(res, -4, -1)) + end + else + print("bad socket.") + end + res, msg = coroutine.resume(toWake, ip) + assert(res, msg) + g_lb:co_exit(fd) +end + +function CasyncDns:dns_lookup(domain) + self._coWake = nil + local res, msg + if domain == "localhost" then + return "127.0.0.1" + end + + local fd, err, errno = psocket.socket(psocket.AF_INET, psocket.SOCK_DGRAM, 0) + if not fd then + system:posixError("new socket failed.", err, errno) + end + local tDist = {family=psocket.AF_INET, addr=self._server, port=53} + + local co = g_lb:co_add(fd, self.waitReq) + local query = packQuery(domain) + local len, err, errno = psocket.sendto(fd, query, tDist) + if not len then + system:posixError("socket send failed.", err, errno) + end + + res, msg = coroutine.resume(co, self, fd) -- send fd + assert(res, msg) + res, msg = coroutine.resume(co, coroutine.running()) -- send to wake + assert(res, msg) + return coroutine.yield() +end + +return CasyncDns \ No newline at end of file diff --git a/source/tools/monitor/unity/httplib/asyncHttp.lua b/source/tools/monitor/unity/httplib/asyncHttp.lua new file mode 100644 index 0000000000000000000000000000000000000000..37ffa8ed0afb45d3c8c1f70097700a87646ea952 --- /dev/null +++ b/source/tools/monitor/unity/httplib/asyncHttp.lua @@ -0,0 +1,374 @@ +--- +--- Generated by EmmyLua(https://github.com/EmmyLua) +--- Created by liaozhaoyan. +--- DateTime: 2023/5/24 15:38 +--- + +require("common.class") +local ChttpComm = require("httplib.httpComm") +local pystring = require("common.pystring") +local psocket = require("posix.sys.socket") +local unistd = require("posix.unistd") +local bit = require("bit") +local fcntl = require("posix.fcntl") +local CasyncDns = require("httplib.asyncDns") + +local CasyncHttp = class("asyncHttp", ChttpComm) + +local ip_pattern = "(%d%d?%d?)%.(%d%d?%d?)%.(%d%d?%d?)%.(%d%d?%d?)" + +local function match_ip(ip) + local d1, d2, d3, d4 = ip:match(ip_pattern) + if d1 and d2 and d3 and d4 then + local num1, num2, num3, num4 = tonumber(d1), tonumber(d2), tonumber(d3), tonumber(d4) + if num1 >= 0 and num1 <= 255 and num2 >= 0 and num2 <= 255 and num3 >= 0 and num3 <= 255 and num4 >= 0 and num4 <= 255 then + return true + end + end + return false +end + +local function getIp(domain) + local ip + if match_ip(domain) then + ip = domain + else + local dns = CasyncDns.new() + ip = dns:dns_lookup(domain) + end + return ip +end + +local function fdNonBlocking(fd) + local res + local flag, err, errno = fcntl.fcntl(fd, fcntl.F_GETFL) + if flag then + res, err, errno = fcntl.fcntl(fd, fcntl.F_SETFL, bit.bor(flag, fcntl.O_NONBLOCK)) + if res then + return + else + print(string.format("fcntl set failed, report:%d, %s", err, errno)) + return -1 + end + else + print(string.format("fcntl get failed, report:%d, %s", err, errno)) + return -1 + end +end + +local function setupFd() + local fd, err, errno + fd, err, errno = psocket.socket(psocket.AF_INET, psocket.SOCK_STREAM, 0) + if fd then -- for socket + if fdNonBlocking(fd) == -1 then + unistd.close(fd) + return -1 + end + return fd + else + print(string.format("socket create failed, report:%d, %s", err, errno)) + return -1 + end +end + +local function tryConnect(fd, tConn) + local res, err, errno + + res, err, errno = psocket.connect(fd, tConn) + if not res then + if errno == 115 then + return 1 + else + print(string.format("socket connect failed, report:%d, %s", err, errno)) + return + end + else + return 0 + end +end + +function CasyncHttp:_init_() + ChttpComm._init_(self) +end + +function CasyncHttp:pack(method, domain, uri, headers, body) + local line = self:packCliHead(method, uri) + headers.Host = domain + headers = self:packCliHeaders(headers, #body) + return pystring:join("\r\n", {line, headers, body}) +end + +local function waitDataRest(fread, rest, tReq) + local len = 0 + local tStream = {tReq.data} + local c = #tStream + while len < rest do + local s = fread() + if s then + len = len + #s + c = c + 1 + tStream[c] = s + else + return -1 + end + end + tReq.data = pystring:join("", tStream) + return 0 +end + +local function waitChuckData(fread, s, size) + while true do + if #s >= size + 2 then + return s + end + local add = fread() + if add then + s = s .. add + else + return nil + end + end +end + +local function waitChuckSize(fread, s) + while true do + if string.find(s, "\r\n") then + return s + end + local add = fread() + if add then + s = s .. add + else + return nil + end + end +end + +local function readChunks(fread, tReq) + local cells = {} + local s = tReq.data + local ssize, size + local len = 1 + local bodies, body + + while true do + if len == 0 then + break + end + s = waitChuckSize(fread, s) + if s then + size, s = unpack(pystring:split(s, "\r\n", 1)) + len = tonumber(size, 16) + bodies = waitChuckData(fread, s, len) + if bodies then + body = string.sub(bodies, 1, len) + s = string.sub(bodies, len + 2) + table.insert(cells, body) + else + return -2 + end + else + return -1 + end + end + tReq.data = pystring:join("", cells) + return 0 +end + +local function waitHttpRest(fread, tReq) + if tReq.header["content-length"] then + local lenData = #tReq.data + local lenInfo = tonumber(tReq.header["content-length"]) + + local rest = lenInfo - lenData + if rest > 10 * 1024 * 1024 then -- limit max data len + return -1 + end + + if waitDataRest(fread, rest, tReq) < 0 then + return -2 + end + else -- chunk mode + if #tReq.data > 0 then + if readChunks(fread, tReq) < 0 then + return -3 + end + end + end + return 0 +end + +local function waitHttpHead(fread) + local stream = "" + while true do + local s = fread() + if s then + stream = stream .. s + if string.find(stream, "\r\n\r\n") then + return stream + end + else + return nil + end + end +end + +function CasyncHttp:parse(fread, stream) + local tStatus = pystring:split(stream, "\r\n", 1) + if #tStatus < 2 then + print("bad stream format.") + return nil + end + + local stat, heads = unpack(tStatus) + local tStat = pystring:split(stat, " ") + if #tStat < 3 then + print("bad stat: "..stat) + return nil + end + + local vers, code, descr = unpack(tStat) + local tReq = { + vers = vers, + code = code, + descr = descr + } + + local tHead = pystring:split(heads, "\r\n\r\n", 1) + if #tHead < 2 then + print("bad head: " .. heads) + return nil + end + local headers, data = unpack(tHead) + local tHeader = pystring:split(headers, "\r\n") + local header = {} + for _, s in ipairs(tHeader) do + local tKv = pystring:split(s, ":", 1) + if #tKv < 2 then + print("bad head kv value: " .. s) + return nil + end + local k, v = unpack(tKv) + k = string.lower(k) + header[k] = pystring:lstrip(v) + end + tReq.header = header + tReq.data = data + if waitHttpRest(fread, tReq) < 0 then + return nil + end + return tReq +end + +function CasyncHttp:result(fread) + local stream = waitHttpHead(fread) + if stream == nil then -- read return stream or error code or nil + return nil + end + return self:parse(fread, stream) +end + +local function checkConnect(fd, connecting, toWake) + local res, msg + if connecting > 0 then + local e = coroutine.yield() + if e.ev_out > 0 then + g_lb:mod_fd(fd, 0) + else + res, msg = coroutine.resume(toWake, "connect failed.") + assert(res, msg) + return -1 + end + end +end + +function CasyncHttp:procStream(fd, stream, toWake) + local res, msg + res = g_lb:write(fd, stream) + if res then + local fread = g_lb:read(fd) + local tReq = self:result(fread) + res, msg = coroutine.resume(toWake, tReq.data) + assert(res, msg) + else + res, msg = coroutine.resume(toWake, "write failed.") + assert(res, msg) + end + g_lb:co_exit(fd) +end + +function CasyncHttp:_get(fd) + local toWake, domain, uri, headers, body, connecting = coroutine.yield() + + if checkConnect(fd, connecting, toWake) == -1 then + g_lb:co_exit(fd) + return + end + local stream = self:pack('GET', domain, uri, headers, body) + self:procStream(fd, stream, toWake) +end + +function CasyncHttp:connect(domain, uri, port, headers, body, cb) + port = port or 80 + local ip = getIp(domain) + if #ip == 0 then + return "request domain failed." + end + local tConn = {family=psocket.AF_INET, addr=ip, port=port} + + local fd = setupFd() + if fd > 0 then + local connect = tryConnect(fd, tConn) + if connect then + local res, msg + + local co = g_lb:co_add(fd, cb) + if connect > 0 then + g_lb:mod_fd(fd, 1) + end + res, msg = coroutine.resume(co, self, fd) + assert(res, msg) + res, msg = coroutine.resume(co, coroutine.running(), domain, uri, headers, body, connect) + assert(res, msg) + return coroutine.yield() + else + return "connect to domain failed." + end + end +end + +function CasyncHttp:get(domain, uri, port) + return self:connect(domain, uri, port, {}, "", self._get) +end + +function CasyncHttp:_put(fd) + local toWake, domain, uri, headers, body, connecting = coroutine.yield() + + if checkConnect(fd, connecting, toWake) == -1 then + g_lb:co_exit(fd) + return + end + local stream = self:pack('PUT', domain, uri, headers, body) + self:procStream(fd, stream, toWake) +end + +function CasyncHttp:put(domain, uri, headers, body, port) + return self:connect(domain, uri, port, headers, body, self._put) +end + +function CasyncHttp:_post(fd) + local toWake, domain, uri, headers, body, connecting = coroutine.yield() + + if checkConnect(fd, connecting, toWake) == -1 then + g_lb:co_exit(fd) + return + end + local stream = self:pack('POST', domain, uri, headers, body) + self:procStream(fd, stream, toWake) +end + +function CasyncHttp:post(domain, uri, headers, body, port) + return self:connect(domain, uri, port, headers, body, self._post) +end + +return CasyncHttp diff --git a/source/tools/monitor/unity/httplib/asyncOSS.lua b/source/tools/monitor/unity/httplib/asyncOSS.lua new file mode 100644 index 0000000000000000000000000000000000000000..b7aa9aa0976937d71f85bf493de0310eb24ef9d8 --- /dev/null +++ b/source/tools/monitor/unity/httplib/asyncOSS.lua @@ -0,0 +1,61 @@ +--- +--- Generated by EmmyLua(https://github.com/EmmyLua) +--- Created by liaozhaoyan. +--- DateTime: 2023/5/24 20:07 +--- + +require("common.class") +local system = require("common.system") +local pystring = require("common.pystring") +local sha1 = require("sha1") +local base64 = require("base64") +local CasyncHttp = require("httplib.asyncHttp") + +local CasyncOSS = class("asyncOSS", CasyncHttp) + +function CasyncOSS:_init_(res) + CasyncHttp._init_(self) + self._bucket = res.bucket + self._endPoint = res.endPoint + self._ak = base64.decode(res.ak) + self._sk = base64.decode(res.sk) +end + +function CasyncOSS:sign(cType, date, uri) + local ss = { + "PUT", -- VERB + "", -- md5 + cType, -- Content-Type + date, -- Date + uri, -- + } + local s = table.concat(ss, '\n') + return base64.encode(sha1.hmac_binary(self._sk, s)) +end + +function CasyncOSS:auth(cType, date, uri) + local ss = {"OSS ", self._ak, ":", self:sign(cType, date, uri)} + return table.concat(ss) +end + +function CasyncOSS:put(uuid, stream) + local bucket = self._bucket + local uri = os.date("/%Y/%m") .. "/" .. uuid + + local uris = table.concat({"/", bucket, uri}) + local date = system:timeRfc1123(os.time()) + local cType = "application/octet-stream" + local host = bucket .. "." .. self._endPoint + + local headers = { + Host = host, + ["Content-Type"] = cType, + ["Content-Length"] = #stream, + date = date, + authorization = self:auth(cType, date, uris) + } + + CasyncHttp.put(self, host, uri, headers, stream) +end + +return CasyncOSS \ No newline at end of file diff --git a/source/tools/monitor/unity/httplib/httpCli.lua b/source/tools/monitor/unity/httplib/httpCli.lua index 3e0674125de0cb97a3813adeed6fca932170e900..5b25cf189f1a0400fa4186eeb31b463c4ff67b5f 100644 --- a/source/tools/monitor/unity/httplib/httpCli.lua +++ b/source/tools/monitor/unity/httplib/httpCli.lua @@ -31,6 +31,27 @@ function ChttpCli:get(Url) } end +function ChttpCli:put(Url, stream, header) + local headers = header or { Connection = 'close' } + local source = self._ltn12.source.string(stream) + local t = {} + local res, code, head = self._http.request{ + url = Url, + method = "PUT", + headers = headers, + source = source, + proxy = self._proxy, + sink = self._ltn12.sink.table(t) + } + local body = table.concat(t) + return { + res = res, + code = code, + head = head, + body = body + } +end + function ChttpCli:post(Url, reqs, header) local headers = header or { Connection = 'close' } local source = self._ltn12.source.string(reqs) diff --git a/source/tools/monitor/unity/httplib/httpComm.lua b/source/tools/monitor/unity/httplib/httpComm.lua index 5986a65b08080d54cbc57aa9eb4bb41b5ce9d90b..436f6ef54c54af2611a42857b93e8986864129bf 100644 --- a/source/tools/monitor/unity/httplib/httpComm.lua +++ b/source/tools/monitor/unity/httplib/httpComm.lua @@ -79,7 +79,7 @@ end local function originServerHeader() return { - server = "beaver/0.0.2", + server = "beaver/0.0.3", date = os.date("%a, %d %b %Y %H:%M:%S %Z", os.time()), } end diff --git a/source/tools/monitor/unity/httplib/ossCli.lua b/source/tools/monitor/unity/httplib/ossCli.lua new file mode 100644 index 0000000000000000000000000000000000000000..e3a436a61226ff2707fb3a2cf4e88737725d4253 --- /dev/null +++ b/source/tools/monitor/unity/httplib/ossCli.lua @@ -0,0 +1,62 @@ +--- +--- Generated by EmmyLua(https://github.com/EmmyLua) +--- Created by liaozhaoyan. +--- DateTime: 2023/5/23 20:43 +--- + +local sha1 = require("sha1") +local md5 = require("md5") +local base64 = require("base64") +local system = require("common.system") +local pystring = require("common.pystring") + +local ChttpCli = require("httplib.httpCli") +local CossCli = class("ossCli", ChttpCli) + +function CossCli:_init_(endPoint, bucket, ak, sk) + ChttpCli._init_(self) + self._endPoint = endPoint + self._bucket = bucket + self._ak = ak + self._sk = sk +end + +function CossCli:sign(cType, date, uri) + local ss = { + "PUT", -- VERB + "", -- md5 + cType, -- Content-Type + date, -- Date + uri, -- + } + local s = table.concat(ss, '\n') + return base64.encode(sha1.hmac_binary(self._sk, s)) +end + +function CossCli:auth(cType, date, uri) + local ss = {"OSS ", self._ak, ":", self:sign(cType, date, uri)} + return table.concat(ss) +end + +function CossCli:put(uri, stream, cType) + local bucket = self._bucket + local uris = table.concat({"/", bucket, uri}) + cType = cType or "application/octet-stream" + + local host = bucket .. "." .. self._endPoint + local date = system:timeRfc1123(os.time()) + local header = { + Host = host, + ["Content-Type"] = cType, + ["Content-Length"] = #stream, + date = date, + authorization = self:auth(cType, date, uris) + } + print(header.authorization) + local url = table.concat({"http://", self._endPoint, uri}) + print(url) + + return ChttpCli.put(self, url, stream, header) +end + +return CossCli diff --git a/source/tools/monitor/unity/test/curl/dns/base.lua b/source/tools/monitor/unity/test/curl/dns/base.lua new file mode 100644 index 0000000000000000000000000000000000000000..8dc44f1a0bf4e917ddc938520af5c6b9b9e46448 --- /dev/null +++ b/source/tools/monitor/unity/test/curl/dns/base.lua @@ -0,0 +1,76 @@ +package.path = package.path .. ";../../../?.lua;" +local socket = require("socket") +local pystring = require("common.pystring") +local system = require("common.system") + +local function lookup_server() + local f = io.open("/etc/resolv.conf") + local server = "" + for line in f:lines() do + if pystring:startswith(line, "nameserver") then + local res = pystring:split(line) + server = res[2] + break + end + end + + f:close() + return server +end + +function dns_lookup(domain_name) + local udp = socket.udp() + local dst = lookup_server() + print(dst) + udp:setpeername(dst, 53) + udp:settimeout(5) + + local cnt = 0 + local queries = {} + local head = string.char( + 0x12, 0x34, -- Query ID + 0x01, 0x00, -- Standard query + 0x00, 0x01, -- Number of questions + 0x00, 0x00, -- Number of answers + 0x00, 0x00, -- Number of authority records + 0x00, 0x00 -- Number of additional records + ) + cnt = cnt + 1 + queries[cnt] = head + + local names = pystring:split(domain_name, ".") + for _, name in ipairs(names) do + cnt = cnt + 1 + queries[cnt] = string.char(string.len(name)) + cnt = cnt + 1 + queries[cnt] = name + end + cnt = cnt + 1 + local tail = string.char( + 0x00, -- End of domain name + 0x00, 0x01, -- Type A record + 0x00, 0x01 -- Class IN + ) + queries[cnt] = tail + + local query = table.concat(queries) + system:hexdump(query) + udp:send(query) + local response = udp:receive() + system:hexdump(response) + udp:close() + if response then + local ip_address = string.format("%d.%d.%d.%d", string.byte(response, -4, -1)) + return ip_address + else + return nil + end +end + +local domain_name = "www.baidu.com" +local ip_address = dns_lookup(domain_name) +if ip_address then + print(string.format("%s -> %s", domain_name, ip_address)) +else + print(string.format("Failed to resolve %s", domain_name)) +end \ No newline at end of file diff --git a/source/tools/monitor/unity/test/curl/dns/base.py b/source/tools/monitor/unity/test/curl/dns/base.py new file mode 100644 index 0000000000000000000000000000000000000000..947979318582bca6ac9b0e816071be4096c28dcc --- /dev/null +++ b/source/tools/monitor/unity/test/curl/dns/base.py @@ -0,0 +1,38 @@ +import socket + + +def dns_lookup(domain_name): + dns_server = "100.100.2.136" + dns_port = 53 + query = bytearray() + query += bytearray.fromhex("AA AA") # Query ID + query += bytearray.fromhex("01 00") # Flags + query += bytearray.fromhex("00 01") # Questions + query += bytearray.fromhex("00 00") # Answers + query += bytearray.fromhex("00 00") # Authority records + query += bytearray.fromhex("00 00") # Additional records + for part in domain_name.split("."): + query += bytes([len(part)]) + query += part.encode() + query += bytearray.fromhex("00") # End of domain name + query += bytearray.fromhex("00 01") # Type A record + query += bytearray.fromhex("00 01") # Class IN + + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + sock.sendto(query, (dns_server, dns_port)) + response, _ = sock.recvfrom(1024) + sock.close() + + if response: + ip_address = ".".join(str(byte) for byte in response[-4:]) + return ip_address + else: + return None + + +domain_name = "www.baidu.com" +ip_address = dns_lookup(domain_name) +if ip_address: + print(f"{domain_name} -> {ip_address}") +else: + print(f"Failed to resolve {domain_name}") \ No newline at end of file diff --git a/source/tools/monitor/unity/test/curl/dns/psock.lua b/source/tools/monitor/unity/test/curl/dns/psock.lua new file mode 100644 index 0000000000000000000000000000000000000000..460ac77a09e9bdacbee1b56a7f81497892c3faf3 --- /dev/null +++ b/source/tools/monitor/unity/test/curl/dns/psock.lua @@ -0,0 +1,80 @@ +--- +--- Generated by EmmyLua(https://github.com/EmmyLua) +--- Created by liaozhaoyan. +--- DateTime: 2023/5/24 11:21 +--- + +package.path = package.path .. ";../../../?.lua;" +local psocket = require("posix.sys.socket") +local unistd = require("posix.unistd") +local pystring = require("common.pystring") +local system = require("common.system") + +local function lookup_server() + local f = io.open("/etc/resolv.conf") + local server = "" + for line in f:lines() do + if pystring:startswith(line, "nameserver") then + local res = pystring:split(line) + server = res[2] + break + end + end + + f:close() + return server +end + +function dns_lookup(domain_name) + local fd = psocket.socket(psocket.AF_INET, psocket.SOCK_DGRAM, 0) + local dst = lookup_server() + local tDist = {family=psocket.AF_INET, addr=dst, port=53} + + local cnt = 0 + local queries = {} + local head = string.char( + 0x12, 0x34, -- Query ID + 0x01, 0x00, -- Standard query + 0x00, 0x01, -- Number of questions + 0x00, 0x00, -- Number of answers + 0x00, 0x00, -- Number of authority records + 0x00, 0x00 -- Number of additional records + ) + cnt = cnt + 1 + queries[cnt] = head + + local names = pystring:split(domain_name, ".") + for _, name in ipairs(names) do + cnt = cnt + 1 + queries[cnt] = string.char(string.len(name)) + cnt = cnt + 1 + queries[cnt] = name + end + cnt = cnt + 1 + local tail = string.char( + 0x00, -- End of domain name + 0x00, 0x01, -- Type A record + 0x00, 0x01 -- Class IN + ) + queries[cnt] = tail + + local query = table.concat(queries) + psocket.sendto(fd, query, tDist) + local response = psocket.recvfrom(fd, 512) + system:hexdump(response) + unistd.close(fd) + if response then + local ip_address = string.format("%d.%d.%d.%d", string.byte(response, -4, -1)) + return ip_address + else + return nil + end +end + +local domain_name = "www.baidu.com" +local ip_address = dns_lookup(domain_name) +if ip_address then + print(string.format("%s -> %s", domain_name, ip_address)) +else + print(string.format("Failed to resolve %s", domain_name)) +end \ No newline at end of file diff --git a/source/tools/monitor/unity/test/curl/ossTest.lua b/source/tools/monitor/unity/test/curl/ossTest.lua new file mode 100644 index 0000000000000000000000000000000000000000..7d5c537209eae377263695d42aa91bc3719f69d3 --- /dev/null +++ b/source/tools/monitor/unity/test/curl/ossTest.lua @@ -0,0 +1,25 @@ +--- +--- Generated by EmmyLua(https://github.com/EmmyLua) +--- Created by liaozhaoyan. +--- DateTime: 2023/5/24 00:12 +--- + +package.path = package.path .. ";../../?.lua;" +local system = require("common.system") +local CossCli = require("httplib.ossCli") + +local function generate_string(size) + local str = "" + local i = 0 + local s = "111111111111111111111111111111112222222222222222222333333333333cccc344444444445" + while i < size do + i = i + #s + str = str .. s + end + return str +end + +local s = generate_string( 1024 * 1024) +local c = CossCli.new("oss-cn-shenzhen.aliyuncs.com", "netinfo-shenzhen", + "ak", "sk") +system:dumps(c:put("/long.txt", s)) diff --git a/source/tools/monitor/unity/test/curl/postOSS.lua b/source/tools/monitor/unity/test/curl/postOSS.lua new file mode 100644 index 0000000000000000000000000000000000000000..8d37e291ee5d97335d751b9170b9abc775b1e15c --- /dev/null +++ b/source/tools/monitor/unity/test/curl/postOSS.lua @@ -0,0 +1,18 @@ +--- +--- Generated by EmmyLua(https://github.com/EmmyLua) +--- Created by liaozhaoyan. +--- DateTime: 2023/5/24 22:12 +--- + +package.path = package.path .. ";../../?.lua;" +local system = require("common.system") +local ChttpCli = require("httplib.httpCli") + +local cli = ChttpCli.new() +local url = "http://127.0.0.1:8400/api/oss" +local file = io.open("test.bin", "rb") +local content = file:read("*all") +file:close() +local req = {stream = content, uuid = system:guid()} +local res = cli:postTable(url, req) +system:dumps(res) \ No newline at end of file diff --git a/source/tools/monitor/unity/test/curl/reqdomain.lua b/source/tools/monitor/unity/test/curl/reqdomain.lua new file mode 100644 index 0000000000000000000000000000000000000000..22504856e3273f8da1d295d13e3c16d156f3fd01 --- /dev/null +++ b/source/tools/monitor/unity/test/curl/reqdomain.lua @@ -0,0 +1,15 @@ +--- +--- Generated by EmmyLua(https://github.com/EmmyLua) +--- Created by liaozhaoyan. +--- DateTime: 2023/5/24 14:15 +--- + +package.path = package.path .. ";../../?.lua;" +local system = require("common.system") +local ChttpCli = require("httplib.httpCli") + +local cli = ChttpCli.new() +local url = "http://127.0.0.1:8400/api/dns" +local req = {domain = "cn.bing.com"} +local res = cli:postTable(url, req) +system:dumps(res) \ No newline at end of file diff --git a/source/tools/monitor/unity/test/curl/reqproxy.lua b/source/tools/monitor/unity/test/curl/reqproxy.lua new file mode 100644 index 0000000000000000000000000000000000000000..972fc7d46587b60c779a3829ed2a40dbbe9118bf --- /dev/null +++ b/source/tools/monitor/unity/test/curl/reqproxy.lua @@ -0,0 +1,15 @@ +--- +--- Generated by EmmyLua(https://github.com/EmmyLua) +--- Created by liaozhaoyan. +--- DateTime: 2023/5/24 17:08 +--- + +package.path = package.path .. ";../../?.lua;" +local system = require("common.system") +local ChttpCli = require("httplib.httpCli") + +local cli = ChttpCli.new() +local url = "http://127.0.0.1:8400/api/proxy" +local req = {host = "www.baidu.com", uri = "/"} +local res = cli:postTable(url, req) +system:dumps(res) \ No newline at end of file