package assets import ( "net/url" "path/filepath" "strconv" ) func getSessionKey(sessionID uint64) string { // Based on timestamp, changes once per week. Check out utils/flacker for understanding sessionID return strconv.FormatUint(sessionID>>50, 10) } func ResolveURL(baseurl string, rawurl string) string { base, _ := url.ParseRequestURI(baseurl) // fn Only for base urls u, _ := url.Parse(rawurl) // TODO: handle errors ? if base == nil || u == nil { return rawurl } return base.ResolveReference(u).String() // ResolveReference same as base.Parse(rawurl) } func isRelativeCachable(relativeURL string) bool { if len(relativeURL) == 0 || relativeURL[0] == '#' { return false } return true } func isCachable(rawurl string) bool { u, _ := url.Parse(rawurl) if u == nil || u.User != nil { return false } if u.Scheme != "http" && u.Scheme != "https" { return false } ext := filepath.Ext(u.Path) return ext == ".css" || ext == ".woff" || ext == ".woff2" || ext == ".ttf" || ext == ".otf" } func GetFullCachableURL(baseURL string, relativeURL string) (string, bool) { if !isRelativeCachable(relativeURL) { return "", false } return ResolveURL(baseURL, relativeURL), true } const ASAYER_QUERY_START = "ASAYER_QUERY_ESCtRT" func getCachePath(rawurl string) string { u, _ := url.Parse(rawurl) s := "/" + u.Scheme + "/" + u.Hostname() + u.Path if u.RawQuery != "" { if (s[len(s) - 1] != '/') { s += "/" } s += ASAYER_QUERY_START + url.PathEscape(u.RawQuery) } return s } func getCachePathWithKey(sessionID uint64, rawurl string) string { return getCachePath(rawurl) + "." + getSessionKey(sessionID) // Be carefull with slashes } func GetCachePathForJS(rawurl string) string { return getCachePath(rawurl) } func GetCachePathForAssets(sessionID uint64, rawurl string) string { return getCachePathWithKey(sessionID, rawurl) } func (r *Rewriter) RewriteURL(sessionID uint64, baseURL string, relativeURL string) string { // TODO: put it in one check within GetFullCachableURL if !isRelativeCachable(relativeURL) { return relativeURL } fullURL := ResolveURL(baseURL, relativeURL) if !isCachable(fullURL) { return relativeURL } u := url.URL{ Path: r.assetsURL.Path + getCachePathWithKey(sessionID, fullURL), Host: r.assetsURL.Host, Scheme: r.assetsURL.Scheme, } return u.String() }