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,18 +65,38 @@ 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 != "" {
U.RespondError(w, U.ErrInvalidKey("url and alias are mutually exclusive"), http.StatusBadRequest)
return
}
// try with url
if url != "" {
var iconURL homepage.IconURL
if err := iconURL.Parse(url); err != nil {
U.RespondError(w, err, http.StatusBadRequest)
return
}
icon, status, errMsg := getFavIconFromURL(&iconURL)
if icon == nil {
http.Error(w, errMsg, status)
return
}
U.WriteBody(w, icon)
return
}
// try with route.Homepage.Icon
r, ok := routes.GetHTTPRoute(alias)
if !ok { if !ok {
http.NotFound(w, req) U.RespondError(w, errors.New("no such route"), http.StatusNotFound)
return return
} }
switch r := r.(type) {
case route.HTTPRoute:
var icon []byte var icon []byte
var status int var status int
var errMsg string var errMsg string
@ -84,12 +104,10 @@ func GetFavIcon(w http.ResponseWriter, req *http.Request) {
hp := r.RawEntry().Homepage.GetOverride() hp := r.RawEntry().Homepage.GetOverride()
if !hp.IsEmpty() && hp.Icon != nil { if !hp.IsEmpty() && hp.Icon != nil {
switch hp.Icon.IconSource { switch hp.Icon.IconSource {
case homepage.IconSourceAbsolute:
icon, status, errMsg = fetchIconAbsolute(hp.Icon.Value)
case homepage.IconSourceRelative: case homepage.IconSourceRelative:
icon, status, errMsg = findIcon(r, req, hp.Icon.Value) icon, status, errMsg = findIcon(r, req, hp.Icon.Value)
case homepage.IconSourceWalkXCode, homepage.IconSourceSelfhSt: default:
icon, status, errMsg = fetchKnownIcon(hp.Icon) icon, status, errMsg = getFavIconFromURL(hp.Icon)
} }
} else { } else {
// try extract from "link[rel=icon]" // try extract from "link[rel=icon]"
@ -100,9 +118,18 @@ func GetFavIcon(w http.ResponseWriter, req *http.Request) {
return return
} }
U.WriteBody(w, icon) U.WriteBody(w, icon)
default: }
http.Error(w, "bad request", http.StatusBadRequest)
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.