Nginx:如何将 post 数据编码从 UTF-8 转换为 TIS-620 并在通过代理之前传递它们

我想将从请求接收到的 POST 数据从 UTF-8 转换为 TIS-620,然后通过代理传递到后端使用以下代码,但我不确定应该怎么做

location / {
   proxy_pass http://targetwebsite;
}

如果我没错的话,我相信我必须使用 Lua 模块 来操作请求,但我不知道它们是否支持任何字符转换。

有人能帮我提供示例代码,使用 LUA 将 POST 数据从 UTF-8 转换为 TIS-620,以及如何验证 POST 数据是否为 UTF-8,或者是否有其他更好的方式在 nginx 中操作/转换 POST 数据?

点赞
用户9383219
用户9383219

我从 Wikipedia 查到了编码方式,然后编写了下面这个将 UTF-8 转换为 TIS-620 的转换方法。它假设 UTF-8 字符串中的所有代码点都有 TIS-620 的编码方式。如果 UTF-8 字符串只包含 ASCII 可打印字符(代码点为 " ""~")或泰国字符(代码点为 "ก""๛"),则它可以正常工作。否则,它将产生错误或可能非常奇怪的结果。

这里假设您拥有 Lua 5.3 的 utf8 库或其等效库。如果您使用早期版本的 Lua,则可以使用 纯 Lua 版本 的 MediaWiki 的 ustring 库(例如 Wikipedia 和 Wiktionary 使用的库)。它提供了一个函数来验证 UTF-8,许多其他函数将自动验证字符串。也就是说,如果字符串无效的 UTF-8,则会引发错误。如果使用该库,则只需将下面的代码中的 utf8.codepoint 替换为 ustring.codepoint

-- 将此数字添加到 TIS-620 值大于 0x80 的值中,以获取 Unicode 代码点。
-- 0xE00 是泰语块的第一个代码点,0xA0 是 TIS-620 中使用的相应字节。
local difference = 0xE00 - 0xA0

function UTF8_to_TIS620(UTF8_string)
    local TIS620_string = UTF8_string:gsub(
      '[\194-\244][\128-\191]+',
      function (non_ASCII)
          return string.char(utf8.codepoint(non_ASCII) - difference)
      end)
    return TIS620_string
end
2018-06-04 10:54:05
用户6834680
用户6834680

这个解决方案适用于 Lua 5.1/5.2/5.3。

local function utf8_to_unicode(utf8str, pos)
   -- pos = starting byte position inside input string
   local code, size = utf8str:byte(pos), 1
   if code >= 0xC0 and code < 0xFE then
      local mask = 64
      code = code - 128
      repeat
         local next_byte = utf8str:byte(pos + size)
         if next_byte and next_byte >= 0x80 and next_byte < 0xC0 then
            code, size = (code - mask - 2) * 64 + next_byte, size + 1
         else
            return
         end
         mask = mask * 32
      until code < mask
   elseif code >= 0x80 then
      return
   end
   -- 返回值:该 UTF-8 字符编码、编码所占的字节数
   return code, size
end

function utf8to620(utf8str)
   local pos, result_620 = 1, {}
   while pos <= #utf8str do
      local code, size = utf8_to_unicode(utf8str, pos)
      if code then
         pos = pos + size
         code =
            (code < 128 or code == 0xA0) and code
            or (code >= 0x0E01 and code <= 0x0E3A or code >= 0x0E3F and code <= 0x0E5B) and code - 0x0E5B + 0xFB
      end
      if not code then
         return utf8str  -- 非 UTF-8 字符串,返回原始字符串
      end
      table.insert(result_620, string.char(code))
   end
   -- 返回值:转换后的字符串
   return table.concat(result_620)
end

使用方法:

local utf8string = "UTF-8 Thai text here"
local tis620string = utf8to620(utf8string)
2018-06-04 11:19:41