/
httpstaticfilestask.go
117 lines (102 loc) · 2.98 KB
/
httpstaticfilestask.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
package http
import (
"fmt"
"io/ioutil"
"mime"
"os"
"path/filepath"
"regexp"
"strings"
"github.com/kklab-com/gone-core/channel"
"github.com/kklab-com/gone-httpheadername"
"github.com/kklab-com/gone-httpstatus"
buf "github.com/kklab-com/goth-bytebuf"
"github.com/kklab-com/goth-kklogger"
"github.com/tdewolff/minify/v2"
"github.com/tdewolff/minify/v2/css"
"github.com/tdewolff/minify/v2/html"
"github.com/tdewolff/minify/v2/js"
"github.com/tdewolff/minify/v2/json"
"github.com/tdewolff/minify/v2/svg"
"github.com/tdewolff/minify/v2/xml"
)
type StaticFilesHandlerTask struct {
DefaultHTTPHandlerTask
FolderPath string
DoMinify bool
DoCache bool
cacheMap map[string]*staticFileCacheEntity
m *minify.M
}
func NewStaticFilesHandlerTask(folderPath string) *StaticFilesHandlerTask {
if folderPath == "" {
folderPath = "./resources/static"
}
s := &StaticFilesHandlerTask{
FolderPath: folderPath,
DoMinify: true,
DoCache: true,
cacheMap: map[string]*staticFileCacheEntity{},
m: minify.New(),
}
s.m.AddFunc("text/css", css.Minify)
s.m.AddFunc("text/html", html.Minify)
s.m.AddFunc("image/svg+xml", svg.Minify)
s.m.AddFuncRegexp(regexp.MustCompile("^(application|text)/(x-)?(java|ecma)script$"), js.Minify)
s.m.AddFuncRegexp(regexp.MustCompile("[/+]json$"), json.Minify)
s.m.AddFuncRegexp(regexp.MustCompile("[/+]xml$"), xml.Minify)
s.m.AddFuncRegexp(regexp.MustCompile("^(application|text)/(x-)?(java|ecma)script$"), js.Minify)
return s
}
func (h *StaticFilesHandlerTask) Get(ctx channel.HandlerContext, req *Request, resp *Response, params map[string]any) ErrorResponse {
path := fmt.Sprintf("%s/%s", h.FolderPath, strings.ReplaceAll(req.Url().Path, "../", "/"))
if entity, err := h._Load(path); entity != nil {
resp.SetStatusCode(httpstatus.OK)
resp.SetHeader(httpheadername.ContentType, entity.contentType)
resp.SetBody(buf.NewByteBuf(entity.data))
} else if err == nil {
resp.SetStatusCode(httpstatus.NotFound)
} else {
resp.SetStatusCode(httpstatus.InternalServerError)
}
return nil
}
func (h *StaticFilesHandlerTask) _Load(path string) (*staticFileCacheEntity, error) {
if h.DoCache {
if entity, f := h.cacheMap[path]; f {
return entity, nil
}
}
if file, e := os.Open(path); e == nil {
defer file.Close()
if data, e := ioutil.ReadAll(file); e == nil {
entity := staticFileCacheEntity{}
entity.contentType = mime.TypeByExtension(filepath.Ext(path))
if h.DoMinify {
mini, err := h.m.Bytes(entity.contentType, data)
if err == nil {
entity.data = mini
}
}
if len(entity.data) == 0 {
entity.data = data
}
if h.DoCache {
h.cacheMap[path] = &entity
}
return &entity, nil
} else {
kklogger.ErrorJ("http:StaticFilesHandlerTask", e.Error())
return nil, e
}
} else if os.IsNotExist(e) {
return nil, nil
} else {
kklogger.WarnJ("http:StaticFilesHandlerTask", e.Error())
return nil, e
}
}
type staticFileCacheEntity struct {
data []byte
contentType string
}