|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"log"
|
|
|
|
"net/http"
|
|
|
|
"os"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/kyokomi/emoji"
|
|
|
|
)
|
|
|
|
|
|
|
|
const defaultListeningPort = "8000"
|
|
|
|
|
|
|
|
func parseEnv() (listeningPort string) {
|
|
|
|
listeningPort = os.Getenv("LISTENINGPORT")
|
|
|
|
if len(listeningPort) == 0 {
|
|
|
|
listeningPort = defaultListeningPort
|
|
|
|
} else {
|
|
|
|
value, err := strconv.Atoi(listeningPort)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(emoji.Sprint(":x:") + " LISTENINGPORT environment variable '" + listeningPort +
|
|
|
|
"' is not a valid integer")
|
|
|
|
}
|
|
|
|
if value < 1024 {
|
|
|
|
if os.Geteuid() == 0 {
|
|
|
|
log.Println(emoji.Sprint(":warning:") + "LISTENINGPORT environment variable '" + listeningPort +
|
|
|
|
"' allowed to be in the reserved system ports range as you are running as root.")
|
|
|
|
} else if os.Geteuid() == -1 {
|
|
|
|
log.Println(emoji.Sprint(":warning:") + "LISTENINGPORT environment variable '" + listeningPort +
|
|
|
|
"' allowed to be in the reserved system ports range as you are running in Windows.")
|
|
|
|
} else {
|
|
|
|
log.Fatal(emoji.Sprint(":x:") + " LISTENINGPORT environment variable '" + listeningPort +
|
|
|
|
"' can't be in the reserved system ports range (1 to 1023) when running without root.")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if value > 65535 {
|
|
|
|
log.Fatal(emoji.Sprint(":x:") + " LISTENINGPORT environment variable '" + listeningPort +
|
|
|
|
"' can't be higher than 65535")
|
|
|
|
}
|
|
|
|
if value > 49151 {
|
|
|
|
// dynamic and/or private ports.
|
|
|
|
log.Println(emoji.Sprint(":warning:") + "LISTENINGPORT environment variable '" + listeningPort +
|
|
|
|
"' is in the dynamic/private ports range (above 49151)")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return listeningPort
|
|
|
|
}
|
|
|
|
|
|
|
|
func healthcheckMode() bool {
|
|
|
|
args := os.Args
|
|
|
|
if len(args) > 1 {
|
|
|
|
if len(args) > 2 {
|
|
|
|
log.Fatal(emoji.Sprint(":x:") + " Too many arguments provided")
|
|
|
|
}
|
|
|
|
if args[1] == "healthcheck" {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
log.Fatal(emoji.Sprint(":x:") + " Argument 1 can only be 'healthcheck', not " + args[1])
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
func healthcheck(listeningPort string) {
|
|
|
|
request, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:"+listeningPort+"/healthcheck", nil)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println("Can't build HTTP request")
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
client := &http.Client{Timeout: time.Duration(1000) * time.Millisecond}
|
|
|
|
response, err := client.Do(request)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println("Can't execute HTTP request")
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
if response.StatusCode != 200 {
|
|
|
|
fmt.Println("Status code is " + response.Status)
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
os.Exit(0)
|
|
|
|
}
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
listeningPort := parseEnv()
|
|
|
|
if healthcheckMode() {
|
|
|
|
healthcheck(listeningPort)
|
|
|
|
}
|
|
|
|
fmt.Println("#####################################")
|
|
|
|
fmt.Println("########## StackEdit Server #########")
|
|
|
|
fmt.Println("########## by Quentin McGaw #########")
|
|
|
|
fmt.Println("########## Give some " + emoji.Sprint(":heart:") + "at ##########")
|
|
|
|
fmt.Println("# github.com/qdm12/stackedit-docker #")
|
|
|
|
fmt.Print("#####################################\n\n")
|
|
|
|
http.HandleFunc("/healthcheck", func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
})
|
|
|
|
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
if len(r.URL.Path) >= 4 && r.URL.Path[:4] == "/app" {
|
|
|
|
if len(r.URL.Path) == 4 {
|
|
|
|
r.URL.Path = "/"
|
|
|
|
} else {
|
|
|
|
r.URL.Path = strings.Replace("/"+r.URL.Path[5:], "//", "/", -1)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
http.ServeFile(w, r, "/html/"+r.URL.Path[1:])
|
|
|
|
})
|
|
|
|
log.Println("Web UI listening on 0.0.0.0:" + listeningPort + emoji.Sprint(" :ear:"))
|
|
|
|
log.Fatal(http.ListenAndServe("0.0.0.0:"+listeningPort, nil))
|
|
|
|
}
|