Skip to content

Instantly share code, notes, and snippets.

@felixbuenemann
Last active September 10, 2016 22:52
Show Gist options
  • Save felixbuenemann/bf300482a2df89970c5b5d7e3191b464 to your computer and use it in GitHub Desktop.
Save felixbuenemann/bf300482a2df89970c5b5d7e3191b464 to your computer and use it in GitHub Desktop.
--- a/bundle/lua-resty-core-0.1.8/lib/resty/core/base64.lua 2016-05-01 22:12:03.000000000 +0200
+++ b/bundle/lua-resty-core-0.1.8/lib/resty/core/base64.lua 2016-05-01 23:44:45.000000000 +0200
@@ -20,9 +20,17 @@
size_t len, unsigned char *dst,
int no_padding);
+ size_t ngx_http_lua_ffi_encode_base64url(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_base64url(const unsigned char *src,
+ size_t len, unsigned char *dst,
+ size_t *dlen);
]]
@@ -63,6 +71,37 @@
end
+ngx.encode_base64url = 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
+ return error("boolean argument only")
+ 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 = C.ngx_http_lua_ffi_encode_base64url(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
@@ -85,6 +124,23 @@
end
+ngx.decode_base64url = function (s)
+ if type(s) ~= 'string' then
+ return error("string argument only")
+ 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 = C.ngx_http_lua_ffi_decode_base64url(s, slen, dst, pdlen)
+ if ok == 0 then
+ return nil
+ end
+ return ffi_string(dst, pdlen[0])
+end
+
+
return {
version = base.version
}
--- a/bundle/ngx_lua-0.10.6/src/ngx_http_lua_string.c 2016-05-01 23:36:37.000000000 +0200
+++ b/bundle/ngx_lua-0.10.6/src/ngx_http_lua_string.c 2016-05-02 00:19:20.000000000 +0200
@@ -45,7 +45,9 @@
#endif
static int ngx_http_lua_ngx_decode_base64(lua_State *L);
+static int ngx_http_lua_ngx_decode_base64url(lua_State *L);
static int ngx_http_lua_ngx_encode_base64(lua_State *L);
+static int ngx_http_lua_ngx_encode_base64url(lua_State *L);
static int ngx_http_lua_ngx_crc32_short(lua_State *L);
static int ngx_http_lua_ngx_crc32_long(lua_State *L);
static int ngx_http_lua_ngx_encode_args(lua_State *L);
@@ -76,9 +78,15 @@
lua_pushcfunction(L, ngx_http_lua_ngx_decode_base64);
lua_setfield(L, -2, "decode_base64");
+ lua_pushcfunction(L, ngx_http_lua_ngx_decode_base64url);
+ lua_setfield(L, -2, "decode_base64url");
+
lua_pushcfunction(L, ngx_http_lua_ngx_encode_base64);
lua_setfield(L, -2, "encode_base64");
+ lua_pushcfunction(L, ngx_http_lua_ngx_encode_base64url);
+ lua_setfield(L, -2, "encode_base64url");
+
lua_pushcfunction(L, ngx_http_lua_ngx_md5_bin);
lua_setfield(L, -2, "md5_bin");
@@ -450,14 +458,49 @@
}
+static int
+ngx_http_lua_ngx_decode_base64url(lua_State *L)
+{
+ ngx_str_t p, src;
+
+ if (lua_gettop(L) != 1) {
+ return luaL_error(L, "expecting one argument");
+ }
+
+ if (lua_type(L, 1) != LUA_TSTRING) {
+ return luaL_error(L, "string argument only");
+ }
+
+ src.data = (u_char *) luaL_checklstring(L, 1, &src.len);
+
+ p.len = ngx_base64_decoded_length(src.len);
+
+ p.data = lua_newuserdata(L, p.len);
+
+ if (ngx_decode_base64url(&p, &src) == NGX_OK) {
+ lua_pushlstring(L, (char *) p.data, p.len);
+
+ } else {
+ lua_pushnil(L);
+ }
+
+ return 1;
+}
+
+
static void
-ngx_http_lua_encode_base64(ngx_str_t *dst, ngx_str_t *src, int no_padding)
+ngx_http_lua_encode_base64(ngx_str_t *dst, ngx_str_t *src, int no_padding, int urlsafe)
{
u_char *d, *s;
size_t len;
static u_char basis[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ if (urlsafe) {
+ basis[62] = '-';
+ basis[63] = '_';
+ }
+
len = src->len;
s = src->data;
d = dst->data;
@@ -532,7 +575,45 @@
p.data = lua_newuserdata(L, p.len);
- ngx_http_lua_encode_base64(&p, &src, no_padding);
+ ngx_http_lua_encode_base64(&p, &src, no_padding, 0);
+
+ lua_pushlstring(L, (char *) p.data, p.len);
+
+ return 1;
+}
+
+
+static int
+ngx_http_lua_ngx_encode_base64url(lua_State *L)
+{
+ int n;
+ int no_padding = 0;
+ ngx_str_t p, src;
+
+ n = lua_gettop(L);
+ if (n != 1 && n != 2) {
+ return luaL_error(L, "expecting one or two arguments");
+ }
+
+ if (lua_isnil(L, 1)) {
+ src.data = (u_char *) "";
+ src.len = 0;
+
+ } else {
+ src.data = (u_char *) luaL_checklstring(L, 1, &src.len);
+ }
+
+ if (n == 2) {
+ /* get the 2nd optional argument */
+ luaL_checktype(L, 2, LUA_TBOOLEAN);
+ no_padding = lua_toboolean(L, 2);
+ }
+
+ p.len = ngx_http_lua_base64_encoded_length(src.len, no_padding);
+
+ p.data = lua_newuserdata(L, p.len);
+
+ ngx_http_lua_encode_base64(&p, &src, no_padding, 1);
lua_pushlstring(L, (char *) p.data, p.len);
@@ -710,7 +791,24 @@
out.data = dst;
- ngx_http_lua_encode_base64(&out, &in, no_padding);
+ ngx_http_lua_encode_base64(&out, &in, no_padding, 0);
+
+ return out.len;
+}
+
+
+size_t
+ngx_http_lua_ffi_encode_base64url(const u_char *src, size_t slen, u_char *dst,
+ int no_padding)
+{
+ ngx_str_t in, out;
+
+ in.data = (u_char *) src;
+ in.len = slen;
+
+ out.data = dst;
+
+ ngx_http_lua_encode_base64(&out, &in, no_padding, 1);
return out.len;
}
@@ -736,6 +834,26 @@
}
+int
+ngx_http_lua_ffi_decode_base64url(const u_char *src, size_t slen, u_char *dst,
+ size_t *dlen)
+{
+ ngx_int_t rc;
+ ngx_str_t in, out;
+
+ in.data = (u_char *) src;
+ in.len = slen;
+
+ out.data = dst;
+
+ rc = ngx_decode_base64url(&out, &in);
+
+ *dlen = out.len;
+
+ return rc == NGX_OK;
+}
+
+
size_t
ngx_http_lua_ffi_unescape_uri(const u_char *src, size_t len, u_char *dst)
{
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment