Browse Source

initializing the new version

Mohamed Al Ashaal 6 years ago
parent
commit
32bd6eb64c
4 changed files with 63 additions and 7 deletions
  1. 6 3
      flags.go
  2. 36 2
      hosts.go
  3. 17 1
      main.go
  4. 4 1
      server.go

+ 6 - 3
flags.go

@@ -2,17 +2,20 @@ package main
 
 import (
 	"flag"
-	"github.com/mitchellh/go-homedir"
+	"os"
 	"path"
 )
 
+import "github.com/mitchellh/go-homedir"
+
 var (
 	HOME_DIR, _ = homedir.Dir()
 	HTTPS_ADDR  = flag.String("https", ":443", "the https address to listen on")
-	STORAGE     = flag.String("storage", path.Join(HOME_DIR, "httpsify/certs"), "the ssl certs storage directory")
-	HOSTS_FILE  = flag.String("hosts", path.Join(HOME_DIR, "httpsify/hosts.json"), "the sites configurations filename")
+	STORAGE     = flag.String("storage", path.Join(HOME_DIR, ".httpsify/certs"), "the ssl certs storage directory")
+	HOSTS_FILE  = flag.String("hosts", path.Join(HOME_DIR, ".httpsify/hosts.json"), "the sites configurations filename")
 )
 
 func InitFlags() {
 	flag.Parse()
+	os.MkdirAll(*STORAGE, 0755)
 }

+ 36 - 2
hosts.go

@@ -6,18 +6,52 @@ import (
 	"sync"
 )
 
+import (
+	"github.com/fatih/color"
+	"github.com/fsnotify/fsnotify"
+)
+
 var (
 	HOSTS  = make(map[string][]string)
 	LOCKER = new(sync.Mutex)
 )
 
-func InitSites() error {
+// Load the hosts file into memory
+func InitHostsList() error {
 	LOCKER.Lock()
 	defer LOCKER.Unlock()
-	f, e := os.Open(*HOSTS_FILE)
+	f, e := os.OpenFile(*HOSTS_FILE, os.O_RDONLY|os.O_CREATE, 0666)
 	if e != nil {
 		return e
 	}
 	defer f.Close()
+	finfo, err := f.Stat()
+	if err != nil {
+		return err
+	}
+	if finfo.Size() == 0 {
+		return nil
+	}
 	return json.NewDecoder(f).Decode(&HOSTS)
 }
+
+// watch the hosts file for any changes and the reload it
+func WatchChanges() {
+	watcher, err := fsnotify.NewWatcher()
+	if err != nil {
+		return
+	}
+	defer watcher.Close()
+	watcher.Add(*HOSTS_FILE)
+	for {
+		select {
+		case <-watcher.Events:
+			colorize(color.FgYellow, "⇛ There is a change in the hosts file, reloading ...")
+			if err := InitHostsList(); err != nil {
+				colorize(color.FgRed, "⇛", err.Error())
+			} else {
+				colorize(color.FgGreen, "⇛ The hosts file has been reloaded successfully!")
+			}
+		}
+	}
+}

+ 17 - 1
main.go

@@ -1,6 +1,22 @@
 package main
 
+import "github.com/fatih/color"
+
 func main() {
+	colorize(color.FgGreen, "⇛ Parsing the specified flags ...")
 	InitFlags()
-	InitSites()
+
+	colorize(color.FgGreen, "⇛ Loading the provided json hosts file from ("+*HOSTS_FILE+") ...")
+	if err := InitHostsList(); err != nil {
+		colorize(color.FgRed, "⇛", err.Error())
+		return
+	}
+
+	colorize(color.FgGreen, "⇛ Watching the hosts file for any change to hot reload it ...")
+	go func() {
+		WatchChanges()
+	}()
+
+	colorize(color.FgGreen, "⇛ Running the HTTPS (HTTP/2) server on address ("+*HTTPS_ADDR+") ...")
+	colorize(color.FgRed, InitServer())
 }

+ 4 - 1
server.go

@@ -14,6 +14,8 @@ import (
 	"golang.org/x/crypto/acme/autocert"
 )
 
+// Initialize the autocert manager and configure it,
+// also create an instance of the http.Server and link the autocert manager to it.
 func InitServer() error {
 	m := autocert.Manager{
 		Cache:  autocert.DirCache(*STORAGE),
@@ -26,13 +28,14 @@ func InitServer() error {
 		},
 	}
 	s := &http.Server{
-		Addr:      ":https",
+		Addr:      *HTTPS_ADDR,
 		TLSConfig: &tls.Config{GetCertificate: m.GetCertificate},
 		Handler:   ServeHTTP(),
 	}
 	return s.ListenAndServeTLS("", "")
 }
 
+// The main server handler
 func ServeHTTP() http.Handler {
 	return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
 		if upstreams, ok := HOSTS[req.Host]; ok {