• 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

    
    

     

     

  • 相关阅读:
    现代 CSS 解决方案:CSS 数学函数
    浅谈逻辑选择器 父选择器它来了!
    Astyle 常用参数整理
    MySQL两阶段提交串讲
    GIL全局解释器锁
    了解进程、线程、协程概念
    go module介绍
    Flutter热重启、热加载、调试与发布应用
    flutter项目配置国内镜像
    excel进度条怎么设置
  • 原文地址:https://www.cnblogs.com/zihunqingxin/p/4654125.html
Copyright © 2020-2023  润新知