openresty开发系列30--openresty中使用http模块

OpenResty默认没有提供Http客户端,需要使用第三方提供的插件
我们可以从github上搜索相应的客户端,比如https://github.com/pintsized/lua-resty-http

安装方法:将 lua-resty-http/lib/resty/ 目录下的 http.lua 和 http_headers.lua 
两个文件拷贝到 /usr/local/openresty/lualib/resty 目录下即可
(假设 OpenResty 安装目录为 /usr/local/openresty)

local res, err = httpc:request_uri(uri, {  
    method = "POST/GET",  ---请求方式
    query = str,  ---get方式传参数
    body = str,     ---post方式传参数
    path = "url" ----路径
    headers = {  ---header参数
        ["Content-Type"] = "application/json",  
    }  
})  


示例:编写模拟请求天猫的查询

--引入http模块
local http = require("resty.http")
--创建http客户端实例
local httpc = http:new()

local resp,err = httpc:request_uri("https://list.tmall.com",
{
    method = "GET",    ---请求方式
    --path="/search_product.htm?q=ipone",
    query="q=iphone",    ---get方式传参数
    body="name='jack'&age=18",    ---post方式传参数
    path="/search_product.htm",    ----路径
    ---header参数
    headers = {["User-Agent"]="Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.111 Safari/537.36"}
})
if not resp then
    ngx.say("request error:",err)
    return
end
--获取状态码
ngx.status = resp.status

--获取响应信息
--响应头中的Transfer-Encoding和Connection可以忽略,因为这个数据是当前server输出的。
--获取遍历返回的头信息

for k, v in pairs(resp.headers) do
    if k ~= "Transfer-Encoding" and k ~= "Connection" then
        ngx.header[k] =v
    end
    if type(v) == "table" then  
        ngx.log(ngx.WARN,"table:"..k, ": ", table.concat(v, ", "))  
    else  
        ngx.log(ngx.WARN,"one:"..k, ": ", v)  
    end  
end
ngx.say("end")
--响应体
ngx.say(resp.body)

httpc:close()


httpc:close()


# 后台日志
# /usr/local/openresty/nginx]# tail -f logs/debug.log 
2019/08/23 17:58:04 [warn] 25373#0: *131 [lua] testhttp02.lua:32: one:ufe-result: A6, client: 192.168.10.164, server: www.server1.com, request: "GET /testhttp02 HTTP/1.1", host: "192.168.10.164"
2019/08/23 17:58:04 [warn] 25373#0: *131 [lua] testhttp02.lua:32: one:Date: Fri, 23 Aug 2019 09:58:04 GMT, client: 192.168.10.164, server: www.server1.com, request: "GET /testhttp02 HTTP/1.1", host: "192.168.10.164"
2019/08/23 17:58:04 [warn] 25373#0: *131 [lua] testhttp02.lua:32: one:Location: https://login.taobao.com/jump?target=https%3A%2F%2Flist.tmall.com%2Fsearch_product.htm%3Ftbpm%3D1%26q%3Diphone, client: 192.168.10.164, server: www.server1.com, request: "GET /testhttp02 HTTP/1.1", host: "192.168.10.164"
2019/08/23 17:58:04 [warn] 25373#0: *131 [lua] testhttp02.lua:32: one:Connection: keep-alive, client: 192.168.10.164, server: www.server1.com, request: "GET /testhttp02 HTTP/1.1", host: "192.168.10.164"
2019/08/23 17:58:04 [warn] 25373#0: *131 [lua] testhttp02.lua:32: one:EagleEye-TraceId: 0bfa16f315665542845385751e42fa, client: 192.168.10.164, server: www.server1.com, request: "GET /testhttp02 HTTP/1.1", host: "192.168.10.164"
2019/08/23 17:58:04 [warn] 25373#0: *131 [lua] testhttp02.lua:32: one:Strict-Transport-Security: max-age=0, client: 192.168.10.164, server: www.server1.com, request: "GET /testhttp02 HTTP/1.1", host: "192.168.10.164"
2019/08/23 17:58:04 [warn] 25373#0: *131 [lua] testhttp02.lua:32: one:Content-Length: 0, client: 192.168.10.164, server: www.server1.com, request: "GET /testhttp02 HTTP/1.1", host: "192.168.10.164"
2019/08/23 17:58:04 [warn] 25373#0: *131 [lua] testhttp02.lua:32: one:Timing-Allow-Origin: *, client: 192.168.10.164, server: www.server1.com, request: "GET /testhttp02 HTTP/1.1", host: "192.168.10.164"
2019/08/23 17:58:04 [warn] 25373#0: *131 [lua] testhttp02.lua:32: one:Server: Tengine/Aserver, client: 192.168.10.164, server: www.server1.com, request: "GET /testhttp02 HTTP/1.1", host: "192.168.10.164"


