From 8526760f4ef00ca26991037a12969621221dc641 Mon Sep 17 00:00:00 2001
From: Andrea Zagli <azagli@libero.it>
Date: Mon, 21 Mar 2022 22:11:59 +0100
Subject: [PATCH 1/1] Specific path watched.

---
 .gitignore |   9 +++
 go.mod     |   3 +
 main.go    | 186 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 198 insertions(+)
 create mode 100644 .gitignore
 create mode 100644 go.mod
 create mode 100644 main.go

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..4b47b40
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,9 @@
+*~*~
+go.sum
+*.toml
+*.bz2
+*.xz
+*.crt
+*.key
+*.db
+*.csv
\ No newline at end of file
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..01ef2b4
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,3 @@
+module example.com/devrevproxy
+
+go 1.15
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..bbeeac4
--- /dev/null
+++ b/main.go
@@ -0,0 +1,186 @@
+package main
+
+import (
+	"errors"
+	"fmt"
+	"log"
+	"net"
+	"net/http"
+	"net/http/httputil"
+	"net/url"
+	"os"
+	"os/exec"
+	"time"
+	"strings"
+)
+
+var pid int
+
+var path = "/home/tux/Documenti/sviluppo/centriestivi"
+
+var watched = make(map[string]time.Time)
+
+// NewProxy takes target host and creates a reverse proxy
+func NewProxy(targetHost string) (*httputil.ReverseProxy, error) {
+	url, err := url.Parse(targetHost)
+	if err != nil {
+		return nil, err
+	}
+
+	proxy := httputil.NewSingleHostReverseProxy(url)
+
+	originalDirector := proxy.Director
+	proxy.Director = func(req *http.Request) {
+		originalDirector(req)
+		modifyRequest(req)
+	}
+
+	/*proxy.ModifyResponse = modifyResponse()
+	proxy.ErrorHandler = errorHandler()*/
+	return proxy, nil
+}
+
+func modifyRequest(req *http.Request) {
+	//req.Header.Set("X-Proxy", "Simple-Reverse-Proxy")
+	req.Header.Set("ZType", "be")
+	fmt.Println(req.URL)
+
+	/* controllo se i file *.go sono cambiati */
+	rebuild := false
+	dir, _ := os.Open(path)
+	dirEntries, _ := dir.ReadDir(0)
+	for _, entry := range dirEntries {
+		if !entry.IsDir() && strings.HasSuffix(entry.Name(), ".go") {
+			info, _ := entry.Info()
+			if _, ok := watched[entry.Name()]; !ok {
+				fmt.Println("File nuovo", entry.Name())
+				watched[entry.Name()] = info.ModTime()
+				rebuild = true
+				break
+			} else {
+				if watched[entry.Name()].Before(info.ModTime()) {
+					watched[entry.Name()] = info.ModTime()
+					rebuild = true
+					break
+				}
+			}
+		}
+	}
+
+	if rebuild {
+		startApp()
+	}
+}
+
+func errorHandler() func(http.ResponseWriter, *http.Request, error) {
+	return func(w http.ResponseWriter, req *http.Request, err error) {
+		fmt.Printf("Got error while modifying response: %v \n", err)
+		return
+	}
+}
+
+func modifyResponse() func(*http.Response) error {
+	return func(resp *http.Response) error {
+		return errors.New("response body is invalid")
+	}
+}
+
+// ProxyRequestHandler handles the http request using proxy
+func ProxyRequestHandler(proxy *httputil.ReverseProxy) func(http.ResponseWriter, *http.Request) {
+	return func(w http.ResponseWriter, r *http.Request) {
+		proxy.ServeHTTP(w, r)
+	}
+}
+
+func startApp() {
+	if pid != 0 {
+		/* kill app */
+		fmt.Println("Killing", pid)
+		p, err := os.FindProcess(pid)
+		if err == nil {
+			p.Kill()
+		}
+	}
+
+	fmt.Println("ESEGUO BUILD")
+	goExecPath, err := exec.LookPath("go")
+	if err != nil {
+		fmt.Println("GO not found in PATH")
+		return
+	}
+
+	cmd := &exec.Cmd {
+		Dir: path,
+		Path: goExecPath,
+		Args: []string{goExecPath, "build", "."},
+		Stdout: os.Stdout,
+		Stderr: os.Stdout,
+	}
+
+	err = cmd.Run()
+	if err != nil {
+		fmt.Println(err)
+	}
+
+	fmt.Println("ESEGUO RUN")
+	cmd = &exec.Cmd {
+		Dir: path,
+		Path: path + "/centriestivi",
+		Args: []string{path + "/centriestivi"},
+		Stdout: os.Stdout,
+		Stderr: os.Stdout,
+	}
+
+	err = cmd.Start()
+	if err != nil {
+		fmt.Println(err)
+	}
+
+	fmt.Println("PID", cmd.Process.Pid)
+	pid = cmd.Process.Pid
+
+	/* devo capire quando accetta richieste */
+	/* per adesso testo se la porta tcp è aperta */
+	for {
+		timeout := time.Second
+		conn, err := net.DialTimeout("tcp", net.JoinHostPort("10.101.101.103", "9083"), timeout)
+		if err != nil {
+			fmt.Println("Connecting error:", err)
+			time.Sleep(5 * time.Second)
+		} else {
+			if conn != nil {
+				defer conn.Close()
+				fmt.Println("Opened", net.JoinHostPort("10.101.101.103", "9083"))
+				break
+			}
+		}
+	}
+}
+
+func watchedInit() {
+	dir, _ := os.Open(path)
+	dirEntries, _ := dir.ReadDir(0)
+	for _, entry := range dirEntries {
+		fmt.Println(entry.Name())
+		if !entry.IsDir() && strings.HasSuffix(entry.Name(), ".go") {
+			info, _ := entry.Info()
+			watched[entry.Name()] = info.ModTime()
+		}
+	}
+}
+
+func main() {
+	watchedInit()
+
+	startApp()
+
+	// initialize a reverse proxy and pass the actual backend server url here
+	proxy, err := NewProxy("http://localhost:9083")
+	if err != nil {
+		panic(err)
+	}
+
+	// handle all requests to your server using the proxy
+	http.HandleFunc("/", ProxyRequestHandler(proxy))
+	log.Fatal(http.ListenAndServe(":9080", nil))
+}
-- 
2.49.0