跳转至

http - http 客户端

作者:朱天华

一、概述

HTTP 在如下的场景,开发成本是最低的:

1、终端和云端交换文件,不用开发复杂的分包组包协议;

2、终端从云端下载各种参数,或者终端向云端提交各种参数, 不用设计报文协议,用http 的参数即可,非常方便。

LuatOS提供了http核心库和httpplus扩展库实现了http客户端

http核心库和httpplus扩展库的区别如下:

区别项 http核心库 httpplus扩展库
文件上传 文件最大64KB 只要内存够用,文件大小不限
文件下载 支持,只要文件系统空间够用,文件大小不限 不支持
http header的key:value的限制 所有header的value总长度不能超过4KB,
单个header的value长度不能超过1KB
只要内存够用,header长度不限
鉴权URL自动识别 不支持 支持
接收到的body数据存储支持zbuff 不支持 支持,可以直接传输给uart等库
接收到的body数据存储到内存中 最大支持32KB 只要内存够用,大小不限
chunk编码 支持 不支持

本篇文章仅介绍http核心库,如果需要了解httpplus扩展库,请 点击此处

二、核心示例

1、核心示例是指:使用本库文件提供的核心API,开发的基础业务逻辑的演示代码;

2、核心示例的作用是:帮助开发者快速理解如何使用本库,所以核心示例的逻辑都比较简单;

3、更加完整和详细的demo,请参考 LuatOS仓库 中各个产品目录下的demo/http

-- 普通的http get请求功能演示
-- 请求的body数据保存到内存变量中,在内存够用的情况下,最大支持32KB的数据存储到内存中
-- timeout可以设置超时时间
-- callback可以设置回调函数,可用于实时检测body数据的下载进度
local function http_app_get()
    -- https get请求https://www.air32.cn/网页内容
    -- 如果请求成功,请求的数据保存到body中
    local code, headers, body = http.request("GET", "https://www.air32.cn/").wait()
    log.info("http_app_get1", 
        code==200 and "success" or "error", 
        code, 
        json.encode(headers or {}), 
        body and (body:len()>512 and body:len() or body) or "nil")

    -- https get请求https://www.luatos.com/网页内容
    -- 请求超时时间为3秒,用户自己写代码时,不要照抄10秒,根据自己业务逻辑的需要设置合适的超时时间
    -- 回调函数为http_cbfunc,回调函数使用的第三个回调参数为"http_app_get2"
    -- 如果请求成功,请求的数据保存到body中
    code, headers, body = http.request("GET", "https://www.luatos.com/", nil, nil, {timeout=10000, userdata="http_app_get2", callback=http_cbfunc}).wait()
    log.info("http_app_get2", 
        code==200 and "success" or "error", 
        code, 
        json.encode(headers or {}), 
        body and (body:len()>512 and body:len() or body) or "nil")

    -- http get请求http://httpbin.air32.cn/get网页内容,超时时间为3秒
    -- 请求超时时间为3秒,用户自己写代码时,不要照抄3秒,根据自己业务逻辑的需要设置合适的超时时间
    -- 回调函数为http_cbfunc,回调函数使用的第三个回调参数为"http_app_get3"
    -- 如果请求成功,请求的数据保存到body中
    code, headers, body = http.request("GET", "http://httpbin.air32.cn/get", nil, nil, {timeout=3000, userdata="http_app_get3", callback=http_cbfunc}).wait()
    log.info("http_app_get3", 
        code==200 and "success" or "error", 
        code, 
        json.encode(headers or {}), 
        body and (body:len()>512 and body:len() or body) or "nil")
end


-- http app task 的任务处理函数
local function http_app_task_func() 
    while true do
        -- 如果当前时间点设置的默认网卡还没有连接成功,一直在这里循环等待
        while not socket.adapter(socket.dft()) do
            log.warn("http_app_task_func", "wait IP_READY", socket.dft())
            -- 在此处阻塞等待默认网卡连接成功的消息"IP_READY"
            -- 或者等待1秒超时退出阻塞等待状态;
            -- 注意:此处的1000毫秒超时不要修改的更长;
            -- 因为当使用libnetif.set_priority_order配置多个网卡连接外网的优先级时,会隐式的修改默认使用的网卡
            -- 当libnetif.set_priority_order的调用时序和此处的socket.adapter(socket.dft())判断时序有可能不匹配
            -- 此处的1秒,能够保证,即使时序不匹配,也能1秒钟退出阻塞状态,再去判断socket.adapter(socket.dft())
            sys.waitUntil("IP_READY", 1000)
        end

        -- 检测到了IP_READY消息
        log.info("http_app_task_func", "recv IP_READY", socket.dft())

        -- 普通的http get请求功能演示
        http_app_get()

        -- 60秒之后,循环测试
        sys.wait(60000)
    end
