This repository has been archived by the owner on Apr 2, 2019. It is now read-only.
/
core.go
114 lines (86 loc) · 2.84 KB
/
core.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
// Core for web framework
package tori
import "log"
import "net/http"
import "github.com/shiroyuki/re"
import yotsuba "github.com/shiroyuki/yotsuba-go"
const serverSignature string = "shiroyuki/tori-go/1.0"
type Core struct { // implements http.Handler
Router *Router
Cache *yotsuba.CacheDriver
Enigma *yotsuba.Enigma
Internal *http.Server
Compressed bool
}
// Create a core of the web framework with everything pre-configured for development.
func NewSimpleCore() *Core {
var enigma = yotsuba.Enigma{}
var router = NewRouter()
var actualCacheDriver = yotsuba.NewInMemoryCacheDriver(&enigma, false)
var castedCacheDriver = yotsuba.CacheDriver(actualCacheDriver)
return NewCore(
router,
&castedCacheDriver,
&enigma,
false,
)
}
func NewCore(
router *Router,
cache *yotsuba.CacheDriver,
enigma *yotsuba.Enigma,
compressed bool,
) *Core {
appCore := Core{
Router: router,
Cache: cache,
Enigma: enigma,
Compressed: compressed,
}
internalServer := &http.Server{
Addr: "0.0.0.0:8000",
Handler: &appCore,
}
appCore.Internal = internalServer
return &appCore
}
// Handle the request and delegate the request to a proper handler.
func (self *Core) ServeHTTP(w http.ResponseWriter, r *http.Request) {
var routingRecord *Record
var parameters *re.MultipleResult
var method string = r.Method
var path string = r.URL.Path
routingRecord, parameters = self.Router.Find(method, path)
w.Header().Set("Server", serverSignature)
if routingRecord == nil {
w.WriteHeader(http.StatusNotFound)
w.Write([]byte("Not Found"))
// TODO Event "web.core.error.404@default": allow flexible error handling for HTTP 404.
return
}
handler := NewHandler(routingRecord.Route, &w, r, parameters)
action := routingRecord.Action
// TODO Event "web.handler.pre.<route_id>": allow flexible interceptions before processing requests.
(*action)(handler)
// TODO Event "web.handler.post.<route_id>": allow flexible interceptions before processing requests.
self.response(handler)
}
func (self *Core) response(handler *Handler) {
var content []byte = handler.Content()
if !self.Compressed {
handler.SetContentLength(len(content))
(*handler.Response).Write(content)
return
}
compressed := self.Enigma.Compress(content)
handler.SetContentEncoding("gzip")
handler.SetContentLength(len(compressed))
(*handler.Response).Write(compressed)
}
func (self *Core) Listen(address *string) {
if address != nil {
self.Internal.Addr = *address
}
log.Println("Listening at:", self.Internal.Addr)
log.Fatal("Terminated due to:", self.Internal.ListenAndServe())
}