A Rate-Limiting HTTP Proxy(4)HTTP MVC

A Rate-Limiting HTTP Proxy(4)HTTP MVC


HTTP
There are several HTTP handling method
Proxy - nginx work as an Proxy
location ~ ^/user {
proxy_pass http://127.0.0.1:8080;
}

I try to make NGINX running on 80 port, but I get this error message:
[emerg] 73020#2236172: bind() to 0.0.0.0:80 failed (13: Permission denied)

Add this to the nginx.conf, restart it with sudoer
user root;

Exception:
nginx: [emerg] getgrnam("root") failed in /opt/luaweb/conf/nginx.conf:1

Solution:
http://blog.csdn.net/u013091013/article/details/51860303
I should as this line to the top.
user root owner;

Add HTML Editor to my Eclipse, add this URL to the plugin list http://download.eclipse.org/releases/mars/ - only select the HTML editor and JS editor

Here is the whole script - nginx.conf
user root owner;
worker_processes 1;
error_log logs/error.log notice;
events {
worker_connections 1024;
}
http {
server {
listen 80;
location / {
root html;
index index.html;
}
location ~ ^/user {
proxy_pass http://localhost:8080;
}
}

lua_package_path "/opt/luaweb/lua/?.lua;;";
server {
listen 8080;
lua_code_cache off;
location ~ /user/(.+) {
default_type text/html;
content_by_lua_file lua/$1.lua;
}
}
}

index.html page to Show the Look and Feel
<html>
<head>
<meta charset="UTF-8">
<title>Login Page</title>
</head>
<body>
UserName: <input type="text" id="username" value="admin">
Password: <input type="password" id="password" value="admin">
<a href="javascript:void(0)" οnclick="login()">Login</a>
<script src="//cdn.bootcss.com/jquery/2.2.4/jquery.min.js"></script>
<script>
function login() {
var username = $('#username').val();
var password = $('#password').val();
$.post('/user/login', {username: username, password: password}, function(res){
console.log(res)
var msg = res.ret ? "登录成功" : "登录失败"
alert(msg)
}, 'json')
}
</script>
</body>
</html>

Here the LUA Script to handle the Login, that can be JAVA,PYTHON or any Other Backend.
lua/login.lua mock the Backend Logic
local req = require "req"
local cjson = require "cjson"

local args = req.getArgs()

local username = args['username']
local password = args['password']

local res = {}

if username == "admin" and password == "admin" then
res['ret'] = true
res['token'] = ngx.md5('admin/' .. tostring(ngx.time()))
else
res['ret'] = false
end

Module ngx.location.capture
We can do something on the params level.
local req = require “req”
local args = req.getArgs()

GET
local res = ngx.location.capture(‘/user/login’, { method = ngx.HTTP_GET, args = args, });

POST
local res = ngx.location.capture(‘/user/login’, { method = ngx.HTTP_POST, body = ngx.encode_args(args), });

Exception if we do GET without Post Body
no request body found; maybe you should turn on lua_need_request_body?

Solution:
That is because the HTTP method is not match in the jQuery. If it is using GET, then lua should be GET, or POST together.

Here is the final local-login.lua
local req = require "req"
local cjson = require "cjson"

local args = req.getArgs()

-- GET
local res = ngx.location.capture('http://localhost/user/login', {method = ngx.HTTP_GET, args = args})
-- POST
-- local res = ngx.location.capture('/user/login', {method = ngx.HTTP_POST, body = ngx.encode_args(args)})

-- print(res.status) -- status code

if res.status == 200 then
local ret = cjson.decode(res.body)
ret['from'] = 'local'
ngx.say(cjson.encode(ret))
else
print(res.body)
ngx.say('{"ret": false, "from": "local"}')
end

HTML button and command in index.html
<a href="javascript:void(0)" οnclick="local_login()">Local Login</a>
function local_login() {
var username = $('#username').val();
var password = $('#password').val();
$.get('/user/local-login', {username: username, password: password}, function(res){
console.log(res)
var msg = res.ret ? "本地登录成功" : "本地登录失败"
alert(msg)
}, 'json')
}

Third Party Module lua-resty-http
https://github.com/pintsized/lua-resty-http

Exception:
2017/05/18 13:48:18 [error] 19934#2742039: *53 lua entry thread aborted: runtime error: /opt/luaweb/lua/local-login.lua:3: module 'resty.http' not found:

Solution:
https://moonbingbing.gitbooks.io/openresty-best-practices/ngx_lua/how_use_third_lib.html
Copy the lua module script in openresty
>cp ~/Downloads/lua-resty-http-master/lib/resty/*.lua ./

Updated local-login.lua to support Third Party
local req = require "req"
local cjson = require "cjson"
local http = require "resty.http"

local args = req.getArgs()

-- GET
-- local res = ngx.location.capture('http://localhost/user/login', {method = ngx.HTTP_GET, args = args})
-- POST
-- local res = ngx.location.capture('/user/login', {method = ngx.HTTP_POST, body = ngx.encode_args(args)})

-- http
local httpc = http.new()
local res = httpc:request_uri("http://127.0.0.1:8080/user/login", {
method = "POST",
body = ngx.encode_args(args),
headers = {
["Accept"] = "application/json",
["Accept-Encoding"] = "utf-8",
["Cookie"] = ngx.req.get_headers()['Cookie'],
["Content-Type"] = "application/x-www-form-urlencoded",
}
})
httpc:set_keepalive(60)

-- print(res.status) -- status code

DispatherServlet — MVC
https://github.com/362228416/openresty-web-dev/tree/master/demo8

nginx.conf
http {
lua_package_path "$prefix/lua/?.lua;$prefix/lualib/?.lua;;";
server {
listen 80;
server_name localhost;
lua_code_cache off;

location / {
default_type "text/html; charset=utf-8";
content_by_lua_file lualib/lite/mvc.lua;
}

location ~ ^/js/|^/css/|\.html {
root html;
}
}
}

lualib/lite/mvc.lua is handle the moduleName/methodName
local uri = ngx.var.uri
-- home page
if uri == "" or uri == "/" then
local res = ngx.location.capture("/index.html", {})
ngx.say(res.body)
return
end

local m, err = ngx.re.match(uri, "([a-zA-Z0-9-]+)/*([a-zA-Z0-9-]+)*")

local is_debug = true

local moduleName = m[1] -- module
local method = m[2] -- method

if not method then
method = "index" -- default method index
else
method = ngx.re.gsub(method, "-", "_")
end

-- controller is under web
local prefix = "web."
local path = prefix .. moduleName

-- input the module web.user
local ret, ctrl, err = pcall(require, path)

if ret == false then
if is_debug then
ngx.status = 404
ngx.say("<p style='font-size: 50px'>Error: <span style='color:red'>" .. ctrl .. "</span> module not found !</p>")
end
ngx.exit(404)
end

-- method of the module, get, index
local req_method = ctrl[method]

if req_method == nil then
if is_debug then
ngx.status = 404
ngx.say("<p style='font-size: 50px'>Error: <span style='color:red'>" .. method .. "()</span> method not found in <span style='color:red'>" .. moduleName .. "</span> lua module !</p>")
end
ngx.exit(404)
end

-- call lua method
ret, err = pcall(req_method)

if ret == false then
if is_debug then
ngx.status = 404
ngx.say("<p style='font-size: 50px'>Error: <span style='color:red'>" .. err .. "</span></p>")
else
ngx.exit(500)
end
end

2 Methods in lua/web/user.lua
local cjson = require "cjson"
local req = require "lite.req"

local _M = {}

local users = {"Mr Li", "Mr Luo", "Mr Kang"}

function _M.index()
ngx.say(cjson.encode(users))
end

function _M.get()
local args = req.getArgs()
local index = tonumber(args['index'])
if not index then
index = 1
end
ngx.say(users[index])
end

return _M

We can visit page URL like this
http://localhost/user — lua/web/user.lua method index
http://localhost/user/get?index=1 — lua/web/user.lua method get

Home Page index.html and index.js index.css are as follow:
<html>
<head>
<meta charset="UTF-8">
<title>Home Page</title>
<link rel="stylesheet" href="/css/index.css">
</head>
<body>
<div class="container">
<h1>UserLists</h1>
<ul id="users"></ul>
<p>Second<span id="user"></span></p>
</div>
<script src="//cdn.bootcss.com/jquery/2.2.4/jquery.min.js"></script>
<script src="/js/index.js"></script>
</body>
</html>

.container {
width: 1000px;
margin: 0 auto;
text-align: center;
}

(function(){
$.getJSON('/user/', function(data){
$('#users').html(data.join(','))
console.log(data)
})
$.get('/user/get', {index: 2}, function(data){
$('#user').html(data)
console.log(data)
})
})()


References:
https://github.com/362228416/openresty-web-dev/tree/master/demo7

https://moonbingbing.gitbooks.io/openresty-best-practices/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值