end

--创建并且启动一个task
--运行这个task的处理函数http_app_task_func
sys.taskInit(http_app_task_func)

三、常量详解

核心库常量,顾名思义是由合宙LuatOS内核固件中定义的、不可重新赋值或修改的固定值,在脚本代码中不需要声明,可直接调用;

http核心库没有常量。

四、函数详解

http.request(method, url, headers, body, opts, server_ca_cert, client_cert, client_key, client_password)

功能

http 客户端,发送http请求到服务器,并且接收服务器应答;

使用时在最后加上一个.wait()方法的调用,使用方式为http.request().wait(),表示阻塞等待返回结果;

只能在task中使用,会阻塞当前task,等待整个过程成功结束或者出现错误异常结束或者超时结束,超时时长和opts.timeout有关;

参数

method

参数含义:HTTP请求方法
数据类型:string
取值范围:支持"GET""POST""HEAD"等所有HTTP请求方法,请求方法用大写字母表示;
是否必选:必须传入此参数;
注意事项:暂无;
参数示例:GET请求时填"GET"POST请求时填"POST"

url

参数含义:HTTP请求的URL地址
数据类型:string
取值范围:支持HTTPHTTPS,支持域名、IP地址,支持自定义端口,标准的HTTP URL格式都支持
是否必选:必须传入此参数;
注意事项:暂无;
参数示例:"https://www.luatos.com/"

headers

参数含义:HTTP请求头
数据类型:table或者nil
取值范围:当为table数据类型时,支持键值对格式的任何请求头;
是否必选:可选传入此参数;
注意事项:暂无;
参数示例:{
             ["Content-Type"] = "application/x-www-form-urlencoded",
             ["self_defined_key"] = "self_defined_value"
         }

body

参数含义:HTTP请求体
数据类型:string或者zbuff或者nil
取值范围:无特别限制;
是否必选:可选传入此参数;
注意事项:如果请求体是一个文件中的内容,需要把文件内容读出来,赋值给body使用
参数示例:"123456" 或者 一个zbuff对象 或者 nil

opts

