Files
MeBox/internal/service/image_proxy_upstream.go
truewhile 9b2b592003 优化
2026-09-20 13:33:45 +08:00

64 lines
1.8 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package service
import (
"net/url"
"strconv"
"strings"
)
// imageCacheKeyURL normalizes an upstream image URL before it is hashed into a
// disk cache key. Credential query parameters are dropped: a remote Emby token
// is per-account, so removing it cannot make two different images collide, but
// it stops a token rotation from invalidating every cached poster at once.
func imageCacheKeyURL(raw string) string {
u, err := url.Parse(strings.TrimSpace(raw))
if err != nil || u.Host == "" {
return raw
}
q := u.Query()
dropped := false
for key := range q {
switch strings.ToLower(key) {
case "api_key", "apikey", "x-emby-token", "x-mediabrowser-token":
q.Del(key)
dropped = true
}
}
if !dropped {
return raw
}
u.RawQuery = q.Encode()
return u.String()
}
// upstreamImageFetchURL forwards the client's thumbnail request to a configured
// remote Emby mount. The remote server can produce the thumbnail itself from
// maxWidth/maxHeight/quality, so the proxy transfers a few dozen KB instead of
// the full-size original and skips the local decode+scale entirely (measured at
// ~400ms for a single 2892×4096 poster).
//
// Other upstreams (TMDb, Douban, adult sites, ...) do not honour these
// parameters, so their originals are still fetched and scaled locally.
func (p *ImageProxy) upstreamImageFetchURL(raw string, opts imageResizeOptions) string {
if p == nil || !opts.active() {
return raw
}
u, err := url.Parse(raw)
if err != nil || u.Host == "" {
return raw
}
if !p.isAllowedRemoteHost(u.Hostname()) {
return raw
}
q := u.Query()
if opts.MaxWidth > 0 {
q.Set("maxWidth", strconv.Itoa(opts.MaxWidth))
}
if opts.MaxHeight > 0 {
q.Set("maxHeight", strconv.Itoa(opts.MaxHeight))
}
q.Set("quality", strconv.Itoa(opts.encodingQuality()))
u.RawQuery = q.Encode()
return u.String()
}