diff --git a/modules/api_rest/api_rest.go b/modules/api_rest/api_rest.go index 11da44aa..444e422d 100644 --- a/modules/api_rest/api_rest.go +++ b/modules/api_rest/api_rest.go @@ -191,6 +191,7 @@ func (mod *RestAPI) Configure() error { router.HandleFunc("/api/session/started-at", mod.sessionRoute) router.HandleFunc("/api/session/wifi", mod.sessionRoute) router.HandleFunc("/api/session/wifi/{mac}", mod.sessionRoute) + router.HandleFunc("/api/file", mod.fileRoute) mod.server.Handler = router diff --git a/modules/api_rest/api_rest_controller.go b/modules/api_rest/api_rest_controller.go index 2e03bfc8..0d7f61f0 100644 --- a/modules/api_rest/api_rest_controller.go +++ b/modules/api_rest/api_rest_controller.go @@ -3,7 +3,11 @@ package api_rest import ( "crypto/subtle" "encoding/json" + "fmt" + "io" + "io/ioutil" "net/http" + "os" "strconv" "strings" @@ -258,6 +262,44 @@ func (mod *RestAPI) sessionRoute(w http.ResponseWriter, r *http.Request) { } } +func (mod *RestAPI) readFile(fileName string, w http.ResponseWriter, r *http.Request) { + fp, err := os.Open(fileName) + if err != nil { + msg := fmt.Sprintf("could not open %s for reading: %s", fileName, err) + mod.Debug(msg) + http.Error(w, msg, 404) + return + } + defer fp.Close() + + w.Header().Set("Content-type", "application/octet-stream") + + io.Copy(w, fp) +} + +func (mod *RestAPI) writeFile(fileName string, w http.ResponseWriter, r *http.Request) { + data, err := ioutil.ReadAll(r.Body) + if err != nil { + msg := fmt.Sprintf("invalid file upload: %s", err) + mod.Warning(msg) + http.Error(w, msg, 404) + return + } + + err = ioutil.WriteFile(fileName, data, 0666) + if err != nil { + msg := fmt.Sprintf("can't write to %s: %s", fileName, err) + mod.Warning(msg) + http.Error(w, msg, 404) + return + } + + mod.toJSON(w, APIResponse{ + Success: true, + Message: fmt.Sprintf("%s created", fileName), + }) +} + func (mod *RestAPI) eventsRoute(w http.ResponseWriter, r *http.Request) { mod.setSecurityHeaders(w) @@ -274,3 +316,22 @@ func (mod *RestAPI) eventsRoute(w http.ResponseWriter, r *http.Request) { http.Error(w, "Bad Request", 400) } } + +func (mod *RestAPI) fileRoute(w http.ResponseWriter, r *http.Request) { + mod.setSecurityHeaders(w) + + if !mod.checkAuth(r) { + mod.setAuthFailed(w, r) + return + } + + fileName := r.URL.Query().Get("name") + + if fileName != "" && r.Method == "GET" { + mod.readFile(fileName, w, r) + } else if fileName != "" && r.Method == "POST" { + mod.writeFile(fileName, w, r) + } else { + http.Error(w, "Bad Request", 400) + } +}