参数含义:HTTP请求的一些额外配置;参数为table类型时table内容格式说明如下
         {
             -- 参数含义:从发送请求到收到服务器响应,整个过程的超时时长,单位毫秒;
             -- 数据类型:number或者nil;
             -- 取值范围:number类型时,取值范围为大于等于0的整数,0表示永久等待;
             -- 是否必选:可选传入此参数,默认值为10分钟;
             -- 注意事项:暂无;
             -- 参数示例:例如20000表示超时时长20秒;  
             timeout = , 

             -- 参数含义:当HTTP请求接收到的body数据需要保存到本地文件中时,此参数表示完整的文件路径;
             -- 数据类型:string或者nil;
             -- 取值范围:无特别限制;
             -- 是否必选:可选传入此参数;
             -- 注意事项:保存数据到文件中时,需要自行保证这个文件存在;
             -- 参数示例:"/download/1.txt";
             dst = ,

             -- 参数含义:上网使用的网卡ID;
             -- 数据类型:number或者nil;
             -- 取值范围:number类型时,取值范围参考socket api中的常量详解;
             -- 是否必选:可选传入此参数;
             -- 注意事项:如果没有传入此参数,内核固件会自动选择当前时间点其他功能模块设置的默认网卡;
             --          除非你HTTP请求时,一定要使用某一种网卡,才设置此参数;
             --          如果没什么特别要求,不要设置此参数,使用系统中设置的默认网卡即可 ;
             --          一般来说,LuatOS的网络应用demo中都会有netdrv_device功能模块设置默认网卡;
             --          所以建议使用http.request接口时,不要设置此参数,直接使用netdrv_device设置的默认网卡就行;
             -- 参数示例:socket.LWIP_GP表示使用4G网卡;        
             adapter = ,

             -- 参数含义:是否打开debug调试信息日志的开关;
             -- 数据类型:boolean或者nil;
             -- 取值范围:boolean类型时,true表示打开,false表示关闭;
             -- 是否必选:可选传入此参数,默认值为false;
             -- 注意事项:暂无;
             -- 参数示例:false;     
             debug = ,    

             -- 参数含义:HTTP请求过程中是否使用ipv6;
             -- 数据类型:boolean或者nil;
             -- 取值范围:boolean类型时,true表示使用ipv6,false表示不使用ipv6;
             -- 是否必选:可选传入此参数,默认值为false;
             -- 注意事项:暂无;
             -- 参数示例:false;     
             ipv6 = ,    

             -- 参数含义:接收HTTP应答body数据过程中的回调函数;回调函数的格式为:
             --          function callback(total_len, received_len, userdata)
             --              -- total_len:number类型,body数据总长度
             --              -- received_len:number类型,已经下载过的body数据长度
             --              -- userdata:下载回调函数使用的用户自定义的回调参数,即opts.userdata
             --              log.info("callback", total_len, received_len, userdata)
             --          end
             -- 数据类型:function或者nil;
             -- 取值范围:无特别限制;
             -- 是否必选:可选传入此参数;
             -- 注意事项:回调函数是在task之外的业务逻辑中被执行的,在回调函数内部无法使用
             --          sys.wait(timeout)、sys.waitUntil(msg, timeout)、sys.waitMsg(task_name, msg, timeout)等必须用在task中的函数;
             -- 参数示例:如下所示,定义了一个函数http_download_cbfunc,http_download_cbfunc就可以做为此参数传入;
             --          local function http_download_cbfunc(total_len, received_len, userdata)
             --              log.info("http_download_cbfunc", total_len, received_len, userdata)
             --          end
             callback = ,

             -- 参数含义:回调函数callback使用的回调参数,自动执行回调函数callback(total_len, received_len, userdata)时,做为第三个参数使用;
             -- 数据类型:任意数据类型;
             -- 取值范围:无特别限制;
             -- 是否必选:可选传入此参数;
             -- 注意事项:暂无;
             -- 参数示例:"download_mp3"或者12000或者任意自定义的参数;       
             userdata = ,    
         }

数据类型:table或者nil
取值范围:参考参数含义内各字段说明    
是否必选:可选传入此参数;
注意事项:暂无;
参数示例:超时3秒;接收的body数据保存到"/http_download/logo.jpg"中;接收数据过程中,回调函数为http_cbfunc,回调函数的回调参数为"download_logo"
         {
             timeout = 3000,      
             dst = "/http_download/logo.jpg",  
             callback = http_cbfunc,        
             userdata = "download_logo"
         }

server_ca_cert

参数含义:服务器ca证书数据
数据类型:string或者nil
取值范围:无特别限制;
是否必选:可选传入此参数;
注意事项:当客户端需要验证服务器证书时,需要此参数,如果证书数据在一个文件中,要把文件内容读出来,赋值给server_ca_cert
参数示例:例如通过Luatools烧录了server_ca.crt文件,就可以通过io.readFile("/luadb/server_ca.crt")读出文件内容赋值给赋值给server_ca_cert

client_cert

参数含义:客户端证书数据;
数据类型:string或者nil
取值范围:无特别限制;
是否必选:可选传入此参数;
注意事项:当服务器需要验证客户端证书时,需要此参数,如果证书数据在一个文件中,要把文件内容读出来,赋值给client_cert
参数示例:例如通过Luatools烧录了clinet.crt文件,就可以通过io.readFile("/luadb/clinet.crt")读出文件内容赋值给赋值给client_cert

client_key

参数含义:加密后的客户端私钥数据;
数据类型:string或者nil
取值范围:无特别限制;
是否必选:可选传入此参数;
注意事项:当服务器需要验证客户端证书时,需要此参数,如果加密后的私钥数据在一个文件中,要把文件内容读出来,赋值给client_key
参数示例:例如通过Luatools烧录了clinet.key文件,就可以通过io.readFile("/luadb/clinet.key")读出文件内容赋值给client.key

client_password

参数含义:客户端私钥口令数据;
数据类型:string或者nil
取值范围:无特别限制;
是否必选:可选传入此参数;
注意事项:当服务器需要验证客户端证书时,需要此参数,如果加密后的私钥数据在一个文件中,要把文件内容读出来,赋值给client_password
参数示例:例如通过Luatools烧录了clinet.password文件,就可以通过io.readFile("/luadb/clinet.password")读出文件内容赋值给client_password