-------------------------------------------------------
发现报错
request error :no resolver defined to resolve "list.tmall.com"


此错误是因为要配置DNS解析器resolver 8.8.8.8,否则域名是无法解析的。
在nginx.conf配置文件中 http模块加上resolver 8.8.8.8; Google提供的免费DNS服务器的IP地址
配置好后,重启nginx


---------------------------------------------------------

访问https错误,因为我们访问的https,需要配置ssl证书
在nginx配置文件中,server虚拟主机模块设置

lua_ssl_verify_depth 2;
lua_ssl_trusted_certificate "/etc/ssl/certs/ca-bundle.crt";


--------------------------------------------------------

http模块应用场景很多,这里只简单介绍了一下http模块的使用

还有很多openresty模块,可以参考 https://github.com/bungle/awesome-resty



以suning.com为例:

local http = require("resty.http")
--创建http客户端实例
local httpc = http:new()

local resp,err = httpc:request_uri("http://issm.suning.com",
{
    method = "GET",
    path="/productDetail_P11271.htm",
    headers = {["User-Agent"]="Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.111 Safari/537.36"}
})
if not resp then
    ngx.say("request error:",err)
    return
end
--获取状态码
ngx.status = resp.status

--获取响应信息
--响应头中的Transfer-Encoding和Connection可以忽略,因为这个数据是当前server输出的。
for k,v in pairs(resp.headers) do
    if k ~= "Transfer-Encoding" and k ~= "Connection" then
        ngx.header[k] =v
    end
end

--响应体
ngx.say(resp.body)

httpc:close()

 

配置示例

# cat /usr/local/openresty/nginx/conf/nginx.conf
worker_processes  4;

#pid        logs/nginx.pid;
events {
    worker_connections  10240;
}

http {
    include       mime.types;
    default_type  text/html;


    sendfile        on;
    keepalive_timeout  65;
    resolver 8.8.8.8;

    server {
        listen       80;
        server_name  www.server1.com;
    lua_ssl_verify_depth 2;
    lua_ssl_trusted_certificate "/etc/ssl/certs/ca-bundle.crt";

    location /tmall {
        access_by_lua_file /usr/local/lua/tmall.lua;
    }

        location / {
            root   html;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

    }


}

lua脚本

# cat /usr/local/lua/tmall.lua 
--引入http模块
local http = require("resty.http")
--创建http客户端实例
local httpc = http:new()

local resp,err = httpc:request_uri("https://list.tmall.com",
{
    method = "GET",    ---请求方式
    --path="/search_product.htm?q=ipone",
    query="q=iphone",    ---get方式传参数
    body="name='jack'&age=18",    ---post方式传参数
    path="/search_product.htm",    ----路径
    ---header参数
    headers = {["User-Agent"]="Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.111 Safari/537.36"}
})
if not resp then
    ngx.say("request error:",err)
    return
end
--获取状态码
ngx.status = resp.status

--获取响应信息
--响应头中的Transfer-Encoding和Connection可以忽略,因为这个数据是当前server输出的。
--获取遍历返回的头信息

for k, v in pairs(resp.headers) do
    if k ~= "Transfer-Encoding" and k ~= "Connection" then
        ngx.header[k] =v
    end
    if type(v) == "table" then  
        ngx.log(ngx.WARN,"table:"..k, ": ", table.concat(v, ", "))  
    else  
        ngx.log(ngx.WARN,"one:"..k, ": ", v)  
    end  
end
ngx.say("end")
--响应体
ngx.say(resp.body)

httpc:close()

 

posted @ 2019-08-30 14:34  reblue520  阅读(4697)  评论(0编辑  收藏  举报