-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
109 lines (93 loc) · 2.06 KB
/
main.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
package main
import (
"flag"
"fmt"
"html/template"
"io"
"io/ioutil"
"log"
"net/http"
"os"
"path"
"path/filepath"
"eagain.net/go/adhoc-httpd-upload/internal"
)
var (
host = flag.String("host", "0.0.0.0", "IP address to bind to")
port = flag.Int("port", 8000, "TCP port to listen on")
)
func usage() {
fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
fmt.Fprintf(os.Stderr, " %s [OPTS] DIR\n", os.Args[0])
flag.PrintDefaults()
}
var page = template.Must(template.New("top").Parse(`
<html>
<head>
<title>Ad hoc file upload</title>
</head>
<body>
<p>{{.}}</p>
<p>Upload a file:</p>
<form action="/" method="POST" enctype="multipart/form-data">
<input type="file" name="f">
<input type="submit" value="Upload">
</form>
</body>
</html>
`))
type uploadDir string
func (dir uploadDir) ServeHTTP(w http.ResponseWriter, req *http.Request) {
if req.Method != "POST" {
page.Execute(w, nil)
return
}
f, hdr, err := req.FormFile("f")
if err != nil {
http.Error(w, "Need a file to upload.", 500)
return
}
defer f.Close()
if !internal.IsSafeName(hdr.Filename) {
http.Error(w, "Unsafe filename.", 400)
return
}
tmp, err := ioutil.TempFile(string(dir), ".tmp-")
if err != nil {
http.Error(w, "Cannot create temp file.", 500)
return
}
defer os.Remove(tmp.Name())
defer tmp.Close()
_, err = io.Copy(tmp, f)
if err != nil {
http.Error(w, "Cannot write to temp file.", 500)
return
}
err = os.Link(tmp.Name(), filepath.Join(string(dir), hdr.Filename))
if err != nil {
http.Error(w, "Cannot save file.", 500)
return
}
log.Printf("Saved %q", hdr.Filename)
page.Execute(w, "Thanks!")
}
func main() {
prog := path.Base(os.Args[0])
log.SetFlags(0)
log.SetPrefix(prog + ": ")
flag.Usage = usage
flag.Parse()
if flag.NArg() != 1 {
usage()
os.Exit(1)
}
dir := flag.Arg(0)
log.Printf("Receiving uploads to %q at http://%s:%d/", dir, *host, *port)
http.Handle("/", uploadDir(dir))
addr := fmt.Sprintf("%s:%d", *host, *port)
err := http.ListenAndServe(addr, nil)
if err != nil {
log.Fatal(err)
}
}