Skip to content

Commit 64e39a7

Browse files
committed
lpeg_patterns/http: Fixup parsing of RFC 7235 headers (WWW_authenticate, Authentication, etc)
1 parent 6117834 commit 64e39a7

File tree

2 files changed

+16
-6
lines changed

2 files changed

+16
-6
lines changed

lpeg_patterns/http.lua

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -549,16 +549,17 @@ _M.Warning = comma_sep_trim(warning_value, 1)
549549

550550
-- RFC 7235 Section 2
551551
local auth_scheme = _M.token
552-
local auth_param = _M.token * _M.BWS * P"=" * _M.BWS * (_M.token + _M.quoted_string)
553-
local token68 = (core.ALPHA + core.DIGIT + P"-" + P"." + P"_" + P"~" + P"+" + P"/" )^1 * (P"=")^0
554-
local challenge = auth_scheme * (core.SP^1 * (token68 + comma_sep(auth_param)))^-1
555-
local credentials = auth_scheme * (core.SP^1 * (token68 + comma_sep(auth_param)))^-1
552+
local auth_param = Cg(_M.token / string.lower * _M.BWS * P"=" * _M.BWS * (_M.token + _M.quoted_string))
553+
local token68 = C((core.ALPHA + core.DIGIT + P"-" + P"." + P"_" + P"~" + P"+" + P"/" )^1 * (P"=")^0)
554+
-- TODO: each parameter name MUST only occur once per challenge
555+
local challenge = auth_scheme * (core.SP^1 * (Cf(Ct(true) * comma_sep(auth_param), rawset) + token68))^-1
556+
local credentials = challenge
556557

557558
-- RFC 7235 Section 4
558559
_M.WWW_Authenticate = comma_sep_trim(Ct(challenge), 1)
559560
_M.Authorization = credentials
560-
_M.Proxy_Authenticate = comma_sep_trim(Ct(challenge), 1)
561-
_M.Proxy_Authorization = credentials
561+
_M.Proxy_Authenticate = _M.WWW_Authenticate
562+
_M.Proxy_Authorization = _M.Proxy_Authorization
562563

563564
-- RFC 7239 Section 4
564565
local value = _M.token + _M.quoted_string

spec/http_spec.lua

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,15 @@ describe("http patterns", function()
236236
assert.same({["max-age"] = "0"; includesubdomains = true}, sts_patt:match("max-age=0;includeSubdomains"))
237237
assert.same({["max-age"] = "0"; includesubdomains = true}, sts_patt:match("max-age=0 ; includeSubdomains"))
238238
end)
239+
it("Parses an WWW_Authenticate header", function()
240+
local WWW_Authenticate = lpeg.Ct(http.WWW_Authenticate) * EOF
241+
assert.same({{"Newauth"}}, WWW_Authenticate:match"Newauth")
242+
assert.same({{"Newauth", {realm = "apps"}}}, WWW_Authenticate:match[[Newauth realm="apps"]])
243+
assert.same({{"Newauth", {realm = "apps"}}}, WWW_Authenticate:match[[Newauth ReaLm="apps"]])
244+
assert.same({{"Newauth"}, {"Basic"}}, WWW_Authenticate:match"Newauth, Basic")
245+
assert.same({{"Newauth", {realm = "apps", type="1", title="Login to \"apps\""}}, {"Basic", {realm="simple"}}},
246+
WWW_Authenticate:match[[Newauth realm="apps", type=1, title="Login to \"apps\"", Basic realm="simple"]])
247+
end)
239248
it("Parses a HPKP header", function()
240249
-- Example from RFC 7469 2.1.5
241250
local pkp_patt = lpeg.Cf(lpeg.Ct(true) * http.Public_Key_Pins, function(t, k, v) table.insert(t, {k,v}) return t end) * EOF

0 commit comments

Comments
 (0)