author | Matthew Wild <mwild1@gmail.com> |
Sun, 17 Mar 2024 10:10:24 +0000 | |
changeset 13464 | a688947fab1e |
parent 13128 | f15e23840780 |
permissions | -rw-r--r-- |
5299
cc9d460aa779
util.http: New module for HTTP helper functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
1 |
-- Prosody IM |
cc9d460aa779
util.http: New module for HTTP helper functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
2 |
-- Copyright (C) 2013 Florian Zeitz |
cc9d460aa779
util.http: New module for HTTP helper functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
3 |
-- |
cc9d460aa779
util.http: New module for HTTP helper functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
4 |
-- This project is MIT/X11 licensed. Please see the |
cc9d460aa779
util.http: New module for HTTP helper functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
5 |
-- COPYING file in the source package for more information. |
cc9d460aa779
util.http: New module for HTTP helper functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
6 |
-- |
cc9d460aa779
util.http: New module for HTTP helper functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
7 |
|
5471
34bfd26525f5
util.http: Refactor and import all necessary functions
Matthew Wild <mwild1@gmail.com>
parents:
5458
diff
changeset
|
8 |
local format, char = string.format, string.char; |
9763
1af5106a2c34
util.http: Pre-generate urlencoding mappings (optimization)
Kim Alvefur <zash@zash.se>
parents:
9507
diff
changeset
|
9 |
local pairs, ipairs = pairs, ipairs; |
5471
34bfd26525f5
util.http: Refactor and import all necessary functions
Matthew Wild <mwild1@gmail.com>
parents:
5458
diff
changeset
|
10 |
local t_insert, t_concat = table.insert, table.concat; |
5299
cc9d460aa779
util.http: New module for HTTP helper functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
11 |
|
9763
1af5106a2c34
util.http: Pre-generate urlencoding mappings (optimization)
Kim Alvefur <zash@zash.se>
parents:
9507
diff
changeset
|
12 |
local url_codes = {}; |
1af5106a2c34
util.http: Pre-generate urlencoding mappings (optimization)
Kim Alvefur <zash@zash.se>
parents:
9507
diff
changeset
|
13 |
for i = 0, 255 do |
1af5106a2c34
util.http: Pre-generate urlencoding mappings (optimization)
Kim Alvefur <zash@zash.se>
parents:
9507
diff
changeset
|
14 |
local c = char(i); |
1af5106a2c34
util.http: Pre-generate urlencoding mappings (optimization)
Kim Alvefur <zash@zash.se>
parents:
9507
diff
changeset
|
15 |
local u = format("%%%02x", i); |
1af5106a2c34
util.http: Pre-generate urlencoding mappings (optimization)
Kim Alvefur <zash@zash.se>
parents:
9507
diff
changeset
|
16 |
url_codes[c] = u; |
1af5106a2c34
util.http: Pre-generate urlencoding mappings (optimization)
Kim Alvefur <zash@zash.se>
parents:
9507
diff
changeset
|
17 |
url_codes[u] = c; |
9789
ff88b03c343f
util.http: Fix decoding of uppercase URL encoded chars
Kim Alvefur <zash@zash.se>
parents:
9763
diff
changeset
|
18 |
url_codes[u:upper()] = c; |
9763
1af5106a2c34
util.http: Pre-generate urlencoding mappings (optimization)
Kim Alvefur <zash@zash.se>
parents:
9507
diff
changeset
|
19 |
end |
5471
34bfd26525f5
util.http: Refactor and import all necessary functions
Matthew Wild <mwild1@gmail.com>
parents:
5458
diff
changeset
|
20 |
local function urlencode(s) |
9763
1af5106a2c34
util.http: Pre-generate urlencoding mappings (optimization)
Kim Alvefur <zash@zash.se>
parents:
9507
diff
changeset
|
21 |
return s and (s:gsub("[^a-zA-Z0-9.~_-]", url_codes)); |
5458
84162b81c863
net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents:
5299
diff
changeset
|
22 |
end |
5471
34bfd26525f5
util.http: Refactor and import all necessary functions
Matthew Wild <mwild1@gmail.com>
parents:
5458
diff
changeset
|
23 |
local function urldecode(s) |
9763
1af5106a2c34
util.http: Pre-generate urlencoding mappings (optimization)
Kim Alvefur <zash@zash.se>
parents:
9507
diff
changeset
|
24 |
return s and (s:gsub("%%%x%x", url_codes)); |
5458
84162b81c863
net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents:
5299
diff
changeset
|
25 |
end |
84162b81c863
net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents:
5299
diff
changeset
|
26 |
|
84162b81c863
net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents:
5299
diff
changeset
|
27 |
local function _formencodepart(s) |
9763
1af5106a2c34
util.http: Pre-generate urlencoding mappings (optimization)
Kim Alvefur <zash@zash.se>
parents:
9507
diff
changeset
|
28 |
return s and (urlencode(s):gsub("%%20", "+")); |
5458
84162b81c863
net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents:
5299
diff
changeset
|
29 |
end |
84162b81c863
net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents:
5299
diff
changeset
|
30 |
|
5471
34bfd26525f5
util.http: Refactor and import all necessary functions
Matthew Wild <mwild1@gmail.com>
parents:
5458
diff
changeset
|
31 |
local function formencode(form) |
5458
84162b81c863
net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents:
5299
diff
changeset
|
32 |
local result = {}; |
84162b81c863
net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents:
5299
diff
changeset
|
33 |
if form[1] then -- Array of ordered { name, value } |
84162b81c863
net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents:
5299
diff
changeset
|
34 |
for _, field in ipairs(form) do |
84162b81c863
net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents:
5299
diff
changeset
|
35 |
t_insert(result, _formencodepart(field.name).."=".._formencodepart(field.value)); |
84162b81c863
net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents:
5299
diff
changeset
|
36 |
end |
84162b81c863
net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents:
5299
diff
changeset
|
37 |
else -- Unordered map of name -> value |
84162b81c863
net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents:
5299
diff
changeset
|
38 |
for name, value in pairs(form) do |
84162b81c863
net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents:
5299
diff
changeset
|
39 |
t_insert(result, _formencodepart(name).."=".._formencodepart(value)); |
84162b81c863
net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents:
5299
diff
changeset
|
40 |
end |
84162b81c863
net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents:
5299
diff
changeset
|
41 |
end |
84162b81c863
net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents:
5299
diff
changeset
|
42 |
return t_concat(result, "&"); |
84162b81c863
net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents:
5299
diff
changeset
|
43 |
end |
84162b81c863
net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents:
5299
diff
changeset
|
44 |
|
5471
34bfd26525f5
util.http: Refactor and import all necessary functions
Matthew Wild <mwild1@gmail.com>
parents:
5458
diff
changeset
|
45 |
local function formdecode(s) |
5458
84162b81c863
net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents:
5299
diff
changeset
|
46 |
if not s:match("=") then return urldecode(s); end |
84162b81c863
net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents:
5299
diff
changeset
|
47 |
local r = {}; |
84162b81c863
net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents:
5299
diff
changeset
|
48 |
for k, v in s:gmatch("([^=&]*)=([^&]*)") do |
84162b81c863
net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents:
5299
diff
changeset
|
49 |
k, v = k:gsub("%+", "%%20"), v:gsub("%+", "%%20"); |
84162b81c863
net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents:
5299
diff
changeset
|
50 |
k, v = urldecode(k), urldecode(v); |
84162b81c863
net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents:
5299
diff
changeset
|
51 |
t_insert(r, { name = k, value = v }); |
84162b81c863
net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents:
5299
diff
changeset
|
52 |
r[k] = v; |
84162b81c863
net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents:
5299
diff
changeset
|
53 |
end |
84162b81c863
net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents:
5299
diff
changeset
|
54 |
return r; |
84162b81c863
net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents:
5299
diff
changeset
|
55 |
end |
84162b81c863
net.http, util.http: Move definitions of urlencode/decode and formencode/decode to util.http (possible to use them without unnecessary network-related dependencies)
Matthew Wild <mwild1@gmail.com>
parents:
5299
diff
changeset
|
56 |
|
5471
34bfd26525f5
util.http: Refactor and import all necessary functions
Matthew Wild <mwild1@gmail.com>
parents:
5458
diff
changeset
|
57 |
local function contains_token(field, token) |
5299
cc9d460aa779
util.http: New module for HTTP helper functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
58 |
field = ","..field:gsub("[ \t]", ""):lower()..","; |
cc9d460aa779
util.http: New module for HTTP helper functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
59 |
return field:find(","..token:lower()..",", 1, true) ~= nil; |
cc9d460aa779
util.http: New module for HTTP helper functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
60 |
end |
cc9d460aa779
util.http: New module for HTTP helper functions
Florian Zeitz <florob@babelmonkeys.de>
parents:
diff
changeset
|
61 |
|
9507
cfbea3064aa9
mod_http: Move normalize_path to util.http
Kim Alvefur <zash@zash.se>
parents:
5471
diff
changeset
|
62 |
local function normalize_path(path, is_dir) |
cfbea3064aa9
mod_http: Move normalize_path to util.http
Kim Alvefur <zash@zash.se>
parents:
5471
diff
changeset
|
63 |
if is_dir then |
cfbea3064aa9
mod_http: Move normalize_path to util.http
Kim Alvefur <zash@zash.se>
parents:
5471
diff
changeset
|
64 |
if path:sub(-1,-1) ~= "/" then path = path.."/"; end |
cfbea3064aa9
mod_http: Move normalize_path to util.http
Kim Alvefur <zash@zash.se>
parents:
5471
diff
changeset
|
65 |
else |
cfbea3064aa9
mod_http: Move normalize_path to util.http
Kim Alvefur <zash@zash.se>
parents:
5471
diff
changeset
|
66 |
if path:sub(-1,-1) == "/" then path = path:sub(1, -2); end |
cfbea3064aa9
mod_http: Move normalize_path to util.http
Kim Alvefur <zash@zash.se>
parents:
5471
diff
changeset
|
67 |
end |
cfbea3064aa9
mod_http: Move normalize_path to util.http
Kim Alvefur <zash@zash.se>
parents:
5471
diff
changeset
|
68 |
if path:sub(1,1) ~= "/" then path = "/"..path; end |
cfbea3064aa9
mod_http: Move normalize_path to util.http
Kim Alvefur <zash@zash.se>
parents:
5471
diff
changeset
|
69 |
return path; |
cfbea3064aa9
mod_http: Move normalize_path to util.http
Kim Alvefur <zash@zash.se>
parents:
5471
diff
changeset
|
70 |
end |
cfbea3064aa9
mod_http: Move normalize_path to util.http
Kim Alvefur <zash@zash.se>
parents:
5471
diff
changeset
|
71 |
|
13128
f15e23840780
util.http: Implement parser for RFC 7239 Forwarded header
Kim Alvefur <zash@zash.se>
parents:
9789
diff
changeset
|
72 |
--- Parse the RFC 7239 Forwarded header into array of key-value pairs. |
f15e23840780
util.http: Implement parser for RFC 7239 Forwarded header
Kim Alvefur <zash@zash.se>
parents:
9789
diff
changeset
|
73 |
local function parse_forwarded(forwarded) |
f15e23840780
util.http: Implement parser for RFC 7239 Forwarded header
Kim Alvefur <zash@zash.se>
parents:
9789
diff
changeset
|
74 |
if type(forwarded) ~= "string" then |
f15e23840780
util.http: Implement parser for RFC 7239 Forwarded header
Kim Alvefur <zash@zash.se>
parents:
9789
diff
changeset
|
75 |
return nil; |
f15e23840780
util.http: Implement parser for RFC 7239 Forwarded header
Kim Alvefur <zash@zash.se>
parents:
9789
diff
changeset
|
76 |
end |
f15e23840780
util.http: Implement parser for RFC 7239 Forwarded header
Kim Alvefur <zash@zash.se>
parents:
9789
diff
changeset
|
77 |
|
f15e23840780
util.http: Implement parser for RFC 7239 Forwarded header
Kim Alvefur <zash@zash.se>
parents:
9789
diff
changeset
|
78 |
local fwd = {}; -- array |
f15e23840780
util.http: Implement parser for RFC 7239 Forwarded header
Kim Alvefur <zash@zash.se>
parents:
9789
diff
changeset
|
79 |
local cur = {}; -- map, to which we add the next key-value pair |
f15e23840780
util.http: Implement parser for RFC 7239 Forwarded header
Kim Alvefur <zash@zash.se>
parents:
9789
diff
changeset
|
80 |
for key, quoted, value, delim in forwarded:gmatch("(%w+)%s*=%s*(\"?)([^,;\"]+)%2%s*(.?)") do |
f15e23840780
util.http: Implement parser for RFC 7239 Forwarded header
Kim Alvefur <zash@zash.se>
parents:
9789
diff
changeset
|
81 |
-- FIXME quoted quotes like "foo\"bar" |
f15e23840780
util.http: Implement parser for RFC 7239 Forwarded header
Kim Alvefur <zash@zash.se>
parents:
9789
diff
changeset
|
82 |
-- unlikely when only dealing with IP addresses |
f15e23840780
util.http: Implement parser for RFC 7239 Forwarded header
Kim Alvefur <zash@zash.se>
parents:
9789
diff
changeset
|
83 |
if quoted == '"' then |
f15e23840780
util.http: Implement parser for RFC 7239 Forwarded header
Kim Alvefur <zash@zash.se>
parents:
9789
diff
changeset
|
84 |
value = value:gsub("\\(.)", "%1"); |
f15e23840780
util.http: Implement parser for RFC 7239 Forwarded header
Kim Alvefur <zash@zash.se>
parents:
9789
diff
changeset
|
85 |
end |
f15e23840780
util.http: Implement parser for RFC 7239 Forwarded header
Kim Alvefur <zash@zash.se>
parents:
9789
diff
changeset
|
86 |
|
f15e23840780
util.http: Implement parser for RFC 7239 Forwarded header
Kim Alvefur <zash@zash.se>
parents:
9789
diff
changeset
|
87 |
cur[key:lower()] = value; |
f15e23840780
util.http: Implement parser for RFC 7239 Forwarded header
Kim Alvefur <zash@zash.se>
parents:
9789
diff
changeset
|
88 |
if delim == "" or delim == "," then |
f15e23840780
util.http: Implement parser for RFC 7239 Forwarded header
Kim Alvefur <zash@zash.se>
parents:
9789
diff
changeset
|
89 |
t_insert(fwd, cur) |
f15e23840780
util.http: Implement parser for RFC 7239 Forwarded header
Kim Alvefur <zash@zash.se>
parents:
9789
diff
changeset
|
90 |
if delim == "" then |
f15e23840780
util.http: Implement parser for RFC 7239 Forwarded header
Kim Alvefur <zash@zash.se>
parents:
9789
diff
changeset
|
91 |
-- end of the string |
f15e23840780
util.http: Implement parser for RFC 7239 Forwarded header
Kim Alvefur <zash@zash.se>
parents:
9789
diff
changeset
|
92 |
break; |
f15e23840780
util.http: Implement parser for RFC 7239 Forwarded header
Kim Alvefur <zash@zash.se>
parents:
9789
diff
changeset
|
93 |
end |
f15e23840780
util.http: Implement parser for RFC 7239 Forwarded header
Kim Alvefur <zash@zash.se>
parents:
9789
diff
changeset
|
94 |
cur = {}; |
f15e23840780
util.http: Implement parser for RFC 7239 Forwarded header
Kim Alvefur <zash@zash.se>
parents:
9789
diff
changeset
|
95 |
elseif delim ~= ";" then |
f15e23840780
util.http: Implement parser for RFC 7239 Forwarded header
Kim Alvefur <zash@zash.se>
parents:
9789
diff
changeset
|
96 |
-- misparsed |
f15e23840780
util.http: Implement parser for RFC 7239 Forwarded header
Kim Alvefur <zash@zash.se>
parents:
9789
diff
changeset
|
97 |
return false; |
f15e23840780
util.http: Implement parser for RFC 7239 Forwarded header
Kim Alvefur <zash@zash.se>
parents:
9789
diff
changeset
|
98 |
end |
f15e23840780
util.http: Implement parser for RFC 7239 Forwarded header
Kim Alvefur <zash@zash.se>
parents:
9789
diff
changeset
|
99 |
end |
f15e23840780
util.http: Implement parser for RFC 7239 Forwarded header
Kim Alvefur <zash@zash.se>
parents:
9789
diff
changeset
|
100 |
|
f15e23840780
util.http: Implement parser for RFC 7239 Forwarded header
Kim Alvefur <zash@zash.se>
parents:
9789
diff
changeset
|
101 |
return fwd; |
f15e23840780
util.http: Implement parser for RFC 7239 Forwarded header
Kim Alvefur <zash@zash.se>
parents:
9789
diff
changeset
|
102 |
end |
f15e23840780
util.http: Implement parser for RFC 7239 Forwarded header
Kim Alvefur <zash@zash.se>
parents:
9789
diff
changeset
|
103 |
|
5471
34bfd26525f5
util.http: Refactor and import all necessary functions
Matthew Wild <mwild1@gmail.com>
parents:
5458
diff
changeset
|
104 |
return { |
34bfd26525f5
util.http: Refactor and import all necessary functions
Matthew Wild <mwild1@gmail.com>
parents:
5458
diff
changeset
|
105 |
urlencode = urlencode, urldecode = urldecode; |
34bfd26525f5
util.http: Refactor and import all necessary functions
Matthew Wild <mwild1@gmail.com>
parents:
5458
diff
changeset
|
106 |
formencode = formencode, formdecode = formdecode; |
34bfd26525f5
util.http: Refactor and import all necessary functions
Matthew Wild <mwild1@gmail.com>
parents:
5458
diff
changeset
|
107 |
contains_token = contains_token; |
9507
cfbea3064aa9
mod_http: Move normalize_path to util.http
Kim Alvefur <zash@zash.se>
parents:
5471
diff
changeset
|
108 |
normalize_path = normalize_path; |
13128
f15e23840780
util.http: Implement parser for RFC 7239 Forwarded header
Kim Alvefur <zash@zash.se>
parents:
9789
diff
changeset
|
109 |
parse_forwarded = parse_forwarded; |
5471
34bfd26525f5
util.http: Refactor and import all necessary functions
Matthew Wild <mwild1@gmail.com>
parents:
5458
diff
changeset
|
110 |
}; |