In order to use TLS and HTTP/2, add the necessary certificate and the key to the staticFiles.zip file and configure Ocean to enable it.
		
			
				
	
	
		
			169 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			169 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package WebServer
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"github.com/SommerEngineering/Ocean/ConfigurationDB"
 | 
						|
	"github.com/SommerEngineering/Ocean/Handlers"
 | 
						|
	"github.com/SommerEngineering/Ocean/Log"
 | 
						|
	LM "github.com/SommerEngineering/Ocean/Log/Meta"
 | 
						|
	"github.com/SommerEngineering/Ocean/StaticFiles"
 | 
						|
	"github.com/SommerEngineering/Ocean/Tools"
 | 
						|
	"io/ioutil"
 | 
						|
	"net/http"
 | 
						|
	"os"
 | 
						|
	"path/filepath"
 | 
						|
	"strconv"
 | 
						|
	"strings"
 | 
						|
	"time"
 | 
						|
)
 | 
						|
 | 
						|
// Setup the web server.
 | 
						|
func init() {
 | 
						|
 | 
						|
	Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameSTARTUP, `Init the web server now.`)
 | 
						|
	defer Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameSTARTUP, `Done init the web server.`)
 | 
						|
 | 
						|
	// Public web server: use the servers public facing IP address and the configured port:
 | 
						|
	serverPublicAddressPort = Tools.LocalIPAddressAndPort()
 | 
						|
 | 
						|
	// Private web server: use the configured end point:
 | 
						|
	serverAdminAddressPort = ConfigurationDB.Read(`AdminWebServerBinding`)
 | 
						|
 | 
						|
	// Setup the public web server:
 | 
						|
	serverPublic = &http.Server{}
 | 
						|
	serverPublic.Addr = serverPublicAddressPort
 | 
						|
	serverPublic.Handler = Handlers.GetPublicMux()
 | 
						|
	serverPublic.SetKeepAlivesEnabled(true)
 | 
						|
 | 
						|
	// Public Web Server: Read Timeout
 | 
						|
	if readTimeoutSeconds, errTimeout := strconv.Atoi(ConfigurationDB.Read(`PublicWebServerReadTimeoutSeconds`)); errTimeout != nil {
 | 
						|
 | 
						|
		// Case: Error! Use a default timeout:
 | 
						|
		Log.LogFull(senderName, LM.CategorySYSTEM, LM.LevelWARN, LM.SeverityLow, LM.ImpactLow, LM.MessageNameCONFIGURATION, `Was not able to read the public server's read timeout value. Use the default of 10 seconds instead.`, errTimeout.Error())
 | 
						|
		serverPublic.ReadTimeout = 10 * time.Second
 | 
						|
	} else {
 | 
						|
		Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameCONFIGURATION, fmt.Sprintf("The public web server's read timeout was set to %d seconds.", readTimeoutSeconds))
 | 
						|
		serverPublic.ReadTimeout = time.Duration(readTimeoutSeconds) * time.Second
 | 
						|
	}
 | 
						|
 | 
						|
	// Public Web Server: Write Timeout
 | 
						|
	if writeTimeoutSeconds, errTimeout := strconv.Atoi(ConfigurationDB.Read(`PublicWebServerWriteTimeoutSeconds`)); errTimeout != nil {
 | 
						|
 | 
						|
		// Case: Error! Use a default timeout:
 | 
						|
		Log.LogFull(senderName, LM.CategorySYSTEM, LM.LevelWARN, LM.SeverityLow, LM.ImpactLow, LM.MessageNameCONFIGURATION, `Was not able to read the public server's write timeout value. Use the default of 10 seconds instead.`, errTimeout.Error())
 | 
						|
		serverPublic.WriteTimeout = 10 * time.Second
 | 
						|
	} else {
 | 
						|
		Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameCONFIGURATION, fmt.Sprintf("The public web server's write timeout was set to %d seconds.", writeTimeoutSeconds))
 | 
						|
		serverPublic.WriteTimeout = time.Duration(writeTimeoutSeconds) * time.Second
 | 
						|
	}
 | 
						|
 | 
						|
	// Public Web Server: Max. Header Size
 | 
						|
	if maxHeaderBytes, errHeaderBytes := strconv.Atoi(ConfigurationDB.Read(`PublicWebServerMaxHeaderLenBytes`)); errHeaderBytes != nil {
 | 
						|
 | 
						|
		// Case: Error! Use a default threshold for the header size:
 | 
						|
		Log.LogFull(senderName, LM.CategorySYSTEM, LM.LevelWARN, LM.SeverityLow, LM.ImpactLow, LM.MessageNameCONFIGURATION, `Was not able to read the public server's max. header size. Use the default of 1048576 bytes instead.`, errHeaderBytes.Error())
 | 
						|
		serverPublic.MaxHeaderBytes = 1048576
 | 
						|
	} else {
 | 
						|
		Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameCONFIGURATION, fmt.Sprintf("The public web server's max. header size was set to %d bytes.", maxHeaderBytes))
 | 
						|
		serverPublic.MaxHeaderBytes = maxHeaderBytes
 | 
						|
	}
 | 
						|
 | 
						|
	// Is TLS configured?
 | 
						|
	if publicTLSEnabled := ConfigurationDB.Read(`PublicWebServerUseTLS`); strings.ToLower(publicTLSEnabled) == `true` {
 | 
						|
 | 
						|
		// TLS is enabled. Copy the certificate and private key to the source directory.
 | 
						|
		publicTLSCertificate := StaticFiles.FindAndReadFileINTERNAL(ConfigurationDB.Read(`PublicWebServerTLSCertificateName`))
 | 
						|
		publicTLSPrivateKey := StaticFiles.FindAndReadFileINTERNAL(ConfigurationDB.Read(`PublicWebServerTLSPrivateKey`))
 | 
						|
 | 
						|
		// Access to the working directory?
 | 
						|
		currentDir, dirError := os.Getwd()
 | 
						|
		if dirError != nil {
 | 
						|
			Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelERROR, LM.MessageNameCONFIGURATION, `Was not able to read the working directory. Thus, cannot store the TLS certificates!`, dirError.Error())
 | 
						|
		} else {
 | 
						|
			// Build the filenames:
 | 
						|
			pathCertificate := filepath.Join(currentDir, ConfigurationDB.Read(`PublicWebServerTLSCertificateName`))
 | 
						|
			pathPrivateKey := filepath.Join(currentDir, ConfigurationDB.Read(`PublicWebServerTLSPrivateKey`))
 | 
						|
 | 
						|
			// Write the files:
 | 
						|
			if writeError := ioutil.WriteFile(pathCertificate, publicTLSCertificate, 0660); writeError != nil {
 | 
						|
				Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelERROR, LM.MessageNameCONFIGURATION, `Was not able to write the TLS certificate to the working directory.`, writeError.Error())
 | 
						|
			}
 | 
						|
			if writeError := ioutil.WriteFile(pathPrivateKey, publicTLSPrivateKey, 0660); writeError != nil {
 | 
						|
				Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelERROR, LM.MessageNameCONFIGURATION, `Was not able to write the TLS private key to the working directory.`, writeError.Error())
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	// Is the private web server (i.e. administration server) enabled?
 | 
						|
	if strings.ToLower(ConfigurationDB.Read(`AdminWebServerEnabled`)) == `true` {
 | 
						|
 | 
						|
		// Setup the private web server:
 | 
						|
		serverAdmin = &http.Server{}
 | 
						|
		serverAdmin.Addr = serverAdminAddressPort
 | 
						|
		serverAdmin.Handler = Handlers.GetAdminMux()
 | 
						|
		serverAdmin.SetKeepAlivesEnabled(true)
 | 
						|
 | 
						|
		// Admin Web Server: Read Timeout
 | 
						|
		if readTimeoutSeconds, errTimeout := strconv.Atoi(ConfigurationDB.Read(`AdminWebServerReadTimeoutSeconds`)); errTimeout != nil {
 | 
						|
 | 
						|
			// Case: Error! Use a default timeout:
 | 
						|
			Log.LogFull(senderName, LM.CategorySYSTEM, LM.LevelWARN, LM.SeverityLow, LM.ImpactLow, LM.MessageNameCONFIGURATION, `Was not able to read the admin server's read timeout value. Use the default of 10 seconds instead.`, errTimeout.Error())
 | 
						|
			serverAdmin.ReadTimeout = 10 * time.Second
 | 
						|
		} else {
 | 
						|
			Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameCONFIGURATION, fmt.Sprintf("The admin web server's read timeout was set to %d seconds.", readTimeoutSeconds))
 | 
						|
			serverAdmin.ReadTimeout = time.Duration(readTimeoutSeconds) * time.Second
 | 
						|
		}
 | 
						|
 | 
						|
		// Admin Web Server: Write Timeout
 | 
						|
		if writeTimeoutSeconds, errTimeout := strconv.Atoi(ConfigurationDB.Read(`AdminWebServerWriteTimeoutSeconds`)); errTimeout != nil {
 | 
						|
 | 
						|
			// Case: Error! Use a default timeout:
 | 
						|
			Log.LogFull(senderName, LM.CategorySYSTEM, LM.LevelWARN, LM.SeverityLow, LM.ImpactLow, LM.MessageNameCONFIGURATION, `Was not able to read the admin server's write timeout value. Use the default of 10 seconds instead.`, errTimeout.Error())
 | 
						|
			serverAdmin.WriteTimeout = 10 * time.Second
 | 
						|
		} else {
 | 
						|
			Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameCONFIGURATION, fmt.Sprintf("The admin web server's write timeout was set to %d seconds.", writeTimeoutSeconds))
 | 
						|
			serverAdmin.WriteTimeout = time.Duration(writeTimeoutSeconds) * time.Second
 | 
						|
		}
 | 
						|
 | 
						|
		// Admin Web Server: Max. Header Size
 | 
						|
		if maxHeaderBytes, errHeaderBytes := strconv.Atoi(ConfigurationDB.Read(`AdminWebServerMaxHeaderLenBytes`)); errHeaderBytes != nil {
 | 
						|
 | 
						|
			// Case: Error! Use a default threshold for the header size:
 | 
						|
			Log.LogFull(senderName, LM.CategorySYSTEM, LM.LevelWARN, LM.SeverityLow, LM.ImpactLow, LM.MessageNameCONFIGURATION, `Was not able to read the admin server's max. header size. Use the default of 1048576 bytes instead.`, errHeaderBytes.Error())
 | 
						|
			serverAdmin.MaxHeaderBytes = 1048576
 | 
						|
		} else {
 | 
						|
			Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameCONFIGURATION, fmt.Sprintf("The admin web server's max. header size was set to %d bytes.", maxHeaderBytes))
 | 
						|
			serverAdmin.MaxHeaderBytes = maxHeaderBytes
 | 
						|
		}
 | 
						|
 | 
						|
		// Is TLS configured?
 | 
						|
		if adminTLSEnabled := ConfigurationDB.Read(`AdminWebServerUseTLS`); strings.ToLower(adminTLSEnabled) == `true` {
 | 
						|
 | 
						|
			// TLS is enabled. Copy the certificate and private key to the source directory.
 | 
						|
			adminTLSCertificate := StaticFiles.FindAndReadFileINTERNAL(ConfigurationDB.Read(`AdminWebServerTLSCertificateName`))
 | 
						|
			adminTLSPrivateKey := StaticFiles.FindAndReadFileINTERNAL(ConfigurationDB.Read(`AdminWebServerTLSPrivateKey`))
 | 
						|
 | 
						|
			// Access to the working directory?
 | 
						|
			currentDir, dirError := os.Getwd()
 | 
						|
			if dirError != nil {
 | 
						|
				Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelERROR, LM.MessageNameCONFIGURATION, `Was not able to read the working directory. Thus, cannot store the TLS certificates!`, dirError.Error())
 | 
						|
			} else {
 | 
						|
				// Build the filenames:
 | 
						|
				pathCertificate := filepath.Join(currentDir, ConfigurationDB.Read(`AdminWebServerTLSCertificateName`))
 | 
						|
				pathPrivateKey := filepath.Join(currentDir, ConfigurationDB.Read(`AdminWebServerTLSPrivateKey`))
 | 
						|
 | 
						|
				// Write the files:
 | 
						|
				if writeError := ioutil.WriteFile(pathCertificate, adminTLSCertificate, 0660); writeError != nil {
 | 
						|
					Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelERROR, LM.MessageNameCONFIGURATION, `Was not able to write the TLS certificate to the working directory.`, writeError.Error())
 | 
						|
				}
 | 
						|
				if writeError := ioutil.WriteFile(pathPrivateKey, adminTLSPrivateKey, 0660); writeError != nil {
 | 
						|
					Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelERROR, LM.MessageNameCONFIGURATION, `Was not able to write the TLS private key to the working directory.`, writeError.Error())
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
	} else {
 | 
						|
		// Private web server is disabled:
 | 
						|
		Log.LogShort(senderName, LM.CategorySYSTEM, LM.LevelINFO, LM.MessageNameSTARTUP, `The admin web server is disabled.`)
 | 
						|
	}
 | 
						|
}
 |