/
main.go
158 lines (130 loc) · 3.82 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
package main
import (
"flag"
"log"
"net/http"
"os"
"path/filepath"
"strconv"
"github.com/gorilla/mux"
"time"
"fmt"
"runtime"
"os/exec"
)
//flags
var (
webDir string
webHost string
webPort int
)
func init() {
log.Println("Initializing...")
//web flags
flag.StringVar(&webDir, "webdir", "web/dist", "Change the web directory")
flag.StringVar(&webHost, "webHost", "localhost", "Change the host")
flag.IntVar(&webPort, "wport", 4444, "Change port for the web server to listen on")
flag.Parse()
webDir = filepath.Clean(webDir)
log.Println("All systems ready!")
}
func Logger(inner http.Handler, name string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
inner.ServeHTTP(w, r)
log.Printf(
"%s\t%s\t%s\t%s",
r.Method,
r.RequestURI,
name,
time.Since(start),
)
})
}
func openBrowser(hostname string, port int) error {
var err error
address := "http://"+hostname+":"+strconv.Itoa(port)+"/"
switch runtime.GOOS {
case "linux":
err = exec.Command("xdg-open", address).Start()
case "windows", "darwin":
err = exec.Command("rundll32", "url.dll,FileProtocolHandler", address).Start()
default:
err = fmt.Errorf("unsupported platform")
}
return err
}
func main() {
//setup all of our routes
r := mux.NewRouter()
// Declare any api handlers here before the asset dirs
// or you can use a separate subrouter to put your api on a subdomain
// we like to do this in production but it's much simpler to not use it
r.HandleFunc("/task", TodoIndex)
// We use RequestPathHandler instead of http.FileServer because it allows us to have clean urls
r.PathPrefix("/app/").HandlerFunc(RequestPathHandler)
r.PathPrefix("/lib/").HandlerFunc(RequestPathHandler)
r.PathPrefix("/css/").HandlerFunc(RequestPathHandler)
r.PathPrefix("/js/").HandlerFunc(RequestPathHandler)
r.PathPrefix("/img/").HandlerFunc(RequestPathHandler)
r.PathPrefix("/fonts/").HandlerFunc(RequestPathHandler)
// General
r.HandleFunc("/favicon.ico", func(w http.ResponseWriter, req *http.Request) {
http.ServeFile(w, req, filepath.Join(webDir, "/favicon.ico"))
})
// For all other routes we serve up our apps index file
r.PathPrefix("/").HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
w.Header().Add("Cache-Control", "no-store")
http.ServeFile(w, req, filepath.Join(webDir, "/index.html"))
})
err := openBrowser(webHost, webPort)
if err != nil {
log.Fatalf("Unable to open browser: %v", err)
}
log.Println("Starting web server")
if err := http.ListenAndServe(":"+strconv.Itoa(webPort), r); err != nil {
log.Fatalln("Server error:", err)
}
}
// Serves files relative to the webDir
// Only safe if you use with PathPrefix() or similar functions
func RequestPathHandler(w http.ResponseWriter, req *http.Request) {
path := filepath.Join(webDir, req.URL.Path)
log.Println("Serving file:", path)
//do not show directories
fi, err := os.Stat(path)
if os.IsNotExist(err) {
log.Println("[FileHandler] error path does not exist:", err)
http.NotFound(w, req)
return
} else if err != nil {
http.NotFound(w, req)
log.Println("[FileHandler] error checking if file is dir:", err)
http.NotFound(w, req)
return
}
if fi.IsDir() {
http.NotFound(w, req)
return
}
http.ServeFile(w, req, path)
}
//func openBrowser(hostname string, port int) error {
//
// var err error
// address := "http://"+hostname+":"+strconv.Itoa(port)+"/"
//
// switch runtime.GOOS {
// case "linux":
// err = exec.Command("xdg-open", address).Start()
// case "windows", "darwin":
// err = exec.Command("rundll32", "url.dll,FileProtocolHandler", address).Start()
// default:
// err = fmt.Errorf("unsupported platform")
// }
//
// return err
//}
func TodoIndex(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Todo Index!")
}