Lua 脚本
#user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log logs/access.log main; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65; gzip on; gzip_min_length 1k; #增加 gzip_buffers 4 16k; #增加 gzip_http_version 1.1; #增加 gzip_comp_level 2; #增加 gzip_types text/plain application/x-javascript text/css application/xml text/javascript; #增加 gzip_vary off; #增加 server { listen 80; server_name localhost; #charset koi8-r; charset utf-8; # dns 解析 resolver 8.8.8.8 114.114.114.114 valid=3600s; # access_log logs/host.access.log main; location = /favicon.ico { root html/peixun86; } location /peixun/clearcache { access_log logs/clearcache.access.log main; # 这个配置很重要 default_type text/html; # set $domain $host proxy_set_header X-real-ip $remote_addr; #直接获取客户端IP proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;#通过代理服务器获取客户端IP # 只会警告,可以忽略,但是线上一定为on lua_code_cache on; content_by_lua_file conf/lua/clearcache_work.lua; } location / { access_log logs/root.access.log main; # 这个配置很重要 default_type text/html; # set $domain $host proxy_set_header X-real-ip $remote_addr; #直接获取客户端IP proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;#通过代理服务器获取客户端IP # 只会警告,可以忽略,但是线上一定为on lua_code_cache on; content_by_lua_file conf/lua/union_lable_work.lua; } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } # proxy the PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ .php$ { # proxy_pass http://127.0.0.1; #} # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # #location ~ .php$ { # root html; # fastcgi_pass 127.0.0.1:9000; # fastcgi_index index.php; # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; # include fastcgi_params; #} # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # #location ~ /.ht { # deny all; #} } # another virtual host using mix of IP-, name-, and port-based configuration # #server { # listen 8000; # listen somename:8080; # server_name somename alias another.alias; # location / { # root html; # index index.html index.htm; # } #} # HTTPS server # #server { # listen 443 ssl; # server_name localhost; # ssl_certificate cert.pem; # ssl_certificate_key cert.key; # ssl_session_cache shared:SSL:1m; # ssl_session_timeout 5m; # ssl_ciphers HIGH:!aNULL:!MD5; # ssl_prefer_server_ciphers on; # location / { # root html; # index index.html index.htm; # } #} }
local function local_print(str) local dbg = io.open("conf/lua/logs/output.txt", "a+") local str = str or "" if dbg then dbg:write(str..' ') dbg:close() end end local template = require("resty.template") local redis = require("resty.redis") local mysql = require("resty.mysql") local context = { title = "测试", name = "张三", description = "<script>alert(1);</script>", script = "alert(1)", age = 20, hobby = {"电影", "音乐", "阅读"}, -- score = {"语文" = 90, "数学" = 80, "英语" = 70}, score2 = { {name = "语文", score = 901}, {name = "数学", score = 810}, {name = "英语", score = 710}, }, file = 'xiaowu' } -- 关闭redis链接 local function close_redes( red ) if not red then return end local ok, err = red:close() if not ok then local_print("close redis error:" .. err) end end -- 创建实例 local red = redis:new() -- 设置超时(毫秒) red:set_timeout(2000) -- 建立连接 local ip = "192.168.10.10" local port = 7000 local ok, err = red:connect(ip, port) if not ok then return end -- 没有密码不需要写 -- local res, err = red:auth("") -- if not res then -- local_print("connect to redis error : " .. err) -- return -- end -- 调用api进行操作 res, err = red:set("msg", "hello world") if not res then local_print("set msg error : " .. err) end local resp, err = red:get("msg") if not resp then local_print("get msg erro:" .. err) else context.title = resp end close_redes(red) --------------------------------------------------------------------------------------- local function close_db( db ) if not db then return end db:close() end -- 创建实例 local db, err = mysql:new() if not db then local_print("new mysql error:" .. err) return end -- 设置超时时间(毫秒) db:set_timeout(5000) local props = { host = "192.168.10.5", port = 3306, database = "union", user = "rshy", password = "123456" } local res, err, errno, sqlstate = db:connect(props) if not res then local_print("connect to mysql error : " .. err, " , errno : " .. errno, " , sqlstate : " .. sqlstate) return close_db(db) else local select_sql = "select teacherid from teacher limit 2" res, err, errno, sqlstate = db:query(select_sql) if not res then local_print("select error : " .. err, " , errno : " .. errno, " , sqlstate : " .. sqlstate) return close_db(db) else for k, v in pairs(res) do local_print(k .. v.teacherid) end end end --------------------------------------------------------------------------------------- template.render("t1.html", context)
local redis = require "resty.redis" local red = redis:new() red:set_timeout(1000) local ok, err = red:connect("127.0.0.1", 6379) if not ok then ngx.say("failed to connect: ", err) return end --密码和选择的桶 red:auth(password) red:select(18) ngx.say("set result: ", ok) local res, err = red:get(download.token.b17efb43-292e-4cc9-ac5d-0b46bce059c5") if not res then ngx.say("failed to get download.token.b17efb43-292e-4cc9-ac5d-0b46bce059c5: ", err) return end if res == ngx.null then ngx.say("download.token.b17efb43-292e-4cc9-ac5d-0b46bce059c5 not found.") return end ngx.say("download.token.b17efb43-292e-4cc9-ac5d-0b46bce059c5: ", res)
-- 区分设备 local function get_device() -- 获取请求头信息 local headers=ngx.req.get_headers() -- 获取ua local ua = headers['user-agent'] or '' local mobel_list = {'mobile', 'android', 'webos', 'iphone', 'ipod', 'blackberry'} for _, k in ipairs(mobel_list) do p, _=string.find(string.lower( ua ), k) if p then return "wap" end end return "pc" end -- 判断文件是否存在 local function file_exists(path) local file = io.open(path, "rb") if file then file:close() end return file ~= nil end -- 字符串分割 local function Split(str, sep) local sep, fields = sep or "/", {} local pattern = string.format("([^%s]+)", sep) str:gsub(pattern, function (c) fields[#fields + 1] = c end) return fields end -- 判断结尾 function string.ends(String,End) return End=='' or string.sub(String,-string.len(End))==End end -- 构建文件路径 local function get_file_path(url_path, host, device) local root_path = '/html/' .. host .. '/' .. device local end_path = string.ends(url_path, '/') if end_path then url_path = string.sub(url_path, 1, -2) url_path = root_path .. url_path .. '.txt' return url_path else url_path = root_path .. url_path .. '.txt' return url_path end end -- 字符串分割 local function Split(str, sep) local sep, fields = sep or "/", {} local pattern = string.format("([^%s]+)", sep) str:gsub(pattern, function (c) fields[#fields + 1] = c end) return fields end -- 去除空格 function trim(s) return (string.gsub(s, "^%s*(.-)%s*$", "%1")) end -- 文件保存 local function file_save(file_path, res) local file_path_temp = file_path local file_path_temp = Split(file_path_temp, "/") table.remove(file_path_temp) local concatret = table.concat(file_path_temp, "/") local concatret = '/' .. concatret ngx.say("<!--request-->") -- /html/tingclass/pc/getjarname/xuexi/wiayu/0-1-4.tx os.execute(string.format("mkdir -p %s", concatret)) File = io.open(file_path, 'w') File:write(res) File:close() end -- 发送请求获取数据 http = require("resty.http") local function get_replace_templte(union_id, url_path, host, host_ip, device) -- 发送请求 local httpc = http.new() timeout = 3000 httpc:set_timeout(timeout) local url = "http://" .. host_ip local resStr --响应结果 local res, err = httpc:request_uri(url, { method = "GET", path = string.format( "/label?aId=%s&deviceType=%s&url=%s",union_id, device, url_path), --args = str, --body = str, headers = { ["Content-Type"] = "text/html; charset=utf-8", ["HOST"] = host, } }) if res.status ~= 200 then ngx.say(string.format("<!--error code: %s-->", res.status)) -- ngx.exit(res.status) return false else --请求之后,状态码 return res.body end end -- 替换数据 local function replace_with(union_id, url_path, body, host, host_ip, device) -- 获取替换模板 local temp = get_replace_templte(union_id, url_path, host, host_ip, device) -- local temp = '<!--luaLabel-->' .. '替换了哦。。' -- "<!--luaLabel-->" if temp then ngx.say("<!--replace-->") local now_time = os.date("%Y-%m-%d-%H-%M-%S", os.time()) temp = "<!--replaceStart-->" .. temp .. "<!--replaceEnd-->" .. "<!--luaLabelRiseTimeStart[" .. now_time .. "]luaLabelRiseTimeEnd-->" local res_body = string.gsub(body, "<!%-%-luaLabel%-%->", temp) return res_body else ngx.say("<!--not replace-->") return false end end -- 发送请求 local function send_request(union_id, url_path, host, host_ip, res_exist, device, file_path) -- 发送请求 local httpc = http.new() -- http://www.tingclass.net/ local url = "http://" .. host_ip .. ngx.var.uri local resStr --响应结果 local res, err = httpc:request_uri(url, { method = "GET", --args = str, --body = str, headers = { ["Content-Type"] = "text/html; charset=utf-8", ["HOST"] = host, } }) if not res then ngx.exit(res.status) else if res.status == 200 then --请求之后,状态码 ngx.status = res.status -- 这里进行修改操作 -- res.body = 修改后数据 res_body = replace_with(union_id, url_path, res.body, host, host_ip, device) if res_body then -- 修改完将数据存入文件 file_save(file_path, res_body) return res_body else file_save(file_path, res.body) return res.body end else ngx.exit(res.status) end end end -- 根据时间清理缓存 local function del_cache(body, union_id, url_path, host, host_ip, res_exist, device, file_path) local res = string.match(tostring(body), 'luaLabelRiseTimeStart%[(.*)%]luaLabelRiseTimeEnd') if res then local del_cache_time = 4 * 60 * 60 ngx.say((string.format("<!--res_body: %s-->", res))) local data_split_table = Split(res, '-') local year_t, month_t, day_t, hour_t, minute_t, second_t = data_split_table[1], data_split_table[2], data_split_table[3], data_split_table[4], data_split_table[5], data_split_table[6] -- ngx.say(year_t, month_t, day_t, hour_t, minute_t, second_t) local now_time = os.time() local old_time = os.time({day=day_t, month=month_t, year=year_t, hour=hour_t, min=minute_t, sec=second_t}) if now_time - old_time >= del_cache_time then ngx.say("<!--del_cache-->") -- 删除进行文章改写 local res_body = send_request(union_id, url_path, host, host_ip, res_exist, device, file_path) return res_body else return body end else return body end end -- 根据文件是否存在进行结果返回 local function get_body(union_id, url_path, host, host_ip, res_exist, device, file_path) -- 文件存在直接返回结果 if res_exist then ngx.say("<!--file-->") local f = io.open(file_path) local body = f:read("*a") f:close() -- 根据换取时间进行判断缓存是否需要清除 local res_body = del_cache(body, union_id, url_path, host, host_ip, res_exist, device, file_path) return res_body -- 不存在发送请求获取结果 else local body = send_request(union_id, url_path, host, host_ip, res_exist, device, file_path) return body end end -- 从上游服务器获取 ip_port local upstream = require "ngx.upstream" local function getUpstreamIps() local us = upstream.get_primary_peers('lua.ip.port') local ips = {} for _, u in ipairs(us) do table.insert(ips, u["name"]) end return ips end local function getFrontIp() local ips = getUpstreamIps() local ramdom = math.random(0, #ips); return ips[ramdom] end local function main() -- 第一步,业务分类 (区分 WAP/PC) local device = get_device() -- 第二步,获取文件路径 local host = ngx.var.http_host local url_path = ngx.var.uri local file_path = get_file_path(url_path, host, device) -- 第三步, 判断文件是否存在 local res_exist = file_exists(file_path) -- 第四步,返回结果 ngx.say(string.format("<!--host: %s-->", host)) local host_ip = getFrontIp() local union_id = 23 local body = get_body(union_id, url_path, host, host_ip, res_exist, device, file_path) -- 文件存在直接返回结果 -- 不存在发送请求获取结果 ngx.say(body) end main()
-- 区分设备 local function get_device() -- 获取请求头信息 local headers=ngx.req.get_headers() -- 获取ua local ua = headers['user-agent'] or '' local mobel_list = {'mobile', 'android', 'webos', 'iphone', 'ipod', 'blackberry'} for _, k in ipairs(mobel_list) do p, _=string.find(string.lower( ua ), k) if p then return "wap" end end return "pc" end -- 判断结尾 function string.ends(String,End) return End=='' or string.sub(String,-string.len(End))==End end -- 构建文件路径 local function get_file_path(url_path, host, device) local root_path = '/html/' .. host .. '/' .. device local end_path = string.ends(url_path, '/') if end_path then url_path = string.sub(url_path, 1, -2) url_path = root_path .. url_path .. '.txt' return url_path else url_path = root_path .. url_path .. '.txt' return url_path end end -- 判断文件是否存在 local function file_exists(path) local file = io.open(path, "rb") if file then file:close() end return file ~= nil end -- 入口函数 local function main() -- (区分 WAP/PC) local device = get_device() -- 获取url - path local url_path = ngx.var.uri local host = ngx.var.http_host --local host = ngx.var.http_host local file_path = get_file_path(url_path, host, device) ngx.say(file_path) ngx.say('<br>') local file_path = string.gsub(file_path, "/clearcache", "") ngx.say(file_path) -- 判断文件是否存在 local res_exist = file_exists(file_path) if res_exist then os.remove( file_path ) ngx.say('<h1>删除成功</h1>') else ngx.say('<h1>没有缓存,不需要删除</h1>') end -- --host_ = "www.tingclass.net" --host_ip_ = "115.159.89.139" --host__ = "tingclass.test.com" --host_ip__ = "192.168.0.146:8081" -- 47.93.220.246 --local host = ngx.var.http_host --"www.tingclass.net" end main()