Skip to content

Instantly share code, notes, and snippets.

@jdutant
Created January 14, 2023 00:04
Show Gist options
  • Save jdutant/59e3d64057099ea1faf5f0029c599259 to your computer and use it in GitHub Desktop.
Save jdutant/59e3d64057099ea1faf5f0029c599259 to your computer and use it in GitHub Desktop.
UTF-8-safe URL encoding and decoding in Lua
--- urlEncode: URL-encode a string.
-- @param str string
-- @param spaceToPlus bool (optional) convert spaces to `+`
local function urlEncode(str, spaceToPlus)
-- safe characters: 0-9a-zA-Z%-._~
-- as per RFC 3986, Section 2.3 <https://www.rfc-editor.org/rfc/rfc3986#section-2.3>
-- %w matches UTF-8 starting bytes but they should be encoded,
-- so we use the explicit charset 0-9a-zA-Z instead.
local charset = '0-9a-zA-Z%-._~'
if spaceToPlus then
charset = charset .. ' '
end
--Ensure all newlines are in CRLF form
str = str:gsub('\r?\n', '\r\n')
--Percent-encode all non-safe chars
str = str:gsub('[^'..charset..']',
function (c) return string.format ("%%%02X", string.byte(c)) end)
--Convert spaces to `+` if required
str = str:gsub(' ', '+')
return str
end
--- urlDecode: decode an URL-encoded string.
-- @param str string
-- @param spaceToPlus bool (optional) whether spaces have been converted to `+`
local function urlDecode(str, spaceToPlus)
str = str:gsub('%%(%x%x)',
function (c) return string.char(tonumber(c, 16)) end)
if spaceToPlus then
str = str:gsub('+', ' ')
end
return str
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment