概述:
lua 你可以理解为又一门比较轻便的语言,他对nginx做了很好的支撑。
本文写的目的主要是做网站的时候,有部分简单逻辑交给了lua,需要发送请求到别的机器,于是就有了本篇lua之HTTP的整理。
实现方式有两种,如下:
方式一:socket.http
github地址:https://github.com/diegonehab/luasocket
包使用:直接解压安装,需要注意的是貌似makefile里面指定了安装的路径,所以安装的时候无需再制定路径,直接
make make install
默认应该是在/usr/local下,这是我之前安装时候遇到的,也许新版会有所不同,具体看README.txt,安装好之后的路径如图
代码示例:
http有GET,POST于是我就对这两个方法进行了封装了下,单写了一个lua的文件如下
lua_http.lua
-- -- Created by IntelliJ IDEA. -- User: lihua -- Date: 2016/2/29 -- Time: 17:44 -- To change this template use File | Settings | File Templates. -- 需要安装luasocket 才会支持 65上的安装地址是 /app/src/lj2/share/lua/5.1 local http = require("socket.http") local ltn12 = require("ltn12") function HttpUtil() local self = {} -- get请求 self.httpget = function(u) local t = {} local r, c, h = http.request{ url = u, -- 20160708 如果传入的是table的话, 就需要用一个容器来接收http body的内容, 也就是sink那个参数 sink = ltn12.sink.table(t)} return r, c, h, table.concat(t) end self.httpPost = function(u,inParam) -- 参考 http://www.stutostu.com/?p=1285 ngx.log(ngx.WARN,"url:"..u) ngx.log(ngx.WARN,"inParam:"..inParam) local response_body = {} local post_data = inParam local res, code = http.request{ url = u, method = "POST", headers = { ["Content-Type"] = "application/json", ["Content-Length"] = #post_data, }, source = ltn12.source.string(post_data), sink = ltn12.sink.table(response_body) } res = table.concat(response_body) ngx.log(ngx.WARN,"res:"..res) ngx.log(ngx.WARN,"code:"..code) return res,code end return self end
调用:
local httputil = HttpUtil() local url = "http://ip地址:端口/...." local resStr --响应结果 local res,code = httputil.httpPost(url,str) if code ~= 200 then ngx.log(ngx.WARN,"非200状态,code:"..code) return resStr end resStr = res
到此,方式一就介绍结束了
使用心得:方式一是我一开始的选择,因为最先学会这个,但是当我遇到我另外一个需求的时候,我发现它满足不了我,就是无法回去响应体的Header的相关的信息,因为我要用Content-Type做一些逻辑处理,百度无解后,于是采用了方式二
方式二:resty.http
github地址:https://github.com/pintsized/lua-resty-http
包说明:这个包不用安装,直接解压,然后把要用的lua文件拷到自己的lualib中就可以了
mkdir -p /app/lua_resty_http/ cd /app/lua_resty_http/ --压缩包上传在这里 解压 tar -xvf lua-resty-http-0.08.tar.gz
将这两个文件拷贝到我openresty安装的lua的lib库中,下图是我openresty中nginx.conf配置文件中制定的lua的支持模块的路径,so
cd /app/openresty/luapro/lualib
看到
把上面的http.lua,http_header.lua放到上图中的resty文件夹中就可以了。
好了,准备工作ok.
代码示例:
这个省事,直接调用了
local http = require "resty.http" local httpc = http.new() local url = "http://ip:端口/......" local resStr --响应结果 local res, err = httpc:request_uri(url, { method = "POST", --args = str, body = str, headers = { ["Content-Type"] = "application/json", } }) if not res then ngx.log(ngx.WARN,"failed to request: ", err) return resStr end --请求之后,状态码 ngx.status = res.status if ngx.status ~= 200 then ngx.log(ngx.WARN,"非200状态,ngx.status:"..ngx.status) return resStr end --header中的信息遍历,只是为了方便看头部信息打的日志,用不到的话,可以不写的 for key, val in pairs(res.headers) do if type(val) == "table" then ngx.log(ngx.WARN,"table:"..key, ": ", table.concat(val, ", ")) else ngx.log(ngx.WARN,"one:"..key, ": ", val) end end --响应的内容 resStr = res.body
ok,大功告成!
上面方式一说的获取不到的header的信息,采用的这个,这个怎么获取的就如上面的for循环,直接都打印出来了,我要用的是Content-Type,使用的方法是,接着上面的代码继续写.....
local typeOfContent = res.headers["content-type"] local byteData local res if typeOfContent == 'image/jpeg;charset=UTF-8' or typeOfContent == 'image/jpg;charset=UTF-8' then res = ngx.encode_base64(resStr) --这个是我页面上想要的格式 res = '{"result":"'..res..'"}' ngx.log(ngx.WARN,"osa--typeOfContent-yes-resStr="..res) resStr = res end
(如果响应体content_type是image的话,为了防止内容被篡改,base64一下,再给页面,页面也是可以显示出图片的,我一开始还在想读流呢!哎,,)
好了 ,结束!
总结:
就上面的两种方法,我觉的方式二相对好点,首先不用安装,其次可以获取响应的Header的内容,也许方式一也可以,但是我没搞出来。
~~~~~~~~纯个人项目遇到的问题总结,如能帮上您,我很开心,如有错误或者不严谨的地方,还望指教!~~~