diff options
author | Christian Pointner <equinox@helsinki.at> | 2016-07-22 14:15:10 (GMT) |
---|---|---|
committer | Christian Pointner <equinox@helsinki.at> | 2016-07-22 14:15:10 (GMT) |
commit | 34d536887eeb88e7b3d407a31332a13bb0bff5f5 (patch) | |
tree | a71af14b00ccbcbcc283a9275a63867d389408cb | |
parent | 458d8f30caca4267bae3733ab3ba1ba55419a14d (diff) |
make uploadWeb part of session store - not finished yet
-rw-r--r-- | src/rhimportd/ctrlWeb.go | 3 | ||||
-rw-r--r-- | src/rhimportd/ctrlWebSocket.go | 13 | ||||
-rw-r--r-- | src/rhimportd/main.go | 9 | ||||
-rw-r--r-- | src/rhimportd/uploadWeb.go | 135 | ||||
-rw-r--r-- | web-static/socket.html | 15 | ||||
-rw-r--r-- | web-static/upload-form.html | 2 |
6 files changed, 23 insertions, 154 deletions
diff --git a/src/rhimportd/ctrlWeb.go b/src/rhimportd/ctrlWeb.go index ae839a7..bd3d776 100644 --- a/src/rhimportd/ctrlWeb.go +++ b/src/rhimportd/ctrlWeb.go @@ -44,14 +44,13 @@ func (self webHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { self.H(self.Config, self.DBChan, self.SessionStoreChan, self.trusted, w, r) } -func StartControlWeb(addr, staticDir string, uploadMaxAge time.Duration, conf *rhimport.Config, db *rddb.DBChan, sessions *rhimport.SessionStoreChan) { +func StartControlWeb(addr, staticDir string, conf *rhimport.Config, db *rddb.DBChan, sessions *rhimport.SessionStoreChan) { http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir(staticDir)))) // http.Handle("/trusted/simple", webHandler{conf, db, sessions, true, webSimpleHandler}) http.Handle("/public/simple", webHandler{conf, db, sessions, false, webSimpleHandler}) http.Handle("/public/socket", webHandler{conf, db, sessions, false, webSocketHandler}) http.Handle("/public/upload", webHandler{conf, db, sessions, false, webUploadHandler}) - go webUploadCleaner(conf, uploadMaxAge) rhl.Println("web-ctrl: listening on", addr) server := &http.Server{Addr: addr, ReadTimeout: 2 * time.Hour, WriteTimeout: 2 * time.Hour} diff --git a/src/rhimportd/ctrlWebSocket.go b/src/rhimportd/ctrlWebSocket.go index 1f04b84..e764085 100644 --- a/src/rhimportd/ctrlWebSocket.go +++ b/src/rhimportd/ctrlWebSocket.go @@ -415,17 +415,8 @@ func webSocketHandler(conf *rhimport.Config, db *rddb.DBChan, sessions *rhimport // rhdl.Printf("Websocket Client %s got: %+v", ws.RemoteAddr(), reqdata) reqchan <- *reqdata case websocket.BinaryMessage: - data, err := ioutil.ReadAll(r) - if err != nil { - if err == io.EOF { - err = io.ErrUnexpectedEOF - } - rhdl.Println("WebSocket Client", ws.RemoteAddr(), "disconnected:", err) - sendWebSocketErrorResponse(ws, http.StatusInternalServerError, err.Error()) - return - } - // rhdl.Printf("WebSocket Client %s: got binary message (%d bytes)", ws.RemoteAddr(), len(data)) - binchan <- data + sendWebSocketErrorResponse(ws, http.StatusBadRequest, "binary messages are not allowed") + io.Copy(ioutil.Discard, r) // consume all the data } } } diff --git a/src/rhimportd/main.go b/src/rhimportd/main.go index 57f8c95..e94476c 100644 --- a/src/rhimportd/main.go +++ b/src/rhimportd/main.go @@ -107,13 +107,6 @@ func main() { localFetchDir := newEnvStringValue("RHIMPORTD_LOCAL_FETCH_DIR", os.TempDir()) flag.Var(localFetchDir, "local-fetch-dir", "base path for local:// urls (environment: RHIMPORTD_LOCAL_FETCH_DIR)") - uploadMaxAge, err := newEnvDurationValue("RHIMPORTD_UPLOAD_MAX_AGE", 30*time.Minute) - if err != nil { - rhl.Println("Error parsing RHIMPORTD_UPLOAD_MAX_AGE from environment:", err) - return - } - flag.Var(uploadMaxAge, "upload-max-age", "maximum age of uploaded files before they get deleted (environment: RHIMPORTD_UPLOAD_MAX_AGE)") - help := flag.Bool("help", false, "show usage") flag.Parse() @@ -149,7 +142,7 @@ func main() { go func() { defer wg.Done() rhl.Println("starting web-ctrl") - StartControlWeb(webAddr.Get().(string), webStaticDir.Get().(string), uploadMaxAge.Get().(time.Duration), conf, db.GetInterface(), sessions.GetInterface()) + StartControlWeb(webAddr.Get().(string), webStaticDir.Get().(string), conf, db.GetInterface(), sessions.GetInterface()) rhl.Println("web-ctrl finished") }() } diff --git a/src/rhimportd/uploadWeb.go b/src/rhimportd/uploadWeb.go index 63d04f4..412df12 100644 --- a/src/rhimportd/uploadWeb.go +++ b/src/rhimportd/uploadWeb.go @@ -26,40 +26,35 @@ package main import ( "bytes" - "code.helsinki.at/rhrd-go/rddb" - "code.helsinki.at/rhrd-go/rhimport" "encoding/json" "fmt" "io" "io/ioutil" "mime/multipart" "net/http" - "os" - "path" - "path/filepath" - "strings" - "time" + + "code.helsinki.at/rhrd-go/rddb" + "code.helsinki.at/rhrd-go/rhimport" ) type webUploadResponseData struct { ResponseCode int `json:"RESPONSE_CODE"` ErrorString string `json:"ERROR_STRING"` - SourceFile string `json:"SOURCE_FILE"` } func webUploadErrorResponse(w http.ResponseWriter, code int, errStr string) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(code) encoder := json.NewEncoder(w) - respdata := webUploadResponseData{code, errStr, ""} + respdata := webUploadResponseData{code, errStr} encoder.Encode(respdata) } -func webUploadResponse(w http.ResponseWriter, file string) { +func webUploadSuccessResponse(w http.ResponseWriter) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) encoder := json.NewEncoder(w) - respdata := webUploadResponseData{http.StatusOK, "success", file} + respdata := webUploadResponseData{http.StatusOK, "success"} encoder.Encode(respdata) } @@ -67,7 +62,7 @@ const ( webUploadMaxRequestSize = (2 << 30) - 1 // 2GB, (2 << 30) overflows int on 32-bit systems therefore we use 2GB - 1 Byte ) -func webUploadParseForm(w http.ResponseWriter, r *http.Request) (username, password, srcfile string, src *multipart.Part, ok bool) { +func webUploadParseForm(w http.ResponseWriter, r *http.Request) (username, sessionid, srcfile string, src *multipart.Part, ok bool) { mpr, err := r.MultipartReader() if err != nil { rhl.Printf("WebUploadHandler: error while parsing multipart-form: %v", err) @@ -86,8 +81,8 @@ func webUploadParseForm(w http.ResponseWriter, r *http.Request) (username, passw switch p.FormName() { case "LOGIN_NAME": dstfield = &username - case "PASSWORD": - dstfield = &password + case "SESSION_ID": + dstfield = &sessionid case "FILENAME": srcfile = p.FileName() src = p @@ -130,7 +125,7 @@ func webUploadHandler(conf *rhimport.Config, db *rddb.DBChan, sessions *rhimport } r.Body = http.MaxBytesReader(w, r.Body, webUploadMaxRequestSize) - username, password, srcfile, src, ok := webUploadParseForm(w, r) + username, sessionid, srcfile, src, ok := webUploadParseForm(w, r) if !ok { return } @@ -138,111 +133,17 @@ func webUploadHandler(conf *rhimport.Config, db *rddb.DBChan, sessions *rhimport webUploadErrorResponse(w, http.StatusBadRequest, "missing field LOGIN_NAME") return } - if password == "" { - webUploadErrorResponse(w, http.StatusBadRequest, "missing field PASSWORD") - return - } - - if authenticated, err := db.CheckPassword(username, password); err != nil { - rhl.Printf("WebUploadHandler: error checking username/password: %v", err) - webUploadErrorResponse(w, http.StatusUnauthorized, err.Error()) - return - } else if !authenticated { - rhl.Printf("WebUploadHandler: invalid username/password") - webUploadErrorResponse(w, http.StatusUnauthorized, "invalid username/password") - return - } - - rhdl.Printf("WebUploadHandler: got request from user '%s', filename='%s'", username, srcfile) - - dstpath, err := ioutil.TempDir(conf.TempDir, "webupload-"+username+"-") - if err != nil { - rhl.Printf("WebUploadHandler: error creating temporary directory: %v", err) - webUploadErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - - dstfile := filepath.Join(dstpath, path.Clean("/"+srcfile)) - dst, err := os.OpenFile(dstfile, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600) - if err != nil { - rhl.Printf("WebUploadHandler: Unable to create file '%s': %v", dstfile, err) - webUploadErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } - defer dst.Close() - - size, err := io.Copy(dst, src) - if err != nil { - rhl.Printf("WebUploadHandler: error storing uploaded file '%s': %v", dstfile, err) - webUploadErrorResponse(w, http.StatusInternalServerError, err.Error()) + if sessionid == "" { + webUploadErrorResponse(w, http.StatusBadRequest, "missing field SESSION_ID") return } - rhl.Printf("WebUploadHandler: stored file '%s' (size: %d Bytes)", dstfile, size) - webUploadResponse(w, "tmp://"+strings.TrimPrefix(dstfile, conf.TempDir)) -} -func webUploadCleanerRun(dir *os.File, conf *rhimport.Config, maxAge time.Duration) { - t := time.NewTicker(1 * time.Minute) - defer t.Stop() - for now := range t.C { - var err error - if _, err = dir.Seek(0, 0); err != nil { - rhl.Printf("webUploadCleaner: reading directory contents failed: %s", err) - return - } + // TODO: get session->attachmentChan from store -> 401 if not found + // TODO: take session -> 403 if already taken - var entries []os.FileInfo - if entries, err = dir.Readdir(0); err != nil { - rhl.Printf("webUploadCleaner: reading directory contents failed: %s", err) - return - } + // TODO: fetch file (src) in chunks and send it to attachmentChan && check for canceled + rhl.Printf("WebUploadHandler: fetching file from '%s' (%v)", srcfile, src) + io.Copy(ioutil.Discard, src) - for _, entry := range entries { - if !strings.HasPrefix(entry.Name(), "webupload-") { - continue - } - - age := now.Sub(entry.ModTime()) - if age <= maxAge { - continue - } - - if err := os.RemoveAll(conf.TempDir + "/" + entry.Name()); err != nil { - rhl.Printf("webUploadCleaner: deleting dir '%s' failed: %v", entry.Name(), err) - continue - } - rhl.Printf("webUploadCleaner: successfully deleted dir '%s', Age: %v", entry.Name(), age) - } - } -} - -func webUploadCleaner(conf *rhimport.Config, maxAge time.Duration) { - first := true - for { - if !first { - time.Sleep(5 * time.Second) - } - first = false - - dir, err := os.Open(conf.TempDir) - if err != nil { - rhl.Printf("webUploadCleaner: %s", err) - continue - } - if i, err := dir.Stat(); err != nil { - rhl.Printf("webUploadCleaner: %s", err) - dir.Close() - continue - } else { - if !i.IsDir() { - rhl.Printf("webUploadCleaner: %s is not a directory", conf.TempDir) - dir.Close() - continue - } - } - rhdl.Printf("webUploadCleaner: running with max age: %v", maxAge) - webUploadCleanerRun(dir, conf, maxAge) - rhdl.Printf("webUploadCleanerRun: returned - restarting in 5 sec...") - dir.Close() - } + webUploadSuccessResponse(w) } diff --git a/web-static/socket.html b/web-static/socket.html index 206ab44..9b118ac 100644 --- a/web-static/socket.html +++ b/web-static/socket.html @@ -74,10 +74,6 @@ } this.sock.onopen = this.sock_onopen.bind(this); - this.sendbinmsg = function(data) { - this.sock.send(data); - } - this.cancel = function() { this.sock.send(JSON.stringify({COMMAND: "cancel"})); } @@ -104,14 +100,6 @@ s = new Session(req); } - function sendbinmsg() { - var byteArray = new Uint8Array(40*1024); - for (var x = 0; x < byteArray.length; x++){ - byteArray[x] = x - } - s.sendbinmsg(new Blob([byteArray], {type: "application/octet-stream"})); - } - function cancel() { s.cancel(); } @@ -124,7 +112,6 @@ function buttonsIdle() { $('#buttonrun').removeAttr('disabled') $('#buttonreconnect').removeAttr('disabled') - $('#buttonbinmsg').attr('disabled','disabled') $('#buttondetach').attr('disabled','disabled') $('#buttoncancel').attr('disabled','disabled') } @@ -132,7 +119,6 @@ function buttonsRunning() { $('#buttonrun').attr('disabled','disabled') $('#buttonreconnect').attr('disabled','disabled') - $('#buttonbinmsg').removeAttr('disabled') $('#buttondetach').removeAttr('disabled') $('#buttoncancel').removeAttr('disabled') } @@ -164,7 +150,6 @@ <input id="source" type="text" size="30" value="fake://10000"> <input id="refid" type="text" size="15" value="test-reference-id"> <button id="buttonrun" onclick="run()">start</button> - <button id="buttonbinmsg" onclick="sendbinmsg()">send binary message</button> <button id="buttondetach" onclick="detach()">detach</button> <input id="sessionid" type="text" size="45"> <button id="buttonreconnect" onclick="reconnect()">reconnect</button> diff --git a/web-static/upload-form.html b/web-static/upload-form.html index 8910a37..c38037e 100644 --- a/web-static/upload-form.html +++ b/web-static/upload-form.html @@ -19,7 +19,7 @@ <form class="form-upload" method="post" action="/public/upload" enctype="multipart/form-data"> <table> <tr><td class="label">Username</td><td><input type="text" name="LOGIN_NAME" size="20" value="heslinki" /></td></tr> - <tr><td class="label">Token</td><td><input type="password" name="PASSWORD" size="20" /></td></tr> + <tr><td class="label">Session</td><td><input type="password" name="SESSION_ID" size="20" /></td></tr> <tr><td class="label">File</td><td><input type="file" name="FILENAME" /></td></tr> <tr><td> </td><td><input type="submit" name="submit" value="Submit"></td></tr> </table> |