aboutsummaryrefslogtreecommitdiff
path: root/src/headers.lua
diff options
context:
space:
mode:
Diffstat (limited to 'src/headers.lua')
-rw-r--r--src/headers.lua148
1 files changed, 54 insertions, 94 deletions
diff --git a/src/headers.lua b/src/headers.lua
index 1eb8223..004ef37 100644
--- a/src/headers.lua
+++ b/src/headers.lua
@@ -7,98 +7,58 @@ local socket = require("socket")
7socket.headers = {} 7socket.headers = {}
8local _M = socket.headers 8local _M = socket.headers
9 9
10_M.canonic = { 10-- capitalizes the first letter of each hyphen-separated word, lowercases
11 ["accept"] = "Accept", 11-- the rest (e.g. "x-request-id" -> "X-Request-Id")
12 ["accept-charset"] = "Accept-Charset", 12local function titlecase(header)
13 ["accept-encoding"] = "Accept-Encoding", 13 return (header:gsub("(%a)([%w]*)", function(a, b) return a:upper()..b:lower() end))
14 ["accept-language"] = "Accept-Language", 14end
15 ["accept-ranges"] = "Accept-Ranges",
16 ["action"] = "Action",
17 ["alternate-recipient"] = "Alternate-Recipient",
18 ["age"] = "Age",
19 ["allow"] = "Allow",
20 ["arrival-date"] = "Arrival-Date",
21 ["authorization"] = "Authorization",
22 ["bcc"] = "Bcc",
23 ["cache-control"] = "Cache-Control",
24 ["cc"] = "Cc",
25 ["comments"] = "Comments",
26 ["connection"] = "Connection",
27 ["content-description"] = "Content-Description",
28 ["content-disposition"] = "Content-Disposition",
29 ["content-encoding"] = "Content-Encoding",
30 ["content-id"] = "Content-ID",
31 ["content-language"] = "Content-Language",
32 ["content-length"] = "Content-Length",
33 ["content-location"] = "Content-Location",
34 ["content-md5"] = "Content-MD5",
35 ["content-range"] = "Content-Range",
36 ["content-transfer-encoding"] = "Content-Transfer-Encoding",
37 ["content-type"] = "Content-Type",
38 ["cookie"] = "Cookie",
39 ["date"] = "Date",
40 ["diagnostic-code"] = "Diagnostic-Code",
41 ["dsn-gateway"] = "DSN-Gateway",
42 ["etag"] = "ETag",
43 ["expect"] = "Expect",
44 ["expires"] = "Expires",
45 ["final-log-id"] = "Final-Log-ID",
46 ["final-recipient"] = "Final-Recipient",
47 ["from"] = "From",
48 ["host"] = "Host",
49 ["if-match"] = "If-Match",
50 ["if-modified-since"] = "If-Modified-Since",
51 ["if-none-match"] = "If-None-Match",
52 ["if-range"] = "If-Range",
53 ["if-unmodified-since"] = "If-Unmodified-Since",
54 ["in-reply-to"] = "In-Reply-To",
55 ["keywords"] = "Keywords",
56 ["last-attempt-date"] = "Last-Attempt-Date",
57 ["last-modified"] = "Last-Modified",
58 ["location"] = "Location",
59 ["max-forwards"] = "Max-Forwards",
60 ["message-id"] = "Message-ID",
61 ["mime-version"] = "MIME-Version",
62 ["original-envelope-id"] = "Original-Envelope-ID",
63 ["original-recipient"] = "Original-Recipient",
64 ["pragma"] = "Pragma",
65 ["proxy-authenticate"] = "Proxy-Authenticate",
66 ["proxy-authorization"] = "Proxy-Authorization",
67 ["range"] = "Range",
68 ["received"] = "Received",
69 ["received-from-mta"] = "Received-From-MTA",
70 ["references"] = "References",
71 ["referer"] = "Referer",
72 ["remote-mta"] = "Remote-MTA",
73 ["reply-to"] = "Reply-To",
74 ["reporting-mta"] = "Reporting-MTA",
75 ["resent-bcc"] = "Resent-Bcc",
76 ["resent-cc"] = "Resent-Cc",
77 ["resent-date"] = "Resent-Date",
78 ["resent-from"] = "Resent-From",
79 ["resent-message-id"] = "Resent-Message-ID",
80 ["resent-reply-to"] = "Resent-Reply-To",
81 ["resent-sender"] = "Resent-Sender",
82 ["resent-to"] = "Resent-To",
83 ["retry-after"] = "Retry-After",
84 ["return-path"] = "Return-Path",
85 ["sender"] = "Sender",
86 ["server"] = "Server",
87 ["smtp-remote-recipient"] = "SMTP-Remote-Recipient",
88 ["status"] = "Status",
89 ["subject"] = "Subject",
90 ["te"] = "TE",
91 ["to"] = "To",
92 ["trailer"] = "Trailer",
93 ["transfer-encoding"] = "Transfer-Encoding",
94 ["upgrade"] = "Upgrade",
95 ["user-agent"] = "User-Agent",
96 ["vary"] = "Vary",
97 ["via"] = "Via",
98 ["warning"] = "Warning",
99 ["will-retry-until"] = "Will-Retry-Until",
100 ["www-authenticate"] = "WWW-Authenticate",
101 ["x-mailer"] = "X-Mailer",
102}
103 15
104return _M \ No newline at end of file 16_M.canonic = {}
17
18setmetatable(_M.canonic, {
19 __index = function(t, key)
20 if type(key) ~= "string" then
21 return nil
22 end
23
24 local lower = key:lower()
25 local v = rawget(t, lower)
26 if v then
27 return v
28 end
29
30 v = titlecase(lower)
31 rawset(t, lower, v)
32 return v
33 end
34})
35
36-- adds a header with a given canonical capitalization, e.g. for headers
37-- whose capitalization titlecase(header) would not reproduce correctly
38function _M.setcanonic(header)
39 if type(header) ~= "string" then
40 error("header must be a string", 2)
41 end
42 _M.canonic[header:lower()] = header
43end
44
45-- headers whose canonical capitalization titlecase() does not reproduce
46-- (acronyms and other irregular capitalization). Anything not listed here
47-- is generated and cached on first lookup by the __index above.
48_M.setcanonic("Content-ID")
49_M.setcanonic("Content-MD5")
50_M.setcanonic("DSN-Gateway")
51_M.setcanonic("ETag")
52_M.setcanonic("Final-Log-ID")
53_M.setcanonic("Message-ID")
54_M.setcanonic("MIME-Version")
55_M.setcanonic("Original-Envelope-ID")
56_M.setcanonic("Received-From-MTA")
57_M.setcanonic("Remote-MTA")
58_M.setcanonic("Reporting-MTA")
59_M.setcanonic("Resent-Message-ID")
60_M.setcanonic("SMTP-Remote-Recipient")
61_M.setcanonic("TE")
62_M.setcanonic("WWW-Authenticate")
63
64return _M