lua https request 調用


網上資料

引用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

 

 

 
        

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM