-
Notifications
You must be signed in to change notification settings - Fork 5
/
file.go
64 lines (52 loc) · 1.41 KB
/
file.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
package pgo2
import (
"net/http"
"os"
"path/filepath"
"github.com/pinguo/pgo2/core"
"github.com/pinguo/pgo2/iface"
"github.com/pinguo/pgo2/util"
)
// File file plugin, this plugin only handle file in @public directory,
// request url with empty or excluded extension will not be handled.
func NewFile(config map[string]interface{}) *File {
f := &File{}
core.Configure(f, config)
return f
}
type File struct {
excludeExtensions []string
}
func (f *File) SetExcludeExtensions(v []interface{}) {
for _, vv := range v {
f.excludeExtensions = append(f.excludeExtensions, vv.(string))
}
}
func (f *File) HandleRequest(ctx iface.IContext) {
// if extension is empty or excluded, pass
if ext := filepath.Ext(ctx.Path()); ext == "" {
return
} else if len(f.excludeExtensions) != 0 {
if util.SliceSearchString(f.excludeExtensions, ext) != -1 {
return
}
}
// skip other plugins
defer ctx.Abort()
// GET or HEAD method is required
method := ctx.Method()
if method != http.MethodGet && method != http.MethodHead {
http.Error(ctx.Output(), "", http.StatusMethodNotAllowed)
return
}
// file in @public directory is required
path := filepath.Join(App().PublicPath(), util.CleanPath(ctx.Path()))
h, e := os.Open(path)
if e != nil {
http.Error(ctx.Output(), "", http.StatusNotFound)
return
}
defer h.Close()
info, _ := h.Stat()
http.ServeContent(ctx.Output(), ctx.Input(), path, info.ModTime(), h)
}