source: code/trunk/partage.go@ 10

Last change on this file since 10 was 10, checked in by dev, 4 years ago

Remove useless call to parseForm()

File size: 2.8 KB
Line 
1package main
2
3import (
4 "fmt"
5 "io"
6 "io/ioutil"
7 "net/http"
8 "os"
9 "path"
10 "path/filepath"
11)
12
13var conf struct {
14 bind string
15 filepath string
16 rootdir string
17 baseuri string
18 filectx string
19 maxsize int64
20}
21
22func contenttype(f *os.File) string {
23 buffer := make([]byte, 512)
24
25 _, err := f.Read(buffer)
26 if err != nil {
27 return ""
28 }
29
30 mime := http.DetectContentType(buffer)
31
32 return mime
33}
34
35func writefile(f *os.File, s io.ReadCloser, contentlength int64) int64 {
36 buffer := make([]byte, 4096)
37 eof := false
38 sz := int64(0)
39
40 defer f.Sync()
41
42 for !eof {
43 n, err := s.Read(buffer)
44 if err != nil && err != io.EOF {
45 fmt.Println(err)
46 return -1
47 } else if err == io.EOF {
48 eof = true
49 }
50
51 /* ensure we don't write more than expected */
52 r := int64(n)
53 if sz+r > contentlength {
54 r = contentlength - sz
55 eof = true
56 }
57
58 _, err = f.Write(buffer[:r])
59 if err != nil {
60 fmt.Println(err)
61 }
62 sz += r
63 }
64
65 return sz
66}
67
68func servefile(f *os.File, w http.ResponseWriter) {
69 buffer := make([]byte, 4096)
70
71 mime := contenttype(f)
72 w.Header().Set("Content-Type", mime)
73
74 f.Seek(0, 0)
75 for {
76 n, err := f.Read(buffer)
77
78 if err != nil {
79 if err == io.EOF {
80 if _, err := w.Write(buffer[:n]); err != nil {
81 fmt.Println(err)
82 }
83 break
84 }
85 fmt.Println(err)
86 return
87 }
88
89 if _, err = w.Write(buffer[:n]); err != nil {
90 fmt.Println(err)
91 }
92 }
93}
94
95func uploaderPut(w http.ResponseWriter, r *http.Request) {
96 // Max 15 Gb uploads
97 if r.ContentLength > conf.maxsize {
98 w.WriteHeader(http.StatusRequestEntityTooLarge)
99 w.Write([]byte("File is too big"))
100 }
101
102 tmp, _ := ioutil.TempFile(conf.filepath, "*"+path.Ext(r.URL.Path))
103 f, err := os.Create(tmp.Name())
104 if err != nil {
105 fmt.Println(err)
106 return
107 }
108 defer f.Close()
109
110 if writefile(f, r.Body, r.ContentLength) < 0 {
111 w.WriteHeader(http.StatusInternalServerError)
112 return
113 }
114
115 resp := conf.baseuri + conf.filectx + filepath.Base(tmp.Name()) + "\r\n"
116 w.Write([]byte(resp))
117}
118
119func uploaderGet(w http.ResponseWriter, r *http.Request) {
120 // r.URL.Path is sanitized regarding "." and ".."
121 filename := r.URL.Path
122 if r.URL.Path == "/" {
123 filename = "/index.html"
124 }
125
126 f, err := os.Open(conf.rootdir + filename)
127 if err != nil {
128 w.WriteHeader(http.StatusNotFound)
129 fmt.Println(err)
130 return
131 }
132 defer f.Close()
133
134 servefile(f, w)
135}
136
137func uploader(w http.ResponseWriter, r *http.Request) {
138 switch r.Method {
139 case "PUT":
140 uploaderPut(w, r)
141 case "GET":
142 uploaderGet(w, r)
143 }
144}
145
146func main() {
147 conf.bind = "0.0.0.0:8080"
148 conf.maxsize = 28 * 1024 * 1024
149 conf.filepath = "/tmp"
150 conf.rootdir = "./static"
151 conf.baseuri = "http://192.168.0.3:8080"
152 conf.filectx = "/f/"
153
154 http.HandleFunc("/", uploader)
155 http.Handle(conf.filectx, http.StripPrefix(conf.filectx, http.FileServer(http.Dir(conf.filepath))))
156 http.ListenAndServe("0.0.0.0:8080", nil)
157}
Note: See TracBrowser for help on using the repository browser.