-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdir.go
More file actions
165 lines (126 loc) · 2.71 KB
/
dir.go
File metadata and controls
165 lines (126 loc) · 2.71 KB
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
package mod
import (
"fmt"
"html"
"net/http"
"os"
"strings"
)
/**
List 使用简洁风格列表目录, root 路径由调用者传递.
参数:
n 限制目录列表的个数, n <= 0 表示不限制.
返回:
true 目录被列表
false 目录未被列表
*/
func List(n int) Dir {
return Dir(func(root http.Dir,
w http.ResponseWriter, req *http.Request) bool {
f, e := root.Open(req.URL.Path)
if e != nil {
return false
}
defer f.Close()
fi, e := f.Stat()
if e != nil || !fi.IsDir() {
return false
}
w.Header().Set("Content-Type", "text/html; charset=utf-8")
fmt.Fprintf(w, "<pre>\n")
fmt.Fprint(w, "<a href=\"../\">..</a>\n")
var dirs []os.FileInfo
for {
dirs, _ = f.Readdir(n)
if len(dirs) == 0 {
break
}
for _, fi = range dirs {
if !fi.IsDir() {
continue
}
fmt.Fprintf(w, "<a href=\"%[1]s/\">%[1]s/</a>\n",
html.EscapeString(fi.Name()))
}
for _, fi = range dirs {
if fi.IsDir() {
continue
}
fmt.Fprintf(w, "<a href=\"%[1]s\">%[1]s</a>\n",
html.EscapeString(fi.Name()))
}
}
fmt.Fprintf(w, "</pre>\n")
return true
})
}
/**
DirList 调用 List 使用简洁风格列表目录.
参数:
root 指定文档根路径
n 限制目录列表的个数, n <= 0 表示不限制.
返回:
true 目录被列表
false 目录未被列表
*/
func DirList(root http.Dir, n int) Finish {
finish := List(n)
return Finish(func(
rw http.ResponseWriter, req *http.Request) bool {
return finish.ServeHTTP(root, rw, req)
})
}
const indexRedirect = "/index.html"
/**
Redirect 遵守 http 1.1 规范对目录进行 301 重定向.
依据:
URL.Path 以 "/index.html" 结尾.
URL.Path 是目录, 没有以 "/" 结尾.
参数:
root 指定文档根路径
*/
func Redirect(root http.Dir,
rw http.ResponseWriter, req *http.Request) bool {
name := req.URL.Path
pos := strings.LastIndex(name, "/")
if len(name) == pos+1 {
return false
}
if name[pos:] == indexRedirect {
name = name[:pos+1]
if q := req.URL.RawQuery; q != "" {
name += "?" + q
}
rw.Header().Set("Location", name)
rw.WriteHeader(http.StatusMovedPermanently)
return true
}
f, e := root.Open(name)
if e != nil {
return false
}
defer f.Close()
fi, e := f.Stat()
if e != nil || !fi.IsDir() {
return false
}
if q := req.URL.RawQuery; q != "" {
name += "/?" + q
} else {
name += "/"
}
rw.Header().Set("Location", name)
rw.WriteHeader(http.StatusMovedPermanently)
return true
}
/**
DirRedirect 调用 Redirect 对目录进行 301 重定向.
参数:
root 指定文档根路径
*/
func DirRedirect(root http.Dir) Finish {
return Finish(func(
rw http.ResponseWriter, req *http.Request) bool {
return Redirect(root, rw, req)
})
}