-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathimage.go
81 lines (76 loc) · 1.95 KB
/
image.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package unfurlist
import (
"context"
"errors"
"fmt"
"image"
_ "image/gif" // register supported image types
_ "image/jpeg"
_ "image/png"
"net/http"
"net/url"
"strings"
)
var errEmptyImageURL = errors.New("empty image url")
// absoluteImageUrl makes imageUrl absolute if it's not. Image url can either be
// relative or schemaless url.
func absoluteImageURL(originURL, imageURL string) (string, error) {
if imageURL == "" {
return "", errEmptyImageURL
}
if strings.HasPrefix(imageURL, "https") {
return imageURL, nil
}
iu, err := url.Parse(imageURL)
if err != nil {
return "", err
}
switch iu.Scheme {
case "https", "":
default:
return "", fmt.Errorf("unsupported url scheme %q", iu.Scheme)
}
base, err := url.Parse(originURL)
if err != nil {
return "", err
}
return base.ResolveReference(iu).String(), nil
}
// imageDimensions tries to retrieve enough of image to get its dimensions. If
// provided client is nil, http.DefaultClient is used.
func imageDimensions(ctx context.Context, client *http.Client, imageURL string) (width, height int, err error) {
cl := client
if cl == nil {
cl = http.DefaultClient
}
req, err := http.NewRequest(http.MethodGet, imageURL, nil)
if err != nil {
return 0, 0, err
}
req = req.WithContext(ctx)
resp, err := cl.Do(req)
if err != nil {
return 0, 0, err
}
defer resp.Body.Close()
if resp.StatusCode >= http.StatusBadRequest {
return 0, 0, errors.New(resp.Status)
}
switch ct := strings.ToLower(resp.Header.Get("Content-Type")); ct {
case "image/jpeg", "image/png", "image/gif":
default:
// for broken servers responding with image/png;charset=UTF-8
// (i.e. www.evernote.com)
if strings.HasPrefix(ct, "image/jpeg") ||
strings.HasPrefix(ct, "image/png") ||
strings.HasPrefix(ct, "image/gif") {
break
}
return 0, 0, fmt.Errorf("unsupported content-type %q", ct)
}
cfg, _, err := image.DecodeConfig(resp.Body)
if err != nil {
return 0, 0, err
}
return cfg.Width, cfg.Height, nil
}