Commit fb1308f7 authored by François Perrad's avatar François Perrad

handle x-www-form-urlencoded in query

parent 399bfd74
Revision history for lua-Silva Revision history for lua-Silva
0.1.1
- handle x-www-form-urlencoded in query
0.1.0 Sat Dec 23 09:30:00 2017 0.1.0 Sat Dec 23 09:30:00 2017
First release First release
...@@ -16,7 +16,10 @@ local function convert (n) ...@@ -16,7 +16,10 @@ local function convert (n)
return char(tonumber(n, 16)) return char(tonumber(n, 16))
end end
local function unescape (s) local function unescape (s, query)
if query then
s = s:gsub('+', ' ') -- x-www-form-urlencoded
end
return (s:gsub('%%(%x%x)', convert)) return (s:gsub('%%(%x%x)', convert))
end end
...@@ -127,6 +130,7 @@ local sep_var = { ...@@ -127,6 +130,7 @@ local sep_var = {
local function match (s, ops) local function match (s, ops)
local capture = {} local capture = {}
local query = false
local function inner (i, ip) local function inner (i, ip)
for k = ip, #ops do for k = ip, #ops do
...@@ -143,6 +147,15 @@ local function match (s, ops) ...@@ -143,6 +147,15 @@ local function match (s, ops)
i = i + 3 i = i + 3
else else
c = s:sub(i, i) c = s:sub(i, i)
if c == '+' and query then
c = ' ' -- x-www-form-urlencoded
end
if c == '?' then
query = true
end
if c == '#' then
query = false
end
i = i + 1 i = i + 1
end end
if c ~= p then if c ~= p then
...@@ -152,6 +165,9 @@ local function match (s, ops) ...@@ -152,6 +165,9 @@ local function match (s, ops)
elseif oper == ';' or oper == '?' or oper == '&' then elseif oper == ';' or oper == '?' or oper == '&' then
local c = s:sub(i, i) local c = s:sub(i, i)
if c == oper then if c == oper then
if c == '?' then
query = true
end
i = i + 1 i = i + 1
local keys = {} local keys = {}
for j = 2, #op do for j = 2, #op do
...@@ -179,7 +195,7 @@ local function match (s, ops) ...@@ -179,7 +195,7 @@ local function match (s, ops)
while i <= #s do while i <= #s do
c = s:sub(i, i) c = s:sub(i, i)
if c == sep_var[oper] then if c == sep_var[oper] then
capture[key] = unescape(s:sub(start, i-1)) capture[key] = unescape(s:sub(start, i-1), query)
i = i + 1 i = i + 1
start = i start = i
break break
...@@ -195,11 +211,12 @@ local function match (s, ops) ...@@ -195,11 +211,12 @@ local function match (s, ops)
end end
end end
if k == #ops then if k == #ops then
capture[key] = unescape(s:sub(start, i-1)) capture[key] = unescape(s:sub(start, i-1), query)
else else
local sav = query
for j = i, start, -1 do for j = i, start, -1 do
if inner(j, k+1) then if inner(j, k+1) then
capture[key] = unescape(s:sub(start, j-1)) capture[key] = unescape(s:sub(start, j-1), sav)
return true return true
end end
end end
...@@ -208,6 +225,9 @@ local function match (s, ops) ...@@ -208,6 +225,9 @@ local function match (s, ops)
else else
local c = s:sub(i, i) local c = s:sub(i, i)
if oper == '1' or oper == '+' or oper == c then if oper == '1' or oper == '+' or oper == c then
if c == '#' then
query = false
end
if oper ~= '1' and oper ~= '+' then if oper ~= '1' and oper ~= '+' then
i = i + 1 i = i + 1
end end
...@@ -217,7 +237,7 @@ local function match (s, ops) ...@@ -217,7 +237,7 @@ local function match (s, ops)
while i <= #s do while i <= #s do
c = s:sub(i, i) c = s:sub(i, i)
if c == sep_var[oper] then if c == sep_var[oper] then
capture[varname] = unescape(s:sub(start, i-1)) capture[varname] = unescape(s:sub(start, i-1), query)
if oper == '/' and not op[nvar+1] then if oper == '/' and not op[nvar+1] then
break break
else else
...@@ -234,11 +254,12 @@ local function match (s, ops) ...@@ -234,11 +254,12 @@ local function match (s, ops)
i = i + 1 i = i + 1
end end
if k == #ops then if k == #ops then
capture[varname] = unescape(s:sub(start, i-1)) capture[varname] = unescape(s:sub(start, i-1), query)
else else
local sav = query
for j = i, start, -1 do for j = i, start, -1 do
if inner(j, k+1) then if inner(j, k+1) then
capture[varname] = unescape(s:sub(start, j-1)) capture[varname] = unescape(s:sub(start, j-1), sav)
return true return true
end end
end end
......
...@@ -18,7 +18,7 @@ local function kv_is (t, k, expected, name) ...@@ -18,7 +18,7 @@ local function kv_is (t, k, expected, name)
end end
end end
plan(123) plan(141)
local ctor = require 'Silva.template' local ctor = require 'Silva.template'
...@@ -274,3 +274,32 @@ sme = ctor'/foo?fixed=yes{&x,y}#fixed' ...@@ -274,3 +274,32 @@ sme = ctor'/foo?fixed=yes{&x,y}#fixed'
capture = sme('/foo?fixed=yes&x=1024&y=768#fixed') capture = sme('/foo?fixed=yes&x=1024&y=768#fixed')
kv_is( capture, 'x', '1024' ) kv_is( capture, 'x', '1024' )
kv_is( capture, 'y', '768' ) kv_is( capture, 'y', '768' )
-- x-www-form-urlencoded
sme = ctor'/foo/{path}{?query}{#frag}'
capture = sme('/foo/bar+baz')
kv_is( capture, 'path', 'bar+baz' )
kv_is( capture, 'query', nil )
kv_is( capture, 'frag', nil )
capture = sme('/foo/bar+baz?query=foo+bar+baz')
kv_is( capture, 'path', 'bar+baz' )
kv_is( capture, 'query', 'foo bar baz' )
kv_is( capture, 'frag', nil )
capture = sme('/foo/bar+baz?query=foo+bar+baz#baz+bar')
kv_is( capture, 'path', 'bar+baz' )
kv_is( capture, 'query', 'foo bar baz' )
kv_is( capture, 'frag', 'baz+bar' )
sme = ctor'/foo/{path}?first=yes%20or%20no{&query}#foo{frag}'
capture = sme('/foo/bar+baz?first=yes+or+no#foo')
kv_is( capture, 'path', 'bar+baz' )
kv_is( capture, 'query', nil )
kv_is( capture, 'frag', '' )
capture = sme('/foo/bar+baz?first=yes+or+no&query=foo+bar+baz#foo')
kv_is( capture, 'path', 'bar+baz' )
kv_is( capture, 'query', 'foo bar baz' )
kv_is( capture, 'frag', '' )
capture = sme('/foo/bar+baz?first=yes+or+no&query=foo+bar+baz#foobaz+bar')
kv_is( capture, 'path', 'bar+baz' )
kv_is( capture, 'query', 'foo bar baz' )
kv_is( capture, 'frag', 'baz+bar' )
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment