1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
-- Copyright (C) Yichun Zhang (agentzh)
local ffi = require "ffi"
local base = require "resty.core.base"
local C = ffi.C
local ffi_string = ffi.string
local ngx = ngx
local type = type
local error = error
local floor = math.floor
local tostring = tostring
local get_string_buf = base.get_string_buf
local get_size_ptr = base.get_size_ptr
local subsystem = ngx.config.subsystem
local ngx_lua_ffi_encode_base64
local ngx_lua_ffi_decode_base64
if subsystem == "http" then
ffi.cdef[[
size_t ngx_http_lua_ffi_encode_base64(const unsigned char *src,
size_t len, unsigned char *dst,
int no_padding);
int ngx_http_lua_ffi_decode_base64(const unsigned char *src,
size_t len, unsigned char *dst,
size_t *dlen);
int ngx_http_lua_ffi_decode_base64mime(const unsigned char *src,
size_t len, unsigned char *dst,
size_t *dlen);
]]
ngx_lua_ffi_encode_base64 = C.ngx_http_lua_ffi_encode_base64
ngx_lua_ffi_decode_base64 = C.ngx_http_lua_ffi_decode_base64
elseif subsystem == "stream" then
ffi.cdef[[
size_t ngx_stream_lua_ffi_encode_base64(const unsigned char *src,
size_t len, unsigned char *dst,
int no_padding);
int ngx_stream_lua_ffi_decode_base64(const unsigned char *src,
size_t len, unsigned char *dst,
size_t *dlen);
]]
ngx_lua_ffi_encode_base64 = C.ngx_stream_lua_ffi_encode_base64
ngx_lua_ffi_decode_base64 = C.ngx_stream_lua_ffi_decode_base64
end
local function base64_encoded_length(len, no_padding)
return no_padding and floor((len * 8 + 5) / 6) or
floor((len + 2) / 3) * 4
end
ngx.encode_base64 = function (s, no_padding)
if type(s) ~= 'string' then
if not s then
s = ''
else
s = tostring(s)
end
end
local slen = #s
local no_padding_bool = false;
local no_padding_int = 0;
if no_padding then
if no_padding ~= true then
local typ = type(no_padding)
error("bad no_padding: boolean expected, got " .. typ, 2)
end
no_padding_bool = true
no_padding_int = 1;
end
local dlen = base64_encoded_length(slen, no_padding_bool)
local dst = get_string_buf(dlen)
local r_dlen = ngx_lua_ffi_encode_base64(s, slen, dst, no_padding_int)
-- if dlen ~= r_dlen then error("discrepancy in len") end
return ffi_string(dst, r_dlen)
end
local function base64_decoded_length(len)
return floor((len + 3) / 4) * 3
end
ngx.decode_base64 = function (s)
if type(s) ~= 'string' then
error("string argument only", 2)
end
local slen = #s
local dlen = base64_decoded_length(slen)
-- print("dlen: ", tonumber(dlen))
local dst = get_string_buf(dlen)
local pdlen = get_size_ptr()
local ok = ngx_lua_ffi_decode_base64(s, slen, dst, pdlen)
if ok == 0 then
return nil
end
return ffi_string(dst, pdlen[0])
end
ngx.decode_base64mime = function (s)
if type(s) ~= 'string' then
error("string argument only", 2)
end
local slen = #s
local dlen = base64_decoded_length(slen)
local dst = get_string_buf(dlen)
local pdlen = get_size_ptr()
local ok = C.ngx_http_lua_ffi_decode_base64mime(s, slen, dst, pdlen)
if ok == 0 then
return nil
end
return ffi_string(dst, pdlen[0])
end
return {
version = base.version
}
|