mirror of
https://github.com/yusing/godoxy.git
synced 2026-03-23 09:52:01 +01:00
This is a large-scale refactoring across the codebase that replaces the custom `gperr.Error` type with Go's standard `error` interface. The changes include: - Replacing `gperr.Error` return types with `error` in function signatures - Using `errors.New()` and `fmt.Errorf()` instead of `gperr.New()` and `gperr.Errorf()` - Using `%w` format verb for error wrapping instead of `.With()` method - Replacing `gperr.Subject()` calls with `gperr.PrependSubject()` - Converting error logging from `gperr.Log*()` functions to zerolog's `.Err().Msg()` pattern - Update NewLogger to handle multiline error message - Updating `goutils` submodule to latest commit This refactoring aligns with Go idioms and removes the dependency on custom error handling abstractions in favor of standard library patterns.
118 lines
2.8 KiB
Go
Executable File
118 lines
2.8 KiB
Go
Executable File
package route
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"net"
|
|
"strings"
|
|
|
|
"github.com/rs/zerolog/log"
|
|
entrypoint "github.com/yusing/godoxy/internal/entrypoint/types"
|
|
"github.com/yusing/godoxy/internal/health/monitor"
|
|
"github.com/yusing/godoxy/internal/idlewatcher"
|
|
nettypes "github.com/yusing/godoxy/internal/net/types"
|
|
"github.com/yusing/godoxy/internal/route/stream"
|
|
"github.com/yusing/godoxy/internal/types"
|
|
"github.com/yusing/goutils/task"
|
|
)
|
|
|
|
// TODO: support stream load balance.
|
|
type StreamRoute struct {
|
|
*Route
|
|
stream nettypes.Stream
|
|
}
|
|
|
|
var _ types.StreamRoute = (*StreamRoute)(nil)
|
|
|
|
func NewStreamRoute(base *Route) (types.Route, error) {
|
|
// TODO: support non-coherent scheme
|
|
return &StreamRoute{Route: base}, nil
|
|
}
|
|
|
|
func (r *StreamRoute) Stream() nettypes.Stream {
|
|
return r.stream
|
|
}
|
|
|
|
// Start implements task.TaskStarter.
|
|
func (r *StreamRoute) Start(parent task.Parent) error {
|
|
if r.LisURL == nil {
|
|
return errors.New("listen URL is not set")
|
|
}
|
|
|
|
stream, err := r.initStream()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
r.stream = stream
|
|
|
|
r.task = parent.Subtask("stream."+r.Name(), !r.ShouldExclude())
|
|
|
|
switch {
|
|
case r.UseIdleWatcher():
|
|
waker, err := idlewatcher.NewWatcher(parent, r, r.IdlewatcherConfig())
|
|
if err != nil {
|
|
r.task.Finish(err)
|
|
return fmt.Errorf("idlewatcher error: %w", err)
|
|
}
|
|
r.stream = waker
|
|
r.HealthMon = waker
|
|
case r.UseHealthCheck():
|
|
r.HealthMon = monitor.NewMonitor(r)
|
|
}
|
|
|
|
if r.HealthMon != nil {
|
|
if err := r.HealthMon.Start(r.task); err != nil {
|
|
log.Warn().Err(err).Msg("health monitor error")
|
|
r.HealthMon = nil
|
|
}
|
|
}
|
|
|
|
ep := entrypoint.FromCtx(parent.Context())
|
|
if ep == nil {
|
|
err := errors.New("entrypoint not initialized")
|
|
r.task.Finish(err)
|
|
return err
|
|
}
|
|
if err := ep.StartAddRoute(r); err != nil {
|
|
r.task.Finish(err)
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (r *StreamRoute) ListenAndServe(ctx context.Context, preDial, onRead nettypes.HookFunc) error {
|
|
return r.stream.ListenAndServe(ctx, preDial, onRead)
|
|
}
|
|
|
|
func (r *StreamRoute) Close() error {
|
|
return r.stream.Close()
|
|
}
|
|
|
|
func (r *StreamRoute) LocalAddr() net.Addr {
|
|
return r.stream.LocalAddr()
|
|
}
|
|
|
|
func (r *StreamRoute) initStream() (nettypes.Stream, error) {
|
|
lurl, rurl := r.LisURL, r.ProxyURL
|
|
// tcp4/tcp6 -> tcp, udp4/udp6 -> udp
|
|
lScheme := strings.TrimRight(lurl.Scheme, "46")
|
|
rScheme := strings.TrimRight(rurl.Scheme, "46")
|
|
if lScheme != rScheme {
|
|
return nil, fmt.Errorf("incoherent scheme is not yet supported: %s != %s", lurl.Scheme, rurl.Scheme)
|
|
}
|
|
|
|
laddr := ":0"
|
|
if lurl != nil {
|
|
laddr = lurl.Host
|
|
}
|
|
|
|
switch rScheme {
|
|
case "tcp":
|
|
return stream.NewTCPTCPStream(lurl.Scheme, rurl.Scheme, laddr, rurl.Host, r.GetAgent())
|
|
case "udp":
|
|
return stream.NewUDPUDPStream(lurl.Scheme, rurl.Scheme, laddr, rurl.Host, r.GetAgent())
|
|
}
|
|
return nil, fmt.Errorf("unknown scheme: %s", rurl.Scheme)
|
|
}
|