Răsfoiți Sursa

Added work in progress dirserv

tobychui 2 ani în urmă
părinte
comite
7c5a0df705
6 a modificat fișierele cu 185 adăugiri și 175 ștergeri
  1. 23 0
      error.go
  2. 22 1
      main.router.go
  3. 0 171
      mod/common.go
  4. 64 0
      mod/fileservers/servers/dirserv/dirserv.go
  5. 24 3
      network.go
  6. 52 0
      web/SystemAO/internalServerError.html

+ 23 - 0
error.go

@@ -35,6 +35,29 @@ func errorHandleNotFound(w http.ResponseWriter, r *http.Request) {
 
 }
 
+func errorHandleInternalServerError(w http.ResponseWriter, r *http.Request) {
+	internalServerErrPage := "./web/SystemAO/internalServerError.html"
+	if fs.FileExists(internalServerErrPage) {
+
+		templateBytes, err := ioutil.ReadFile(internalServerErrPage)
+		template := string(templateBytes)
+		if err != nil {
+			http.NotFound(w, r)
+		} else {
+			//Replace the request URL inside the page
+			template = strings.ReplaceAll(template, "{{request_url}}", r.RequestURI)
+			rel := getRootEscapeFromCurrentPath(r.RequestURI)
+			template = strings.ReplaceAll(template, "{{root_escape}}", rel)
+			w.WriteHeader(http.StatusInternalServerError)
+			w.Write([]byte(template))
+		}
+	} else {
+		w.WriteHeader(http.StatusInternalServerError)
+		w.Write([]byte("500 - Internal Server Error"))
+	}
+
+}
+
 func errorHandlePermissionDenied(w http.ResponseWriter, r *http.Request) {
 	unauthorizedPage := "./web/SystemAO/unauthorized.html"
 	if fs.FileExists(unauthorizedPage) {

+ 22 - 1
main.router.go

@@ -65,12 +65,33 @@ func mrouter(h http.Handler) http.Handler {
 			h.ServeHTTP(w, r)
 
 		} else if len(r.URL.Path) >= len("/webdav") && r.URL.Path[:7] == "/webdav" {
-			//WebDAV special handler
+			//WebDAV sub-router
+			if WebDAVManager == nil {
+				errorHandleInternalServerError(w, r)
+				return
+			}
 			WebDAVManager.HandleRequest(w, r)
 		} else if len(r.URL.Path) >= len("/share") && r.URL.Path[:6] == "/share" {
+			//Share Manager sub-router
+			if shareManager == nil {
+				errorHandleInternalServerError(w, r)
+				return
+			}
 			shareManager.HandleShareAccess(w, r)
 		} else if len(r.URL.Path) >= len("/api/remote") && r.URL.Path[:11] == "/api/remote" {
+			//Serverless sub-router
+			if AGIGateway == nil {
+				errorHandleInternalServerError(w, r)
+				return
+			}
 			AGIGateway.ExtAPIHandler(w, r)
+		} else if len(r.URL.Path) >= len("/fileview") && r.URL.Path[:9] == "/fileview" {
+			//File server sub-router
+			if DirListManager == nil {
+				errorHandleInternalServerError(w, r)
+				return
+			}
+			DirListManager.ServerWebFileRequest(w, r)
 		} else if r.URL.Path == "/" && authAgent.CheckAuth(r) {
 			//Use logged in and request the index. Serve the user's interface module
 			w.Header().Set("Cache-Control", "no-cache, no-store, no-transform, must-revalidate, private, max-age=0")

+ 0 - 171
mod/common.go

@@ -1,171 +0,0 @@
-package main
-
-import (
-	"bufio"
-	"encoding/base64"
-	"errors"
-	"io/ioutil"
-	"log"
-	"net/http"
-	"os"
-	"time"
-)
-
-/*
-	SYSTEM COMMON FUNCTIONS
-
-	This is a system function that put those we usually use function but not belongs to
-	any module / system.
-
-	E.g. fileExists / IsDir etc
-
-*/
-
-/*
-	Basic Response Functions
-
-	Send response with ease
-*/
-//Send text response with given w and message as string
-func sendTextResponse(w http.ResponseWriter, msg string) {
-	w.Write([]byte(msg))
-}
-
-//Send JSON response, with an extra json header
-func sendJSONResponse(w http.ResponseWriter, json string) {
-	w.Header().Set("Content-Type", "application/json")
-	w.Write([]byte(json))
-}
-
-func sendErrorResponse(w http.ResponseWriter, errMsg string) {
-	w.Header().Set("Content-Type", "application/json")
-	w.Write([]byte("{\"error\":\"" + errMsg + "\"}"))
-}
-
-func sendOK(w http.ResponseWriter) {
-	w.Header().Set("Content-Type", "application/json")
-	w.Write([]byte("\"OK\""))
-}
-
-/*
-	The paramter move function (mv)
-
-	You can find similar things in the PHP version of ArOZ Online Beta. You need to pass in
-	r (HTTP Request Object)
-	getParamter (string, aka $_GET['This string])
-
-	Will return
-	Paramter string (if any)
-	Error (if error)
-
-*/
-func mv(r *http.Request, getParamter string, postMode bool) (string, error) {
-	if postMode == false {
-		//Access the paramter via GET
-		keys, ok := r.URL.Query()[getParamter]
-
-		if !ok || len(keys[0]) < 1 {
-			//log.Println("Url Param " + getParamter +" is missing")
-			return "", errors.New("GET paramter " + getParamter + " not found or it is empty")
-		}
-
-		// Query()["key"] will return an array of items,
-		// we only want the single item.
-		key := keys[0]
-		return string(key), nil
-	} else {
-		//Access the parameter via POST
-		r.ParseForm()
-		x := r.Form.Get(getParamter)
-		if len(x) == 0 || x == "" {
-			return "", errors.New("POST paramter " + getParamter + " not found or it is empty")
-		}
-		return string(x), nil
-	}
-
-}
-
-func stringInSlice(a string, list []string) bool {
-	for _, b := range list {
-		if b == a {
-			return true
-		}
-	}
-	return false
-}
-
-func fileExists(filename string) bool {
-	_, err := os.Stat(filename)
-	if os.IsNotExist(err) {
-		return false
-	}
-	return true
-}
-
-func isDir(path string) bool {
-	if fileExists(path) == false {
-		return false
-	}
-	fi, err := os.Stat(path)
-	if err != nil {
-		log.Fatal(err)
-		return false
-	}
-	switch mode := fi.Mode(); {
-	case mode.IsDir():
-		return true
-	case mode.IsRegular():
-		return false
-	}
-	return false
-}
-
-func inArray(arr []string, str string) bool {
-	for _, a := range arr {
-		if a == str {
-			return true
-		}
-	}
-	return false
-}
-
-func timeToString(targetTime time.Time) string {
-	return targetTime.Format("2006-01-02 15:04:05")
-}
-
-func loadImageAsBase64(filepath string) (string, error) {
-	if !fileExists(filepath) {
-		return "", errors.New("File not exists")
-	}
-	f, _ := os.Open(filepath)
-	reader := bufio.NewReader(f)
-	content, _ := ioutil.ReadAll(reader)
-	encoded := base64.StdEncoding.EncodeToString(content)
-	return string(encoded), nil
-}
-
-func pushToSliceIfNotExist(slice []string, newItem string) []string {
-	itemExists := false
-	for _, item := range slice {
-		if item == newItem {
-			itemExists = true
-		}
-	}
-
-	if !itemExists {
-		slice = append(slice, newItem)
-	}
-
-	return slice
-}
-
-func removeFromSliceIfExists(slice []string, target string) []string {
-	newSlice := []string{}
-	for _, item := range slice {
-		if item != target {
-			newSlice = append(newSlice, item)
-		}
-	}
-
-	return newSlice
-}

+ 64 - 0
mod/fileservers/servers/dirserv/dirserv.go

@@ -0,0 +1,64 @@
+package dirserv
+
+import (
+	"net/http"
+
+	"imuslab.com/arozos/mod/database"
+	"imuslab.com/arozos/mod/fileservers"
+	"imuslab.com/arozos/mod/user"
+)
+
+/*
+	dirserv.go
+
+	This module help serve the virtual file system in apache like directory listing interface
+	Suitable for legacy web browser
+*/
+
+type Option struct {
+	Sysdb *database.Database
+}
+
+type Manager struct {
+	enabled bool
+	option  *Option
+}
+
+//Create a new web directory server
+func NewDirectoryServer(option *Option) *Manager {
+	//Create a table to store which user enabled dirlisting on their own root
+	option.Sysdb.NewTable("dirserv")
+
+	defaultEnable := false
+	if option.Sysdb.KeyExists("dirserv", "enabled") {
+		option.Sysdb.Read("dirserv", "enabled", &defaultEnable)
+	}
+
+	return &Manager{
+		enabled: defaultEnable,
+		option:  option,
+	}
+}
+
+func (m *Manager) DirServerEnabled() bool {
+	return m.enabled
+}
+
+func (m *Manager) Toggle(enabled bool) error {
+	m.enabled = !m.enabled
+	return nil
+}
+
+func (m *Manager) ListEndpoints(userinfo *user.User) []*fileservers.Endpoint {
+	results := []*fileservers.Endpoint{}
+
+	return results
+}
+
+/*
+	Router request handler
+*/
+
+func (m *Manager) ServerWebFileRequest(w http.ResponseWriter, r *http.Request) {
+
+}

+ 24 - 3
network.go

@@ -7,6 +7,7 @@ import (
 	"strings"
 
 	"imuslab.com/arozos/mod/fileservers"
+	"imuslab.com/arozos/mod/fileservers/servers/dirserv"
 	"imuslab.com/arozos/mod/fileservers/servers/ftpserv"
 	"imuslab.com/arozos/mod/fileservers/servers/sftpserv"
 	"imuslab.com/arozos/mod/fileservers/servers/webdavserv"
@@ -29,9 +30,10 @@ var (
 	WebSocketRouter *websocket.Router
 
 	//File Server Managers
-	FTPManager    *ftpserv.Manager
-	WebDAVManager *webdavserv.Manager
-	SFTPManager   *sftpserv.Manager
+	FTPManager     *ftpserv.Manager
+	WebDAVManager  *webdavserv.Manager
+	SFTPManager    *sftpserv.Manager
+	DirListManager *dirserv.Manager
 )
 
 func NetworkServiceInit() {
@@ -307,6 +309,10 @@ func FileServerInit() {
 		Sysdb:       sysdb,
 	})
 
+	DirListManager = dirserv.NewDirectoryServer(&dirserv.Option{
+		Sysdb: sysdb,
+	})
+
 	//Register Endpoints
 	//WebDAV
 	http.HandleFunc("/system/network/webdav/list", WebDAVManager.HandleConnectionList)
@@ -373,6 +379,21 @@ func FileServerInit() {
 		GetEndpoints:      FTPManager.FTPGetEndpoints,
 	})
 
+	networkFileServerDaemon = append(networkFileServerDaemon, &fileservers.Server{
+		ID:                "dirserv",
+		Name:              "Directory Server",
+		Desc:              "List direcotires with basic HTML",
+		IconPath:          "img/system/network-folder-blue.svg",
+		DefaultPorts:      []int{},
+		Ports:             []int{},
+		ForwardPortIfUpnp: false,
+		ConnInstrPage:     "SystemAO/disk/instr/dirserv.html",
+		ConfigPage:        "SystemAO/disk/dirserv.html",
+		EnableCheck:       DirListManager.DirServerEnabled,
+		ToggleFunc:        DirListManager.Toggle,
+		GetEndpoints:      DirListManager.ListEndpoints,
+	})
+
 	router.HandleFunc("/system/network/server/list", NetworkHandleGetFileServerServiceList)
 	router.HandleFunc("/system/network/server/endpoints", NetworkHandleGetFileServerEndpoints)
 	router.HandleFunc("/system/network/server/status", NetworkHandleGetFileServerStatus)

+ 52 - 0
web/SystemAO/internalServerError.html

@@ -0,0 +1,52 @@
+<html>
+    <head>
+        <meta charset="UTF-8">
+        <meta name="viewport" content="width=device-width, initial-scale=1.0 user-scalable=no">
+        <link rel="stylesheet" href="{{root_escape}}script/semantic/semantic.min.css">
+        <script type="text/javascript" src="{{root_escape}}script/jquery.min.js"></script>
+        <script type="text/javascript" src="{{root_escape}}script/semantic/semantic.min.js"></script>
+        <title>Internal Server Error</title>
+        <style>
+            #msg{
+                position: absolute;
+                top: calc(50% - 150px);
+                left: calc(50% - 250px);
+                width: 500px;
+                height: 300px;
+                text-align: center;
+            }
+
+            #footer{
+                position: fixed;
+                padding: 2em;
+                padding-left: 5em;
+                padding-right: 5em;
+                bottom: 0px;
+                left: 0px;
+                width: 100%;
+            }   
+
+            small{
+                word-break: break-word;
+            }
+        </style>
+    </head>
+    <body>
+        <div id="msg">
+            <h1 style="font-size: 6em; margin-bottom: 0px;">500</h1>
+            <div>
+                <h3 class="">Internal Server Error</h3>
+                <div class="ui divider"></div>
+                <p>Unable to serve the requested page due to some unknown backend error. <br><a href="{{root_escape}}">Back</a></p>
+                <div class="ui divider"></div>
+                <div style="text-align: left;">
+                    <small>Request time: <span id="reqtime"></span></small><br>
+                    <small id="reqURLDisplay">Request URI: {{request_url}}</small>
+                </div>
+            </div>
+        </div>
+        <script>
+            $("#reqtime").text(new Date().toLocaleString(undefined, {year: 'numeric', month: '2-digit', day: '2-digit', weekday:"long", hour: '2-digit', hour12: false, minute:'2-digit', second:'2-digit'}));
+        </script>
+    </body>
+</html>