This repository has been archived by the owner on Aug 21, 2019. It is now read-only.
/
webserver.go
117 lines (89 loc) · 2.56 KB
/
webserver.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
package webserver
import (
"code.google.com/p/tcgl/applog"
"flag"
"fmt"
"net/http"
"os"
"path"
"time"
)
type Environment struct {
Listen string
PublicFolder string
LogLevel int
}
type WebServer struct {
appHandler http.Handler
}
func New(handler http.Handler) *WebServer {
return &WebServer{handler}
}
func (srv *WebServer) Run(env *Environment) error {
applog.Infof("Starting application")
disp := newDispatcher(srv, env)
http.Handle("/", disp)
applog.Infof("Listening to incoming connection on %s", env.Listen)
if err := http.ListenAndServe(env.Listen, nil); err != nil {
applog.Criticalf(err.Error())
return err
}
return nil
}
func (srv *WebServer) RunCLI() {
env := &Environment{
Listen: "0.0.0.0:9000",
LogLevel: applog.LevelDebug,
PublicFolder: "public",
}
cli := flag.NewFlagSet("WebServer", flag.ExitOnError)
cli.StringVar(&env.Listen, "l", env.Listen, "The address to listen for incoming connections ([host]:port)")
cli.Usage = func() {
fmt.Printf("Usage: %s [options]\n\n", os.Args[0])
fmt.Printf("Available options:\n")
cli.PrintDefaults()
}
if err := cli.Parse(os.Args[1:]); err == flag.ErrHelp {
cli.Usage()
os.Exit(1)
}
applog.SetLevel(env.LogLevel)
if err := srv.Run(env); err != nil {
panic(err)
}
}
type dispatcher struct {
env *Environment
appHandler, publicHandler http.Handler
}
func newDispatcher(srv *WebServer, env *Environment) *dispatcher {
return &dispatcher{env, srv.appHandler, http.FileServer(http.Dir(env.PublicFolder))}
}
func (disp *dispatcher) ServeHTTP(w http.ResponseWriter, req *http.Request) {
dispatched := false
startTime := time.Now()
applog.Infof("Started %s %s", req.Method, req.URL)
localPath := path.Join(disp.env.PublicFolder, req.URL.Path)
applog.Debugf("Checking for existance of %s", localPath)
if info, err := os.Stat(localPath); err == nil {
if info.IsDir() {
indexPath := path.Join(localPath, "index.html")
applog.Debugf("%s is a directory, checking for existance of %s", localPath, indexPath)
if _, err := os.Stat(indexPath); err == nil {
applog.Debugf("Serving static file %s", indexPath)
disp.publicHandler.ServeHTTP(w, req)
dispatched = true
}
} else {
applog.Debugf("Serving static file %s", localPath)
disp.publicHandler.ServeHTTP(w, req)
dispatched = true
}
}
if !dispatched {
applog.Debugf("Dispatching %s", req.URL)
disp.appHandler.ServeHTTP(w, req)
}
duration := time.Now().Sub(startTime)
applog.Infof("Finished processing %s %s (%s)", req.Method, req.URL, duration.String())
}