返回值

local code, headers, body = http.request().wait()

code

含义说明:HTTP请求的执行结果
数据类型:number
取值范围:大于等于100或者小于0
         大于等于100时,表示服务器返回的HTTP状态码,例如200表示成功,详细说明可以通过搜索引擎搜索“HTTP状态码”自行了解;
         小于0时,表示内核固件中检测到通信异常,有如下几种
             -1HTTP_ERROR_STATE,错误的状态, 一般是底层异常,如果出现此问题,可以联系合宙技术人员报issue解决    
             -2HTTP_ERROR_HEADER,错误的响应头部, 通常是服务器问题;    
             -3HTTP_ERROR_BODY,错误的响应体,通常是服务器问题;    
             -4HTTP_ERROR_CONNECT,连接服务器失败, 未联网,地址错误,域名错误等问题;    
             -5HTTP_ERROR_CLOSE,提前断开了连接, 网络或服务器问题;    
             -6HTTP_ERROR_RX,接收数据报错, 网络问题;    
             -7HTTP_ERROR_DOWNLOAD,下载文件过程报错, 网络问题或下载路径问题;    
             -8HTTP_ERROR_TIMEOU 超时, 包括连接超时,发送数据超时,接收数据超时;    
             -9HTTP_ERROR_FOTA,使用此接口下载升级包时,fota功能报错,通常是更新包不合法;
注意事项:暂无;
返回示例:例如200就表示请求成功;

headers

含义说明:HTTP服务器返回的应答头
数据类型:table或者nil
取值范围:大于等于100或者小于0
         code大于等于100时headers是table类型,表示服务器返回的应答头;
         code小于0时headers为nil
注意事项:暂无;
返回示例:{
             ["Content-Length"] = "265",
             ["Date"] = "Sat, 30 Aug 2025 01",
             ["Connection"] = "close",
             ["Content-Type"] = "application/json"
         }

body

含义说明:HTTP服务器返回的应答体
数据类型:string或者number或者nil
取值范围:当code的返回值大于等于100时,如果请求的body数据不需要保存到文件中,而是直接保存到内存中,则body表示请求到的数据内容string类型
         code的返回值大于等于100时,如果请求的body数据需要保存到文件中,则body表示保存请求数据后的文件的大小number类型
         code的返回值小于0时body为nil
注意事项:暂无;
返回示例:"this is a text"

示例

本示例章节仅列举一些常用功能的核心代码片段

更加完整和详细的demo,请参考 https://gitee.com/openLuat/LuatOS/tree/master/module 各个产品目录下的demo/http下的http_app.lua

-- 普通的http get请求功能演示
-- 请求的body数据保存到内存变量中,在内存够用的情况下,最大支持32KB的数据存储到内存中
-- timeout可以设置超时时间
-- callback可以设置回调函数,可用于实时检测body数据的下载进度
local function http_app_get()
    -- https get请求https://www.air32.cn/网页内容
    -- 如果请求成功,请求的数据保存到body中
    local code, headers, body = http.request("GET", "https://www.air32.cn/").wait()
    log.info("http_app_get1", 
        code==200 and "success" or "error", 
        code, 
        json.encode(headers or {}), 
        body and (body:len()>512 and body:len() or body) or "nil")

    -- https get请求https://www.luatos.com/网页内容
    -- 请求超时时间为3秒,用户自己写代码时,不要照抄10秒,根据自己业务逻辑的需要设置合适的超时时间
    -- 回调函数为http_cbfunc,回调函数使用的第三个回调参数为"http_app_get2"
    -- 如果请求成功,请求的数据保存到body中
    code, headers, body = http.request("GET", "https://www.luatos.com/", nil, nil, {timeout=10000, userdata="http_app_get2", callback=http_cbfunc}).wait()
    log.info("http_app_get2", 
        code==200 and "success" or "error", 
        code, 
        json.encode(headers or {}), 
        body and (body:len()>512 and body:len() or body) or "nil")

    -- http get请求http://httpbin.air32.cn/get网页内容,超时时间为3秒
    -- 请求超时时间为3秒,用户自己写代码时,不要照抄3秒,根据自己业务逻辑的需要设置合适的超时时间
    -- 回调函数为http_cbfunc,回调函数使用的第三个回调参数为"http_app_get3"
    -- 如果请求成功,请求的数据保存到body中
    code, headers, body = http.request("GET", "http://httpbin.air32.cn/get", nil, nil, {timeout=3000, userdata="http_app_get3", callback=http_cbfunc}).wait()
    log.info("http_app_get3", 
        code==200 and "success" or "error", 
        code, 
        json.encode(headers or {}), 
        body and (body:len()>512 and body:len() or body) or "nil")
