作者:shihuaping0918@163.com,轉(zhuǎn)載請(qǐng)注明作者
skynet中有http server和http client的代碼,用來支持http訪問。在分析http之前屈芜,要先看一下url庫。文件位于skyet/lualib/http/url.lua。
回顧一下http協(xié)議井佑,http協(xié)議有消息頭属铁,消息體,消息頭和消息體以\r\n分隔躬翁,消息頭以\r\n結(jié)束焦蘑。對(duì)于較長數(shù)據(jù)塊,以chunk的形式傳輸姆另。http發(fā)送請(qǐng)求有g(shù)et/post兩種方式喇肋。但不管是哪種方式都會(huì)用到url,而url是可以帶參數(shù)的迹辐,這個(gè)參數(shù)部分有個(gè)專門的名字叫做query string。
就是下面這一行甚侣,"?"后面的query明吩。
http_URL = "http:" "http://" host [ ":" port ] [ abs_path [ "?" query ]]
設(shè)計(jì)過字符串協(xié)議的同學(xué)應(yīng)該都很清楚,字符串協(xié)議是需要有保留字符或者保留字符串的殷费。對(duì)于url也不例外印荔,所以query string需要對(duì)保留字做特殊處理,這個(gè)處理就叫做percent-encoding详羡。將保留字轉(zhuǎn)換為%xx仍律,也就是16進(jìn)制的字符串表示方式。當(dāng)服務(wù)器收到這個(gè)query string時(shí)实柠,需要對(duì)它做一次解碼水泉。
local url = {}
--將16進(jìn)制字符轉(zhuǎn)為數(shù)字,再將數(shù)字轉(zhuǎn)為ascii碼
local function decode_func(c)
return string.char(tonumber(c, 16))
end
-- 將字符串中的+替換為空格
-- 將%xx轉(zhuǎn)換為字符
local function decode(str)
local str = str:gsub('+', ' ')
return str:gsub("%%(..)", decode_func)
end
--將url提取為absolute path和query string
function url.parse(u)
local path,query = u:match "([^?]*)%??(.*)"
if path then
path = decode(path)
end
return path, query
end
--解析query string
--query string格式為a=b&c=d&e=f
function url.parse_query(q)
local r = {}
-- .- 表示匹配多個(gè)字符
-- = 表示匹配等于號(hào)
-- ()用于分組窒盐,以對(duì)應(yīng)k,v
for k,v in q:gmatch "(.-)=([^&]*)&?" do
r[decode(k)] = decode(v)
end
return r
end
return url