Added support for custom ports
Signed-off-by: arzumify <jliwin98@danwin1210.de>
This commit is contained in:
parent
d04a40f655
commit
5145c65d04
2
build.sh
2
build.sh
|
@ -30,4 +30,4 @@ clear
|
||||||
fancy "\033[1;105m" "Building Fulgens..."
|
fancy "\033[1;105m" "Building Fulgens..."
|
||||||
go build --ldflags "-s -w" -o "$path/fulgens" || exit 1
|
go build --ldflags "-s -w" -o "$path/fulgens" || exit 1
|
||||||
clear
|
clear
|
||||||
fancy "\033[1;102m" "Fulgensfas has been built successfully!"
|
fancy "\033[1;102m" "Fulgens has been built successfully!"
|
|
@ -4,10 +4,6 @@
|
||||||
global: {
|
global: {
|
||||||
# IP defines the IP address to bind to.
|
# IP defines the IP address to bind to.
|
||||||
ip: "0.0.0.0",
|
ip: "0.0.0.0",
|
||||||
# httpPort defines the port to bind to for HTTP.
|
|
||||||
httpPort: "8080",
|
|
||||||
# httpsPort defines the port to bind to for HTTPS (TLS).
|
|
||||||
httpsPort: "8443",
|
|
||||||
# serviceDirectory defines the directory to look for services in.
|
# serviceDirectory defines the directory to look for services in.
|
||||||
serviceDirectory: "./services",
|
serviceDirectory: "./services",
|
||||||
# resourceDirectory defines the directory to look for resources in.
|
# resourceDirectory defines the directory to look for resources in.
|
||||||
|
@ -19,13 +15,6 @@ global: {
|
||||||
# level defines the compression level to use, possible values are 1-9 for gzip, 0-11 for brotli and 1-22 for zstd.
|
# level defines the compression level to use, possible values are 1-9 for gzip, 0-11 for brotli and 1-22 for zstd.
|
||||||
level: 5
|
level: 5
|
||||||
},
|
},
|
||||||
# https defines the HTTPS settings on a global level - per-route settings override these. It is optional.
|
|
||||||
https: {
|
|
||||||
# certificate defines the path to the certificate file (must be a wildcard in order to support multiple subdomains).
|
|
||||||
certificate: "./certs/localhost.crt",
|
|
||||||
# key defines the path to the key file (must be a wildcard in order to support multiple subdomains).
|
|
||||||
key: "./certs/localhost.key"
|
|
||||||
},
|
|
||||||
# logging defines the logging settings.
|
# logging defines the logging settings.
|
||||||
logging: {
|
logging: {
|
||||||
# enabled defines whether logging is enabled.
|
# enabled defines whether logging is enabled.
|
||||||
|
@ -41,6 +30,23 @@ global: {
|
||||||
path: "./databases",
|
path: "./databases",
|
||||||
# connectionString defines the connection string to use for the database (postgres only).
|
# connectionString defines the connection string to use for the database (postgres only).
|
||||||
connectionString: "postgres://user:password@localhost:5432/database"
|
connectionString: "postgres://user:password@localhost:5432/database"
|
||||||
|
},
|
||||||
|
# stealth enables stealth mode, which makes the server look like some preset http servers.
|
||||||
|
# stealth mode overrides all proxy preservations and headers.
|
||||||
|
stealth: {
|
||||||
|
# enabled defines whether stealth mode is enabled.
|
||||||
|
enabled: true,
|
||||||
|
# server defines the server to pretend to be, possible values are "nginx" or "net/http".
|
||||||
|
server: "nginx",
|
||||||
|
# php defines if the server should pretend to be running PHP. This should only be used on nginx.
|
||||||
|
php: {
|
||||||
|
# enabled defines whether PHP spoofing is enabled.
|
||||||
|
enabled: true,
|
||||||
|
# version defines the version of PHP to pretend to be.
|
||||||
|
version: "8.2.25"
|
||||||
|
},
|
||||||
|
# aspnet defines if the server should pretend to be running ASP.NET. This should only be used on nginx.
|
||||||
|
aspNet: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,6 +55,8 @@ routes: [
|
||||||
{
|
{
|
||||||
# none is a special subdomain that matches all requests without a subdomain (Host header).
|
# none is a special subdomain that matches all requests without a subdomain (Host header).
|
||||||
subdomain: "none",
|
subdomain: "none",
|
||||||
|
# port defines the port to use for this route. They do not have to be unique.
|
||||||
|
port: "8080",
|
||||||
# services defines the services to use for this route. Services must be defined on a per-subdomain basis.
|
# services defines the services to use for this route. Services must be defined on a per-subdomain basis.
|
||||||
# Each service may not be used more than once globally. The server will fail to start if this is violated.
|
# Each service may not be used more than once globally. The server will fail to start if this is violated.
|
||||||
services: ["authentication"]
|
services: ["authentication"]
|
||||||
|
@ -56,7 +64,11 @@ routes: [
|
||||||
{
|
{
|
||||||
# any subdomain value that isn't "none" will match that specific subdomain.
|
# any subdomain value that isn't "none" will match that specific subdomain.
|
||||||
subdomain: "www.localhost",
|
subdomain: "www.localhost",
|
||||||
# https defines the HTTPS settings for this route.
|
# port defines the port to use for this route. They do not have to be unique.
|
||||||
|
port: "8443",
|
||||||
|
# https defines the HTTPS settings for this route. If this block is missing, HTTPS will not be enabled for this port.
|
||||||
|
# If https is set once for any subdomain with this port, it will be enabled for all subdomains with this port.
|
||||||
|
# The connection will fail if the above condition is true, but there is not an HTTPS block for that subdomain.
|
||||||
https: {
|
https: {
|
||||||
# certificate defines the path to the certificate file.
|
# certificate defines the path to the certificate file.
|
||||||
certificate: "./certs/localhost.crt",
|
certificate: "./certs/localhost.crt",
|
||||||
|
@ -66,8 +78,8 @@ routes: [
|
||||||
# paths defines per-path settings (NOT for services, which MUST be defined on a per-subdomain basis).
|
# paths defines per-path settings (NOT for services, which MUST be defined on a per-subdomain basis).
|
||||||
paths: [
|
paths: [
|
||||||
{
|
{
|
||||||
# path defines the path to match. They can contain wildcards.
|
# paths defines the paths to match. They can contain wildcards.
|
||||||
path: "/static/*",
|
paths: ["/static", "/static/*"],
|
||||||
# static defines the static file serving settings for this path. This conflicts with proxy and redirect.
|
# static defines the static file serving settings for this path. This conflicts with proxy and redirect.
|
||||||
# static > proxy > redirect in terms of precedence.
|
# static > proxy > redirect in terms of precedence.
|
||||||
static: {
|
static: {
|
||||||
|
@ -79,39 +91,43 @@ routes: [
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
# path defines the path to match. They can contain wildcards.
|
# paths defines the paths to match. They can contain wildcards.
|
||||||
path: "/proxy/*",
|
paths: ["/proxy", "/proxy/*"],
|
||||||
# proxy defines the proxy settings for this path. This conflicts with static and redirect.
|
# proxy defines the proxy settings for this path. This conflicts with static and redirect.
|
||||||
# static > proxy > redirect in terms of precedence.
|
# static > proxy > redirect in terms of precedence.
|
||||||
proxy: {
|
proxy: {
|
||||||
# url defines the URL to proxy requests to.
|
# url defines the URL to proxy requests to.
|
||||||
url: "http://localhost:8000",
|
url: "http://localhost:8000",
|
||||||
# stripPrefix defines whether to strip the prefix from the path before proxying.
|
# stripPrefix defines whether to strip the prefix from the path before proxying.
|
||||||
stripPrefix: true
|
stripPrefix: true,
|
||||||
headers: {
|
headers: {
|
||||||
# forbid defines the headers to forbid from being sent to the proxied server.
|
# forbid defines the headers to forbid from being sent to the proxied server.
|
||||||
forbid: ["Authorization"],
|
forbid: [ "User-Agent" ],
|
||||||
# preserve defines the headers to preserve when sending to the client.
|
# preserveServer defines whether to preserve the server header from the proxied server.
|
||||||
preserve: [X-Powered-By", "Server"]
|
preserveServer: true,
|
||||||
# host defines whether the host / :authority header should be sent to the proxied server.
|
# preserveAltSvc defines whether to preserve the Alt-Svc header from the proxied server.
|
||||||
host: true,
|
preserveAltSvc: true,
|
||||||
|
# preserveXPoweredBy defines whether to preserve the X-Powered-By header from the proxied server.
|
||||||
|
preserveXPoweredBy: true,
|
||||||
|
# passHost defines whether the host / :authority header should be sent to the proxied server.
|
||||||
|
passHost: true,
|
||||||
# xForward defines whether to send the X-Forwarded-For and X-Forwarded-Proto headers.
|
# xForward defines whether to send the X-Forwarded-For and X-Forwarded-Proto headers.
|
||||||
xForward: true
|
xForward: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
# path defines the path to match. They can contain wildcards.
|
# paths defines the paths to match. They can contain wildcards.
|
||||||
path: "/redirect/*",
|
paths: ["/redirect", "/redirect/*"],
|
||||||
# redirect defines the redirect settings for this path. This conflicts with proxy and static.
|
# redirect defines the redirect settings for this path. This conflicts with proxy and static.
|
||||||
# static > proxy > redirect in terms of precedence.
|
# static > proxy > redirect in terms of precedence.
|
||||||
redirect: {
|
redirect: {
|
||||||
# url defines the URL to redirect to.
|
# url defines the URL to redirect to.
|
||||||
url: "https://www.google.com",
|
url: "https://www.ailur.dev",
|
||||||
# permanent defines whether the redirect is permanent (301) or temporary (302).
|
# permanent defines whether the redirect is permanent (301) or temporary (302).
|
||||||
permanent: true
|
permanent: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
216
main.go
216
main.go
|
@ -1,7 +1,10 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
library "git.ailur.dev/ailur/fg-library/v2"
|
library "git.ailur.dev/ailur/fg-library/v2"
|
||||||
|
"os/signal"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
|
@ -40,18 +43,9 @@ import (
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Global struct {
|
Global struct {
|
||||||
IP string `yaml:"ip" validate:"required,ip_addr"`
|
IP string `yaml:"ip" validate:"required,ip_addr"`
|
||||||
HTTPPort string `yaml:"httpPort" validate:"required"`
|
|
||||||
HTTPSPort string `yaml:"httpsPort" validate:"required"`
|
|
||||||
ServiceDirectory string `yaml:"serviceDirectory" validate:"required"`
|
ServiceDirectory string `yaml:"serviceDirectory" validate:"required"`
|
||||||
ResourceDirectory string `yaml:"resourceDirectory" validate:"required"`
|
ResourceDirectory string `yaml:"resourceDirectory" validate:"required"`
|
||||||
Compression struct {
|
Compression CompressionSettings `yaml:"compression"`
|
||||||
Algorithm string `yaml:"algorithm" validate:"omitempty,oneof=gzip brotli zstd"`
|
|
||||||
Level float64 `yaml:"level" validate:"omitempty,min=1,max=22"`
|
|
||||||
} `yaml:"compression"`
|
|
||||||
HTTPS struct {
|
|
||||||
CertificatePath string `yaml:"certificate" validate:"required"`
|
|
||||||
KeyPath string `yaml:"key" validate:"required"`
|
|
||||||
} `yaml:"https"`
|
|
||||||
Logging struct {
|
Logging struct {
|
||||||
Enabled bool `yaml:"enabled"`
|
Enabled bool `yaml:"enabled"`
|
||||||
File string `yaml:"file" validate:"required_if=Enabled true"`
|
File string `yaml:"file" validate:"required_if=Enabled true"`
|
||||||
|
@ -72,6 +66,7 @@ type Config struct {
|
||||||
}
|
}
|
||||||
} `yaml:"global" validate:"required"`
|
} `yaml:"global" validate:"required"`
|
||||||
Routes []struct {
|
Routes []struct {
|
||||||
|
Port string `yaml:"port" validate:"required"`
|
||||||
Subdomain string `yaml:"subdomain" validate:"required"`
|
Subdomain string `yaml:"subdomain" validate:"required"`
|
||||||
Services []string `yaml:"services"`
|
Services []string `yaml:"services"`
|
||||||
Paths []struct {
|
Paths []struct {
|
||||||
|
@ -94,10 +89,7 @@ type Config struct {
|
||||||
CertificatePath string `yaml:"certificate" validate:"required"`
|
CertificatePath string `yaml:"certificate" validate:"required"`
|
||||||
KeyPath string `yaml:"key" validate:"required"`
|
KeyPath string `yaml:"key" validate:"required"`
|
||||||
} `yaml:"https"`
|
} `yaml:"https"`
|
||||||
Compression struct {
|
Compression CompressionSettings `yaml:"compression"`
|
||||||
Algorithm string `yaml:"algorithm" validate:"omitempty,oneof=gzip brotli zstd"`
|
|
||||||
Level float64 `yaml:"level" validate:"omitempty,min=1,max=22"`
|
|
||||||
} `yaml:"compression"`
|
|
||||||
} `yaml:"routes"`
|
} `yaml:"routes"`
|
||||||
Services map[string]interface{} `yaml:"services"`
|
Services map[string]interface{} `yaml:"services"`
|
||||||
}
|
}
|
||||||
|
@ -119,22 +111,75 @@ type Service struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type CompressionSettings struct {
|
type CompressionSettings struct {
|
||||||
Level int
|
Algorithm string `yaml:"algorithm" validate:"omitempty,oneof=gzip brotli zstd"`
|
||||||
Algorithm string
|
Level float64 `yaml:"level" validate:"omitempty,min=1,max=22"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkCompressionAlgorithm(algorithm string, handler http.Handler, request *http.Request) http.Handler {
|
type RouterAndCompression struct {
|
||||||
var compressionLevel int
|
Router *chi.Mux
|
||||||
compressionSettings, ok := compression[request.Host]
|
Compression CompressionSettings
|
||||||
|
}
|
||||||
|
|
||||||
|
type PortRouter struct {
|
||||||
|
https struct {
|
||||||
|
enabled bool
|
||||||
|
httpSettings map[string]*tls.Certificate
|
||||||
|
}
|
||||||
|
routers map[string]RouterAndCompression
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPortRouter() *PortRouter {
|
||||||
|
return &PortRouter{
|
||||||
|
routers: make(map[string]RouterAndCompression),
|
||||||
|
https: struct {
|
||||||
|
enabled bool
|
||||||
|
httpSettings map[string]*tls.Certificate
|
||||||
|
}{enabled: false, httpSettings: make(map[string]*tls.Certificate)},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pr *PortRouter) Register(router *chi.Mux, compression CompressionSettings, subdomain string, certificate ...*tls.Certificate) {
|
||||||
|
fmt.Println(subdomain)
|
||||||
|
pr.routers[subdomain] = RouterAndCompression{Router: router, Compression: compression}
|
||||||
|
fmt.Println(pr.routers)
|
||||||
|
if len(certificate) > 0 {
|
||||||
|
pr.https.enabled = true
|
||||||
|
pr.https.httpSettings[subdomain] = certificate[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pr *PortRouter) Router(w http.ResponseWriter, r *http.Request) {
|
||||||
|
host := strings.Split(r.Host, ":")[0]
|
||||||
|
router, ok := pr.routers[host]
|
||||||
if !ok {
|
if !ok {
|
||||||
compressionLevel = int(config.Global.Compression.Level)
|
fmt.Println(pr.routers)
|
||||||
} else {
|
router, ok = pr.routers["none"]
|
||||||
compressionLevel = compressionSettings.Level
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch algorithm {
|
if router.Compression.Algorithm != "none" {
|
||||||
|
compressRouter(router.Compression, router.Router).ServeHTTP(w, r)
|
||||||
|
} else {
|
||||||
|
router.Router.ServeHTTP(w, r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pr *PortRouter) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||||||
|
cert, ok := pr.https.httpSettings[hello.ServerName]
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("certificate not found")
|
||||||
|
} else {
|
||||||
|
return cert, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pr *PortRouter) HTTPSEnabled() bool {
|
||||||
|
return pr.https.enabled
|
||||||
|
}
|
||||||
|
|
||||||
|
func compressRouter(settings CompressionSettings, handler http.Handler) http.Handler {
|
||||||
|
switch settings.Algorithm {
|
||||||
case "gzip":
|
case "gzip":
|
||||||
encoder, err := gzip.New(gzip.Options{Level: compressionLevel})
|
encoder, err := gzip.New(gzip.Options{Level: int(settings.Level)})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("Error creating gzip encoder: " + err.Error())
|
slog.Error("Error creating gzip encoder: " + err.Error())
|
||||||
return handler
|
return handler
|
||||||
|
@ -146,7 +191,7 @@ func checkCompressionAlgorithm(algorithm string, handler http.Handler, request *
|
||||||
}
|
}
|
||||||
return gzipHandler(handler)
|
return gzipHandler(handler)
|
||||||
case "brotli":
|
case "brotli":
|
||||||
encoder, err := brotli.New(brotli.Options{Quality: compressionLevel})
|
encoder, err := brotli.New(brotli.Options{Quality: int(settings.Level)})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("Error creating brotli encoder: " + err.Error())
|
slog.Error("Error creating brotli encoder: " + err.Error())
|
||||||
return handler
|
return handler
|
||||||
|
@ -158,7 +203,7 @@ func checkCompressionAlgorithm(algorithm string, handler http.Handler, request *
|
||||||
}
|
}
|
||||||
return brotliHandler(handler)
|
return brotliHandler(handler)
|
||||||
case "zstd":
|
case "zstd":
|
||||||
encoder, err := zstd.New(kpzstd.WithEncoderLevel(kpzstd.EncoderLevelFromZstd(compressionLevel)))
|
encoder, err := zstd.New(kpzstd.WithEncoderLevel(kpzstd.EncoderLevelFromZstd(int(settings.Level))))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("Error creating zstd encoder: " + err.Error())
|
slog.Error("Error creating zstd encoder: " + err.Error())
|
||||||
return handler
|
return handler
|
||||||
|
@ -470,35 +515,13 @@ func serverError(w http.ResponseWriter, status int) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func hostRouter(w http.ResponseWriter, r *http.Request) {
|
|
||||||
host := strings.Split(r.Host, ":")[0]
|
|
||||||
router, ok := subdomains[host]
|
|
||||||
if !ok {
|
|
||||||
router, ok = subdomains["none"]
|
|
||||||
if !ok {
|
|
||||||
serverError(w, 404)
|
|
||||||
slog.Error("No subdomain found for " + host)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
compressionSettings, ok := compression[host]
|
|
||||||
if !ok {
|
|
||||||
checkCompressionAlgorithm(config.Global.Compression.Algorithm, router, r).ServeHTTP(w, r)
|
|
||||||
} else {
|
|
||||||
checkCompressionAlgorithm(compressionSettings.Algorithm, router, r).ServeHTTP(w, r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
validate *validator.Validate
|
validate *validator.Validate
|
||||||
lock sync.RWMutex
|
lock sync.RWMutex
|
||||||
config Config
|
config Config
|
||||||
registeredServices = make(map[string]Service)
|
registeredServices = make(map[string]Service)
|
||||||
activeServices = make(map[uuid.UUID]Service)
|
activeServices = make(map[uuid.UUID]Service)
|
||||||
certificates = make(map[string]*tls.Certificate)
|
portRouters = make(map[string]*PortRouter)
|
||||||
compression = make(map[string]CompressionSettings)
|
|
||||||
subdomains = make(map[string]*chi.Mux)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func loadTLSCertificate(certificatePath, keyPath string) (*tls.Certificate, error) {
|
func loadTLSCertificate(certificatePath, keyPath string) (*tls.Certificate, error) {
|
||||||
|
@ -510,19 +533,6 @@ func loadTLSCertificate(certificatePath, keyPath string) (*tls.Certificate, erro
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTLSCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
|
||||||
cert, ok := certificates[hello.ServerName]
|
|
||||||
if !ok {
|
|
||||||
if config.Global.HTTPS.CertificatePath == "" || config.Global.HTTPS.KeyPath == "" {
|
|
||||||
return nil, errors.New("no certificate found")
|
|
||||||
} else {
|
|
||||||
return certificates["none"], nil
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return cert, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func svInit(message library.InterServiceMessage) {
|
func svInit(message library.InterServiceMessage) {
|
||||||
// Service database initialization message
|
// Service database initialization message
|
||||||
// Check if the service has the necessary permissions
|
// Check if the service has the necessary permissions
|
||||||
|
@ -883,11 +893,11 @@ func parseConfig(path string) Config {
|
||||||
|
|
||||||
func iterateThroughSubdomains(globalOutbox chan library.InterServiceMessage) {
|
func iterateThroughSubdomains(globalOutbox chan library.InterServiceMessage) {
|
||||||
for _, route := range config.Routes {
|
for _, route := range config.Routes {
|
||||||
if route.Compression.Level != 0 {
|
var compressionSettings CompressionSettings
|
||||||
compression[route.Subdomain] = CompressionSettings{
|
if route.Compression != (CompressionSettings{}) {
|
||||||
Level: int(route.Compression.Level),
|
compressionSettings = route.Compression
|
||||||
Algorithm: route.Compression.Algorithm,
|
} else {
|
||||||
}
|
compressionSettings = config.Global.Compression
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the subdomain router
|
// Create the subdomain router
|
||||||
|
@ -896,9 +906,22 @@ func iterateThroughSubdomains(globalOutbox chan library.InterServiceMessage) {
|
||||||
serverError(w, 404)
|
serverError(w, 404)
|
||||||
})
|
})
|
||||||
|
|
||||||
subdomains[route.Subdomain] = subdomainRouter
|
_, ok := portRouters[route.Port]
|
||||||
subdomains[route.Subdomain].Use(logger)
|
if !ok {
|
||||||
subdomains[route.Subdomain].Use(serverChanger)
|
portRouters[route.Port] = NewPortRouter()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if HTTPS is enabled
|
||||||
|
if route.HTTPS.KeyPath != "" && route.HTTPS.CertificatePath != "" {
|
||||||
|
certificate, err := loadTLSCertificate(route.HTTPS.CertificatePath, route.HTTPS.KeyPath)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("Error loading TLS certificate: " + err.Error())
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
portRouters[route.Port].Register(subdomainRouter, compressionSettings, route.Subdomain, certificate)
|
||||||
|
} else {
|
||||||
|
portRouters[route.Port].Register(subdomainRouter, compressionSettings, route.Subdomain)
|
||||||
|
}
|
||||||
|
|
||||||
// Check the services
|
// Check the services
|
||||||
if route.Services != nil {
|
if route.Services != nil {
|
||||||
|
@ -953,15 +976,6 @@ func iterateThroughSubdomains(globalOutbox chan library.InterServiceMessage) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the TLS certificate
|
|
||||||
if route.HTTPS.CertificatePath != "" && route.HTTPS.KeyPath != "" {
|
|
||||||
certificate, err := loadTLSCertificate(route.HTTPS.CertificatePath, route.HTTPS.KeyPath)
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("Error loading TLS certificate: " + err.Error() + ", TLS will not be available for subdomain " + route.Subdomain)
|
|
||||||
}
|
|
||||||
certificates[route.Subdomain] = certificate
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1075,16 +1089,6 @@ func main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the root TLS certificate exists
|
|
||||||
if config.Global.HTTPS.CertificatePath != "" && config.Global.HTTPS.KeyPath != "" {
|
|
||||||
certificate, err := loadTLSCertificate(config.Global.HTTPS.CertificatePath, config.Global.HTTPS.KeyPath)
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("Error loading TLS certificate: " + err.Error() + ", TLS will not be available unless specified in the subdomains")
|
|
||||||
}
|
|
||||||
|
|
||||||
certificates["none"] = certificate
|
|
||||||
}
|
|
||||||
|
|
||||||
// Walk through the service directory and load the plugins
|
// Walk through the service directory and load the plugins
|
||||||
err := registerServices()
|
err := registerServices()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1105,31 +1109,37 @@ func main() {
|
||||||
// Iterate through the subdomains and create the routers as well as the compression levels and service maps
|
// Iterate through the subdomains and create the routers as well as the compression levels and service maps
|
||||||
iterateThroughSubdomains(globalOutbox)
|
iterateThroughSubdomains(globalOutbox)
|
||||||
|
|
||||||
// Start the server
|
// Start the servers
|
||||||
slog.Info("Starting server on " + config.Global.IP + " with ports " + config.Global.HTTPPort + " and " + config.Global.HTTPSPort)
|
for port, router := range portRouters {
|
||||||
|
slog.Info("Starting server on port " + port)
|
||||||
|
if !router.HTTPSEnabled() {
|
||||||
go func() {
|
go func() {
|
||||||
|
// Start the HTTP server
|
||||||
|
err = http.ListenAndServe(config.Global.IP+":"+port, logger(serverChanger(http.HandlerFunc(router.Router))))
|
||||||
|
slog.Error("Error starting server: " + err.Error())
|
||||||
|
os.Exit(1)
|
||||||
|
}()
|
||||||
|
} else {
|
||||||
// Create the TLS server
|
// Create the TLS server
|
||||||
server := &http.Server{
|
server := &http.Server{
|
||||||
Addr: config.Global.IP + ":" + config.Global.HTTPSPort,
|
Addr: config.Global.IP + ":" + port,
|
||||||
Handler: http.HandlerFunc(hostRouter),
|
Handler: logger(serverChanger(http.HandlerFunc(router.Router))),
|
||||||
TLSConfig: &tls.Config{
|
TLSConfig: &tls.Config{
|
||||||
GetCertificate: getTLSCertificate,
|
GetCertificate: router.GetCertificate,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
// Start the TLS server
|
// Start the TLS server
|
||||||
err = server.ListenAndServeTLS("", "")
|
err = server.ListenAndServeTLS("", "")
|
||||||
slog.Error("Error starting HTTPS server: " + err.Error())
|
slog.Error("Error starting HTTPS server: " + err.Error())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}()
|
}()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Start the HTTP server
|
// Wait for a signal to stop the server
|
||||||
err = http.ListenAndServe(config.Global.IP+":"+config.Global.HTTPPort, http.HandlerFunc(hostRouter))
|
signalChannel := make(chan os.Signal, 1)
|
||||||
if err != nil {
|
signal.Notify(signalChannel, os.Interrupt, syscall.SIGTERM)
|
||||||
slog.Error("Error starting server: " + err.Error())
|
<-signalChannel
|
||||||
} else {
|
|
||||||
// This should never happen
|
|
||||||
slog.Error("Bit flip error: Impossible service ID. Move away from radiation or use ECC memory.")
|
|
||||||
}
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue