OpenResty完全开发指南:构建百万级别并发的Web应用 综合实例

 --功能描述

-- 实现基本的时间服务,具体功能是
--1:只支持GET和POST方法
--2:只支持HTTP 1.1/2协议
--3:只允许某些用户访问
--4:GET方法获取当前时间,以HTTP时间格式输出
--5:POST方法在请求体力传入时间戳,服务器转换为http时间格式
--6:可以使用URI参数 “need_encode=1”输出会做base64编码

 --设计

-- 依据openresty的阶段式处理逻辑,可以把整个应用划分为四个部分,每个部分都有一个独立的lua文件
--1:rewrite_by_lua:正确性检查
--2:accessby_lua:使用白名单做访问控制
--3:content_by_lua:产生响应内容
--4:body_filter_by_lua:加工数据,base64编码

 --正确性检查

rewrite_demo1.lua文件
--1:rewrite_by_lua:正确性检查
local method=ngx.req.get_method() -- 获取请求方法
if method ~= "GET" and method ~= "POST" then
    ngx.header['Allow'] = 'GET,POST' --方法错误返回Allow头字段
    ngx.exit(405)                    -- 返回状态码405 结束请求
end

local ver = ngx.req.http_version() --获取协议版本号
if ver  < 1.1 then
    ngx.log(ngx.WARN,"VERSION IS LOWER THEN 1.1" .. ver)
    ngx.exit(400)
end
ngx.ctx.encode = ngx.var.arg_need_encode -- 取URI参数里need_ecncode字段
ngx.header.content_length = nil          -- 删除长度头,谜面客户端接受错误

 --白名单控制

access_demo1.lua
local white_list={... } -- 若干白名单ip地址
local ip = ngx.var.remote_addr --获取客户端地址

if not white_list[ip] then
    ngx.log(ngx.WARN, ip,"access was refaused")
    ngx.exit(403)
end

 -- 业务逻辑

content_demo1.lua
local action_get=function()
    ngx.req.discard_body() -- 显示丢弃请求体

    local tmpstamp = ngx.time() -- 获取当前时间戳
    ngx.say(ngx.http_time(tmpstamp)) --转换为http格式
end

local action_post = function()
    ngx.req.read_body() -- 要求非阻塞读取请求体
    local data = ngx.req.get_body_data() -- 获取请求体数据
    local num = tonumber(data) -- 转换数字

    if not num then
        ngx.log(ngx.ERR, num, "is ")
        ngx.exit(400)
    end
    ngx.say(ngx.http_time(num))
end

local actions={ --一个表映射方法与处理函数
    GET = action_get,
    post= action_post
}

local fun = ngx.req.get_method() -- 获取请求方法
actions[fun]()

 --数据加工

if ngx.status ~= ngx.HTTP_OK then--错误信息不会编码
    return
end

if ngx.ctx.encode then
    ngx.arg[1] = ngx.encode_base64(ngx.arg[1]) -- 改写响应体数据, 对数据做base64编码
end

 -- 部署应用

location = /demo1 {
    rewrite_by_lua_file             /usr/openResty/src/rewrite_demo1.lua;
    access_by_lua_file             /usr/openResty/src/access_demo1.lua;
    content_by_lua_file             /usr/openResty/src/content_demo1.lua;
    body_filter_by_lua_file             /usr/openResty/src/body_filter_demo1.lua;
}

 --测试

--测试
--curl ' 127.0.0.1/example '                            #发送GET 请求
--curl ' 127.0.0.1/example ' d ' 1516765407 '             #发送POST 请求
--curl ' 127.0.0.1/example '-X DELETE                     #发送DE LETE 请求,返回405
--curl ' 127.0.0.1/example?need_encode=l '                  #要求Base64 编码

 



posted @ 2020-05-27 09:53  first_semon  阅读(738)  评论(0编辑  收藏  举报