(ctx context.Context, pageURL *url.URL, imageURLStr string)
| 742 | break |
| 743 | } |
| 744 | } |
| 745 | |
| 746 | result := openGraphResult{Title: title, Description: description} |
| 747 | |
| 748 | pageURL, err := url.Parse(urlStr) |
| 749 | if err != nil { |
| 750 | log.Warn().Err(err).Str("url", urlStr).Msg("Failed to parse page URL for resolving image URL") |
| 751 | return result |
| 752 | } |
| 753 | |
| 754 | fetchOpenGraphImage(ctx, pageURL, imageURLStr, &result) |
| 755 | return result |
| 756 | } |
| 757 | |
| 758 | func encodeJPEGThumbnail(img image.Image) []byte { |
| 759 | var buf bytes.Buffer |
| 760 | if err := jpeg.Encode(&buf, img, &jpeg.Options{Quality: openGraphJpegQuality}); err != nil { |
| 761 | log.Warn().Err(err).Msg("Failed to encode thumbnail to JPEG") |
| 762 | return nil |
| 763 | } |
| 764 | return buf.Bytes() |
| 765 | } |
| 766 | |
| 767 | func fetchOpenGraphImage(ctx context.Context, pageURL *url.URL, imageURLStr string, result *openGraphResult) { |
| 768 | // No image found on the page; an empty string would resolve to the page |
| 769 | // URL itself and we would try to decode HTML as an image. |
| 770 | if imageURLStr == "" { |
| 771 | return |
| 772 | } |
| 773 | |
| 774 | imageURL, err := url.Parse(imageURLStr) |
| 775 | if err != nil { |
| 776 | log.Warn().Err(err).Str("imageURL", imageURLStr).Msg("Failed to parse Open Graph image URL") |
| 777 | return |
| 778 | } |
| 779 | |
| 780 | resolvedImageURL := pageURL.ResolveReference(imageURL).String() |
| 781 | imgBytes, _, err := fetchURLBytes(ctx, resolvedImageURL, openGraphImageMaxBytes) |
| 782 | if err != nil { |
| 783 | log.Warn().Err(err).Str("imageURL", resolvedImageURL).Msg("Failed to fetch Open Graph image") |
| 784 | return |
| 785 | } |
| 786 | |
| 787 | imgConfig, _, err := image.DecodeConfig(bytes.NewReader(imgBytes)) |
| 788 | if err != nil { |
| 789 | log.Warn().Err(err).Str("imageURL", resolvedImageURL).Msg("Failed to decode Open Graph image config") |
| 790 | return |
no test coverage detected