You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

112 lines
3.4 KiB

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: 1 * time.Second}
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))
}