You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
187 lines
5.9 KiB
Lua
187 lines
5.9 KiB
Lua
-- RFC 7231
|
|
-- Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content
|
|
|
|
local lpeg = require "lpeg"
|
|
local core = require "lpeg_patterns.core"
|
|
local http_core = require "lpeg_patterns.http.core"
|
|
local email = require "lpeg_patterns.email"
|
|
local language = require "lpeg_patterns.language"
|
|
local uri = require "lpeg_patterns.uri"
|
|
|
|
local Cc = lpeg.Cc
|
|
local Cf = lpeg.Cf
|
|
local Cg = lpeg.Cg
|
|
local Ct = lpeg.Ct
|
|
local P = lpeg.P
|
|
local S = lpeg.S
|
|
|
|
|
|
-- RFC 7231 Section 3.1.1
|
|
local content_coding = http_core.token / string.lower -- case insensitive
|
|
local Content_Encoding = http_core.comma_sep_trim(content_coding, 1)
|
|
|
|
-- RFC 7231 Section 3.1.2
|
|
local type = http_core.token / string.lower -- case insensitive
|
|
local subtype = http_core.token / string.lower -- case insensitive
|
|
local parameter = http_core.token / string.lower -- case insensitive
|
|
* P"=" * (http_core.token + http_core.quoted_string)
|
|
local media_type = Cg(type, "type") * P"/" * Cg(subtype, "subtype")
|
|
* Cg(Cf(Ct(true) * (http_core.OWS * P";" * http_core.OWS * Cg(parameter))^0, rawset), "parameters")
|
|
local charset = http_core.token / string.lower -- case insensitive
|
|
local Content_Type = Ct(media_type)
|
|
|
|
-- RFC 7231 Section 3.1.3
|
|
local Content_Language = http_core.comma_sep_trim(language.Language_Tag, 1)
|
|
|
|
-- RFC 7231 Section 3.1.4.2
|
|
local Content_Location = uri.absolute_uri + http_core.partial_uri
|
|
|
|
-- RFC 7231 Section 5.1.1
|
|
local Expect = P"100-"*S"cC"*S"oO"*S"nN"*S"tT"*S"iI"*S"nN"*S"uU"*S"eE" * Cc("100-continue")
|
|
|
|
-- RFC 7231 Section 5.1.2
|
|
local Max_Forwards = core.DIGIT^1 / tonumber
|
|
|
|
-- RFC 7231 Section 5.3.1
|
|
-- local qvalue = http_core.rank -- luacheck: ignore 211
|
|
local weight = http_core.t_ranking
|
|
|
|
-- RFC 7231 Section 5.3.2
|
|
local media_range = (P"*/*"
|
|
+ (Cg(type, "type") * P"/*")
|
|
+ (Cg(type, "type") * P"/" * Cg(subtype, "subtype"))
|
|
) * Cg(Cf(Ct(true) * (http_core.OWS * ";" * http_core.OWS * Cg(parameter) - weight)^0, rawset), "parameters")
|
|
local accept_ext = http_core.OWS * P";" * http_core.OWS * http_core.token * (P"=" * (http_core.token + http_core.quoted_string))^-1
|
|
local accept_params = Cg(weight, "q") * Cg(Cf(Ct(true) * Cg(accept_ext)^0, rawset), "extensions")
|
|
local Accept = http_core.comma_sep_trim(Ct(media_range * (accept_params+Cg(Ct(true), "extensions"))))
|
|
|
|
-- RFC 7231 Section 5.3.3
|
|
local Accept_Charset = http_core.comma_sep_trim((charset + P"*") * weight^-1, 1)
|
|
|
|
-- RFC 7231 Section 5.3.4
|
|
local codings = content_coding + "*"
|
|
local Accept_Encoding = http_core.comma_sep_trim(codings * weight^-1)
|
|
|
|
-- RFC 4647 Section 2.1
|
|
local alphanum = core.ALPHA + core.DIGIT
|
|
local language_range = (core.ALPHA * core.ALPHA^-7 * (P"-" * alphanum * alphanum^-7)^0) + P"*"
|
|
-- RFC 7231 Section 5.3.5
|
|
local Accept_Language = http_core.comma_sep_trim(language_range * weight^-1, 1)
|
|
|
|
-- RFC 7231 Section 5.5.1
|
|
local From = email.mailbox
|
|
|
|
-- RFC 7231 Section 5.5.2
|
|
local Referer = uri.absolute_uri + http_core.partial_uri
|
|
|
|
-- RFC 7231 Section 5.5.3
|
|
local product_version = http_core.token
|
|
local product = http_core.token * (P"/" * product_version)^-1
|
|
local User_Agent = product * (http_core.RWS * (product + http_core.comment))^0
|
|
|
|
-- RFC 7231 Section 7.1.1.1
|
|
-- Uses os.date field names
|
|
local day_name = Cg(P"Mon"*Cc(2)
|
|
+ P"Tue"*Cc(3)
|
|
+ P"Wed"*Cc(4)
|
|
+ P"Thu"*Cc(5)
|
|
+ P"Fri"*Cc(6)
|
|
+ P"Sat"*Cc(7)
|
|
+ P"Sun"*Cc(1), "wday")
|
|
local day = Cg(core.DIGIT * core.DIGIT / tonumber, "day")
|
|
local month = Cg(P"Jan"*Cc(1)
|
|
+ P"Feb"*Cc(2)
|
|
+ P"Mar"*Cc(3)
|
|
+ P"Apr"*Cc(4)
|
|
+ P"May"*Cc(5)
|
|
+ P"Jun"*Cc(6)
|
|
+ P"Jul"*Cc(7)
|
|
+ P"Aug"*Cc(8)
|
|
+ P"Sep"*Cc(9)
|
|
+ P"Oct"*Cc(10)
|
|
+ P"Nov"*Cc(11)
|
|
+ P"Dec"*Cc(12), "month")
|
|
local year = Cg(core.DIGIT * core.DIGIT * core.DIGIT * core.DIGIT / tonumber, "year")
|
|
local date1 = day * core.SP * month * core.SP * year
|
|
|
|
local GMT = P"GMT"
|
|
|
|
local minute = Cg(core.DIGIT * core.DIGIT / tonumber, "min")
|
|
local second = Cg(core.DIGIT * core.DIGIT / tonumber, "sec")
|
|
local hour = Cg(core.DIGIT * core.DIGIT / tonumber, "hour")
|
|
-- XXX only match 00:00:00 - 23:59:60 (leap second)?
|
|
|
|
local time_of_day = hour * P":" * minute * P":" * second
|
|
local IMF_fixdate = Ct(day_name * P"," * core.SP * date1 * core.SP * time_of_day * core.SP * GMT)
|
|
|
|
local date2 do
|
|
local year_barrier = 70
|
|
local twodayyear = Cg(core.DIGIT * core.DIGIT / function(y)
|
|
y = tonumber(y, 10)
|
|
if y < year_barrier then
|
|
return 2000+y
|
|
else
|
|
return 1900+y
|
|
end
|
|
end, "year")
|
|
date2 = day * P"-" * month * P"-" * twodayyear
|
|
end
|
|
local day_name_l = Cg(P"Monday"*Cc(2)
|
|
+ P"Tuesday"*Cc(3)
|
|
+ P"Wednesday"*Cc(4)
|
|
+ P"Thursday"*Cc(5)
|
|
+ P"Friday"*Cc(6)
|
|
+ P"Saturday"*Cc(7)
|
|
+ P"Sunday"*Cc(1), "wday")
|
|
local rfc850_date = Ct(day_name_l * P"," * core.SP * date2 * core.SP * time_of_day * core.SP * GMT)
|
|
|
|
local date3 = month * core.SP * (day + Cg(core.SP * core.DIGIT / tonumber, "day"))
|
|
local asctime_date = Ct(day_name * core.SP * date3 * core.SP * time_of_day * core.SP * year)
|
|
local obs_date = rfc850_date + asctime_date
|
|
|
|
local HTTP_date = IMF_fixdate + obs_date
|
|
local Date = HTTP_date
|
|
|
|
-- RFC 7231 Section 7.1.2
|
|
local Location = uri.uri_reference
|
|
|
|
-- RFC 7231 Section 7.1.3
|
|
local delay_seconds = core.DIGIT^1 / tonumber
|
|
local Retry_After = HTTP_date + delay_seconds
|
|
|
|
-- RFC 7231 Section 7.1.4
|
|
local Vary = P"*" + http_core.comma_sep(http_core.field_name, 1)
|
|
|
|
-- RFC 7231 Section 7.4.1
|
|
local Allow = http_core.comma_sep_trim(http_core.method)
|
|
|
|
-- RFC 7231 Section 7.4.2
|
|
local Server = product * (http_core.RWS * (product + http_core.comment))^0
|
|
|
|
return {
|
|
HTTP_date = HTTP_date;
|
|
IMF_fixdate = IMF_fixdate;
|
|
media_type = media_type;
|
|
parameter = parameter;
|
|
|
|
Accept = Accept;
|
|
Accept_Charset = Accept_Charset;
|
|
Accept_Encoding = Accept_Encoding;
|
|
Accept_Language = Accept_Language;
|
|
Allow = Allow;
|
|
Content_Encoding = Content_Encoding;
|
|
Content_Language = Content_Language;
|
|
Content_Location = Content_Location;
|
|
Content_Type = Content_Type;
|
|
Date = Date;
|
|
Expect = Expect;
|
|
From = From;
|
|
Location = Location;
|
|
Max_Forwards = Max_Forwards;
|
|
Referer = Referer;
|
|
Retry_After = Retry_After;
|
|
Server = Server;
|
|
User_Agent = User_Agent;
|
|
Vary = Vary;
|
|
}
|