diff options
-rw-r--r-- | src/ninjacloud.go | 164 |
1 files changed, 157 insertions, 7 deletions
diff --git a/src/ninjacloud.go b/src/ninjacloud.go index 57e939a..9ec2962 100644 --- a/src/ninjacloud.go +++ b/src/ninjacloud.go | |||
@@ -2,14 +2,12 @@ package main | |||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "encoding/json" | 4 | "encoding/json" |
5 | //"errors" | ||
6 | "flag" | 5 | "flag" |
6 | "io" | ||
7 | "io/ioutil" | 7 | "io/ioutil" |
8 | "log" | 8 | "log" |
9 | "net/http" | 9 | "net/http" |
10 | "os" | 10 | "os" |
11 | //"path" | ||
12 | "io" | ||
13 | "path/filepath" | 11 | "path/filepath" |
14 | ) | 12 | ) |
15 | 13 | ||
@@ -29,7 +27,8 @@ const statusPath = "/cloudstatus" | |||
29 | const filePathLen = len(filePath) | 27 | const filePathLen = len(filePath) |
30 | const dirPathLen = len(dirPath) | 28 | const dirPathLen = len(dirPath) |
31 | const webPathLen = len(webPath) | 29 | const webPathLen = len(webPath) |
32 | const statusPathLen = len(statusPath) | 30 | |
31 | //const statusPathLen = len(statusPath) | ||
33 | 32 | ||
34 | //////// FILESYSTEM | 33 | //////// FILESYSTEM |
35 | 34 | ||
@@ -41,6 +40,10 @@ func exist(path string) bool { | |||
41 | return false | 40 | return false |
42 | } | 41 | } |
43 | 42 | ||
43 | func isInRoot(path string) bool { | ||
44 | return filepath.HasPrefix(path, rootFlag) | ||
45 | } | ||
46 | |||
44 | //// Files | 47 | //// Files |
45 | 48 | ||
46 | func writeFile(path string, content []byte, overwrite bool) (err error) { | 49 | func writeFile(path string, content []byte, overwrite bool) (err error) { |
@@ -49,6 +52,11 @@ func writeFile(path string, content []byte, overwrite bool) (err error) { | |||
49 | err = os.ErrExist | 52 | err = os.ErrExist |
50 | return | 53 | return |
51 | } | 54 | } |
55 | } else { | ||
56 | if !exist(path) { | ||
57 | err = os.ErrNotExist | ||
58 | return | ||
59 | } | ||
52 | } | 60 | } |
53 | err = ioutil.WriteFile(path, content, 0600) | 61 | err = ioutil.WriteFile(path, content, 0600) |
54 | return | 62 | return |
@@ -157,22 +165,113 @@ func copyDir(source string, dest string) (err error) { | |||
157 | func fileHandler(w http.ResponseWriter, r *http.Request) { | 165 | func fileHandler(w http.ResponseWriter, r *http.Request) { |
158 | p := r.URL.Path[filePathLen:] | 166 | p := r.URL.Path[filePathLen:] |
159 | filepath.Clean(p) | 167 | filepath.Clean(p) |
168 | if !isInRoot(p) { | ||
169 | w.WriteHeader(http.StatusForbidden) | ||
170 | return | ||
171 | } | ||
160 | 172 | ||
161 | switch r.Method { | 173 | switch r.Method { |
162 | case "POST": | 174 | case "POST": |
163 | // Create a new file | 175 | // Create a new file |
176 | content, err := ioutil.ReadAll(r.Body) | ||
177 | if err != nil { | ||
178 | w.WriteHeader(http.StatusInternalServerError) | ||
179 | return | ||
180 | } | ||
181 | err = writeFile(p, *&content, false) | ||
182 | if err == os.ErrExist { | ||
183 | w.WriteHeader(http.StatusBadRequest) | ||
184 | } else if err != nil { | ||
185 | w.WriteHeader(http.StatusInternalServerError) | ||
186 | return | ||
187 | } | ||
188 | w.WriteHeader(http.StatusCreated) | ||
189 | return | ||
164 | case "PUT": | 190 | case "PUT": |
165 | if r.Header.Get("sourceURI") == "" { | 191 | source := r.Header.Get("sourceURI") |
192 | if source == "" { | ||
166 | // Update an existing file (save over existing file) | 193 | // Update an existing file (save over existing file) |
194 | content, err := ioutil.ReadAll(r.Body) | ||
195 | if err != nil { | ||
196 | w.WriteHeader(http.StatusInternalServerError) | ||
197 | return | ||
198 | } | ||
199 | err = writeFile(p, *&content, true) | ||
200 | if err == os.ErrNotExist { | ||
201 | w.WriteHeader(http.StatusNotFound) | ||
202 | } else if err != nil { | ||
203 | w.WriteHeader(http.StatusInternalServerError) | ||
204 | return | ||
205 | } | ||
206 | w.WriteHeader(http.StatusNoContent) | ||
207 | return | ||
167 | } else { | 208 | } else { |
168 | // Copy, Move of an existing file | 209 | // Copy, Move of an existing file |
210 | if r.Header.Get("overwrite-destination") == "true" { | ||
211 | err := removeFile(p) | ||
212 | if err == os.ErrNotExist { | ||
213 | w.WriteHeader(http.StatusNotFound) | ||
214 | return | ||
215 | } else if err != nil { | ||
216 | w.WriteHeader(http.StatusInternalServerError) | ||
217 | return | ||
218 | } | ||
219 | } | ||
220 | if r.Header.Get("delete-source") == "true" { | ||
221 | err := moveFile(source, p) | ||
222 | if err == os.ErrNotExist { | ||
223 | w.WriteHeader(http.StatusNotFound) | ||
224 | return | ||
225 | } else if err != nil { | ||
226 | w.WriteHeader(http.StatusInternalServerError) | ||
227 | return | ||
228 | } | ||
229 | } else { | ||
230 | err := copyFile(source, p) | ||
231 | if err == os.ErrNotExist { | ||
232 | w.WriteHeader(http.StatusNotFound) | ||
233 | return | ||
234 | } else if err != nil { | ||
235 | w.WriteHeader(http.StatusInternalServerError) | ||
236 | return | ||
237 | } | ||
238 | } | ||
239 | w.WriteHeader(http.StatusNoContent) | ||
240 | return | ||
169 | } | 241 | } |
170 | case "DELETE": | 242 | case "DELETE": |
171 | // Delete an existing file | 243 | // Delete an existing file |
244 | err := removeFile(p) | ||
245 | if err == os.ErrNotExist { | ||
246 | w.WriteHeader(http.StatusNotFound) | ||
247 | return | ||
248 | } else if err != nil { | ||
249 | w.WriteHeader(http.StatusInternalServerError) | ||
250 | return | ||
251 | } | ||
252 | w.WriteHeader(http.StatusNoContent) | ||
253 | return | ||
172 | case "GET": | 254 | case "GET": |
173 | // Read an existing file | 255 | // Read an existing file |
256 | modifiedSince := r.Header.Get("If-modified-since") | ||
257 | if modifiedSince != "" { | ||
258 | // TODO | ||
259 | var test os.FileInfo | ||
260 | test.ModTime() | ||
261 | } else if r.Header.Get("check-existence-only") == "true" { | ||
262 | if exist(p) { | ||
263 | w.WriteHeader(http.StatusNoContent) | ||
264 | return | ||
265 | } else { | ||
266 | w.WriteHeader(http.StatusNotFound) | ||
267 | return | ||
268 | } | ||
269 | } else if r.Header.Get("get-file-info") != "" { | ||
270 | // TODO | ||
271 | } else { | ||
272 | // TODO | ||
273 | } | ||
174 | } | 274 | } |
175 | |||
176 | } | 275 | } |
177 | 276 | ||
178 | //// Directory APIs | 277 | //// Directory APIs |
@@ -180,18 +279,69 @@ func fileHandler(w http.ResponseWriter, r *http.Request) { | |||
180 | func dirHandler(w http.ResponseWriter, r *http.Request) { | 279 | func dirHandler(w http.ResponseWriter, r *http.Request) { |
181 | p := r.URL.Path[dirPathLen:] | 280 | p := r.URL.Path[dirPathLen:] |
182 | filepath.Clean(p) | 281 | filepath.Clean(p) |
282 | if !isInRoot(p) { | ||
283 | w.WriteHeader(http.StatusForbidden) | ||
284 | return | ||
285 | } | ||
183 | 286 | ||
184 | switch r.Method { | 287 | switch r.Method { |
185 | case "POST": | 288 | case "POST": |
186 | // Create a new directory | 289 | // Create a new directory |
290 | err := createDir(p) | ||
291 | if err != nil { | ||
292 | w.WriteHeader(http.StatusBadRequest) | ||
293 | return | ||
294 | } | ||
295 | w.WriteHeader(http.StatusCreated) | ||
296 | return | ||
187 | case "DELETE": | 297 | case "DELETE": |
188 | // Delete an existing directory | 298 | // Delete an existing directory |
299 | err := removeDir(p) | ||
300 | if err == os.ErrNotExist { | ||
301 | w.WriteHeader(http.StatusNotFound) | ||
302 | return | ||
303 | } else if err != nil { | ||
304 | w.WriteHeader(http.StatusInternalServerError) | ||
305 | return | ||
306 | } | ||
307 | w.WriteHeader(http.StatusNoContent) | ||
308 | return | ||
189 | case "GET": | 309 | case "GET": |
190 | // List the contents of an existing directory | 310 | // List the contents of an existing directory |
311 | // TODO | ||
191 | case "PUT": | 312 | case "PUT": |
192 | // Copy, Move of an existing directory | 313 | // Copy, Move of an existing directory |
314 | source := r.Header.Get("sourceURI") | ||
315 | if exist(p) { | ||
316 | w.WriteHeader(http.StatusBadRequest) | ||
317 | return | ||
318 | } | ||
319 | operation := r.Header.Get("operation") | ||
320 | if operation == "move" { | ||
321 | err := moveDir(source, p) | ||
322 | if err == os.ErrNotExist { | ||