diff --git a/Makefile.example b/Makefile.example new file mode 100644 index 0000000000000000000000000000000000000000..c9d8453ecd167bfc2ce8bad811a1ab3a110fb302 --- /dev/null +++ b/Makefile.example @@ -0,0 +1,72 @@ +############################################################################################# +############################################################################################# +## +## PROJECT-DEFINITIONS +## +############################################################################################# +############################################################################################# + +COMPONENT_NAME := Monster + +############################################################################################# +############################################################################################# +## +## MORE GENERAL BLOCK WITH STANDARD DEFINITIONS +## +############################################################################################# +############################################################################################# + +# get Makefile directory name: http://stackoverflow.com/a/5982798/376773 +THIS_MAKEFILE_PATH:=$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)) +PROJECT_ROOT:=$(shell cd $(dir $(THIS_MAKEFILE_PATH));pwd)/ +THIS_MAKEFILE:=$(PROJECT_ROOT)$(THIS_MAKEFILE_PATH) + + +-include $(PROJECT_ROOT)project.mk + + +## Define the location of Makefiles +MAKEFILE_IMPORT_PATH?=$(PROJECT_ROOT)makefiles/ +-include $(MAKEFILE_IMPORT_PATH)project.mk + +############################################################################################# +############################################################################################# +## +## INCLUSION OF VARIOUS STANDARD RULES +## +############################################################################################# +############################################################################################# + +include $(MAKEFILE_IMPORT_PATH)directories-standard.mk +#include $(MAKEFILE_IMPORT_PATH)jsdoc.mk +include $(MAKEFILE_IMPORT_PATH)output.mk +include $(MAKEFILE_IMPORT_PATH)placeholder.mk +#include $(MAKEFILE_IMPORT_PATH)s3.mk +#include $(MAKEFILE_IMPORT_PATH)license-agpl3.mk +#include $(MAKEFILE_IMPORT_PATH)jsdoc-json.mk +#include $(MAKEFILE_IMPORT_PATH)go.mk +include $(MAKEFILE_IMPORT_PATH)gitignore.mk +include $(MAKEFILE_IMPORT_PATH)color.mk +include $(MAKEFILE_IMPORT_PATH)version.mk +#include $(MAKEFILE_IMPORT_PATH)node.mk +include $(MAKEFILE_IMPORT_PATH)terminal.mk +#include $(MAKEFILE_IMPORT_PATH)target-go-fetch-licenses.mk +#include $(MAKEFILE_IMPORT_PATH)target-deploy-tool.mk +#include $(MAKEFILE_IMPORT_PATH)target-jsdoc-build.mk +#include $(MAKEFILE_IMPORT_PATH)target-jekyll.mk +#include $(MAKEFILE_IMPORT_PATH)target-minerva.mk +#include $(MAKEFILE_IMPORT_PATH)target-docman.mk +#include $(MAKEFILE_IMPORT_PATH)target-node-build.mk +#include $(MAKEFILE_IMPORT_PATH)target-caddy.mk +include $(MAKEFILE_IMPORT_PATH)target-update-makefiles.mk +include $(MAKEFILE_IMPORT_PATH)target-help.mk +#include $(MAKEFILE_IMPORT_PATH)target-go-build.mk +#include $(MAKEFILE_IMPORT_PATH)target-node-test.mk +#include $(MAKEFILE_IMPORT_PATH)target-npm-publish.mk +include $(MAKEFILE_IMPORT_PATH)target-git.mk +include $(MAKEFILE_IMPORT_PATH)target-init-standard.mk +include $(MAKEFILE_IMPORT_PATH)target-variable.mk +include $(MAKEFILE_IMPORT_PATH)terminal-check.mk + + +############################################################################################# diff --git a/application/source/constants/context.go b/application/source/constants/context.go index 78990c5678a24f6daaacab25d080ff611190eeb2..1e89c9bd6dfc69c6ccc49eb9df57493a98d191ad 100644 --- a/application/source/constants/context.go +++ b/application/source/constants/context.go @@ -10,3 +10,5 @@ const AppStyleDirectory = "styles" const AppScriptDirectory = "scripts" const StandardCacheControl = "no-cache, no-store, must-revalidate" + +const WebsocketPath = "/websocketPath" diff --git a/application/source/server/cache.go b/application/source/server/cache.go new file mode 100644 index 0000000000000000000000000000000000000000..a61ba6f01ef446a554415dd15d71043cfbc8e631 --- /dev/null +++ b/application/source/server/cache.go @@ -0,0 +1,44 @@ +package server + +import ( + "net/http" + "time" +) + +var epoch = time.Unix(0, 0).Format(time.RFC1123) + +var noCacheHeaders = map[string]string{ + "Expires": epoch, + "Cache-Control": "no-cache, private, max-age=0", + "Pragma": "no-cache", + "X-Accel-Expires": "0", +} + +var etagHeaders = []string{ + "ETag", + "If-Modified-Since", + "If-Match", + "If-None-Match", + "If-Range", + "If-Unmodified-Since", +} + +func NoCache(h http.Handler) http.Handler { + fn := func(w http.ResponseWriter, r *http.Request) { + // Delete any ETag headers that may have been set + for _, v := range etagHeaders { + if r.Header.Get(v) != "" { + r.Header.Del(v) + } + } + + // Set our NoCache headers + for k, v := range noCacheHeaders { + w.Header().Set(k, v) + } + + h.ServeHTTP(w, r) + } + + return http.HandlerFunc(fn) +} diff --git a/application/source/server/inject.go b/application/source/server/inject.go new file mode 100644 index 0000000000000000000000000000000000000000..dcedc6b92c4982920a449dd6872ef1ae59dd2488 --- /dev/null +++ b/application/source/server/inject.go @@ -0,0 +1,128 @@ +package server + +import ( + "gitlab.schukai.com/oss/utilities/conan/configuration" + "gitlab.schukai.com/oss/utilities/conan/constants" + "gitlab.schukai.com/oss/utilities/conan/logging" + "net/http" + "os" + "regexp" + "strings" +) + +func injectHandler(next http.Handler) http.Handler { + + fn := func(w http.ResponseWriter, r *http.Request) { + + if strings.HasSuffix(r.URL.Path, ".html") { + + path := configuration.GetServerWebPath() + "/" + r.URL.Path + p, err := os.ReadFile(path) + if err != nil { + logging.LogError("injectHandler error %s", err.Error()) + return + } + + p = injectScript(p) + + w.Header().Set("Content-Type", "text/html") + w.Write(p) + + return + + } + + next.ServeHTTP(w, r) + + } + + return http.HandlerFunc(fn) + +} + +var script string + +func init() { + + script = `<head> + <script type="module"> + + try { + let counter = 0; + let socket + let url = "" + if (document.location.protocol == 'https:') { + url = 'wss://' + } else { + url = 'ws://' + } + url += document.location.host + "{{ constants.WebsocketPath }}"; + + function connectWebsocket() { + + if (socket) { + socket.close() + } + + if (counter++ > 20) { + console.error("Failed 20 times to connect to websocket. Giving up.") + return + } + + + socket = new WebSocket(url) + + socket.onopen = function (e) { + console.log("[conan] Connection established"); + counter = 0 + }; + + socket.onmessage = function (event) { + console.log("[conan] Data received from server: " + event?.data); + + if (event?.data == "reload") { + console.log("[conan] Reloading page") + window.location.reload(); + } + }; + + socket.onclose = function (event) { + if (event.wasClean) { + console.log("[conan] Connection closed cleanly, code=" + event?.code + " reason=" + event?.reason + ""); + } else { + console.error("[conan] Connection died"); + setTimeout(connectWebsocket, 3000*counter) + } + }; + + socket.onerror = function (error) { + console.error("[conan] " + error?.message); + }; + + } + + document.addEventListener("DOMContentLoaded", () => { + connectWebsocket() + }) + + } catch (e) { + console.error(e) + } + + + </script>` + + script = strings.Replace(script, "{{ constants.WebsocketPath }}", constants.WebsocketPath, -1) + +} + +func injectScript(p []byte) []byte { + + s := string(p) + + reg := regexp.MustCompile(`<head>`) + s = reg.ReplaceAllString(s, script) + + return []byte(s) + +} diff --git a/application/source/server/routing.go b/application/source/server/routing.go index 6ba82653943c2f8da5ce72ba10b7dde985e8cc45..f7816977cd5ea46847f58dadab27ecf4dc82041c 100644 --- a/application/source/server/routing.go +++ b/application/source/server/routing.go @@ -2,11 +2,14 @@ package server import ( "crypto/tls" + "gitea.com/go-chi/session" "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" "gitlab.schukai.com/oss/utilities/conan/configuration" + "gitlab.schukai.com/oss/utilities/conan/constants" "gitlab.schukai.com/oss/utilities/conan/header" "gitlab.schukai.com/oss/utilities/conan/logging" + "gitlab.schukai.com/oss/utilities/conan/websocket" "net/http" ) @@ -25,12 +28,16 @@ func getRouter() *chi.Mux { router.Use(middleware.Compress(5)) router.Use(logging.LoggerMiddleware) router.Use(reloadMiddleware) + router.Use(NoCache) - router.Handle("/*", http.FileServer( - http.Dir(configuration.GetServerWebPath()+"/"))) + router.Use(session.Sessioner()) - return router + router.Handle(constants.WebsocketPath, websocket.GetWebsocketHandler()) -} + //fs := NoListFileSystem{http.Dir(configuration.GetServerWebPath() + "/")} + // router.Handle("*.html", injectHandler(http.FileServer(http.Dir(configuration.GetServerWebPath()+"/")))) + router.Handle("/*", injectHandler(http.FileServer(http.Dir(configuration.GetServerWebPath()+"/")))) + return router +} diff --git a/application/source/watch/resources.go b/application/source/watch/resources.go index 6647ce214a66345c6fa692ff3c6a988363020e4c..03538cee61a01d6d2005de26baecf9634d0f372e 100644 --- a/application/source/watch/resources.go +++ b/application/source/watch/resources.go @@ -7,6 +7,7 @@ import ( "gitlab.schukai.com/oss/utilities/conan/configuration" "gitlab.schukai.com/oss/utilities/conan/constants" "gitlab.schukai.com/oss/utilities/conan/logging" + "gitlab.schukai.com/oss/utilities/conan/websocket" "os" "path" "path/filepath" @@ -65,6 +66,12 @@ func executeWatchAction(watchPath string) { } } + if w.Command == "" { + logging.LogInfo("watching: no command defined for %s", watchPath) + websocket.SendReloadMessage() + continue + } + logging.LogDebug("watching: execute watch action: %s", w.Command) t, err := template.New("command").Parse(w.Command) @@ -109,6 +116,8 @@ func executeWatchAction(watchPath string) { r, err := result.String() logging.LogDebug("%s", r) + websocket.SendReloadMessage() + if err != nil { logging.LogError("watching: execute watch action error: %v", err.Error()) continue diff --git a/application/source/websocket/connection.go b/application/source/websocket/connection.go index 14c190b8c64ea833df407261a379ca3388d26c9d..01eb4dd74c836fe0fbca7db3fb00081de6f1df66 100644 --- a/application/source/websocket/connection.go +++ b/application/source/websocket/connection.go @@ -14,20 +14,6 @@ var ( connections = make(map[string]*websocket.Conn) ) -//func getCmd(input string) string { -// inputArr := strings.Split(input, " ") -// return inputArr[0] -//} -// -//func getMessage(input string) string { -// inputArr := strings.Split(input, " ") -// var result string -// for i := 1; i < len(inputArr); i++ { -// result += inputArr[i] -// } -// return result -//} - func SendMessageToAll(message []byte) { for _, conn := range connections { @@ -45,6 +31,10 @@ func closeConnection(session string) error { return nil } +func SendReloadMessage() { + SendMessageToAll([]byte("reload")) +} + func GetWebsocketHandler() http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -69,11 +59,6 @@ func GetWebsocketHandler() http.Handler { closeConnection(session) }() - //if sessionStore.Get("user") == nil { - // http.Error(w, "Forbidden", http.StatusForbidden) - // return - //} - // Continuosly read and write message for { mt, message, err := conn.ReadMessage() @@ -87,25 +72,6 @@ func GetWebsocketHandler() http.Handler { } fmt.Println(mt, string(message), "!!!!!!!!!!!!!!!!!!") - //input := string(message) - //cmd := getCmd(input) - //msg := getMessage(input) - //if cmd == "x" { - // todoList = append(todoList, msg) - //} else if cmd == "done" { - // updateTodoList(msg) - //} - //output := "Current Todos: \n" - //for _, todo := range todoList { - // output += "\n - " + todo + "\n" - //} - //output += "\n----------------------------------------" - //message = []byte(output) - //err = conn.WriteMessage(mt, message) - //if err != nil { - // log.Println("write failed:", err) - // break - //} } }) } diff --git a/development/examples/e1/config.yaml b/development/examples/e1/config.yaml index 84514f3310daa07a4c6b81dfba9ea9568b806797..0b0f8b8d09ba554e16105ee5c703ed3b5ae6de44 100644 --- a/development/examples/e1/config.yaml +++ b/development/examples/e1/config.yaml @@ -22,6 +22,10 @@ Server: Exclude: - ~$ - ^\. + - Path: web + Exclude: + - ~$ + - ^\. Flags: FollowSymlinks: true diff --git a/development/examples/e1/src/main.js b/development/examples/e1/src/main.js index a657bdc91e1b91d78d778d247c8ddafe1feb70ba..8e3ac04755b361e84440d385a8a83300c96dda0f 100644 --- a/development/examples/e1/src/main.js +++ b/development/examples/e1/src/main.js @@ -1 +1,4 @@ -console.log('Hello ME!?'); \ No newline at end of file +document.addEventListener("DOMContentLoaded", () => { + document.querySelector("#app").innerHTML = "Hello!!! World?!"; +}) +// Language: javascript \ No newline at end of file diff --git a/development/examples/e1/web/hello.html b/development/examples/e1/web/hello.html index 4e8540f2147d5ecced121d402d28c3516baa7032..f82764ddfd376f0fff250accb58347ac3fabbed8 100644 --- a/development/examples/e1/web/hello.html +++ b/development/examples/e1/web/hello.html @@ -6,5 +6,8 @@ <script src="scripts/bundle.js"></script> </head> <body> - <h1>Hello World</h1> + <h1>Hello ...ddd</h1> + +<div id="app"></div> + </body> diff --git a/development/examples/e1/web/scripts/bundle.js b/development/examples/e1/web/scripts/bundle.js index b5d19a84fb6c89396be3650f96a38674d88e39d6..4bd7bb6aa0602e764ab595092e4aeee697734aec 100644 --- a/development/examples/e1/web/scripts/bundle.js +++ b/development/examples/e1/web/scripts/bundle.js @@ -1,5 +1,7 @@ (() => { // src/main.js - console.log("Hello ME!?"); + document.addEventListener("DOMContentLoaded", () => { + document.querySelector("#app").innerHTML = "Hello!!! World?!"; + }); })(); //# sourceMappingURL=bundle.js.map diff --git a/development/examples/e1/web/scripts/bundle.js.map b/development/examples/e1/web/scripts/bundle.js.map index e98b515a1bf09363b9d5f4f2e846218d00887bf9..11dffab33a2b7f500b21594b9b009bb76a5b55c0 100644 --- a/development/examples/e1/web/scripts/bundle.js.map +++ b/development/examples/e1/web/scripts/bundle.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../src/main.js"], - "sourcesContent": ["console.log('Hello ME!?');"], - "mappings": ";;AAAA,UAAQ,IAAI,YAAY;", + "sourcesContent": ["document.addEventListener(\"DOMContentLoaded\", () => {\n document.querySelector(\"#app\").innerHTML = \"Hello!!! World?!\";\n})\n// Language: javascript "], + "mappings": ";;AAAA,WAAS,iBAAiB,oBAAoB,MAAM;AAChD,aAAS,cAAc,MAAM,EAAE,YAAY;AAAA,EAC/C,CAAC;", "names": [] }