mirror of
https://github.com/casdoor/casdoor.git
synced 2025-05-22 18:25:47 +08:00
Improve getFaviconFileBuffer()
This commit is contained in:
parent
b9140e2d5a
commit
ac4b870309
@ -54,19 +54,24 @@ func downloadImage(client *http.Client, url string) (*bytes.Buffer, string, erro
|
||||
// Get the content type and determine the file extension
|
||||
contentType := resp.Header.Get("Content-Type")
|
||||
fileExtension := ""
|
||||
switch contentType {
|
||||
case "image/jpeg":
|
||||
fileExtension = ".jpg"
|
||||
case "image/png":
|
||||
fileExtension = ".png"
|
||||
case "image/gif":
|
||||
fileExtension = ".gif"
|
||||
case "image/vnd.microsoft.icon":
|
||||
fileExtension = ".ico"
|
||||
case "image/x-icon":
|
||||
fileExtension = ".ico"
|
||||
default:
|
||||
return nil, "", fmt.Errorf("unsupported content type: %s", contentType)
|
||||
|
||||
if strings.Contains(contentType, "text/html") {
|
||||
fileExtension = ".html"
|
||||
} else {
|
||||
switch contentType {
|
||||
case "image/jpeg":
|
||||
fileExtension = ".jpg"
|
||||
case "image/png":
|
||||
fileExtension = ".png"
|
||||
case "image/gif":
|
||||
fileExtension = ".gif"
|
||||
case "image/vnd.microsoft.icon":
|
||||
fileExtension = ".ico"
|
||||
case "image/x-icon":
|
||||
fileExtension = ".ico"
|
||||
default:
|
||||
return nil, "", fmt.Errorf("unsupported content type: %s", contentType)
|
||||
}
|
||||
}
|
||||
|
||||
// Save the image to a bytes.Buffer
|
||||
|
@ -18,9 +18,173 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/net/html"
|
||||
)
|
||||
|
||||
type Link struct {
|
||||
Rel string
|
||||
Sizes string
|
||||
Href string
|
||||
}
|
||||
|
||||
func GetFaviconUrl(htmlStr string) (string, error) {
|
||||
doc, err := html.Parse(strings.NewReader(htmlStr))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var links []Link
|
||||
findLinks(doc, &links)
|
||||
|
||||
if len(links) == 0 {
|
||||
return "", fmt.Errorf("no Favicon links found")
|
||||
}
|
||||
|
||||
chosenLink := chooseFaviconLink(links)
|
||||
if chosenLink == nil {
|
||||
return "", fmt.Errorf("unable to determine favicon URL")
|
||||
}
|
||||
|
||||
return chosenLink.Href, nil
|
||||
}
|
||||
|
||||
func findLinks(n *html.Node, links *[]Link) {
|
||||
if n.Type == html.ElementNode && n.Data == "link" {
|
||||
link := parseLink(n)
|
||||
if link != nil {
|
||||
*links = append(*links, *link)
|
||||
}
|
||||
}
|
||||
|
||||
for c := n.FirstChild; c != nil; c = c.NextSibling {
|
||||
findLinks(c, links)
|
||||
}
|
||||
}
|
||||
|
||||
func parseLink(n *html.Node) *Link {
|
||||
var link Link
|
||||
|
||||
for _, attr := range n.Attr {
|
||||
switch attr.Key {
|
||||
case "rel":
|
||||
link.Rel = attr.Val
|
||||
case "sizes":
|
||||
link.Sizes = attr.Val
|
||||
case "href":
|
||||
link.Href = attr.Val
|
||||
}
|
||||
}
|
||||
|
||||
if link.Href != "" {
|
||||
return &link
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func chooseFaviconLink(links []Link) *Link {
|
||||
var appleTouchLinks []Link
|
||||
var shortcutLinks []Link
|
||||
var iconLinks []Link
|
||||
|
||||
for _, link := range links {
|
||||
switch link.Rel {
|
||||
case "apple-touch-icon":
|
||||
appleTouchLinks = append(appleTouchLinks, link)
|
||||
case "shortcut icon":
|
||||
shortcutLinks = append(shortcutLinks, link)
|
||||
case "icon":
|
||||
iconLinks = append(iconLinks, link)
|
||||
}
|
||||
}
|
||||
|
||||
if len(appleTouchLinks) > 0 {
|
||||
return chooseFaviconLinkBySizes(appleTouchLinks)
|
||||
}
|
||||
|
||||
if len(shortcutLinks) > 0 {
|
||||
return chooseFaviconLinkBySizes(shortcutLinks)
|
||||
}
|
||||
|
||||
if len(iconLinks) > 0 {
|
||||
return chooseFaviconLinkBySizes(iconLinks)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func chooseFaviconLinkBySizes(links []Link) *Link {
|
||||
if len(links) == 1 {
|
||||
return &links[0]
|
||||
}
|
||||
|
||||
var chosenLink *Link
|
||||
|
||||
for _, link := range links {
|
||||
if chosenLink == nil || compareSizes(link.Sizes, chosenLink.Sizes) > 0 {
|
||||
chosenLink = &link
|
||||
}
|
||||
}
|
||||
|
||||
return chosenLink
|
||||
}
|
||||
|
||||
func compareSizes(sizes1, sizes2 string) int {
|
||||
if sizes1 == sizes2 {
|
||||
return 0
|
||||
}
|
||||
|
||||
size1 := parseSize(sizes1)
|
||||
size2 := parseSize(sizes2)
|
||||
|
||||
if size1 == nil {
|
||||
return -1
|
||||
}
|
||||
|
||||
if size2 == nil {
|
||||
return 1
|
||||
}
|
||||
|
||||
if size1[0] == size2[0] {
|
||||
return size1[1] - size2[1]
|
||||
}
|
||||
|
||||
return size1[0] - size2[0]
|
||||
}
|
||||
|
||||
func parseSize(sizes string) []int {
|
||||
size := strings.Split(sizes, "x")
|
||||
if len(size) != 2 {
|
||||
return nil
|
||||
}
|
||||
|
||||
var result []int
|
||||
|
||||
for _, s := range size {
|
||||
val := strings.TrimSpace(s)
|
||||
if len(val) > 0 {
|
||||
num := 0
|
||||
for i := 0; i < len(val); i++ {
|
||||
if val[i] >= '0' && val[i] <= '9' {
|
||||
num = num*10 + int(val[i]-'0')
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
result = append(result, num)
|
||||
}
|
||||
}
|
||||
|
||||
if len(result) == 2 {
|
||||
return result
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getFaviconFileBuffer(client *http.Client, email string) (*bytes.Buffer, string, error) {
|
||||
tokens := strings.Split(email, "@")
|
||||
domain := tokens[1]
|
||||
@ -28,9 +192,29 @@ func getFaviconFileBuffer(client *http.Client, email string) (*bytes.Buffer, str
|
||||
return nil, "", nil
|
||||
}
|
||||
|
||||
//htmlUrl := fmt.Sprintf("https://%s", domain)
|
||||
//buffer, fileExtension, err := downloadImage(client, htmlUrl)
|
||||
htmlUrl := fmt.Sprintf("https://%s", domain)
|
||||
buffer, _, err := downloadImage(client, htmlUrl)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
faviconUrl := fmt.Sprintf("https://%s/favicon.ico", domain)
|
||||
faviconUrl := ""
|
||||
if buffer != nil {
|
||||
faviconUrl, err = GetFaviconUrl(buffer.String())
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(faviconUrl, "http") {
|
||||
faviconUrl, err = url.JoinPath(htmlUrl, faviconUrl)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if faviconUrl == "" {
|
||||
faviconUrl = fmt.Sprintf("https://%s/favicon.ico", domain)
|
||||
}
|
||||
return downloadImage(client, faviconUrl)
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ func TestUpdateAvatars(t *testing.T) {
|
||||
// continue
|
||||
//}
|
||||
|
||||
if user.AvatarType != "Favicon" {
|
||||
if user.AvatarType != "Auto" {
|
||||
continue
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user