-
Notifications
You must be signed in to change notification settings - Fork 11
/
runner.go
266 lines (242 loc) · 9.05 KB
/
runner.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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
package xamboo
import (
"crypto/tls"
"log"
"net"
"net/http"
"time"
"golang.org/x/text/language"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"github.com/webability-go/xamboo/applications"
"github.com/webability-go/xamboo/cms/engines"
"github.com/webability-go/xamboo/components"
"github.com/webability-go/xamboo/components/host"
"github.com/webability-go/xamboo/config"
"github.com/webability-go/xamboo/i18n"
"github.com/webability-go/xamboo/loggers"
"github.com/webability-go/xamboo/utils"
)
func Run(file string, args ...interface{}) error {
// Load the language if needed for messages
if len(args) > 0 {
lang, haslang := args[0].(language.Tag)
if haslang {
i18n.Load(lang)
}
}
// Link the engines
// assets.EngineWrapper = cms.Wrapper
// assets.EngineWrapperString = cms.Wrapperstring
// Load the config, FIRST PASS
err := config.Config.Load(file)
if err != nil {
log.Printf(i18n.Get("config.error"), file, err)
return err
}
config.Config.Version = VERSION
// Launch the system based on Config
// Launch system wide Loggers
loggers.StartSystem()
// Link engines (load external apps and create linker matrix)
engines.Link()
// Link components and call Start to start them globally
components.Link()
// link Applications and call StartHost to start them on each Hosts
applications.Link()
// Launch remaining loggers: listeners, hosts (they may link to an application)
loggers.Start()
// Finally link the logs call for loggers
applications.LinkCalls()
// And call hosts starts for components
components.StartHost()
// The encapsulation system works as follow (all the layers are in order in the main config file):
// EXTERNAL LAYER:
// The main listener/host dispatcher. Will create a core writer to link the listener and host to the request.
// COMPONENT LAYERS:
// Every component will test if it is available on the host, and call it if yes.
// SERVER LAYER:
// Will call the server layer to resolve the page or file.
// ERROR LAYER:
// Will finally call the error handler.
handler := func(w http.ResponseWriter, r *http.Request) {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
}
// build Handlers
for _, componentid := range components.ComponentsOrder {
if components.Components[componentid].NeedHandler() {
handler = components.Components[componentid].Handler(handler)
}
}
handler = host.Handler(handler)
http.HandleFunc("/", handler)
// build the different servers
xlogger := loggers.GetCoreLogger("sys")
for _, l := range config.Config.Listeners {
xlogger.Printf(i18n.Get("listener.scan"), l.Name)
go func(listener config.Listener) {
llogger := loggers.GetListenerLogger(listener.Name, "server")
xlogger.Printf(i18n.Get("listener.launch"), listener.Name)
// If the server is protocol HTTPS, we have to scan all the certificates for this listener
if listener.Protocol == config.PROTOCOL_HTTPS {
numcertificates := 0
// We search for all the hosts on this listener
for _, host := range config.Config.Hosts {
if utils.SearchInArray(listener.Name, host.Listeners) {
numcertificates++
}
}
tlsConfig := &tls.Config{
CipherSuites: []uint16{
// obsolete tls options
// tls.TLS_RSA_WITH_RC4_128_SHA,
// tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
// tls.TLS_RSA_WITH_AES_128_CBC_SHA,
// tls.TLS_RSA_WITH_AES_256_CBC_SHA,
// tls.TLS_RSA_WITH_AES_128_CBC_SHA256,
// tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
// tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
// tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
// tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA,
// tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
},
}
tlsConfig.PreferServerCipherSuites = true
tlsConfig.MinVersion = tls.VersionTLS12
tlsConfig.MaxVersion = tls.VersionTLS13
tlsConfig.Certificates = make([]tls.Certificate, numcertificates)
i := 0
var certerror error
for _, host := range config.Config.Hosts {
if utils.SearchInArray(listener.Name, host.Listeners) {
tlsConfig.Certificates[i], certerror = tls.LoadX509KeyPair(host.Cert, host.PrivateKey)
if certerror != nil {
xlogger.Fatal(certerror)
}
xlogger.Printf(i18n.Get("host.link"), host.Name, listener.Name)
i++
}
}
tlsConfig.BuildNameToCertificate()
server := &http.Server{
Addr: ":" + listener.Port,
ErrorLog: llogger,
ReadTimeout: time.Duration(listener.ReadTimeOut) * time.Second,
ReadHeaderTimeout: time.Duration(listener.ReadTimeOut) * time.Second,
IdleTimeout: time.Duration(listener.ReadTimeOut) * time.Second,
WriteTimeout: time.Duration(listener.WriteTimeOut) * time.Second,
MaxHeaderBytes: listener.HeaderSize,
}
server.TLSConfig = tlsConfig
xserver, err := tls.Listen("tcp", listener.IP+":"+listener.Port, tlsConfig)
if err != nil {
xlogger.Fatal(err)
}
servererr := server.Serve(xserver)
if servererr != nil {
xlogger.Fatal(err)
}
} else if listener.Protocol == config.PROTOCOL_HTTP {
// *******************************************
// VERIFICAR EL LISTEN AND SERVE POR DEFECTO SIN TLS; ESTA MAL IMPLEMENTADO: HAY QUE USAR EL HANDLER Y TIMEOUTS Y ETC
xlogger.Fatal(http.ListenAndServe(listener.IP+":"+listener.Port, nil))
} else if listener.Protocol == config.PROTOCOL_gRPC {
lis, err := net.Listen("tcp", listener.IP+":"+listener.Port)
if err != nil {
xlogger.Fatal(err)
}
grpcServer := grpc.NewServer()
if err := grpcServer.Serve(lis); err != nil {
xlogger.Fatal(err)
}
} else if listener.Protocol == config.PROTOCOL_gRPCS {
numcertificates := 0
// We search for all the hosts on this listener
for _, host := range config.Config.Hosts {
if utils.SearchInArray(listener.Name, host.Listeners) {
numcertificates++
}
}
tlsConfig := &tls.Config{
CipherSuites: []uint16{
// obsolete tls options
// tls.TLS_RSA_WITH_RC4_128_SHA,
// tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
// tls.TLS_RSA_WITH_AES_128_CBC_SHA,
// tls.TLS_RSA_WITH_AES_256_CBC_SHA,
// tls.TLS_RSA_WITH_AES_128_CBC_SHA256,
// tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
// tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
// tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
// tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA,
// tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
},
}
tlsConfig.PreferServerCipherSuites = true
tlsConfig.MinVersion = tls.VersionTLS12
tlsConfig.MaxVersion = tls.VersionTLS13
tlsConfig.Certificates = make([]tls.Certificate, numcertificates)
i := 0
var certerror error
for _, host := range config.Config.Hosts {
if utils.SearchInArray(listener.Name, host.Listeners) {
tlsConfig.Certificates[i], certerror = tls.LoadX509KeyPair(host.Cert, host.PrivateKey)
if certerror != nil {
xlogger.Fatal(certerror)
}
xlogger.Printf(i18n.Get("host.link"), host.Name, listener.Name)
i++
}
}
tlsConfig.BuildNameToCertificate()
lis, err := net.Listen("tcp", listener.IP+":"+listener.Port)
if err != nil {
xlogger.Fatal(err)
}
s := grpc.NewServer(grpc.Creds(credentials.NewTLS(tlsConfig)))
if err = s.Serve(lis); err != nil {
xlogger.Fatal(err)
}
} else {
// FATAL ERROR, protocol not known
xlogger.Fatal("Error, protocol not known")
}
}(l)
}
finish := make(chan bool)
<-finish // never finish by itself for now (OS will take care of this with systemctl or KILL -9)
return nil
}
func OverLoad() error {
err := config.OverLoad(config.Config.File)
if err != nil {
return err
}
// restart Hosts
components.StartHost()
return nil
}