-
Notifications
You must be signed in to change notification settings - Fork 10
/
mycel.go
124 lines (104 loc) · 2.51 KB
/
mycel.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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package mycel
import (
"bytes"
"context"
"github.com/psilva261/mycel/logger"
"golang.org/x/text/encoding"
"golang.org/x/text/encoding/htmlindex"
"golang.org/x/text/encoding/unicode"
"io/ioutil"
"mime"
"net/url"
"strings"
)
type Fetcher interface {
Ctx() context.Context
Origin() *url.URL
// LinkedUrl relative to current page
LinkedUrl(string) (*url.URL, error)
Get(*url.URL) ([]byte, ContentType, error)
}
type ContentType struct {
MediaType string
Params map[string]string
}
// NewContentType based on mime type string and url including file extension as fallback
func NewContentType(s string, u *url.URL) (c ContentType, err error) {
if s == "" && u != nil && strings.Contains(u.String(), ".") {
l := strings.Split(u.String(), ".")
ext := l[len(l)-1]
switch ext {
case "jpg":
return NewContentType("image/jpeg", u)
case "png":
return NewContentType("image/png", u)
case "gif":
return NewContentType("image/gif", u)
default:
return ContentType{}, nil
}
}
c.MediaType, c.Params, err = mime.ParseMediaType(s)
return
}
func (c ContentType) IsEmpty() bool {
return c.MediaType == ""
}
func (c ContentType) IsHTML() bool {
return c.MediaType == "text/html"
}
func (c ContentType) IsCSS() bool {
return c.MediaType != "text/html"
}
func (c ContentType) IsJS() bool {
for _, t := range []string{"application/javascript", "application/ecmascript", "text/javascript", "text/ecmascript"} {
if t == c.MediaType {
return true
}
}
return false
}
func (c ContentType) IsPlain() bool {
return c.MediaType == "text/plain"
}
func (c ContentType) IsDownload() bool {
return c.MediaType == "application/octet-stream" ||
c.MediaType == "application/zip"
}
func (c ContentType) IsSvg() bool {
return c.MediaType == "image/svg+xml"
}
func (c ContentType) Charset() (cs string) {
cs, ok := c.Params["charset"]
if !ok {
return "UTF-8"
}
return
}
func (c ContentType) Encoding() (e encoding.Encoding) {
charset, ok := c.Params["charset"]
if !ok || charset == "utf8" || charset == "utf-8" {
return unicode.UTF8
}
e, err := htmlindex.Get(charset)
if err != nil || e == nil {
log.Errorf("encoding %v: %v", charset, err)
return unicode.UTF8
}
return
}
func (c ContentType) Utf8(buf []byte) string {
e := c.Encoding()
if e == unicode.UTF8 {
return string(buf)
}
r := bytes.NewReader(buf)
cr := e.NewDecoder().Reader(r)
updated, err := ioutil.ReadAll(cr)
if err == nil {
buf = updated
} else {
log.Errorf("utf8: unable to decode to %v: %v", e, err)
}
return string(buf)
}