diff --git a/docker/nginx/conf.d/include/location-skylink b/docker/nginx/conf.d/include/location-skylink index da4727c7..c613fe29 100644 --- a/docker/nginx/conf.d/include/location-skylink +++ b/docker/nginx/conf.d/include/location-skylink @@ -7,7 +7,7 @@ limit_conn downloads_by_ip 100; # ddos protection: max 100 downloads at a time # ensure that skylink that we pass around is base64 encoded (transform base32 encoded ones) # this is important because we want only one format in cache keys and logs -set_by_lua_block $skylink { return require("skynet.skylink").parse(ngx.var.skylink) } +set_by_lua_block $skylink { return require("skynet.skylink").base64(ngx.var.skylink) } # $skylink_v1 and $skylink_v2 variables default to the same value but in case the requested skylink was: # a) skylink v1 - it would not matter, no additional logic is executed diff --git a/docker/nginx/conf.d/server/server.api b/docker/nginx/conf.d/server/server.api index 11a3ee75..640401f7 100644 --- a/docker/nginx/conf.d/server/server.api +++ b/docker/nginx/conf.d/server/server.api @@ -352,7 +352,13 @@ location ~ "^/(([a-zA-Z0-9-_]{46}|[a-z0-9]{55})(/.*)?)$" { set $skylink $2; set $path $3; - include /etc/nginx/conf.d/include/location-skylink; + rewrite_by_lua_block { + local skynet_skylink = require("skynet.skylink") + local base32_skylink = skynet_skylink.base32(ngx.var.skylink) + local base32_url = ngx.var.scheme .. "://" .. base32_skylink .. "." .. ngx.var.skynet_portal_domain .. ngx.var.path + + return ngx.redirect(base32_url, ngx.HTTP_MOVED_PERMANENTLY) + } } location ~ "^/file/(([a-zA-Z0-9-_]{46}|[a-z0-9]{55})(/.*)?)$" { diff --git a/docker/nginx/conf.d/server/server.dnslink b/docker/nginx/conf.d/server/server.dnslink index 32e454cc..22ce75a3 100644 --- a/docker/nginx/conf.d/server/server.dnslink +++ b/docker/nginx/conf.d/server/server.dnslink @@ -37,7 +37,7 @@ location / { ngx.var.skylink = cache_value end - ngx.var.skylink = require("skynet.skylink").parse(ngx.var.skylink) + ngx.var.skylink = require("skynet.skylink").base64(ngx.var.skylink) ngx.var.skylink_v1 = ngx.var.skylink ngx.var.skylink_v2 = ngx.var.skylink } diff --git a/docker/nginx/libs/skynet/skylink.lua b/docker/nginx/libs/skynet/skylink.lua index adcf0b70..c6372a41 100644 --- a/docker/nginx/libs/skynet/skylink.lua +++ b/docker/nginx/libs/skynet/skylink.lua @@ -3,10 +3,13 @@ local _M = {} local basexx = require("basexx") local hasher = require("hasher") +-- use lowercase alphabet since our skylinks are part of urls +local base32_alphabet = "0123456789abcdefghijklmnopqrstuv" + -- parse any skylink and return base64 version -function _M.parse(skylink) +function _M.base64(skylink) if string.len(skylink) == 55 then - local decoded = basexx.from_basexx(string.upper(skylink), "0123456789ABCDEFGHIJKLMNOPQRSTUV", 5) + local decoded = basexx.from_basexx(string.lower(skylink), base32_alphabet, 5) return basexx.to_url64(decoded) end @@ -14,10 +17,21 @@ function _M.parse(skylink) return skylink end +-- parse any skylink and return base32 version +function _M.base32(skylink) + if string.len(skylink) == 46 then + local decoded = basexx.from_url64(skylink) + + return basexx.to_basexx(decoded, base32_alphabet, 5) + end + + return skylink +end + -- hash skylink into 32 bytes hash used in blocklist function _M.hash(skylink) -- ensure that the skylink is base64 encoded - local base64Skylink = _M.parse(skylink) + local base64Skylink = _M.base64(skylink) -- decode skylink from base64 encoding local rawSkylink = basexx.from_url64(base64Skylink) diff --git a/docker/nginx/libs/skynet/skylink.spec.lua b/docker/nginx/libs/skynet/skylink.spec.lua index 0502a833..9949e534 100644 --- a/docker/nginx/libs/skynet/skylink.spec.lua +++ b/docker/nginx/libs/skynet/skylink.spec.lua @@ -1,15 +1,28 @@ local skynet_skylink = require("skynet.skylink") -describe("parse", function() +describe("base64", function() local base32 = "0404dsjvti046fsua4ktor9grrpe76erq9jot9cvopbhsvsu76r4r30" local base64 = "AQBG8n_sgEM_nlEp3G0w3vLjmdvSZ46ln8ZXHn-eObZNjA" it("should return unchanged base64 skylink", function() - assert.is.same(skynet_skylink.parse(base64), base64) + assert.is.same(skynet_skylink.base64(base64), base64) end) it("should transform base32 skylink into base64", function() - assert.is.same(skynet_skylink.parse(base32), base64) + assert.is.same(skynet_skylink.base64(base32), base64) + end) +end) + +describe("base32", function() + local base32 = "0404dsjvti046fsua4ktor9grrpe76erq9jot9cvopbhsvsu76r4r30" + local base64 = "AQBG8n_sgEM_nlEp3G0w3vLjmdvSZ46ln8ZXHn-eObZNjA" + + it("should return unchanged base32 skylink", function() + assert.is.same(skynet_skylink.base32(base32), base32) + end) + + it("should transform base64 skylink into base32", function() + assert.is.same(skynet_skylink.base32(base64), base32) end) end)