網上資料
引用ssl.https 包
local https = require("ssl.https")
之后按同http一樣調用。
但是,這種只最基本的實現了訪問https服務的要求,卻沒有驗證數字證書的示例說明。
數字證書的調用
類似
wget --private-key /root/client.key --certificate /root/client.crt --ca-certificate /root/ca.crt https://www.test.com -O wgetssl curl --key /root/client.key --cert /root/client.crt --cacert /root/ca.crt https://www.test.com
必須要傳入證書文件
再搜 資料很少
最有用的是
http://notebook.kulchenko.com/programming/https-ssl-calls-with-lua-and-luasec
講的是socket 建立連接,和https差了一層。
就差一步了……
再也沒找到任何資料。
所以,查lua包源碼
https的部分內容
local ssl = require("ssl") function request(url, body) local result_table = {} local stringrequest = type(url) == "string" if stringrequest then url = urlstring_totable(url, body, result_table) else url.url = default_https_port(url.url) end if http.PROXY or url.proxy then return nil, "proxy not supported" elseif url.redirect then return nil, "redirect not supported" elseif url.create then return nil, "create function not permitted" end -- New 'create' function to establish a secure connection url.create = tcp(url) local res, code, headers, status = http.request(url) if res and stringrequest then return table.concat(result_table), code, headers, status end return res, code, headers, status end -- Return a function which performs the SSL/TLS connection. local function tcp(params) params = params or {} -- Default settings for k, v in pairs(cfg) do params[k] = params[k] or v end -- Force client mode params.mode = "client" -- 'create' function for LuaSocket return function () local conn = {} conn.sock = try(socket.tcp()) local st = getmetatable(conn.sock).__index.settimeout function conn:settimeout(...) return st(self.sock, ...) end -- Replace TCP's connection function function conn:connect(host, port) try(self.sock:connect(host, port)) self.sock = try(ssl.wrap(self.sock, params)) try(self.sock:dohandshake()) reg(self, getmetatable(self.sock)) return 1 end return conn end end
https.request
url.create = tcp(url)
會調用tcp函數。
params = params or {}
-- Default settings
for k, v in pairs(cfg) do
params[k] = params[k] or v
end
self.sock = try(ssl.wrap(self.sock, params))
而tcp函數又用requset傳入的參數創建名為 params的table類對象,傳入params調用ssl.warp函數
好吧,再去ssl函數看源碼
function newcontext(cfg) local succ, msg, ctx -- Create the context ctx, msg = context.create(cfg.protocol) if not ctx then return nil, msg end -- Mode succ, msg = context.setmode(ctx, cfg.mode) if not succ then return nil, msg end -- Load the key if cfg.key then succ, msg = context.loadkey(ctx, cfg.key, cfg.password) if not succ then return nil, msg end end -- Load the certificate if cfg.certificate then succ, msg = context.loadcert(ctx, cfg.certificate) if not succ then return nil, msg end end -- Load the CA certificates if cfg.cafile or cfg.capath then succ, msg = context.locations(ctx, cfg.cafile, cfg.capath) if not succ then return nil, msg end end -- Set the verification options succ, msg = optexec(context.setverify, cfg.verify, ctx) if not succ then return nil, msg end -- Set SSL options succ, msg = optexec(context.setoptions, cfg.options, ctx) if not succ then return nil, msg end -- Set the depth for certificate verification if cfg.depth then succ, msg = context.setdepth(ctx, cfg.depth) if not succ then return nil, msg end end return ctx end -- -- -- function wrap(sock, cfg) local ctx, msg if type(cfg) == "table" then ctx, msg = newcontext(cfg) if not ctx then return nil, msg end else ctx = cfg end local s, msg = core.create(ctx) if s then core.setfd(s, sock:getfd()) sock:setfd(core.invalidfd) return s end return nil, msg end
眼前一亮,看到熟悉的證書參數了,key,password,ca...
懂的看代碼就該如何作了。
首先wrap調用newcontext
而newcontext應用 之前request傳入的參數
那把key,password,ca等,寫入https.request就全通了。
寫demo
測試通過。
不傳證書
#!/usr/bin/lua require("socket") local https = require("ssl.https") local one, code, headers, status = https.request{ url = "https://www.test.com" } print(code) print(header) print(status) print(one)
結果為
root@LeWiFi:~# lua luahttps.test
nil
nil
nil
nil
傳入證書
#!/usr/bin/lua require("socket") local https = require("ssl.https") local one, code, headers, status = https.request{ url = "https://www.test.com", key = "/root/client.key", certificate="/root/client.crt", cafile="/root/ca.crt" } print(code) print(header) print(status) print(one)
結果
root@LeWiFi:~# lua luahttps.test 200 nil HTTP/1.1 200 OK 1
success
