99 lines
2.4 KiB
Go
99 lines
2.4 KiB
Go
package assets
|
|
|
|
import (
|
|
"net/url"
|
|
"path/filepath"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"openreplay/backend/pkg/flakeid"
|
|
)
|
|
|
|
func getSessionKey(sessionID uint64) string {
|
|
return strconv.FormatUint(
|
|
uint64(time.UnixMilli(
|
|
int64(flakeid.ExtractTimestamp(sessionID)),
|
|
).Day()),
|
|
10,
|
|
)
|
|
}
|
|
|
|
func ResolveURL(baseurl string, rawurl string) string {
|
|
rawurl = strings.Trim(rawurl, " ")
|
|
if !isRelativeCachable(rawurl) {
|
|
return rawurl
|
|
}
|
|
baseurl = strings.Split(baseurl, "#")[0] // remove #fragment suffix if present
|
|
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 == ".ashx" || // ASP .NET
|
|
ext == ".woff" ||
|
|
ext == ".woff2" ||
|
|
ext == ".ttf" ||
|
|
ext == ".otf" ||
|
|
ext == ".eot"
|
|
}
|
|
|
|
func GetFullCachableURL(baseURL string, relativeURL string) (string, bool) {
|
|
if !isRelativeCachable(relativeURL) {
|
|
return relativeURL, false
|
|
}
|
|
fullURL := ResolveURL(baseURL, relativeURL)
|
|
if !isCachable(fullURL) {
|
|
return fullURL, false
|
|
}
|
|
return fullURL, true
|
|
}
|
|
|
|
func getCachePath(rawurl string) string {
|
|
return "/" + strings.ReplaceAll(url.QueryEscape(rawurl), "%", "!") // s3 keys are ok with "!"
|
|
}
|
|
|
|
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 {
|
|
fullURL, cachable := GetFullCachableURL(baseURL, relativeURL)
|
|
if !cachable {
|
|
return fullURL
|
|
}
|
|
|
|
u := url.URL{
|
|
Path: r.assetsURL.Path + getCachePathWithKey(sessionID, fullURL),
|
|
Host: r.assetsURL.Host,
|
|
Scheme: r.assetsURL.Scheme,
|
|
}
|
|
return u.String()
|
|
}
|