package favicon import ( "errors" "net/http" "github.com/yusing/go-proxy/internal/gperr" "github.com/yusing/go-proxy/internal/homepage" "github.com/yusing/go-proxy/internal/net/gphttp" "github.com/yusing/go-proxy/internal/route/routes" ) // GetFavIcon returns the favicon of the route // // Returns: // - 200 OK: if icon found // - 400 Bad Request: if alias is empty or route is not HTTPRoute // - 404 Not Found: if route or icon not found // - 500 Internal Server Error: if internal error // - others: depends on route handler response func GetFavIcon(w http.ResponseWriter, req *http.Request) { url, alias := req.FormValue("url"), req.FormValue("alias") if url == "" && alias == "" { gphttp.ClientError(w, gphttp.ErrMissingKey("url or alias"), http.StatusBadRequest) return } if url != "" && alias != "" { gphttp.ClientError(w, gperr.New("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 { gphttp.ClientError(w, err, http.StatusBadRequest) return } fetchResult := homepage.FetchFavIconFromURL(req.Context(), &iconURL) if !fetchResult.OK() { http.Error(w, fetchResult.ErrMsg, fetchResult.StatusCode) return } w.Header().Set("Content-Type", fetchResult.ContentType()) gphttp.WriteBody(w, fetchResult.Icon) return } // try with route.Icon r, ok := routes.HTTP.Get(alias) if !ok { gphttp.ClientError(w, errors.New("no such route"), http.StatusNotFound) return } var result *homepage.FetchResult hp := r.HomepageItem() if hp.Icon != nil { if hp.Icon.IconSource == homepage.IconSourceRelative { result = homepage.FindIcon(req.Context(), r, hp.Icon.Value) } else { result = homepage.FetchFavIconFromURL(req.Context(), hp.Icon) } } else { // try extract from "link[rel=icon]" result = homepage.FindIcon(req.Context(), r, "/") } if result.StatusCode == 0 { result.StatusCode = http.StatusOK } if !result.OK() { http.Error(w, result.ErrMsg, result.StatusCode) return } w.Header().Set("Content-Type", result.ContentType()) gphttp.WriteBody(w, result.Icon) }