This commit is contained in:
despiegk 2025-05-24 06:56:02 +04:00
parent 55a05a5571
commit b8c8da9e31
11 changed files with 517 additions and 119 deletions

View File

@ -5,49 +5,72 @@ import (
"fmt"
"log"
"os"
"strconv"
"git.ourworld.tf/herocode/heroagent/pkg/heroagent"
"git.ourworld.tf/herocode/heroagent/pkg/servers/ui" // Import the new UI package
"git.ourworld.tf/herocode/heroagent/pkg/servers/heroagent"
)
func main() {
// Parse command-line flags
portFlag := flag.String("port", "", "Port to run the HeroLauncher on")
uiPortFlag := flag.String("uiport", "3000", "Port to run the UI server on") // New flag for UI port
redisPortFlag := flag.Int("redisport", 6378, "Port to run the Redis server on")
webdavPortFlag := flag.Int("webdavport", 9001, "Port to run the WebDAV server on")
uiPortFlag := flag.Int("uiport", 9002, "Port to run the UI server on")
// Flags to enable/disable specific servers
enableRedisFlag := flag.Bool("redis", true, "Enable Redis server")
enableWebDAVFlag := flag.Bool("webdav", true, "Enable WebDAV server")
enableUIFlag := flag.Bool("ui", true, "Enable UI server")
flag.Parse()
// Initialize HeroLauncher with default configuration
// Initialize ServerFactory with default configuration
config := heroagent.DefaultConfig()
// Override with command-line flags if provided
if *portFlag != "" {
config.Port = *portFlag
}
config.Redis.TCPPort = *redisPortFlag
config.WebDAV.Config.TCPPort = *webdavPortFlag
config.UI.Port = strconv.Itoa(*uiPortFlag)
// Set server enable flags
config.EnableRedis = *enableRedisFlag
config.EnableWebDAV = *enableWebDAVFlag
config.EnableUI = *enableUIFlag
// Override with environment variables if provided
if port := os.Getenv("PORT"); port != "" {
config.Port = port
if redisPortStr := os.Getenv("REDIS_PORT"); redisPortStr != "" {
if port, err := strconv.Atoi(redisPortStr); err == nil {
config.Redis.TCPPort = port
}
}
if webdavPortStr := os.Getenv("WEBDAV_PORT"); webdavPortStr != "" {
if port, err := strconv.Atoi(webdavPortStr); err == nil {
config.WebDAV.Config.TCPPort = port
}
}
if uiPort := os.Getenv("UI_PORT"); uiPort != "" {
config.UI.Port = uiPort
}
// Create HeroLauncher instance
launcher := heroagent.New(config)
// Create ServerFactory instance
factory := heroagent.New(config)
// Initialize and start the UI server in a new goroutine
go func() {
uiApp := ui.NewApp(ui.AppConfig{}) // Assuming default AppConfig is fine
uiPort := *uiPortFlag
if envUiPort := os.Getenv("UIPORT"); envUiPort != "" {
uiPort = envUiPort
}
fmt.Printf("Starting UI server on port %s...\n", uiPort)
if err := uiApp.Listen(":" + uiPort); err != nil {
log.Printf("Failed to start UI server: %v", err) // Use Printf to not exit main app
}
}()
// Start the main HeroLauncher server
fmt.Printf("Starting HeroLauncher on port %s...\n", config.Port)
if err := launcher.Start(); err != nil {
log.Fatalf("Failed to start HeroLauncher: %v", err)
// Start all servers
fmt.Println("Starting HeroAgent servers...")
if err := factory.Start(); err != nil {
log.Fatalf("Failed to start servers: %v", err)
}
fmt.Printf("All servers started successfully:\n")
if config.EnableRedis {
fmt.Printf("- Redis server running on port %d\n", config.Redis.TCPPort)
}
if config.EnableWebDAV {
fmt.Printf("- WebDAV server running on port %d\n", config.WebDAV.Config.TCPPort)
}
if config.EnableUI {
fmt.Printf("- UI server running on port %s\n", config.UI.Port)
}
// Keep the main goroutine running
select {}
}

1
go.mod
View File

@ -5,6 +5,7 @@ go 1.23.0
toolchain go1.23.6
require (
github.com/go-redis/redis/v8 v8.11.5
github.com/gofiber/fiber/v2 v2.52.8
github.com/gofiber/template/jet/v2 v2.1.12
github.com/mholt/archiver/v3 v3.5.1

14
go.sum
View File

@ -54,11 +54,15 @@ github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707/go.mod h1:qssHWj6
github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
github.com/gofiber/fiber/v2 v2.52.8 h1:xl4jJQ0BV5EJTA2aWiKw/VddRpHrKeZLF0QPUxqn0x4=
github.com/gofiber/fiber/v2 v2.52.8/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw=
github.com/gofiber/template v1.8.3 h1:hzHdvMwMo/T2kouz2pPCA0zGiLCeMnoGsQZBTSYgZxc=
@ -141,6 +145,12 @@ github.com/nwaples/rardecode v1.1.0 h1:vSxaY8vQhOcVr4mm5e8XllHWTiM4JF507A0Katqw7
github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
github.com/nwaples/rardecode/v2 v2.0.0-beta.4 h1:sdiJxQdPjECn2lh9nLFFhgLCf+0ulDU5rODbtERTlUY=
github.com/nwaples/rardecode/v2 v2.0.0-beta.4/go.mod h1:yntwv/HfMc/Hbvtq9I19D1n58te3h6KsqCf3GxyfBGY=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
@ -376,7 +386,11 @@ google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

BIN
heroagent Executable file

Binary file not shown.

106
pkg/herojobs/factory.go Normal file
View File

@ -0,0 +1,106 @@
package herojobs
import (
"context"
"fmt"
"time"
"github.com/go-redis/redis/v8"
)
const (
defaultRedisURL = "redis://localhost:6379/0"
)
// Factory manages job-related operations, including Redis connectivity and watchdog.
type Factory struct {
redisClient *redis.Client
// Add other fields as needed, e.g., for watchdog
}
// NewFactory creates a new Factory instance.
// It takes a redisURL string; if empty, it defaults to defaultRedisURL.
func NewFactory(redisURL string) (*Factory, error) {
if redisURL == "" {
redisURL = defaultRedisURL
}
opt, err := redis.ParseURL(redisURL)
if err != nil {
return nil, fmt.Errorf("invalid redis URL: %w", err)
}
client := redis.NewClient(opt)
// Check connection to Redis
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
_, err = client.Ping(ctx).Result()
if err != nil {
return nil, fmt.Errorf("failed to connect to redis at %s: %w", redisURL, err)
}
fmt.Printf("Successfully connected to Redis at %s\n", redisURL)
factory := &Factory{
redisClient: client,
}
// TODO: Properly start the watchdog here
fmt.Println("Watchdog placeholder: Watchdog would be started here.")
return factory, nil
}
// Close closes the Redis client connection.
func (f *Factory) Close() error {
if f.redisClient != nil {
return f.redisClient.Close()
}
return nil
}
// GetJob retrieves a job by its ID from Redis.
func (f *Factory) GetJob(ctx context.Context, jobID string) (string, error) {
// Example: Assuming jobs are stored as string values
val, err := f.redisClient.Get(ctx, jobID).Result()
if err == redis.Nil {
return "", fmt.Errorf("job with ID %s not found", jobID)
} else if err != nil {
return "", fmt.Errorf("failed to get job %s from redis: %w", jobID, err)
}
return val, nil
}
// ListJobs lists all job IDs (or a subset) from Redis.
// This is a simplified example; real-world job listing might involve more complex data structures.
func (f *Factory) ListJobs(ctx context.Context) ([]string, error) {
// Example: List all keys that might represent jobs.
// In a real application, you'd likely use specific Redis data structures (e.g., sorted sets, hashes)
// to manage jobs more efficiently and avoid scanning all keys.
keys, err := f.redisClient.Keys(ctx, "job:*").Result() // Assuming job keys are prefixed with "job:"
if err != nil {
return nil, fmt.Errorf("failed to list jobs from redis: %w", err)
}
return keys, nil
}
// AddJob adds a new job to Redis.
func (f *Factory) AddJob(ctx context.Context, jobID string, jobData string) error {
// Example: Store job data as a string
err := f.redisClient.Set(ctx, jobID, jobData, 0).Err() // 0 for no expiration
if err != nil {
return fmt.Errorf("failed to add job %s to redis: %w", jobID, err)
}
return nil
}
// DeleteJob deletes a job from Redis.
func (f *Factory) DeleteJob(ctx context.Context, jobID string) error {
_, err := f.redisClient.Del(ctx, jobID).Result()
if err != nil {
return fmt.Errorf("failed to delete job %s from redis: %w", jobID, err)
}
return nil
}

View File

@ -0,0 +1,63 @@
package heroagent
import (
"git.ourworld.tf/herocode/heroagent/pkg/servers/ui"
"git.ourworld.tf/herocode/heroagent/pkg/servers/webdavserver"
)
// Config holds the configuration for the HeroAgent server factory
type Config struct {
// Redis server configuration
Redis RedisConfig
// WebDAV server configuration
WebDAV WebDAVConfig
// UI server configuration
UI UIConfig
// Enable/disable specific servers
EnableRedis bool
EnableWebDAV bool
EnableUI bool
}
// RedisConfig holds the configuration for the Redis server
type RedisConfig struct {
TCPPort int
UnixSocketPath string
}
// WebDAVConfig holds the configuration for the WebDAV server
type WebDAVConfig struct {
// Use webdavserver.Config directly
Config webdavserver.Config
}
// UIConfig holds the configuration for the UI server
type UIConfig struct {
// UI server configuration
Port string
// Any additional UI-specific configuration
AppConfig ui.AppConfig
}
// DefaultConfig returns the default configuration for the HeroAgent
func DefaultConfig() Config {
return Config{
Redis: RedisConfig{
TCPPort: 6378,
UnixSocketPath: "/tmp/redis.sock",
},
WebDAV: WebDAVConfig{
Config: webdavserver.DefaultConfig(),
},
UI: UIConfig{
Port: "9001", // Port is a string in UIConfig
AppConfig: ui.AppConfig{},
},
EnableRedis: true,
EnableWebDAV: true,
EnableUI: true,
}
}

View File

@ -0,0 +1,179 @@
package heroagent
import (
"fmt"
"log"
"sync"
"git.ourworld.tf/herocode/heroagent/pkg/servers/redisserver"
"git.ourworld.tf/herocode/heroagent/pkg/servers/ui"
"git.ourworld.tf/herocode/heroagent/pkg/servers/webdavserver"
"github.com/gofiber/fiber/v2"
)
// ServerFactory manages the lifecycle of all servers
type ServerFactory struct {
config Config
// Server instances
redisServer *redisserver.Server
webdavServer *webdavserver.Server
uiApp *AppInstance
// Control channels
stopCh chan struct{}
wg sync.WaitGroup
}
// AppInstance wraps the UI app and its listening status
type AppInstance struct {
App *fiber.App
Port string
}
// New creates a new ServerFactory with the given configuration
func New(config Config) *ServerFactory {
return &ServerFactory{
config: config,
stopCh: make(chan struct{}),
}
}
// Start initializes and starts all enabled servers
func (f *ServerFactory) Start() error {
log.Println("Starting HeroAgent ServerFactory...")
// Start Redis server if enabled
if f.config.EnableRedis {
if err := f.startRedisServer(); err != nil {
return fmt.Errorf("failed to start Redis server: %w", err)
}
}
// Start WebDAV server if enabled
if f.config.EnableWebDAV {
if err := f.startWebDAVServer(); err != nil {
return fmt.Errorf("failed to start WebDAV server: %w", err)
}
}
// Start UI server if enabled
if f.config.EnableUI {
if err := f.startUIServer(); err != nil {
return fmt.Errorf("failed to start UI server: %w", err)
}
}
log.Println("All servers started successfully")
return nil
}
// Stop gracefully stops all running servers
func (f *ServerFactory) Stop() error {
log.Println("Stopping all servers...")
// Signal all goroutines to stop
close(f.stopCh)
// Stop WebDAV server if it's running
if f.webdavServer != nil {
if err := f.webdavServer.Stop(); err != nil {
log.Printf("Error stopping WebDAV server: %v", err)
}
}
// Wait for all goroutines to finish
f.wg.Wait()
log.Println("All servers stopped")
return nil
}
// startRedisServer initializes and starts the Redis server
func (f *ServerFactory) startRedisServer() error {
log.Println("Starting Redis server...")
// Create Redis server configuration
redisConfig := redisserver.ServerConfig{
TCPPort: f.config.Redis.TCPPort,
UnixSocketPath: f.config.Redis.UnixSocketPath,
}
// Create and start Redis server
f.redisServer = redisserver.NewServer(redisConfig)
log.Printf("Redis server started on port %d and socket %s",
redisConfig.TCPPort, redisConfig.UnixSocketPath)
return nil
}
// startWebDAVServer initializes and starts the WebDAV server
func (f *ServerFactory) startWebDAVServer() error {
log.Println("Starting WebDAV server...")
// Create WebDAV server
webdavServer, err := webdavserver.NewServer(f.config.WebDAV.Config)
if err != nil {
return fmt.Errorf("failed to create WebDAV server: %w", err)
}
f.webdavServer = webdavServer
// Start WebDAV server in a goroutine
f.wg.Add(1)
go func() {
defer f.wg.Done()
// Start the server
if err := webdavServer.Start(); err != nil {
log.Printf("WebDAV server error: %v", err)
}
}()
log.Printf("WebDAV server started on port %d", f.config.WebDAV.Config.TCPPort)
return nil
}
// startUIServer initializes and starts the UI server
func (f *ServerFactory) startUIServer() error {
log.Println("Starting UI server...")
// Create UI app
uiApp := ui.NewApp(f.config.UI.AppConfig)
// Store UI app instance
f.uiApp = &AppInstance{
App: uiApp,
Port: f.config.UI.Port,
}
// Start UI server in a goroutine
f.wg.Add(1)
go func() {
defer f.wg.Done()
// Start the server
addr := ":" + f.config.UI.Port
log.Printf("UI server listening on %s", addr)
if err := uiApp.Listen(addr); err != nil {
log.Printf("UI server error: %v", err)
}
}()
return nil
}
// GetRedisServer returns the Redis server instance
func (f *ServerFactory) GetRedisServer() *redisserver.Server {
return f.redisServer
}
// GetWebDAVServer returns the WebDAV server instance
func (f *ServerFactory) GetWebDAVServer() *webdavserver.Server {
return f.webdavServer
}
// GetUIApp returns the UI app instance
func (f *ServerFactory) GetUIApp() *AppInstance {
return f.uiApp
}

View File

@ -6,6 +6,7 @@ import (
"fmt"
"log"
"os"
"strconv"
"strings"
"sync"
"time"
@ -16,7 +17,7 @@ import (
func main() {
// Parse command line flags
tcpPort := flag.String("tcp-port", "7777", "Redis server TCP port")
tcpPortStr := flag.String("tcp-port", "7777", "Redis server TCP port")
unixSocket := flag.String("unix-socket", "/tmp/redis-test.sock", "Redis server Unix domain socket path")
username := flag.String("user", "jan", "Username to check")
mailbox := flag.String("mailbox", "inbox", "Mailbox to check")
@ -24,8 +25,13 @@ func main() {
dbNum := flag.Int("db", 0, "Redis database number")
flag.Parse()
tcpPort, err := strconv.Atoi(*tcpPortStr)
if err != nil {
log.Fatalf("Invalid TCP port: %v", err)
}
// Start Redis server in a goroutine
log.Printf("Starting Redis server on TCP port %s and Unix socket %s", *tcpPort, *unixSocket)
log.Printf("Starting Redis server on TCP port %d and Unix socket %s", tcpPort, *unixSocket)
// Create a wait group to ensure the server is started before testing
var wg sync.WaitGroup
@ -44,7 +50,7 @@ func main() {
// Start the Redis server in a goroutine
go func() {
// Create a new server instance
_ = redisserver.NewServer(redisserver.ServerConfig{TCPPort: *tcpPort, UnixSocketPath: *unixSocket})
_ = redisserver.NewServer(redisserver.ServerConfig{TCPPort: tcpPort, UnixSocketPath: *unixSocket})
// Signal that the server is ready
wg.Done()
@ -61,7 +67,7 @@ func main() {
// Test TCP connection
log.Println("Testing TCP connection")
tcpAddr := fmt.Sprintf("localhost:%s", *tcpPort)
tcpAddr := fmt.Sprintf("localhost:%d", tcpPort)
testRedisConnection(tcpAddr, username, mailbox, debug, dbNum)
// Test Unix socket connection if supported

View File

@ -62,14 +62,19 @@ func (ts *TestSuite) PrintResults() {
func main() {
// Parse command line flags
tcpPort := flag.String("tcp-port", "7777", "Redis server TCP port")
tcpPortStr := flag.String("tcp-port", "7777", "Redis server TCP port")
unixSocket := flag.String("unix-socket", "/tmp/redis-test.sock", "Redis server Unix domain socket path")
debug := flag.Bool("debug", false, "Enable debug output")
dbNum := flag.Int("db", 0, "Redis database number")
flag.Parse()
tcpPortInt, err := strconv.Atoi(*tcpPortStr)
if err != nil {
log.Fatalf("Invalid TCP port: %v", err)
}
// Start Redis server in a goroutine
log.Printf("Starting Redis server on TCP port %s and Unix socket %s", *tcpPort, *unixSocket)
log.Printf("Starting Redis server on TCP port %d and Unix socket %s", tcpPortInt, *unixSocket)
// Create a wait group to ensure the server is started before testing
var wg sync.WaitGroup
@ -88,7 +93,7 @@ func main() {
// Start the Redis server in a goroutine
go func() {
// Create a new server instance
_ = redisserver.NewServer(redisserver.ServerConfig{TCPPort: *tcpPort, UnixSocketPath: *unixSocket})
_ = redisserver.NewServer(redisserver.ServerConfig{TCPPort: tcpPortInt, UnixSocketPath: *unixSocket})
// Signal that the server is ready
wg.Done()
@ -105,7 +110,7 @@ func main() {
// Test TCP connection
log.Println("Testing TCP connection")
tcpAddr := fmt.Sprintf("localhost:%s", *tcpPort)
tcpAddr := fmt.Sprintf("localhost:%d", tcpPortInt)
runTests(tcpAddr, *debug, *dbNum)
// Test Unix socket connection if supported

View File

@ -1,6 +1,7 @@
package redisserver
import (
"strconv"
"sync"
"time"
)
@ -20,7 +21,7 @@ type Server struct {
}
type ServerConfig struct {
TCPPort string
TCPPort int
UnixSocketPath string
}
@ -38,8 +39,8 @@ func NewServer(config ServerConfig) *Server {
go s.cleanupExpiredKeys()
// Start TCP server if port is provided
if config.TCPPort != "" {
tcpAddr := ":" + config.TCPPort
if config.TCPPort != 0 {
tcpAddr := ":" + strconv.Itoa(config.TCPPort)
go s.startRedisServer(tcpAddr, "")
}

View File

@ -26,22 +26,22 @@ import (
// Config holds the configuration for the WebDAV server
type Config struct {
Host string
Port int
BasePath string
FileSystem string
ReadTimeout time.Duration
WriteTimeout time.Duration
DebugMode bool
UseAuth bool
Username string
Password string
UseHTTPS bool
CertFile string
KeyFile string
AutoGenerateCerts bool
CertValidityDays int
CertOrganization string
Host string
TCPPort int
BasePath string
FileSystem string
ReadTimeout time.Duration
WriteTimeout time.Duration
DebugMode bool
UseAuth bool
Username string
Password string
UseHTTPS bool
CertFile string
KeyFile string
AutoGenerateCerts bool
CertValidityDays int
CertOrganization string
}
// Server represents the WebDAV server
@ -74,8 +74,8 @@ func (rw *responseWrapper) Write(b []byte) (int, error) {
// NewServer creates a new WebDAV server
func NewServer(config Config) (*Server, error) {
log.Printf("Creating new WebDAV server with config: host=%s, port=%d, basePath=%s, fileSystem=%s, debug=%v, auth=%v, https=%v",
config.Host, config.Port, config.BasePath, config.FileSystem, config.DebugMode, config.UseAuth, config.UseHTTPS)
log.Printf("Creating new WebDAV server with config: host=%s, TCPPort=%d, basePath=%s, fileSystem=%s, debug=%v, auth=%v, https=%v",
config.Host, config.TCPPort, config.BasePath, config.FileSystem, config.DebugMode, config.UseAuth, config.UseHTTPS)
// Ensure the file system directory exists
if err := os.MkdirAll(config.FileSystem, 0755); err != nil {
@ -115,7 +115,7 @@ func NewServer(config Config) (*Server, error) {
// Create HTTP server
httpServer := &http.Server{
Addr: fmt.Sprintf("%s:%d", config.Host, config.Port),
Addr: fmt.Sprintf("%s:%d", config.Host, config.TCPPort),
ReadTimeout: config.ReadTimeout,
WriteTimeout: config.WriteTimeout,
}
@ -392,7 +392,7 @@ func DefaultConfig() Config {
return Config{
Host: "0.0.0.0",
Port: 9999,
TCPPort: 9999,
BasePath: "/",
FileSystem: defaultBasePath,
ReadTimeout: 30 * time.Second,