Skip to content

Commit 7c14f4a

Browse files
author
Jack Tang
committed
UPT: twist listing page
1 parent 1493e00 commit 7c14f4a

File tree

2 files changed

+64
-50
lines changed

2 files changed

+64
-50
lines changed

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module github.com/jackhftang/tusc
33
go 1.12
44

55
require (
6-
github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40 // indirect
6+
github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40
77
github.com/davecgh/go-spew v1.1.1 // indirect
88
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815
99
github.com/eventials/go-tus v0.0.0-20190617130015-9db47421f6a0

internal/server.go

+63-49
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package internal
22

33
import (
44
"fmt"
5+
"github.com/bmizerany/pat"
56
"github.com/docopt/docopt-go"
67
"github.com/jackhftang/tusc/internal/util"
78
"github.com/tus/tusd"
@@ -24,10 +25,12 @@ Usage:
2425
tusc (server|s) --help
2526
2627
Options:
27-
-h --host HOST Host to bind HTTP server to [default: 0.0.0.0]
28+
-u --url URL Url of HTTP server [default: http://localhost:1080]
29+
-b --bind ADDR Address to bind HTTP server to [default: 0.0.0.0]
2830
-p --port PORT Port to bind HTTP server to [default: 1080]
2931
-d --dir PATH Directory to store uploads in [default: ./data]
30-
--base-path PATH Basepath of the HTTP server [default: /files/]
32+
--listing-endpoint PATH Http path for flies listing [default: /]
33+
--files-endpoint PATH Http path for files [default: /files/]
3134
--unix-sock PATH If set will listen to a UNIX socket at this location instead of a TCP socket
3235
--max-size SIZE Maximum size of a single upload in bytes [default: 0]
3336
--store-size BYTE Size of space allowed for storage [default: 0]
@@ -36,16 +39,17 @@ Options:
3639
`
3740

3841
type ServerConf struct {
39-
httpHost string
40-
httpPort string
41-
httpSock string
42-
maxSize int64
43-
uploadDir string
44-
storeSize int64
45-
listingEndpoint string
46-
uploadEndpoint string
47-
timeout int64
48-
isBehindProxy bool
42+
Url string `docopt:"--url"`
43+
BindAddr string `docopt:"--bind"`
44+
Port string `docopt:"--port"`
45+
HttpSock string `docopt:"--unix-sock"`
46+
MaxSize int64 `docopt:"--max-size"`
47+
UploadDir string `docopt:"--dir"`
48+
StoreSize int64 `docopt:"--store-size"`
49+
ListingEndpoint string `docopt:"--listing-endpoint"`
50+
FilesEndpoint string `docopt:"--files-endpoint"`
51+
Timeout int64 `docopt:"--timeout"`
52+
IsBehindProxy bool `docopt:"--behind-proxy"`
4953
}
5054

5155
var stdout = log.New(os.Stdout, "[tusd] ", log.Ldate|log.Ltime)
@@ -58,61 +62,62 @@ func logEv(logOutput *log.Logger, eventName string, details ...string) {
5862
func Server() {
5963
var conf ServerConf
6064
arguments, _ := docopt.ParseDoc(serverUsage)
61-
conf.httpHost, _ = arguments.String("--host")
62-
conf.httpPort, _ = arguments.String("--port")
63-
conf.httpSock, _ = arguments.String("--unix-sock")
64-
conf.maxSize = util.GetInt64(arguments, "--max-size")
65-
conf.uploadDir, _ = arguments.String("--dir")
66-
conf.storeSize = util.GetInt64(arguments, "--store-size")
67-
conf.listingEndpoint = "/"
68-
conf.uploadEndpoint, _ = arguments.String("--base-path")
69-
conf.timeout = util.GetInt64(arguments, "--timeout")
70-
conf.isBehindProxy, _ = arguments.Bool("--behind-proxy")
65+
//arguments.Bind(&conf) // todo: bug
66+
conf.Url, _ = arguments.String("--url")
67+
conf.BindAddr, _ = arguments.String("--bind")
68+
conf.Port, _ = arguments.String("--port")
69+
conf.HttpSock, _ = arguments.String("--unix-sock")
70+
conf.MaxSize = util.GetInt64(arguments, "--max-size")
71+
conf.UploadDir, _ = arguments.String("--dir")
72+
conf.StoreSize = util.GetInt64(arguments, "--store-size")
73+
conf.ListingEndpoint, _ = arguments.String("--listing-endpoint")
74+
conf.FilesEndpoint, _ = arguments.String("--files-endpoint")
75+
conf.Timeout = util.GetInt64(arguments, "--timeout")
76+
conf.IsBehindProxy, _ = arguments.Bool("--behind-proxy")
77+
fmt.Println(conf)
7178

7279
storeCompoesr := tusd.NewStoreComposer()
7380

74-
stdout.Printf("Using '%s' as directory storage.\n", conf.uploadDir)
75-
if err := os.MkdirAll(conf.uploadDir, os.FileMode(0774)); err != nil {
81+
stdout.Printf("Using '%s' as directory storage.\n", conf.UploadDir)
82+
if err := os.MkdirAll(conf.UploadDir, os.FileMode(0774)); err != nil {
7683
stderr.Fatalf("Unable to ensure directory exists: %s", err)
7784
}
78-
store := filestore.New(conf.uploadDir)
85+
store := filestore.New(conf.UploadDir)
7986
store.UseIn(storeCompoesr)
8087

81-
if conf.storeSize > 0 {
82-
limitedstore.New(conf.storeSize, storeCompoesr.Core, storeCompoesr.Terminater).UseIn(storeCompoesr)
83-
stdout.Printf("Using %.2fMB as storage size.\n", float64(conf.storeSize)/1024/1024)
88+
if conf.StoreSize > 0 {
89+
limitedstore.New(conf.StoreSize, storeCompoesr.Core, storeCompoesr.Terminater).UseIn(storeCompoesr)
90+
stdout.Printf("Using %.2fMB as storage size.\n", float64(conf.StoreSize)/1024/1024)
8491

8592
// We need to ensure that a single upload can fit into the storage size
86-
if conf.maxSize > conf.storeSize || conf.maxSize == 0 {
87-
conf.maxSize = conf.storeSize
93+
if conf.MaxSize > conf.StoreSize || conf.MaxSize == 0 {
94+
conf.MaxSize = conf.StoreSize
8895
}
8996
}
9097

91-
stdout.Printf("Using %.2fMB as maximum size.\n", float64(conf.maxSize)/1024/1024)
92-
93-
// Serve
98+
stdout.Printf("Using %.2fMB as maximum size.\n", float64(conf.MaxSize)/1024/1024)
9499

95100
// Address
96101
address := ""
97-
if conf.httpSock != "" {
98-
address = conf.httpSock
102+
if conf.HttpSock != "" {
103+
address = conf.HttpSock
99104
stdout.Printf("Using %s as socket to listen.\n", address)
100105
} else {
101-
address = conf.httpHost + ":" + conf.httpPort
106+
address = conf.BindAddr + ":" + conf.Port
102107
stdout.Printf("Using %s as address to listen.\n", address)
103108
}
104109

105110
// Base path
106-
stdout.Printf("Using %s as the base path.\n", conf.uploadEndpoint)
111+
stdout.Printf("Using %s as the base path.\n", conf.FilesEndpoint)
107112

108113
// show capabilities
109114
stdout.Printf(storeCompoesr.Capabilities())
110115

111116
// tus handler
112117
handler, err := tusd.NewHandler(tusd.Config{
113-
MaxSize: conf.maxSize,
114-
BasePath: conf.uploadEndpoint,
115-
RespectForwardedHeaders: conf.isBehindProxy,
118+
MaxSize: conf.MaxSize,
119+
BasePath: conf.FilesEndpoint,
120+
RespectForwardedHeaders: conf.IsBehindProxy,
116121
StoreComposer: storeCompoesr,
117122
NotifyCompleteUploads: false,
118123
NotifyTerminatedUploads: false,
@@ -123,31 +128,34 @@ func Server() {
123128
stderr.Fatalf("Unable to create handler: %s", err)
124129
}
125130

126-
http.Handle(conf.uploadEndpoint, http.StripPrefix(conf.uploadEndpoint, handler))
127-
if conf.listingEndpoint != conf.uploadEndpoint {
128-
http.Handle(conf.listingEndpoint, http.StripPrefix(conf.listingEndpoint, homepage(store)))
131+
if conf.ListingEndpoint != conf.FilesEndpoint {
132+
mux := pat.New()
133+
mux.Get("/", listingHandler(conf, store))
134+
http.Handle(conf.ListingEndpoint, mux)
129135
}
136+
http.Handle(conf.FilesEndpoint, http.StripPrefix(conf.FilesEndpoint, handler))
137+
130138

131139
var listener net.Listener
132-
timeoutDuration := time.Duration(conf.timeout) * time.Millisecond
140+
timeoutDuration := time.Duration(conf.Timeout) * time.Millisecond
133141

134-
if conf.httpSock != "" {
142+
if conf.HttpSock != "" {
135143
if listener, err = util.NewUnixListener(address, timeoutDuration, timeoutDuration); err != nil {
136144
stderr.Fatalf("Unable to create listener: %s", err)
137145
}
138-
stdout.Printf("You can now upload files to: http://%s%s", address, conf.uploadEndpoint)
139146
} else {
140147
if listener, err = util.NewListener(address, timeoutDuration, timeoutDuration); err != nil {
141148
stderr.Fatalf("Unable to create listener: %s", err)
142149
}
150+
stdout.Printf("You can now upload files to: http://%s%s", address, conf.FilesEndpoint)
143151
}
144152

145153
if err = http.Serve(listener, nil); err != nil {
146154
stderr.Fatalf("Unable to serve: %s", err)
147155
}
148156
}
149157

150-
func homepage(store filestore.FileStore) http.HandlerFunc {
158+
func listingHandler(conf ServerConf, store filestore.FileStore) http.HandlerFunc {
151159
t, err := template.New("foo").Parse(`{{define "listing"}}<html><head><title>File Listing</title><style>
152160
* {
153161
font-family: monospace;
@@ -178,7 +186,7 @@ li {
178186
padding: 0;
179187
}
180188
</style></head><body><ul>
181-
{{ range . }}<li><a href="http://127.0.0.1:1080/files/{{ .ID }}">{{ index .MetaData "filename" }}</a></li>{{ end }}
189+
{{ range .Infos }}<li><a href="{{ $.Conf.Url }}{{ $.Conf.FilesEndpoint }}{{ .ID }}">{{ index .MetaData "filename" }}</a></li>{{ end }}
182190
</ul>
183191
</body>
184192
</html>{{end}}`)
@@ -189,6 +197,8 @@ li {
189197
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
190198
var err error
191199
var fileInfos []os.FileInfo
200+
201+
// todo: here read once, calling GetInfo read another once
192202
if fileInfos, err = ioutil.ReadDir(store.Path); err != nil {
193203
http.Error(w, "", 500)
194204
return
@@ -217,7 +227,11 @@ li {
217227
sort.Slice(infos, func(i, j int) bool {
218228
return infos[i].MetaData["filename"] < infos[j].MetaData["filename"]
219229
})
220-
if err = t.ExecuteTemplate(w, "listing", infos); err != nil {
230+
data := struct {
231+
Infos []tusd.FileInfo
232+
Conf ServerConf
233+
}{infos, conf,}
234+
if err = t.ExecuteTemplate(w, "listing", data); err != nil {
221235
//stderr.Fatalf("Unable to render template: %s", err)
222236
http.Error(w, "", 500)
223237
return

0 commit comments

Comments
 (0)