From 34d536887eeb88e7b3d407a31332a13bb0bff5f5 Mon Sep 17 00:00:00 2001
From: Christian Pointner <equinox@helsinki.at>
Date: Fri, 22 Jul 2016 16:15:10 +0200
Subject: make uploadWeb part of session store - not finished yet


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>&nbsp;</td><td><input type="submit" name="submit" value="Submit"></td></tr>
         </table>
-- 
cgit v0.10.2