-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathshare.go
126 lines (113 loc) · 2.42 KB
/
share.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
125
126
package main
import (
"html/template"
"log"
"net/http"
"os"
"path"
"sort"
"strings"
"sync"
)
type shareDir struct {
dir string
lock sync.RWMutex
}
type dirItem struct {
N int
Name string
Typ string
}
func (s *shareDir) GetRealPath(path1 string) string {
return path.Join(s.dir, path1)
}
func (s *shareDir) Get() string {
return s.dir
}
func (s *shareDir) Set(v string) {
s.lock.Lock()
s.dir = v
s.lock.Unlock()
}
var fileServ http.Handler
//GetType 0-not exist,1-file,2-dir
func (s *shareDir) GetType(realPath string) int {
if strings.HasPrefix(realPath, "../") || strings.Contains(realPath, "/..") {
return 0
}
stat1, err := os.Stat(realPath)
if err != nil {
log.Println(err)
return 0
}
if stat1.IsDir() {
return 2
}
return 1
}
func sortDirs(infos []os.FileInfo) []os.FileInfo {
sort.Slice(infos, func(i, j int) bool {
info1 := infos[i].(os.FileInfo)
info2 := infos[j].(os.FileInfo)
return strings.Compare(info1.Name(), info2.Name()) == -1
})
return infos
}
//ListDir 必须先确定为目录
func (s *shareDir) ListDir(realPath string) []dirItem {
dir1, _ := os.Open(realPath)
infos, _ := dir1.Readdir(0)
infos = sortDirs(infos)
res := []dirItem{}
var typ string
for i, v := range infos {
if strings.HasPrefix(v.Name(), ".") {
continue
}
tail := ""
if v.IsDir() {
typ = "D"
tail = "/"
} else {
typ = "F"
}
res = append(res, dirItem{i + 1, v.Name() + tail, typ})
}
return res
}
var share *shareDir
const shareBase = "/share/"
const lenShareBase = len(shareBase)
func setShareDir(dir string) {
http.HandleFunc(shareBase, handleShare)
share = &shareDir{}
share.Set(dir)
//fileServ = http.StripPrefix(shareBase, http.FileServer(http.Dir(dir)))
}
func handleShare(w http.ResponseWriter, r *http.Request) {
//fileServ.ServeHTTP(w, r)
if strings.Contains("/"+r.URL.Path[lenShareBase:], "/.") {
w.WriteHeader(404)
return
}
realPath := share.GetRealPath(r.URL.Path[lenShareBase:])
switch share.GetType(realPath) {
case 0:
w.WriteHeader(404)
case 1:
http.ServeFile(w, r, realPath)
case 2:
// buf := bytes.NewBufferString(r.URL.Path + "\n")
list1 := share.ListDir(realPath)
// for _, v := range list1 {
// buf.WriteString(fmt.Sprintf("%d . %s %v\n", v.N, v.Typ, v.Name))
// }
t := template.New("")
t.Parse(tmplDir)
data := make(map[string]interface{})
data["title"] = r.URL.Path
data["links"] = list1
w.WriteHeader(200)
t.Execute(w, data)
}
}