end


-- http get下载数据保存到文件中的功能演示
-- 请求的body数据保存到文件中,在文件系统够用的情况下,文件大小不限
-- timeout可以设置超时时间
-- callback可以设置回调函数,可用于实时检测文件下载进度
local function http_app_get_file()

    -- 创建/http_download目录,用来存放通过http下载的文件
    -- 重复创建目录会返回失败
    -- 在创建目录之前可以使用api判断下目录是否存在
    -- 不过只有最新版本的内核固件才支持判断目录是否存在的api
    -- 在编写本demo时还没有这个api
    -- 如果Luatools烧录软件时,没有勾选 清除FS分区,此处日志有可能输出error
    -- 如果输出error,不用理会,不会影响后续逻辑的执行
    -- 等后续的新版本内核固件支持 判断目录是否存在 的api之后,再加上api判断
    local download_dir = "/http_download/"
    local result, reason = io.mkdir(download_dir)
    if not result then
        log.error("http_app_get_file io.mkdir error", reason)
    end


    local file_path = download_dir.."get_file1.html"
    -- https get请求https://www.air32.cn/网页内容
    -- 如果请求成功,请求的数据保存到文件file_path中
    local code, headers, body_size = http.request("GET", "https://www.air32.cn/", nil, nil, {dst=file_path}).wait()
    log.info("http_app_get_file1", 
        code==200 and "success" or "error", 
        code, 
        json.encode(headers or {}), 
        body_size)

    -- 如果下载成功
    if code==200 then
        -- 读取文件大小
        local size = io.fileSize(file_path)
        log.info("http_app_get_file1", "io.fileSize="..size)

        if size~=body_size then
            log.error("io.fileSize doesn't equal with body_size, error", size, body_size)
        end

        --文件使用完之后,如果以后不再用到,根据需要可以自行删除
        os.remove(file_path)
    end




    file_path = download_dir.."get_file2.html"
    -- https get请求https://www.luatos.com/网页内容
    -- 请求超时时间为3秒,用户自己写代码时,不要照抄10秒,根据自己业务逻辑的需要设置合适的超时时间
    -- 回调函数为http_cbfunc,回调函数使用的第三个回调参数为"http_app_get_file2"
    -- 如果请求成功,请求的数据保存到文件file_path中
    code, headers, body_size = http.request("GET", "https://www.luatos.com/", nil, nil, {dst=file_path, timeout=10000, userdata="http_app_get_file2", callback=http_cbfunc}).wait()
    log.info("http_app_get_file2", 
        code==200 and "success" or "error", 
        code, 
        json.encode(headers or {}), 
        body_size)

    -- 如果下载成功
    if code==200 then
        -- 读取文件大小
        local size = io.fileSize(file_path)
        log.info("http_app_get_file2", "io.fileSize="..size)

        if size~=body_size then
            log.error("io.fileSize doesn't equal with body_size, error", size, body_size)
        end

        --文件使用完之后,如果以后不再用到,根据需要可以自行删除
        os.remove(file_path)
    end




    file_path = download_dir.."get_file3.html"
    -- http get请求http://httpbin.air32.cn/get网页内容,超时时间为3秒
    -- 请求超时时间为3秒,用户自己写代码时,不要照抄3秒,根据自己业务逻辑的需要设置合适的超时时间
    -- 回调函数为http_cbfunc,回调函数使用的第三个回调参数为"http_app_get_file3"
    -- 如果请求成功,请求的数据保存到文件file_path中
    code, headers, body_size = http.request("GET", "http://httpbin.air32.cn/get", nil, nil, {dst=file_path, timeout=3000, userdata="http_app_get_file3", callback=http_cbfunc}).wait()
    log.info("http_app_get_file3", 
        code==200 and "success" or "error", 
        code, 
        json.encode(headers or {}), 
        body_size)

    -- 如果下载成功
    if code==200 then
        -- 读取文件大小
        local size = io.fileSize(file_path)
        log.info("http_app_get_file3", "io.fileSize="..size)

        if size~=body_size then
            log.error("io.fileSize doesn't equal with body_size, error", size, body_size)
        end

        --文件使用完之后,如果以后不再用到,根据需要可以自行删除
        os.remove(file_path)
    end
