local socket = require "levent.socket"
local levent = require "levent.levent"
local seri = require "levent.tpseri"
local dns = require "levent.dns"
local mt = {}
mt.__index = mt
buflen = 4096
mt.get_base_header = function(self)
local start_pos, end_pos
while true do
self.client_buffer = self.client_buffer .. self.client:recv(buflen)
start_pos, end_pos = self.client_buffer:find("\n")
if start_pos then
break
end
end
base_header = self.client_buffer:sub(1, start_pos)
local result = {}
for i in string.gmatch(base_header, "%s ") do
table.insert(result, i)
end
self.client_buffer = self.client_buffer:sub(start_pos 1, -1)
return table.unpack(result)
end
mt.connect_target = function(self, host)
local i = host:find(":")
local port
if not i then
port = 80
else
host = host:sub(1, i)
port = tonumber(host:sub(i,-1))
end
local ips, err = dns.resolve(host)
local ip = ips[1]
self.target, err = socket.socket(socket.af_inet, socket.sock_stream)
self.target:connect(ip, port)
end
mt.method_connect = function(self)
print("enter method connect")
self.path = self.path:sub(8, -1)
local i = self.path:find("/")
local host = self.path:sub(1, i - 1)
local path = self.path:sub(i, -1)
self:connect_target(host)
self.target:sendall("http/1.1 200 connection established\n proxy-agent: 0.0.1\n\n")
self.client_buffer = ""
self:flush_two_socket()
end
mt.keep_request = function(self)
print("keep request")
while true do
local req, err = self.client:recv(buflen)
if req and #req > 0 then
self.target:sendall(req)
else
break
end
end
end
mt.keep_resp = function(self)
print("keep resp")
while true do
local resp, err = self.target:recv(buflen)
if resp and #resp > 0 then
self.client:sendall(resp)
else
break
end
end
end
mt.flush_two_socket = function(self)
levent.spawn(self.keep_resp, self)
levent.spawn(self.keep_request, self)
levent.sleep(1)
end
mt.method_others = function(self)
self.path = self.path:sub(8, -1)
local i = self.path:find("/")
local host = self.path:sub(1, i - 1)
local path = self.path:sub(i, -1)
self:connect_target(host)
local first_data = string.format("%s %s %s\r\n", self.method, path, self.protocol)..self.client_buffer
print(string.format("%q", first_data))
self.target:sendall(first_data)
self:flush_two_socket()
end
local other_method = {
options=1,
get = 1,
head = 1,
post=1,
put=1,
delete=1,
trace=1,
}
mt.handle = function(self, csock)
self.client = csock
self.client_buffer = ""
self.timeout = timeout
self.method, self.path, self.protocol = self:get_base_header()
print(self.method, self.path, self.protocol)
if self.method == "connect" then
self:method_connect()
elseif other_method[self.method] then
self:method_others()
end
self.client:close()
self.target:close()
print("close all socket")
end
local sock, err = socket.socket(socket.af_inet, socket.sock_stream)
assert(sock, errmsg)
print("bind:", sock:bind("0.0.0.0", 8858))
print("listen:", sock:listen())
function start_server()
while true do
local csock, err = sock:accept()
if not csock then
print("accept failed:", err)
break
end
print("new conn from:", csock:getpeername())
local a = {}
setmetatable(a, mt)
levent.spawn(a.handle, a, csock)
end
end
levent.start(start_server)
用户登录
还没有账号?立即注册
用户注册
投稿取消
| 文章分类: |
|
还能输入300字
上传中....
缘生缘灭缘如水