api: allow favicon endpoint to use url instead of alias

This commit is contained in:
yusing 2025-01-21 06:48:56 +08:00
parent 8b1a3a31ff
commit dd2b8f600d
2 changed files with 55 additions and 28 deletions

View file

@ -33,7 +33,7 @@ func NewHandler(cfg config.ConfigInstance) http.Handler {
mux.HandleFunc("GET", "/v1/stats/ws", useCfg(cfg, v1.StatsWS)) mux.HandleFunc("GET", "/v1/stats/ws", useCfg(cfg, v1.StatsWS))
mux.HandleFunc("GET", "/v1/health/ws", auth.RequireAuth(useCfg(cfg, v1.HealthWS))) mux.HandleFunc("GET", "/v1/health/ws", auth.RequireAuth(useCfg(cfg, v1.HealthWS)))
mux.HandleFunc("GET", "/v1/logs/ws", auth.RequireAuth(useCfg(cfg, v1.LogsWS()))) mux.HandleFunc("GET", "/v1/logs/ws", auth.RequireAuth(useCfg(cfg, v1.LogsWS())))
mux.HandleFunc("GET", "/v1/favicon/{alias}", auth.RequireAuth(favicon.GetFavIcon)) mux.HandleFunc("GET", "/v1/favicon", auth.RequireAuth(favicon.GetFavIcon))
mux.HandleFunc("POST", "/v1/homepage/set", auth.RequireAuth(v1.SetHomePageOverrides)) mux.HandleFunc("POST", "/v1/homepage/set", auth.RequireAuth(v1.SetHomePageOverrides))
defaultAuth := auth.GetDefaultAuth() defaultAuth := auth.GetDefaultAuth()

View file

@ -65,44 +65,71 @@ func (c *content) Hijack() (net.Conn, *bufio.ReadWriter, error) {
// - 500 Internal Server Error: if internal error // - 500 Internal Server Error: if internal error
// - others: depends on route handler response // - others: depends on route handler response
func GetFavIcon(w http.ResponseWriter, req *http.Request) { func GetFavIcon(w http.ResponseWriter, req *http.Request) {
alias := req.PathValue("alias") url, alias := req.FormValue("url"), req.FormValue("alias")
if alias == "" { if url == "" && alias == "" {
U.RespondError(w, U.ErrMissingKey("alias"), http.StatusBadRequest) U.RespondError(w, U.ErrMissingKey("url or alias"), http.StatusBadRequest)
return return
} }
r, ok := routes.GetHTTPRoutes().Load(alias) if url != "" && alias != "" {
if !ok { U.RespondError(w, U.ErrInvalidKey("url and alias are mutually exclusive"), http.StatusBadRequest)
http.NotFound(w, req)
return return
} }
switch r := r.(type) {
case route.HTTPRoute:
var icon []byte
var status int
var errMsg string
hp := r.RawEntry().Homepage.GetOverride() // try with url
if !hp.IsEmpty() && hp.Icon != nil { if url != "" {
switch hp.Icon.IconSource { var iconURL homepage.IconURL
case homepage.IconSourceAbsolute: if err := iconURL.Parse(url); err != nil {
icon, status, errMsg = fetchIconAbsolute(hp.Icon.Value) U.RespondError(w, err, http.StatusBadRequest)
case homepage.IconSourceRelative: return
icon, status, errMsg = findIcon(r, req, hp.Icon.Value)
case homepage.IconSourceWalkXCode, homepage.IconSourceSelfhSt:
icon, status, errMsg = fetchKnownIcon(hp.Icon)
}
} else {
// try extract from "link[rel=icon]"
icon, status, errMsg = findIcon(r, req, "/")
} }
if status != http.StatusOK { icon, status, errMsg := getFavIconFromURL(&iconURL)
if icon == nil {
http.Error(w, errMsg, status) http.Error(w, errMsg, status)
return return
} }
U.WriteBody(w, icon) U.WriteBody(w, icon)
default: return
http.Error(w, "bad request", http.StatusBadRequest)
} }
// try with route.Homepage.Icon
r, ok := routes.GetHTTPRoute(alias)
if !ok {
U.RespondError(w, errors.New("no such route"), http.StatusNotFound)
return
}
var icon []byte
var status int
var errMsg string
hp := r.RawEntry().Homepage.GetOverride()
if !hp.IsEmpty() && hp.Icon != nil {
switch hp.Icon.IconSource {
case homepage.IconSourceRelative:
icon, status, errMsg = findIcon(r, req, hp.Icon.Value)
default:
icon, status, errMsg = getFavIconFromURL(hp.Icon)
}
} else {
// try extract from "link[rel=icon]"
icon, status, errMsg = findIcon(r, req, "/")
}
if status != http.StatusOK {
http.Error(w, errMsg, status)
return
}
U.WriteBody(w, icon)
}
func getFavIconFromURL(iconURL *homepage.IconURL) ([]byte, int, string) {
switch iconURL.IconSource {
case homepage.IconSourceAbsolute:
return fetchIconAbsolute(iconURL.URL())
case homepage.IconSourceRelative:
return nil, http.StatusBadRequest, "unexpected relative icon"
case homepage.IconSourceWalkXCode, homepage.IconSourceSelfhSt:
return fetchKnownIcon(iconURL)
}
return nil, http.StatusBadRequest, "invalid icon source"
} }
// cache key can be absolute url or route name. // cache key can be absolute url or route name.