mirror of
https://github.com/casdoor/casdoor.git
synced 2025-05-23 02:35:49 +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
|
// Get the content type and determine the file extension
|
||||||
contentType := resp.Header.Get("Content-Type")
|
contentType := resp.Header.Get("Content-Type")
|
||||||
fileExtension := ""
|
fileExtension := ""
|
||||||
switch contentType {
|
|
||||||
case "image/jpeg":
|
if strings.Contains(contentType, "text/html") {
|
||||||
fileExtension = ".jpg"
|
fileExtension = ".html"
|
||||||
case "image/png":
|
} else {
|
||||||
fileExtension = ".png"
|
switch contentType {
|
||||||
case "image/gif":
|
case "image/jpeg":
|
||||||
fileExtension = ".gif"
|
fileExtension = ".jpg"
|
||||||
case "image/vnd.microsoft.icon":
|
case "image/png":
|
||||||
fileExtension = ".ico"
|
fileExtension = ".png"
|
||||||
case "image/x-icon":
|
case "image/gif":
|
||||||
fileExtension = ".ico"
|
fileExtension = ".gif"
|
||||||
default:
|
case "image/vnd.microsoft.icon":
|
||||||
return nil, "", fmt.Errorf("unsupported content type: %s", contentType)
|
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
|
// Save the image to a bytes.Buffer
|
||||||
|
@ -18,9 +18,173 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
"strings"
|
"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) {
|
func getFaviconFileBuffer(client *http.Client, email string) (*bytes.Buffer, string, error) {
|
||||||
tokens := strings.Split(email, "@")
|
tokens := strings.Split(email, "@")
|
||||||
domain := tokens[1]
|
domain := tokens[1]
|
||||||
@ -28,9 +192,29 @@ func getFaviconFileBuffer(client *http.Client, email string) (*bytes.Buffer, str
|
|||||||
return nil, "", nil
|
return nil, "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//htmlUrl := fmt.Sprintf("https://%s", domain)
|
htmlUrl := fmt.Sprintf("https://%s", domain)
|
||||||
//buffer, fileExtension, err := downloadImage(client, htmlUrl)
|
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)
|
return downloadImage(client, faviconUrl)
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ func TestUpdateAvatars(t *testing.T) {
|
|||||||
// continue
|
// continue
|
||||||
//}
|
//}
|
||||||
|
|
||||||
if user.AvatarType != "Favicon" {
|
if user.AvatarType != "Auto" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user