function getFastestHost() { var fastest = arguments[0], fastestDuration = 600000, timing = [], track = function (host) { var tracker = new Image(); tracker.src = "/set.gif?cdn=" + host; }; for (var i = 0; i < arguments.length; i++) { (function(host) { var image = new Image(), timeStart = (new Date()).getTime(); image.onload = function () { var duration = (new Date()).getTime() - timeStart; if (duration < fastestDuration) { fastestDuration = duration; fastest = host; } timing[timing.length] = duration; if (timing.length == arguments.length) { track(fastest); } } image.onerror = function () { timing[timing.length] = -1 if (timing.length == arguments.length) { track(fastest); } } image.src = host + "/empty.gif"; }(arguments[i])); } }
init_by_lua_block { -- function getCdnHosts(file) local hosts = {} for line in io.lines(file) do table.insert(hosts, line) end return hosts end -- function stringToTable(t, s) local it, err = ngx.re.gmatch(s, "(//[^;]+);?") while true do local m, err = it() if not m then break end table.insert(t, m[1]) end return t end -- function valueExists(tbl, value) for k,v in pairs(tbl) do if value == v then return true end end return false end } server { server_name kolesa.kz; # cdn set $cdn_project kl; # cdn set $cookie_host .kolesa.kz; # cdn set $cdn_hosts_file "/etc/nginx/cdn/cdn.data.active"; # set $replace_hosts "//photos-a-kl.kcdn.kz;//photos-b-kl.kcdn.kz"; # uri location / { proxy_set_header Host kolesa.kz; proxy_pass http://kolesa; header_filter_by_lua_block { ngx.header.content_length = nil } body_filter_by_lua_block { allCdnHosts = getCdnHosts(ngx.var["cdn_hosts_file"]) replaceHosts = stringToTable({}, ngx.var["replace_hosts"]) cdnHost = ngx.var["cookie_" .. ngx.var["cdn_project"] .. "_cdn_host"] replaceEof = ngx.arg[2] if cdnHost ~= nil and valueExists(allCdnHosts, cdnHost) == true then -- , , for k,v in pairs(replaceHosts) do local newStr, n, err = ngx.re.gsub(ngx.arg[1], v, cdnHost) if n > 0 then ngx.arg[1] = newStr replaceEof = false end end else -- , local scriptStr = "<script src='/cdn.js' type='text/javascript'></script>" .. "<script type='text/javascript'>" .. "(function(){" .. "getFastestHost('" .. table.concat(allCdnHosts, "', '") .. "')" .. "}())" .. "</script>" local newStr, n, err = ngx.re.gsub(ngx.arg[1], "(</body>)", scriptStr .. "$1", "i") if n > 0 then ngx.arg[1] = newStr replaceEof = false end end ngx.arg[2] = replaceEof } } }
Source: https://habr.com/ru/post/328844/
All Articles