Improve web service related aspects
This commit is contained in:
@@ -1,9 +1,21 @@
|
||||
{
|
||||
"server": {
|
||||
"host": "0.0.0.0",
|
||||
"port": 2233
|
||||
"port": 2233,
|
||||
"tls": {
|
||||
"enabled": false,
|
||||
"cert_file": "",
|
||||
"key_file": ""
|
||||
},
|
||||
"advanced": {
|
||||
"read_timeout": 30,
|
||||
"write_timeout": 30,
|
||||
"idle_timeout": 300,
|
||||
"max_header_bytes": 1
|
||||
}
|
||||
},
|
||||
"database": {
|
||||
"driver": "mysql",
|
||||
"host": "localhost",
|
||||
"port": 3306,
|
||||
"username": "root",
|
||||
|
||||
1
internal/handler/index.go
Normal file
1
internal/handler/index.go
Normal file
@@ -0,0 +1 @@
|
||||
package handler
|
||||
20
internal/handler/stop.go
Normal file
20
internal/handler/stop.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// HandleStop handles the stop signal and exits the program.
|
||||
func HandleStop() {
|
||||
sigCh := make(chan os.Signal, 1)
|
||||
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
|
||||
|
||||
go func() {
|
||||
sig := <-sigCh
|
||||
log.Printf("[Info] Received signal: %v,stopping...\r\n", sig)
|
||||
os.Exit(0)
|
||||
}()
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
config Config
|
||||
configOnce sync.Once
|
||||
configErr error
|
||||
configPath string
|
||||
)
|
||||
|
||||
// loadConfig initializes the config from file
|
||||
func loadConfig() {
|
||||
exePath, err := os.Executable()
|
||||
configPath := os.Getenv("CONFIG_PATH")
|
||||
if err != nil {
|
||||
configErr = err
|
||||
return
|
||||
}
|
||||
if configPath == "" {
|
||||
exeDir := filepath.Dir(exePath)
|
||||
configPath = filepath.Join(exeDir, "config.json")
|
||||
}
|
||||
|
||||
data, err := os.ReadFile(configPath)
|
||||
if err != nil {
|
||||
configErr = err
|
||||
return
|
||||
}
|
||||
|
||||
err = json.Unmarshal(data, &config)
|
||||
if err != nil {
|
||||
configErr = err
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// GetConfig returns the singleton instance of the config.
|
||||
// It's safe for concurrent use and loads the config only once per process lifetime.
|
||||
func GetConfig() (*Config, error) {
|
||||
configOnce.Do(loadConfig)
|
||||
return &config, configErr
|
||||
}
|
||||
|
||||
// ConfigPath returns the path to the loaded config file (useful for logging or reload later if needed)
|
||||
func ConfigPath() string {
|
||||
// Make sure config is at least attempted to be loaded
|
||||
configOnce.Do(loadConfig)
|
||||
return configPath
|
||||
}
|
||||
|
||||
1
internal/service/route.go
Normal file
1
internal/service/route.go
Normal file
@@ -0,0 +1 @@
|
||||
package service
|
||||
@@ -5,8 +5,20 @@ type Config struct {
|
||||
Server struct {
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
Tls struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
Cert string `json:"cert_file"`
|
||||
Key string `json:"key_file"`
|
||||
} `json:"tls"`
|
||||
Advanced struct {
|
||||
Readtimeout int `json:"read_timeout"`
|
||||
Writetimeout int `json:"write_timeout"`
|
||||
Idletimeout int `json:"idle_timeout"`
|
||||
Maxheaderbytes int `json:"max_header_bytes"`
|
||||
} `json:"advanced"`
|
||||
} `json:"server"`
|
||||
Database struct {
|
||||
Driver string `json:"driver"`
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
Username string `json:"username"`
|
||||
|
||||
@@ -1,15 +1,66 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"log"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
func WebService() {
|
||||
log.Printf("[Info] Starting web service")
|
||||
log.Printf("[Info] Web service started on 0.0.0.0:2233")
|
||||
err := http.ListenAndServe("0.0.0.0:2233", nil)
|
||||
func getServerAddress(host string, port int) string {
|
||||
return host + ":" + strconv.Itoa(port)
|
||||
}
|
||||
|
||||
func CreateWebService() *http.Server {
|
||||
log.Printf("[Info] Create web service")
|
||||
config, err := GetConfig()
|
||||
if err != nil {
|
||||
log.Fatalf("[Error] Failed to start server: %v", err)
|
||||
log.Fatalf("[Error] Failed to load config: %v", err)
|
||||
}
|
||||
|
||||
addr := getServerAddress(config.Server.Host, config.Server.Port)
|
||||
|
||||
server := &http.Server{
|
||||
Addr: addr,
|
||||
ReadTimeout: time.Duration(config.Server.Advanced.Readtimeout) * time.Second,
|
||||
WriteTimeout: time.Duration(config.Server.Advanced.Writetimeout) * time.Second,
|
||||
IdleTimeout: time.Duration(config.Server.Advanced.Idletimeout) * time.Second,
|
||||
MaxHeaderBytes: config.Server.Advanced.Maxheaderbytes << 16,
|
||||
}
|
||||
if config.Server.Tls.Enabled {
|
||||
log.Printf("[Info] TLS enabled")
|
||||
server.TLSConfig = &tls.Config{
|
||||
PreferServerCipherSuites: true,
|
||||
SessionTicketsDisabled: false,
|
||||
}
|
||||
}
|
||||
return server
|
||||
}
|
||||
|
||||
func ListenWebService(server *http.Server) {
|
||||
config, err := GetConfig()
|
||||
if err != nil {
|
||||
log.Fatalf("[Error] Failed to load config: %v", err)
|
||||
}
|
||||
addr := getServerAddress(config.Server.Host, config.Server.Port)
|
||||
if config.Server.Tls.Enabled {
|
||||
log.Printf("[Info] Starting HTTPS server on %s", addr)
|
||||
err := server.ListenAndServeTLS(
|
||||
config.Server.Tls.Cert,
|
||||
config.Server.Tls.Key,
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatalf("[Error] HTTPS server failed: %v", err)
|
||||
}
|
||||
} else {
|
||||
log.Printf("[Info] Starting HTTP server on %s", addr)
|
||||
err := server.ListenAndServe()
|
||||
if err != nil {
|
||||
log.Fatalf("[Error] HTTP server failed: %v", err)
|
||||
}
|
||||
}
|
||||
if err != nil && err != http.ErrServerClosed {
|
||||
log.Fatalf("[Error] Web server terminated unexpectedly: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user