end


-- http post提交表单数据功能演示
local function http_app_post_form()
    local params = {
        username = "LuatOS",
        password = "123456"
    }
    local body = ""
    -- 拼接成url编码的键值对的形式
    for k, v in pairs(params) do
        body = body .. k .. "=" .. tostring(v):urlEncode() .. "&"
    end
    -- 删除最后一位的&字符,最终为string类型的username=LuatOS&password=123456
    body = body:sub(1,-2)

    -- http post提交表单数据
    -- http://httpbin.air32.cn/post为回环测试服务器,服务器收到post提交的表单数据后,还会下发同样的表单数据给设备
    -- ["Content-Type"] = "application/x-www-form-urlencoded" 表示post提交的body数据格式为url编码的键值对形式的表单数据
    -- 如果请求成功,服务器应答的数据会保存到resp_body中
    local code, headers, resp_body = http.request("POST", "http://httpbin.air32.cn/post", {["Content-Type"] = "application/x-www-form-urlencoded"}, body).wait()
    log.info("http_app_post_form", 
        code==200 and "success" or "error", 
        code, 
        json.encode(headers or {}), 
        resp_body and (resp_body:len()>512 and resp_body:len() or resp_body) or "nil")
end


-- http post文件上传功能演示
local function http_app_post_file()
    -- 此接口post_multipart_form_data支持单文件上传、多文件上传、单文本上传、多文本上传、单/多文本+单/多文件上传
    -- http://airtest.openluat.com:2900/uploadFileToStatic 仅支持单文件上传,并且上传的文件name必须使用"uploadFile"
    -- 所以此处仅演示了单文件上传功能,并且"uploadFile"不能改成其他名字,否则会出现上传失败的应答
    -- 如果你自己的http服务支持更多类型的文本/文件混合上传,可以打开注释自行验证
    post_multipart_form_data(
        "http://airtest.openluat.com:2900/uploadFileToStatic",
        {
            -- texts = 
            -- {
            --     ["username"] = "LuatOS",
            --     ["password"] = "123456"
            -- },

            files =
            {
                ["uploadFile"] = "/luadb/logo.jpg",
                -- ["logo1.jpg"] = "/luadb/logo.jpg",
            }
        }
    )
end


-- http app task 的任务处理函数
local function http_app_task_func() 
    while true do
        -- 如果当前时间点设置的默认网卡还没有连接成功,一直在这里循环等待
        while not socket.adapter(socket.dft()) do
            log.warn("http_app_task_func", "wait IP_READY", socket.dft())
            -- 在此处阻塞等待默认网卡连接成功的消息"IP_READY"
            -- 或者等待1秒超时退出阻塞等待状态;
            -- 注意:此处的1000毫秒超时不要修改的更长;
            -- 因为当使用libnetif.set_priority_order配置多个网卡连接外网的优先级时,会隐式的修改默认使用的网卡
            -- 当libnetif.set_priority_order的调用时序和此处的socket.adapter(socket.dft())判断时序有可能不匹配
            -- 此处的1秒,能够保证,即使时序不匹配,也能1秒钟退出阻塞状态,再去判断socket.adapter(socket.dft())
            sys.waitUntil("IP_READY", 1000)
        end

        -- 检测到了IP_READY消息
        log.info("http_app_task_func", "recv IP_READY", socket.dft())

        -- 普通的http get请求功能演示
        http_app_get()
        -- http get下载压缩数据的功能演示
        -- http_app_get_gzip()
        -- http get下载数据保存到文件中的功能演示
        http_app_get_file()
        -- http post提交表单数据功能演示
        http_app_post_form()
        -- http post提交json数据功能演示
        -- http_app_post_json()
        -- http post提交纯文本数据功能演示
        -- http_app_post_text()
        -- http post提交xml数据功能演示
        -- http_app_post_xml()
        -- http post提交原始二进制数据功能演示
        -- http_app_post_binary()
        -- http post文件上传功能演示
        http_app_post_file()

        -- 60秒之后,循环测试
        sys.wait(60000)
    end
end

--创建并且启动一个task
--运行这个task的处理函数http_app_task_func
sys.taskInit(http_app_task_func)

五、产品支持说明

支持LuatOS开发的所有产品都支持http核心库。