现在,服务端收到客户的一个url请求如下:
http://127.0.0.1/$userid/play/live/01.m3u8
1、对请求url进行正则校验,如果正则合法,就放通。正则非法就拒绝服务。
2、拿到这个请求后,先校验$userid合法性,比如是1000以下为合法。
3、所有检查满足要求后,返回一个01.m3u8的内容,类似如下:
#EXTM3U
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:1
#EXTINF:10, http://media.example.com/segment0.ts
#EXTINF:10, http://media.example.com/segment1.ts
#EXTINF:10, http://media.example.com/segment2.ts
一、修改nginx.conf配置,以适配m3u8的后缀请求
location ~/.*m3u8 {
content_by_lua_file lua/check.lua;
~区分大小写 ; 以x.m3u8结尾的请求
二、进入lua文件,开始正则校验
查看ngx lua 的正则匹配函数 https://github.com/openresty/lua-nginx-module#ngxrematch
url中有4个‘/’,那么,在check.lua中,匹配为:
local m,err=ngx.re.match(httpUri, "/.*/.*/.*/.*")
此时给一个请求,curl -i http://127.0.0.1/play/live/01.m3u8 返回,MATCH NOT FOUND。因为只有 /play/live/01.m3u8 3个“/”
给一个请求,curl -i http://127.0.0.1/userid/play/live/01.m3u8 返回,/USERID/PLAY/LIVE/01.M3U8,满足4个“/”
三、判断userid合法性,
提取userid的数值出来,根据 ngxrematch 的提示,要用(),并不影响原有正则的功能,只是要提取参数。
使用local m,err=ngx.re.match(httpUri, "/(.*)/(.*)/.*/(.*)")
返回值中,m[0]中存放的是匹配到的整个字符串,为:/userid/play/live/01.m3u8
m[1] 中存放userdid字段,为 $userid
m[3]中存放01.m3u8频道信息,其中/opt/video/hls/目录下,提前放好一个01.m3u8文件,内容为
#EXTM3U
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:1
#EXTINF:10, HTTP://MEDIA.EXAMPLE.COM/SEGMENT0.TS
#EXTINF:10, HTTP://MEDIA.EXAMPLE.COM/SEGMENT1.TS
#EXTINF:10, HTTP://MEDIA.EXAMPLE.COM/SEGMENT2.TS
check.lua中正则和判断的逻辑为:
--这里要用绝对路径
local m3u8_path = '/opt/video/hls/'
--ngx.print(getContent(string.format('%s%s', m3u8_path, m[3]), blockPath))
--获取请求url
local httpUri = ngx.unescape_uri(ngx.var.request_uri)
--ngx.say(ngx.ERR, "httpurl:",httpUri )
--正则提取参数
local m,err=ngx.re.match(httpUri, "/(.*)/(.*)/.*/(.*)")
if m then
ngx.log(ngx.DEBUG,m[1],ngx.DEBUG,m[2])
--把userid的数字string 转成int,使用tonumber
if tonumber(m[1]) < 1000 then
--读取01.m3u8的文件,存放在/opt/video/hls/目录下
ngx.say(getContent(string.format('%s%s', m3u8_path, m[3]), blockPath))
ngx.log(ngx.NOTICE,"check ok!")
else
ngx.log(ngx.ERR,"check err!")
ngx.say("check err!")
return
end
else
if err then
ngx.log(ngx.ERR, "error: ", err)
return
end
ngx.say("match not found")
end
给一个请求,userid=99时,可以通过,并返回ts信息。userid=1000检查失败。
root@ubuntu:/opt/openresty/nginx/lua# curl http://127.0.0.1/99/play/live/01.m3u8
#EXTM3U
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:1
#EXTINF:10, HTTP://MEDIA.EXAMPLE.COM/SEGMENT0.TS
#EXTINF:10, HTTP://MEDIA.EXAMPLE.COM/SEGMENT1.TS
#EXTINF:10, HTTP://MEDIA.EXAMPLE.COM/SEGMENT2.TS
root@ubuntu:/opt/openresty/nginx/lua# curl http://127.0.0.1/1000/play/live/01.m3u8
CHECK ERR!