diff --git a/agent/cmd/main.go b/agent/cmd/main.go
index a4c7a28..2369706 100644
--- a/agent/cmd/main.go
+++ b/agent/cmd/main.go
@@ -6,7 +6,7 @@ import (
"github.com/yusing/go-proxy/agent/pkg/agent"
"github.com/yusing/go-proxy/agent/pkg/env"
"github.com/yusing/go-proxy/agent/pkg/server"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/logging"
"github.com/yusing/go-proxy/internal/task"
"github.com/yusing/go-proxy/pkg"
@@ -16,7 +16,7 @@ func main() {
args := os.Args
if len(args) > 1 && args[1] == "migrate" {
if err := agent.MigrateFromOld(); err != nil {
- E.LogFatal("failed to migrate from old docker compose", err)
+ gperr.LogFatal("failed to migrate from old docker compose", err)
}
return
}
@@ -24,21 +24,21 @@ func main() {
ca := &agent.PEMPair{}
err := ca.Load(env.AgentCACert)
if err != nil {
- E.LogFatal("init CA error", err)
+ gperr.LogFatal("init CA error", err)
}
caCert, err := ca.ToTLSCert()
if err != nil {
- E.LogFatal("init CA error", err)
+ gperr.LogFatal("init CA error", err)
}
srv := &agent.PEMPair{}
srv.Load(env.AgentSSLCert)
if err != nil {
- E.LogFatal("init SSL error", err)
+ gperr.LogFatal("init SSL error", err)
}
srvCert, err := srv.ToTLSCert()
if err != nil {
- E.LogFatal("init SSL error", err)
+ gperr.LogFatal("init SSL error", err)
}
logging.Info().Msgf("GoDoxy Agent version %s", pkg.GetVersion())
diff --git a/agent/pkg/agent/config.go b/agent/pkg/agent/config.go
index 7bcdc52..6849342 100644
--- a/agent/pkg/agent/config.go
+++ b/agent/pkg/agent/config.go
@@ -12,9 +12,9 @@ import (
"github.com/rs/zerolog"
"github.com/yusing/go-proxy/agent/pkg/certs"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/logging"
- gphttp "github.com/yusing/go-proxy/internal/net/http"
+ gphttp "github.com/yusing/go-proxy/internal/net/gphttp"
"github.com/yusing/go-proxy/internal/net/types"
"github.com/yusing/go-proxy/internal/task"
"github.com/yusing/go-proxy/pkg"
@@ -80,17 +80,17 @@ func checkVersion(a, b string) bool {
return withoutBuildTime(a) == withoutBuildTime(b)
}
-func (cfg *AgentConfig) StartWithCerts(parent task.Parent, ca, crt, key []byte) E.Error {
+func (cfg *AgentConfig) StartWithCerts(parent task.Parent, ca, crt, key []byte) error {
clientCert, err := tls.X509KeyPair(crt, key)
if err != nil {
- return E.Wrap(err)
+ return err
}
// create tls config
caCertPool := x509.NewCertPool()
ok := caCertPool.AppendCertsFromPEM(ca)
if !ok {
- return E.New("invalid CA certificate")
+ return gperr.New("invalid CA certificate")
}
cfg.tlsConfig = &tls.Config{
@@ -108,17 +108,17 @@ func (cfg *AgentConfig) StartWithCerts(parent task.Parent, ca, crt, key []byte)
// check agent version
version, _, err := cfg.Fetch(ctx, EndpointVersion)
if err != nil {
- return E.Wrap(err)
+ return err
}
if !checkVersion(string(version), pkg.GetVersion()) {
- return E.Errorf("agent version mismatch: server: %s, agent: %s", pkg.GetVersion(), string(version))
+ return gperr.Errorf("agent version mismatch: server: %s, agent: %s", pkg.GetVersion(), string(version))
}
// get agent name
name, _, err := cfg.Fetch(ctx, EndpointName)
if err != nil {
- return E.Wrap(err)
+ return err
}
cfg.name = string(name)
@@ -128,18 +128,18 @@ func (cfg *AgentConfig) StartWithCerts(parent task.Parent, ca, crt, key []byte)
return nil
}
-func (cfg *AgentConfig) Start(parent task.Parent) E.Error {
+func (cfg *AgentConfig) Start(parent task.Parent) error {
certData, err := os.ReadFile(certs.AgentCertsFilename(cfg.Addr))
if err != nil {
if os.IsNotExist(err) {
- return E.Errorf("agents certs not found, did you run `godoxy new-agent %s ...`?", cfg.Addr)
+ return gperr.Errorf("agents certs not found, did you run `godoxy new-agent %s ...`?", cfg.Addr)
}
- return E.Wrap(err)
+ return gperr.Wrap(err)
}
ca, crt, key, err := certs.ExtractCert(certData)
if err != nil {
- return E.Wrap(err)
+ return gperr.Wrap(err)
}
return cfg.StartWithCerts(parent, ca, crt, key)
diff --git a/agent/pkg/agent/docker_compose.go b/agent/pkg/agent/docker_compose.go
index 503df65..02fe9a9 100644
--- a/agent/pkg/agent/docker_compose.go
+++ b/agent/pkg/agent/docker_compose.go
@@ -9,7 +9,7 @@ import (
_ "embed"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/logging"
"github.com/yusing/go-proxy/internal/utils"
"gopkg.in/yaml.v3"
@@ -110,11 +110,11 @@ func MigrateFromOld() error {
composeConfig.SSLCert = agentCert.String()
composeTemplate, err := composeConfig.Generate()
if err != nil {
- return E.Wrap(err, "failed to generate new docker compose")
+ return gperr.Wrap(err, "failed to generate new docker compose")
}
if err := os.WriteFile("/app/compose.yml", []byte(composeTemplate), 0600); err != nil {
- return E.Wrap(err, "failed to write new docker compose")
+ return gperr.Wrap(err, "failed to write new docker compose")
}
logging.Info().Msg("Migrated from old docker compose:")
diff --git a/agent/pkg/handler/check_health.go b/agent/pkg/handler/check_health.go
index f697721..1dfadd7 100644
--- a/agent/pkg/handler/check_health.go
+++ b/agent/pkg/handler/check_health.go
@@ -7,7 +7,7 @@ import (
"os"
"strings"
- apiUtils "github.com/yusing/go-proxy/internal/api/v1/utils"
+ "github.com/yusing/go-proxy/internal/net/gphttp"
"github.com/yusing/go-proxy/internal/net/types"
"github.com/yusing/go-proxy/internal/watcher/health"
"github.com/yusing/go-proxy/internal/watcher/health/monitor"
@@ -72,5 +72,5 @@ func CheckHealth(w http.ResponseWriter, r *http.Request) {
return
}
- apiUtils.RespondJSON(w, r, result)
+ gphttp.RespondJSON(w, r, result)
}
diff --git a/agent/pkg/handler/docker_socket.go b/agent/pkg/handler/docker_socket.go
index e50ffaf..7e2d132 100644
--- a/agent/pkg/handler/docker_socket.go
+++ b/agent/pkg/handler/docker_socket.go
@@ -8,7 +8,7 @@ import (
"github.com/yusing/go-proxy/internal/common"
"github.com/yusing/go-proxy/internal/docker"
"github.com/yusing/go-proxy/internal/logging"
- "github.com/yusing/go-proxy/internal/net/http/reverseproxy"
+ "github.com/yusing/go-proxy/internal/net/gphttp/reverseproxy"
"github.com/yusing/go-proxy/internal/net/types"
)
diff --git a/agent/pkg/handler/proxy_http.go b/agent/pkg/handler/proxy_http.go
index 8b864b1..712f261 100644
--- a/agent/pkg/handler/proxy_http.go
+++ b/agent/pkg/handler/proxy_http.go
@@ -8,10 +8,10 @@ import (
"time"
"github.com/yusing/go-proxy/agent/pkg/agent"
- agentproxy "github.com/yusing/go-proxy/agent/pkg/agentproxy"
+ "github.com/yusing/go-proxy/agent/pkg/agentproxy"
"github.com/yusing/go-proxy/internal/logging"
- gphttp "github.com/yusing/go-proxy/internal/net/http"
- "github.com/yusing/go-proxy/internal/net/http/reverseproxy"
+ "github.com/yusing/go-proxy/internal/net/gphttp"
+ "github.com/yusing/go-proxy/internal/net/gphttp/reverseproxy"
"github.com/yusing/go-proxy/internal/net/types"
"github.com/yusing/go-proxy/internal/utils/strutils"
)
diff --git a/agent/pkg/server/server.go b/agent/pkg/server/server.go
index 20a2fc3..736fd81 100644
--- a/agent/pkg/server/server.go
+++ b/agent/pkg/server/server.go
@@ -14,7 +14,7 @@ import (
"github.com/yusing/go-proxy/agent/pkg/env"
"github.com/yusing/go-proxy/agent/pkg/handler"
"github.com/yusing/go-proxy/internal/logging"
- "github.com/yusing/go-proxy/internal/net/http/server"
+ "github.com/yusing/go-proxy/internal/net/gphttp/server"
"github.com/yusing/go-proxy/internal/task"
)
diff --git a/cmd/main.go b/cmd/main.go
index fbc704b..b50396f 100755
--- a/cmd/main.go
+++ b/cmd/main.go
@@ -11,10 +11,10 @@ import (
"github.com/yusing/go-proxy/internal/api/v1/query"
"github.com/yusing/go-proxy/internal/common"
"github.com/yusing/go-proxy/internal/config"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/homepage"
"github.com/yusing/go-proxy/internal/logging"
- "github.com/yusing/go-proxy/internal/net/http/middleware"
+ "github.com/yusing/go-proxy/internal/net/gphttp/middleware"
"github.com/yusing/go-proxy/internal/route/routes/routequery"
"github.com/yusing/go-proxy/internal/task"
"github.com/yusing/go-proxy/pkg"
@@ -32,7 +32,7 @@ func main() {
return
case common.CommandReload:
if err := query.ReloadServer(); err != nil {
- E.LogFatal("server reload error", err)
+ gperr.LogFatal("server reload error", err)
}
rawLogger.Println("ok")
return
@@ -88,9 +88,9 @@ func main() {
middleware.LoadComposeFiles()
var cfg *config.Config
- var err E.Error
+ var err gperr.Error
if cfg, err = config.Load(); err != nil {
- E.LogWarn("errors in config", err)
+ gperr.LogWarn("errors in config", err)
}
switch args.Command {
diff --git a/internal/api/handler.go b/internal/api/handler.go
index 6ec1e47..9de8651 100644
--- a/internal/api/handler.go
+++ b/internal/api/handler.go
@@ -13,7 +13,7 @@ import (
"github.com/yusing/go-proxy/internal/logging"
"github.com/yusing/go-proxy/internal/logging/memlogger"
"github.com/yusing/go-proxy/internal/metrics/uptime"
- "github.com/yusing/go-proxy/internal/net/http/httpheaders"
+ "github.com/yusing/go-proxy/internal/net/gphttp/httpheaders"
"github.com/yusing/go-proxy/internal/utils/strutils"
)
diff --git a/internal/api/v1/agents.go b/internal/api/v1/agents.go
index d722bee..d9d2a87 100644
--- a/internal/api/v1/agents.go
+++ b/internal/api/v1/agents.go
@@ -6,18 +6,19 @@ import (
"github.com/coder/websocket"
"github.com/coder/websocket/wsjson"
- U "github.com/yusing/go-proxy/internal/api/v1/utils"
config "github.com/yusing/go-proxy/internal/config/types"
- "github.com/yusing/go-proxy/internal/net/http/httpheaders"
+ "github.com/yusing/go-proxy/internal/net/gphttp"
+ "github.com/yusing/go-proxy/internal/net/gphttp/gpwebsocket"
+ "github.com/yusing/go-proxy/internal/net/gphttp/httpheaders"
)
func ListAgents(cfg config.ConfigInstance, w http.ResponseWriter, r *http.Request) {
if httpheaders.IsWebsocket(r.Header) {
- U.PeriodicWS(w, r, 10*time.Second, func(conn *websocket.Conn) error {
+ gpwebsocket.Periodic(w, r, 10*time.Second, func(conn *websocket.Conn) error {
wsjson.Write(r.Context(), conn, cfg.ListAgents())
return nil
})
} else {
- U.RespondJSON(w, r, cfg.ListAgents())
+ gphttp.RespondJSON(w, r, cfg.ListAgents())
}
}
diff --git a/internal/api/v1/auth/auth.go b/internal/api/v1/auth/auth.go
index ed0060e..705c74b 100644
--- a/internal/api/v1/auth/auth.go
+++ b/internal/api/v1/auth/auth.go
@@ -3,9 +3,9 @@ package auth
import (
"net/http"
- U "github.com/yusing/go-proxy/internal/api/v1/utils"
"github.com/yusing/go-proxy/internal/common"
"github.com/yusing/go-proxy/internal/logging"
+ "github.com/yusing/go-proxy/internal/net/gphttp"
)
var defaultAuth Provider
@@ -44,7 +44,7 @@ func RequireAuth(next http.HandlerFunc) http.HandlerFunc {
if IsEnabled() {
return func(w http.ResponseWriter, r *http.Request) {
if err := defaultAuth.CheckToken(r); err != nil {
- U.RespondError(w, err, http.StatusUnauthorized)
+ gphttp.ClientError(w, err, http.StatusUnauthorized)
} else {
next(w, r)
}
diff --git a/internal/api/v1/auth/oidc.go b/internal/api/v1/auth/oidc.go
index d08d674..e22904c 100644
--- a/internal/api/v1/auth/oidc.go
+++ b/internal/api/v1/auth/oidc.go
@@ -12,9 +12,8 @@ import (
"time"
"github.com/coreos/go-oidc/v3/oidc"
- U "github.com/yusing/go-proxy/internal/api/v1/utils"
"github.com/yusing/go-proxy/internal/common"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/net/gphttp"
CE "github.com/yusing/go-proxy/internal/utils"
"github.com/yusing/go-proxy/internal/utils/strutils"
"golang.org/x/oauth2"
@@ -154,7 +153,7 @@ func generateState() (string, error) {
func (auth *OIDCProvider) RedirectLoginPage(w http.ResponseWriter, r *http.Request) {
state, err := generateState()
if err != nil {
- U.HandleErr(w, r, err, http.StatusInternalServerError)
+ gphttp.ServerError(w, r, err)
return
}
http.SetCookie(w, &http.Cookie{
@@ -171,7 +170,7 @@ func (auth *OIDCProvider) RedirectLoginPage(w http.ResponseWriter, r *http.Reque
if auth.isMiddleware {
u, err := r.URL.Parse(redirURL)
if err != nil {
- U.HandleErr(w, r, err, http.StatusInternalServerError)
+ gphttp.ServerError(w, r, err)
return
}
q := u.Query()
@@ -201,31 +200,31 @@ func (auth *OIDCProvider) LoginCallbackHandler(w http.ResponseWriter, r *http.Re
state, err := r.Cookie(CookieOauthState)
if err != nil {
- U.HandleErr(w, r, E.New("missing state cookie"), http.StatusBadRequest)
+ gphttp.BadRequest(w, "missing state cookie")
return
}
query := r.URL.Query()
if query.Get("state") != state.Value {
- U.HandleErr(w, r, E.New("invalid oauth state"), http.StatusBadRequest)
+ gphttp.BadRequest(w, "invalid oauth state")
return
}
oauth2Token, err := auth.exchange(r)
if err != nil {
- U.HandleErr(w, r, fmt.Errorf("failed to exchange token: %w", err), http.StatusInternalServerError)
+ gphttp.ServerError(w, r, fmt.Errorf("failed to exchange token: %w", err))
return
}
rawIDToken, ok := oauth2Token.Extra("id_token").(string)
if !ok {
- U.HandleErr(w, r, E.New("missing id_token"), http.StatusInternalServerError)
+ gphttp.BadRequest(w, "missing id_token")
return
}
idToken, err := auth.oidcVerifier.Verify(r.Context(), rawIDToken)
if err != nil {
- U.HandleErr(w, r, fmt.Errorf("failed to verify ID token: %w", err), http.StatusInternalServerError)
+ gphttp.ServerError(w, r, fmt.Errorf("failed to verify ID token: %w", err))
return
}
@@ -243,7 +242,7 @@ func (auth *OIDCProvider) LogoutCallbackHandler(w http.ResponseWriter, r *http.R
token, err := r.Cookie(auth.TokenCookieName())
if err != nil {
- U.HandleErr(w, r, E.New("missing token cookie"), http.StatusBadRequest)
+ gphttp.BadRequest(w, "missing token cookie")
return
}
clearTokenCookie(w, r, auth.TokenCookieName())
@@ -258,12 +257,12 @@ func (auth *OIDCProvider) LogoutCallbackHandler(w http.ResponseWriter, r *http.R
func (auth *OIDCProvider) handleTestCallback(w http.ResponseWriter, r *http.Request) {
state, err := r.Cookie(CookieOauthState)
if err != nil {
- U.HandleErr(w, r, E.New("missing state cookie"), http.StatusBadRequest)
+ gphttp.BadRequest(w, "missing state cookie")
return
}
if r.URL.Query().Get("state") != state.Value {
- U.HandleErr(w, r, E.New("invalid oauth state"), http.StatusBadRequest)
+ gphttp.BadRequest(w, "invalid oauth state")
return
}
diff --git a/internal/api/v1/auth/userpass.go b/internal/api/v1/auth/userpass.go
index 7c6512c..239a4cc 100644
--- a/internal/api/v1/auth/userpass.go
+++ b/internal/api/v1/auth/userpass.go
@@ -7,16 +7,16 @@ import (
"time"
"github.com/golang-jwt/jwt/v5"
- U "github.com/yusing/go-proxy/internal/api/v1/utils"
"github.com/yusing/go-proxy/internal/common"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
+ "github.com/yusing/go-proxy/internal/net/gphttp"
"github.com/yusing/go-proxy/internal/utils/strutils"
"golang.org/x/crypto/bcrypt"
)
var (
- ErrInvalidUsername = E.New("invalid username")
- ErrInvalidPassword = E.New("invalid password")
+ ErrInvalidUsername = gperr.New("invalid username")
+ ErrInvalidPassword = gperr.New("invalid password")
)
type (
@@ -94,7 +94,7 @@ func (auth *UserPassAuth) CheckToken(r *http.Request) error {
case claims.Username != auth.username:
return ErrUserNotAllowed.Subject(claims.Username)
case claims.ExpiresAt.Before(time.Now()):
- return E.Errorf("token expired on %s", strutils.FormatTime(claims.ExpiresAt.Time))
+ return gperr.Errorf("token expired on %s", strutils.FormatTime(claims.ExpiresAt.Time))
}
return nil
@@ -111,17 +111,16 @@ func (auth *UserPassAuth) LoginCallbackHandler(w http.ResponseWriter, r *http.Re
}
err := json.NewDecoder(r.Body).Decode(&creds)
if err != nil {
- U.HandleErr(w, r, err, http.StatusBadRequest)
+ gphttp.Unauthorized(w, "invalid credentials")
return
}
if err := auth.validatePassword(creds.User, creds.Pass); err != nil {
- U.LogError(r).Err(err).Msg("auth: invalid credentials")
- U.RespondError(w, E.New("invalid credentials"), http.StatusUnauthorized)
+ gphttp.Unauthorized(w, "invalid credentials")
return
}
token, err := auth.NewToken()
if err != nil {
- U.HandleErr(w, r, err, http.StatusInternalServerError)
+ gphttp.ServerError(w, r, err)
return
}
setTokenCookie(w, r, auth.TokenCookieName(), token, auth.tokenTTL)
diff --git a/internal/api/v1/auth/utils.go b/internal/api/v1/auth/utils.go
index 05a1558..91eec3e 100644
--- a/internal/api/v1/auth/utils.go
+++ b/internal/api/v1/auth/utils.go
@@ -5,14 +5,14 @@ import (
"net/http"
"time"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/utils/strutils"
)
var (
- ErrMissingToken = E.New("missing token")
- ErrInvalidToken = E.New("invalid token")
- ErrUserNotAllowed = E.New("user not allowed")
+ ErrMissingToken = gperr.New("missing token")
+ ErrInvalidToken = gperr.New("invalid token")
+ ErrUserNotAllowed = gperr.New("user not allowed")
)
// cookieFQDN returns the fully qualified domain name of the request host
diff --git a/internal/api/v1/favicon/favicon.go b/internal/api/v1/favicon/favicon.go
index 5376644..055c74f 100644
--- a/internal/api/v1/favicon/favicon.go
+++ b/internal/api/v1/favicon/favicon.go
@@ -13,10 +13,10 @@ import (
"github.com/PuerkitoBio/goquery"
"github.com/vincent-petithory/dataurl"
- U "github.com/yusing/go-proxy/internal/api/v1/utils"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/homepage"
"github.com/yusing/go-proxy/internal/logging"
- gphttp "github.com/yusing/go-proxy/internal/net/http"
+ gphttp "github.com/yusing/go-proxy/internal/net/gphttp"
"github.com/yusing/go-proxy/internal/route/routes"
route "github.com/yusing/go-proxy/internal/route/types"
)
@@ -53,11 +53,11 @@ func (res *fetchResult) ContentType() string {
func GetFavIcon(w http.ResponseWriter, req *http.Request) {
url, alias := req.FormValue("url"), req.FormValue("alias")
if url == "" && alias == "" {
- U.RespondError(w, U.ErrMissingKey("url or alias"), http.StatusBadRequest)
+ gphttp.ClientError(w, gphttp.ErrMissingKey("url or alias"), http.StatusBadRequest)
return
}
if url != "" && alias != "" {
- U.RespondError(w, U.ErrInvalidKey("url and alias are mutually exclusive"), http.StatusBadRequest)
+ gphttp.ClientError(w, gperr.New("url and alias are mutually exclusive"), http.StatusBadRequest)
return
}
@@ -65,7 +65,7 @@ func GetFavIcon(w http.ResponseWriter, req *http.Request) {
if url != "" {
var iconURL homepage.IconURL
if err := iconURL.Parse(url); err != nil {
- U.RespondError(w, err, http.StatusBadRequest)
+ gphttp.ClientError(w, err, http.StatusBadRequest)
return
}
fetchResult := getFavIconFromURL(&iconURL)
@@ -74,14 +74,14 @@ func GetFavIcon(w http.ResponseWriter, req *http.Request) {
return
}
w.Header().Set("Content-Type", fetchResult.ContentType())
- U.WriteBody(w, fetchResult.icon)
+ gphttp.WriteBody(w, fetchResult.icon)
return
}
// try with route.Homepage.Icon
r, ok := routes.GetHTTPRoute(alias)
if !ok {
- U.RespondError(w, errors.New("no such route"), http.StatusNotFound)
+ gphttp.ClientError(w, errors.New("no such route"), http.StatusNotFound)
return
}
@@ -105,7 +105,7 @@ func GetFavIcon(w http.ResponseWriter, req *http.Request) {
return
}
w.Header().Set("Content-Type", result.ContentType())
- U.WriteBody(w, result.icon)
+ gphttp.WriteBody(w, result.icon)
}
func getFavIconFromURL(iconURL *homepage.IconURL) *fetchResult {
@@ -125,7 +125,7 @@ func fetchIconAbsolute(url string) *fetchResult {
return result
}
- resp, err := U.Get(url)
+ resp, err := gphttp.Get(url)
if err != nil || resp.StatusCode != http.StatusOK {
if err == nil {
err = errors.New(resp.Status)
diff --git a/internal/api/v1/file.go b/internal/api/v1/file.go
index 0a84977..d05c1db 100644
--- a/internal/api/v1/file.go
+++ b/internal/api/v1/file.go
@@ -7,11 +7,11 @@ import (
"path"
"strings"
- U "github.com/yusing/go-proxy/internal/api/v1/utils"
"github.com/yusing/go-proxy/internal/common"
config "github.com/yusing/go-proxy/internal/config/types"
- E "github.com/yusing/go-proxy/internal/error"
- "github.com/yusing/go-proxy/internal/net/http/middleware"
+ "github.com/yusing/go-proxy/internal/gperr"
+ "github.com/yusing/go-proxy/internal/net/gphttp"
+ "github.com/yusing/go-proxy/internal/net/gphttp/middleware"
"github.com/yusing/go-proxy/internal/route/provider"
)
@@ -51,12 +51,12 @@ func (t FileType) GetPath(filename string) string {
func getArgs(r *http.Request) (fileType FileType, filename string, err error) {
fileType = FileType(r.PathValue("type"))
if !fileType.IsValid() {
- err = U.ErrInvalidKey("type")
+ err = gphttp.ErrInvalidKey("type")
return
}
filename = r.PathValue("filename")
if filename == "" {
- err = U.ErrMissingKey("filename")
+ err = gphttp.ErrMissingKey("filename")
}
return
}
@@ -64,23 +64,23 @@ func getArgs(r *http.Request) (fileType FileType, filename string, err error) {
func GetFileContent(w http.ResponseWriter, r *http.Request) {
fileType, filename, err := getArgs(r)
if err != nil {
- U.RespondError(w, err, http.StatusBadRequest)
+ gphttp.BadRequest(w, err.Error())
return
}
content, err := os.ReadFile(fileType.GetPath(filename))
if err != nil {
- U.HandleErr(w, r, err)
+ gphttp.ServerError(w, r, err)
return
}
- U.WriteBody(w, content)
+ gphttp.WriteBody(w, content)
}
-func validateFile(fileType FileType, content []byte) error {
+func validateFile(fileType FileType, content []byte) gperr.Error {
switch fileType {
case FileTypeConfig:
return config.Validate(content)
case FileTypeMiddleware:
- errs := E.NewBuilder("middleware errors")
+ errs := gperr.NewBuilder("middleware errors")
middleware.BuildMiddlewaresFromYAML("", content, errs)
return errs.Error()
}
@@ -90,18 +90,17 @@ func validateFile(fileType FileType, content []byte) error {
func ValidateFile(w http.ResponseWriter, r *http.Request) {
fileType := FileType(r.PathValue("type"))
if !fileType.IsValid() {
- U.RespondError(w, U.ErrInvalidKey("type"), http.StatusBadRequest)
+ gphttp.BadRequest(w, "invalid file type")
return
}
content, err := io.ReadAll(r.Body)
if err != nil {
- U.HandleErr(w, r, err)
+ gphttp.ServerError(w, r, err)
return
}
r.Body.Close()
- err = validateFile(fileType, content)
- if err != nil {
- U.RespondError(w, err, http.StatusBadRequest)
+ if valErr := validateFile(fileType, content); valErr != nil {
+ gphttp.JSONError(w, valErr, http.StatusBadRequest)
return
}
w.WriteHeader(http.StatusOK)
@@ -110,23 +109,23 @@ func ValidateFile(w http.ResponseWriter, r *http.Request) {
func SetFileContent(w http.ResponseWriter, r *http.Request) {
fileType, filename, err := getArgs(r)
if err != nil {
- U.RespondError(w, err, http.StatusBadRequest)
+ gphttp.BadRequest(w, err.Error())
return
}
content, err := io.ReadAll(r.Body)
if err != nil {
- U.HandleErr(w, r, err)
+ gphttp.ServerError(w, r, err)
return
}
if valErr := validateFile(fileType, content); valErr != nil {
- U.RespondError(w, valErr, http.StatusBadRequest)
+ gphttp.JSONError(w, valErr, http.StatusBadRequest)
return
}
err = os.WriteFile(fileType.GetPath(filename), content, 0o644)
if err != nil {
- U.HandleErr(w, r, err)
+ gphttp.ServerError(w, r, err)
return
}
w.WriteHeader(http.StatusOK)
diff --git a/internal/api/v1/health.go b/internal/api/v1/health.go
index 2856aaf..3379022 100644
--- a/internal/api/v1/health.go
+++ b/internal/api/v1/health.go
@@ -6,17 +6,18 @@ import (
"github.com/coder/websocket"
"github.com/coder/websocket/wsjson"
- U "github.com/yusing/go-proxy/internal/api/v1/utils"
- "github.com/yusing/go-proxy/internal/net/http/httpheaders"
+ "github.com/yusing/go-proxy/internal/net/gphttp"
+ "github.com/yusing/go-proxy/internal/net/gphttp/gpwebsocket"
+ "github.com/yusing/go-proxy/internal/net/gphttp/httpheaders"
"github.com/yusing/go-proxy/internal/route/routes/routequery"
)
func Health(w http.ResponseWriter, r *http.Request) {
if httpheaders.IsWebsocket(r.Header) {
- U.PeriodicWS(w, r, 1*time.Second, func(conn *websocket.Conn) error {
+ gpwebsocket.Periodic(w, r, 1*time.Second, func(conn *websocket.Conn) error {
return wsjson.Write(r.Context(), conn, routequery.HealthMap())
})
} else {
- U.RespondJSON(w, r, routequery.HealthMap())
+ gphttp.RespondJSON(w, r, routequery.HealthMap())
}
}
diff --git a/internal/api/v1/homepage_overrides.go b/internal/api/v1/homepage_overrides.go
index 0d570fb..f9d6448 100644
--- a/internal/api/v1/homepage_overrides.go
+++ b/internal/api/v1/homepage_overrides.go
@@ -5,8 +5,8 @@ import (
"io"
"net/http"
- "github.com/yusing/go-proxy/internal/api/v1/utils"
"github.com/yusing/go-proxy/internal/homepage"
+ "github.com/yusing/go-proxy/internal/net/gphttp"
)
const (
@@ -37,13 +37,13 @@ type (
func SetHomePageOverrides(w http.ResponseWriter, r *http.Request) {
what := r.FormValue("what")
if what == "" {
- http.Error(w, "missing what or which", http.StatusBadRequest)
+ gphttp.BadRequest(w, "missing what or which")
return
}
data, err := io.ReadAll(r.Body)
if err != nil {
- utils.RespondError(w, err, http.StatusBadRequest)
+ gphttp.ClientError(w, err, http.StatusBadRequest)
return
}
r.Body.Close()
@@ -53,21 +53,21 @@ func SetHomePageOverrides(w http.ResponseWriter, r *http.Request) {
case HomepageOverrideItem:
var params HomepageOverrideItemParams
if err := json.Unmarshal(data, ¶ms); err != nil {
- utils.RespondError(w, err, http.StatusBadRequest)
+ gphttp.ClientError(w, err, http.StatusBadRequest)
return
}
overrides.OverrideItem(params.Which, ¶ms.Value)
case HomepageOverrideItemsBatch:
var params HomepageOverrideItemsBatchParams
if err := json.Unmarshal(data, ¶ms); err != nil {
- utils.RespondError(w, err, http.StatusBadRequest)
+ gphttp.ClientError(w, err, http.StatusBadRequest)
return
}
overrides.OverrideItems(params.Value)
case HomepageOverrideItemVisible: // POST /v1/item_visible [a,b,c], false => hide a, b, c
var params HomepageOverrideItemVisibleParams
if err := json.Unmarshal(data, ¶ms); err != nil {
- utils.RespondError(w, err, http.StatusBadRequest)
+ gphttp.ClientError(w, err, http.StatusBadRequest)
return
}
if params.Value {
@@ -78,7 +78,7 @@ func SetHomePageOverrides(w http.ResponseWriter, r *http.Request) {
case HomepageOverrideCategoryOrder:
var params HomepageOverrideCategoryOrderParams
if err := json.Unmarshal(data, ¶ms); err != nil {
- utils.RespondError(w, err, http.StatusBadRequest)
+ gphttp.ClientError(w, err, http.StatusBadRequest)
return
}
overrides.SetCategoryOrder(params.Which, params.Value)
diff --git a/internal/api/v1/index.go b/internal/api/v1/index.go
index 71bbf2e..dcaa976 100644
--- a/internal/api/v1/index.go
+++ b/internal/api/v1/index.go
@@ -3,9 +3,9 @@ package v1
import (
"net/http"
- . "github.com/yusing/go-proxy/internal/api/v1/utils"
+ "github.com/yusing/go-proxy/internal/net/gphttp"
)
func Index(w http.ResponseWriter, r *http.Request) {
- WriteBody(w, []byte("API ready"))
+ gphttp.WriteBody(w, []byte("API ready"))
}
diff --git a/internal/api/v1/list.go b/internal/api/v1/list.go
index 2e861c1..cdb520b 100644
--- a/internal/api/v1/list.go
+++ b/internal/api/v1/list.go
@@ -1,15 +1,16 @@
package v1
import (
+ "fmt"
"net/http"
"strconv"
"strings"
"github.com/yusing/go-proxy/internal"
- U "github.com/yusing/go-proxy/internal/api/v1/utils"
"github.com/yusing/go-proxy/internal/common"
config "github.com/yusing/go-proxy/internal/config/types"
- "github.com/yusing/go-proxy/internal/net/http/middleware"
+ "github.com/yusing/go-proxy/internal/net/gphttp"
+ "github.com/yusing/go-proxy/internal/net/gphttp/middleware"
"github.com/yusing/go-proxy/internal/route/routes/routequery"
route "github.com/yusing/go-proxy/internal/route/types"
"github.com/yusing/go-proxy/internal/task"
@@ -41,26 +42,25 @@ func List(cfg config.ConfigInstance, w http.ResponseWriter, r *http.Request) {
case ListRoute:
if route := listRoute(which); route == nil {
http.NotFound(w, r)
- return
} else {
- U.RespondJSON(w, r, route)
+ gphttp.RespondJSON(w, r, route)
}
case ListRoutes:
- U.RespondJSON(w, r, routequery.RoutesByAlias(route.RouteType(r.FormValue("type"))))
+ gphttp.RespondJSON(w, r, routequery.RoutesByAlias(route.RouteType(r.FormValue("type"))))
case ListFiles:
listFiles(w, r)
case ListMiddlewares:
- U.RespondJSON(w, r, middleware.All())
+ gphttp.RespondJSON(w, r, middleware.All())
case ListMiddlewareTraces:
- U.RespondJSON(w, r, middleware.GetAllTrace())
+ gphttp.RespondJSON(w, r, middleware.GetAllTrace())
case ListMatchDomains:
- U.RespondJSON(w, r, cfg.Value().MatchDomains)
+ gphttp.RespondJSON(w, r, cfg.Value().MatchDomains)
case ListHomepageConfig:
- U.RespondJSON(w, r, routequery.HomepageConfig(cfg.Value().Homepage.UseDefaultCategories, r.FormValue("category"), r.FormValue("provider")))
+ gphttp.RespondJSON(w, r, routequery.HomepageConfig(cfg.Value().Homepage.UseDefaultCategories, r.FormValue("category"), r.FormValue("provider")))
case ListRouteProviders:
- U.RespondJSON(w, r, cfg.RouteProviderList())
+ gphttp.RespondJSON(w, r, cfg.RouteProviderList())
case ListHomepageCategories:
- U.RespondJSON(w, r, routequery.HomepageCategories())
+ gphttp.RespondJSON(w, r, routequery.HomepageCategories())
case ListIcons:
limit, err := strconv.Atoi(r.FormValue("limit"))
if err != nil {
@@ -68,17 +68,17 @@ func List(cfg config.ConfigInstance, w http.ResponseWriter, r *http.Request) {
}
icons, err := internal.SearchIcons(r.FormValue("keyword"), limit)
if err != nil {
- U.RespondError(w, err)
+ gphttp.ClientError(w, err)
return
}
if icons == nil {
icons = []string{}
}
- U.RespondJSON(w, r, icons)
+ gphttp.RespondJSON(w, r, icons)
case ListTasks:
- U.RespondJSON(w, r, task.DebugTaskList())
+ gphttp.RespondJSON(w, r, task.DebugTaskList())
default:
- U.HandleErr(w, r, U.ErrInvalidKey("what"), http.StatusBadRequest)
+ gphttp.BadRequest(w, fmt.Sprintf("invalid what: %s", what))
}
}
@@ -99,7 +99,7 @@ func listRoute(which string) any {
func listFiles(w http.ResponseWriter, r *http.Request) {
files, err := utils.ListFiles(common.ConfigBasePath, 0, true)
if err != nil {
- U.HandleErr(w, r, err)
+ gphttp.ServerError(w, r, err)
return
}
resp := map[FileType][]string{
@@ -116,12 +116,12 @@ func listFiles(w http.ResponseWriter, r *http.Request) {
mids, err := utils.ListFiles(common.MiddlewareComposeBasePath, 0, true)
if err != nil {
- U.HandleErr(w, r, err)
+ gphttp.ServerError(w, r, err)
return
}
for _, mid := range mids {
mid = strings.TrimPrefix(mid, common.MiddlewareComposeBasePath+"/")
resp[FileTypeMiddleware] = append(resp[FileTypeMiddleware], mid)
}
- U.RespondJSON(w, r, resp)
+ gphttp.RespondJSON(w, r, resp)
}
diff --git a/internal/api/v1/new_agent.go b/internal/api/v1/new_agent.go
index c328bdd..ecb6daa 100644
--- a/internal/api/v1/new_agent.go
+++ b/internal/api/v1/new_agent.go
@@ -12,8 +12,9 @@ import (
"github.com/yusing/go-proxy/agent/pkg/agent"
"github.com/yusing/go-proxy/agent/pkg/certs"
- U "github.com/yusing/go-proxy/internal/api/v1/utils"
config "github.com/yusing/go-proxy/internal/config/types"
+ "github.com/yusing/go-proxy/internal/gperr"
+ "github.com/yusing/go-proxy/internal/net/gphttp"
"github.com/yusing/go-proxy/internal/utils/strutils"
)
@@ -21,27 +22,27 @@ func NewAgent(w http.ResponseWriter, r *http.Request) {
q := r.URL.Query()
name := q.Get("name")
if name == "" {
- U.RespondError(w, U.ErrMissingKey("name"))
+ gphttp.ClientError(w, gphttp.ErrMissingKey("name"))
return
}
host := q.Get("host")
if host == "" {
- U.RespondError(w, U.ErrMissingKey("host"))
+ gphttp.ClientError(w, gphttp.ErrMissingKey("host"))
return
}
portStr := q.Get("port")
if portStr == "" {
- U.RespondError(w, U.ErrMissingKey("port"))
+ gphttp.ClientError(w, gphttp.ErrMissingKey("port"))
return
}
port, err := strconv.Atoi(portStr)
if err != nil || port < 1 || port > 65535 {
- U.RespondError(w, U.ErrInvalidKey("port"))
+ gphttp.ClientError(w, gphttp.ErrInvalidKey("port"))
return
}
hostport := fmt.Sprintf("%s:%d", host, port)
if _, ok := config.GetInstance().GetAgent(hostport); ok {
- U.RespondError(w, U.ErrAlreadyExists("agent", hostport), http.StatusConflict)
+ gphttp.ClientError(w, gphttp.ErrAlreadyExists("agent", hostport), http.StatusConflict)
return
}
t := q.Get("type")
@@ -49,13 +50,13 @@ func NewAgent(w http.ResponseWriter, r *http.Request) {
case "docker":
break
case "system":
- U.RespondError(w, U.Errorf("system agent is not supported yet"), http.StatusNotImplemented)
+ gphttp.ClientError(w, gperr.Errorf("system agent is not supported yet"), http.StatusNotImplemented)
return
case "":
- U.RespondError(w, U.ErrMissingKey("type"))
+ gphttp.ClientError(w, gphttp.ErrMissingKey("type"))
return
default:
- U.RespondError(w, U.ErrInvalidKey("type"))
+ gphttp.ClientError(w, gphttp.ErrInvalidKey("type"))
return
}
@@ -69,7 +70,7 @@ func NewAgent(w http.ResponseWriter, r *http.Request) {
ca, srv, client, err := agent.NewAgent()
if err != nil {
- U.HandleErr(w, r, err)
+ gphttp.ServerError(w, r, err)
return
}
@@ -83,11 +84,11 @@ func NewAgent(w http.ResponseWriter, r *http.Request) {
template, err := cfg.Generate()
if err != nil {
- U.HandleErr(w, r, err)
+ gphttp.ServerError(w, r, err)
return
}
- U.RespondJSON(w, r, map[string]any{
+ gphttp.RespondJSON(w, r, map[string]any{
"compose": template,
"ca": ca,
"client": client,
@@ -98,7 +99,7 @@ func AddAgent(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
clientPEMData, err := io.ReadAll(r.Body)
if err != nil {
- U.HandleErr(w, r, err)
+ gphttp.ServerError(w, r, err)
return
}
@@ -109,24 +110,24 @@ func AddAgent(w http.ResponseWriter, r *http.Request) {
}
if err := json.Unmarshal(clientPEMData, &data); err != nil {
- U.RespondError(w, err, http.StatusBadRequest)
+ gphttp.ClientError(w, err, http.StatusBadRequest)
return
}
nRoutesAdded, err := config.GetInstance().AddAgent(data.Host, data.CA, data.Client)
if err != nil {
- U.RespondError(w, err)
+ gphttp.ClientError(w, err)
return
}
zip, err := certs.ZipCert(data.CA.Cert, data.Client.Cert, data.Client.Key)
if err != nil {
- U.HandleErr(w, r, err)
+ gphttp.ServerError(w, r, err)
return
}
if err := os.WriteFile(certs.AgentCertsFilename(data.Host), zip, 0600); err != nil {
- U.HandleErr(w, r, err)
+ gphttp.ServerError(w, r, err)
return
}
diff --git a/internal/api/v1/query/query.go b/internal/api/v1/query/query.go
index 7b59772..0a1d576 100644
--- a/internal/api/v1/query/query.go
+++ b/internal/api/v1/query/query.go
@@ -7,20 +7,20 @@ import (
"net/http"
v1 "github.com/yusing/go-proxy/internal/api/v1"
- U "github.com/yusing/go-proxy/internal/api/v1/utils"
"github.com/yusing/go-proxy/internal/common"
- E "github.com/yusing/go-proxy/internal/error"
- "github.com/yusing/go-proxy/internal/net/http/middleware"
+ "github.com/yusing/go-proxy/internal/gperr"
+ "github.com/yusing/go-proxy/internal/net/gphttp"
+ "github.com/yusing/go-proxy/internal/net/gphttp/middleware"
)
-func ReloadServer() E.Error {
- resp, err := U.Post(common.APIHTTPURL+"/v1/reload", "", nil)
+func ReloadServer() gperr.Error {
+ resp, err := gphttp.Post(common.APIHTTPURL+"/v1/reload", "", nil)
if err != nil {
- return E.From(err)
+ return gperr.Wrap(err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
- failure := E.Errorf("server reload status %v", resp.StatusCode)
+ failure := gperr.Errorf("server reload status %v", resp.StatusCode)
body, err := io.ReadAll(resp.Body)
if err != nil {
return failure.With(err)
@@ -31,34 +31,34 @@ func ReloadServer() E.Error {
return nil
}
-func List[T any](what string) (_ T, outErr E.Error) {
- resp, err := U.Get(fmt.Sprintf("%s/v1/list/%s", common.APIHTTPURL, what))
+func List[T any](what string) (_ T, outErr gperr.Error) {
+ resp, err := gphttp.Get(fmt.Sprintf("%s/v1/list/%s", common.APIHTTPURL, what))
if err != nil {
- outErr = E.From(err)
+ outErr = gperr.Wrap(err)
return
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
- outErr = E.Errorf("list %s: failed, status %v", what, resp.StatusCode)
+ outErr = gperr.Errorf("list %s: failed, status %v", what, resp.StatusCode)
return
}
var res T
err = json.NewDecoder(resp.Body).Decode(&res)
if err != nil {
- outErr = E.From(err)
+ outErr = gperr.Wrap(err)
return
}
return res, nil
}
-func ListRoutes() (map[string]map[string]any, E.Error) {
+func ListRoutes() (map[string]map[string]any, gperr.Error) {
return List[map[string]map[string]any](v1.ListRoutes)
}
-func ListMiddlewareTraces() (middleware.Traces, E.Error) {
+func ListMiddlewareTraces() (middleware.Traces, gperr.Error) {
return List[middleware.Traces](v1.ListMiddlewareTraces)
}
-func DebugListTasks() (map[string]any, E.Error) {
+func DebugListTasks() (map[string]any, gperr.Error) {
return List[map[string]any](v1.ListTasks)
}
diff --git a/internal/api/v1/reload.go b/internal/api/v1/reload.go
index defa4e4..1460d47 100644
--- a/internal/api/v1/reload.go
+++ b/internal/api/v1/reload.go
@@ -3,14 +3,14 @@ package v1
import (
"net/http"
- U "github.com/yusing/go-proxy/internal/api/v1/utils"
config "github.com/yusing/go-proxy/internal/config/types"
+ "github.com/yusing/go-proxy/internal/net/gphttp"
)
func Reload(cfg config.ConfigInstance, w http.ResponseWriter, r *http.Request) {
if err := cfg.Reload(); err != nil {
- U.HandleErr(w, r, err)
+ gphttp.ServerError(w, r, err)
return
}
- U.WriteBody(w, []byte("OK"))
+ gphttp.WriteBody(w, []byte("OK"))
}
diff --git a/internal/api/v1/stats.go b/internal/api/v1/stats.go
index ffdece9..1fbac51 100644
--- a/internal/api/v1/stats.go
+++ b/internal/api/v1/stats.go
@@ -6,19 +6,20 @@ import (
"github.com/coder/websocket"
"github.com/coder/websocket/wsjson"
- U "github.com/yusing/go-proxy/internal/api/v1/utils"
config "github.com/yusing/go-proxy/internal/config/types"
- "github.com/yusing/go-proxy/internal/net/http/httpheaders"
+ "github.com/yusing/go-proxy/internal/net/gphttp"
+ "github.com/yusing/go-proxy/internal/net/gphttp/gpwebsocket"
+ "github.com/yusing/go-proxy/internal/net/gphttp/httpheaders"
"github.com/yusing/go-proxy/internal/utils/strutils"
)
func Stats(cfg config.ConfigInstance, w http.ResponseWriter, r *http.Request) {
if httpheaders.IsWebsocket(r.Header) {
- U.PeriodicWS(w, r, 1*time.Second, func(conn *websocket.Conn) error {
+ gpwebsocket.Periodic(w, r, 1*time.Second, func(conn *websocket.Conn) error {
return wsjson.Write(r.Context(), conn, getStats(cfg))
})
} else {
- U.RespondJSON(w, r, getStats(cfg))
+ gphttp.RespondJSON(w, r, getStats(cfg))
}
}
diff --git a/internal/api/v1/system_info.go b/internal/api/v1/system_info.go
index 1c06dad..31f6829 100644
--- a/internal/api/v1/system_info.go
+++ b/internal/api/v1/system_info.go
@@ -4,12 +4,12 @@ import (
"net/http"
agentPkg "github.com/yusing/go-proxy/agent/pkg/agent"
- U "github.com/yusing/go-proxy/internal/api/v1/utils"
config "github.com/yusing/go-proxy/internal/config/types"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/metrics/systeminfo"
- "github.com/yusing/go-proxy/internal/net/http/httpheaders"
- "github.com/yusing/go-proxy/internal/net/http/reverseproxy"
+ "github.com/yusing/go-proxy/internal/net/gphttp"
+ "github.com/yusing/go-proxy/internal/net/gphttp/httpheaders"
+ "github.com/yusing/go-proxy/internal/net/gphttp/reverseproxy"
)
func SystemInfo(cfg config.ConfigInstance, w http.ResponseWriter, r *http.Request) {
@@ -23,7 +23,7 @@ func SystemInfo(cfg config.ConfigInstance, w http.ResponseWriter, r *http.Reques
agent, ok := cfg.GetAgent(agentAddr)
if !ok {
- U.HandleErr(w, r, U.ErrInvalidKey("agent_addr"), http.StatusNotFound)
+ gphttp.NotFound(w, "agent_addr")
return
}
@@ -31,20 +31,20 @@ func SystemInfo(cfg config.ConfigInstance, w http.ResponseWriter, r *http.Reques
if !isWS {
respData, status, err := agent.Forward(r, agentPkg.EndpointSystemInfo)
if err != nil {
- U.HandleErr(w, r, E.Wrap(err, "failed to forward request to agent"))
+ gphttp.ServerError(w, r, gperr.Wrap(err, "failed to forward request to agent"))
return
}
if status != http.StatusOK {
http.Error(w, string(respData), status)
return
}
- U.WriteBody(w, respData)
+ gphttp.WriteBody(w, respData)
} else {
rp := reverseproxy.NewReverseProxy("agent", agentPkg.AgentURL, agent.Transport())
header := r.Header.Clone()
r, err := http.NewRequestWithContext(r.Context(), r.Method, agentPkg.EndpointSystemInfo+"?"+query.Encode(), nil)
if err != nil {
- U.HandleErr(w, r, E.Wrap(err, "failed to create request"))
+ gphttp.ServerError(w, r, gperr.Wrap(err, "failed to create request"))
return
}
r.Header = header
diff --git a/internal/api/v1/utils/error.go b/internal/api/v1/utils/error.go
deleted file mode 100644
index 422f1c9..0000000
--- a/internal/api/v1/utils/error.go
+++ /dev/null
@@ -1,66 +0,0 @@
-package utils
-
-import (
- "context"
- "errors"
- "net/http"
- "syscall"
-
- E "github.com/yusing/go-proxy/internal/error"
- "github.com/yusing/go-proxy/internal/net/http/httpheaders"
- "github.com/yusing/go-proxy/internal/utils/strutils/ansi"
-)
-
-// HandleErr logs the error and returns an error code to the client.
-// If code is specified, it will be used as the HTTP status code; otherwise,
-// http.StatusInternalServerError is used.
-//
-// The error is only logged but not returned to the client.
-func HandleErr(w http.ResponseWriter, r *http.Request, err error, code ...int) {
- switch {
- case err == nil,
- errors.Is(err, context.Canceled),
- errors.Is(err, syscall.EPIPE),
- errors.Is(err, syscall.ECONNRESET):
- return
- }
- LogError(r).Msg(err.Error())
- if httpheaders.IsWebsocket(r.Header) {
- return
- }
- if len(code) == 0 {
- code = []int{http.StatusInternalServerError}
- }
- http.Error(w, http.StatusText(code[0]), code[0])
-}
-
-// RespondError returns error details to the client.
-// If code is specified, it will be used as the HTTP status code; otherwise,
-// http.StatusBadRequest is used.
-func RespondError(w http.ResponseWriter, err error, code ...int) {
- if len(code) == 0 {
- code = []int{http.StatusBadRequest}
- }
- w.Header().Set("Content-Type", "text/plain; charset=utf-8")
- http.Error(w, ansi.StripANSI(err.Error()), code[0])
-}
-
-func Errorf(format string, args ...any) error {
- return E.Errorf(format, args...)
-}
-
-func ErrMissingKey(k string) error {
- return E.New(k + " is required")
-}
-
-func ErrInvalidKey(k string) error {
- return E.New(k + " is invalid")
-}
-
-func ErrAlreadyExists(k, v string) error {
- return E.Errorf("%s %q already exists", k, v)
-}
-
-func ErrNotFound(k, v string) error {
- return E.Errorf("%s %q not found", k, v)
-}
diff --git a/internal/api/v1/version.go b/internal/api/v1/version.go
index f0db6bf..f43a9d6 100644
--- a/internal/api/v1/version.go
+++ b/internal/api/v1/version.go
@@ -3,10 +3,10 @@ package v1
import (
"net/http"
- . "github.com/yusing/go-proxy/internal/api/v1/utils"
+ "github.com/yusing/go-proxy/internal/net/gphttp"
"github.com/yusing/go-proxy/pkg"
)
func GetVersion(w http.ResponseWriter, r *http.Request) {
- WriteBody(w, []byte(pkg.GetVersion()))
+ gphttp.WriteBody(w, []byte(pkg.GetVersion()))
}
diff --git a/internal/autocert/config.go b/internal/autocert/config.go
index 3a32f73..19de2ba 100644
--- a/internal/autocert/config.go
+++ b/internal/autocert/config.go
@@ -10,7 +10,7 @@ import (
"github.com/go-acme/lego/v4/certcrypto"
"github.com/go-acme/lego/v4/lego"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/logging"
"github.com/yusing/go-proxy/internal/utils"
"github.com/yusing/go-proxy/internal/utils/strutils"
@@ -30,17 +30,17 @@ type (
)
var (
- ErrMissingDomain = E.New("missing field 'domains'")
- ErrMissingEmail = E.New("missing field 'email'")
- ErrMissingProvider = E.New("missing field 'provider'")
- ErrInvalidDomain = E.New("invalid domain")
- ErrUnknownProvider = E.New("unknown provider")
+ ErrMissingDomain = gperr.New("missing field 'domains'")
+ ErrMissingEmail = gperr.New("missing field 'email'")
+ ErrMissingProvider = gperr.New("missing field 'provider'")
+ ErrInvalidDomain = gperr.New("invalid domain")
+ ErrUnknownProvider = gperr.New("unknown provider")
)
var domainOrWildcardRE = regexp.MustCompile(`^\*?([^.]+\.)+[^.]+$`)
// Validate implements the utils.CustomValidator interface.
-func (cfg *AutocertConfig) Validate() E.Error {
+func (cfg *AutocertConfig) Validate() gperr.Error {
if cfg == nil {
return nil
}
@@ -50,7 +50,7 @@ func (cfg *AutocertConfig) Validate() E.Error {
return nil
}
- b := E.NewBuilder("autocert errors")
+ b := gperr.NewBuilder("autocert errors")
if cfg.Provider != ProviderLocal {
if len(cfg.Domains) == 0 {
b.Add(ErrMissingDomain)
@@ -79,7 +79,7 @@ func (cfg *AutocertConfig) Validate() E.Error {
return b.Error()
}
-func (cfg *AutocertConfig) GetProvider() (*Provider, E.Error) {
+func (cfg *AutocertConfig) GetProvider() (*Provider, gperr.Error) {
if cfg == nil {
cfg = new(AutocertConfig)
}
@@ -107,10 +107,10 @@ func (cfg *AutocertConfig) GetProvider() (*Provider, E.Error) {
logging.Info().Msg("generate new ACME private key")
privKey, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
- return nil, E.New("generate ACME private key").With(err)
+ return nil, gperr.New("generate ACME private key").With(err)
}
if err = cfg.saveACMEKey(privKey); err != nil {
- return nil, E.New("save ACME private key").With(err)
+ return nil, gperr.New("save ACME private key").With(err)
}
}
}
diff --git a/internal/autocert/provider.go b/internal/autocert/provider.go
index eaad175..9948d32 100644
--- a/internal/autocert/provider.go
+++ b/internal/autocert/provider.go
@@ -4,6 +4,7 @@ import (
"crypto/tls"
"crypto/x509"
"errors"
+ "fmt"
"os"
"path"
"reflect"
@@ -14,7 +15,7 @@ import (
"github.com/go-acme/lego/v4/challenge"
"github.com/go-acme/lego/v4/lego"
"github.com/go-acme/lego/v4/registration"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/logging"
"github.com/yusing/go-proxy/internal/task"
U "github.com/yusing/go-proxy/internal/utils"
@@ -32,7 +33,7 @@ type (
tlsCert *tls.Certificate
certExpiries CertExpiries
}
- ProviderGenerator func(ProviderOpt) (challenge.Provider, E.Error)
+ ProviderGenerator func(ProviderOpt) (challenge.Provider, gperr.Error)
CertExpiries map[string]time.Time
)
@@ -62,7 +63,7 @@ func (p *Provider) GetExpiries() CertExpiries {
return p.certExpiries
}
-func (p *Provider) ObtainCert() E.Error {
+func (p *Provider) ObtainCert() error {
if p.cfg.Provider == ProviderLocal {
return nil
}
@@ -75,7 +76,7 @@ func (p *Provider) ObtainCert() E.Error {
if p.user.Registration == nil {
if err := p.registerACME(); err != nil {
- return E.From(err)
+ return err
}
}
@@ -100,22 +101,22 @@ func (p *Provider) ObtainCert() E.Error {
Bundle: true,
})
if err != nil {
- return E.From(err)
+ return err
}
}
if err = p.saveCert(cert); err != nil {
- return E.From(err)
+ return err
}
tlsCert, err := tls.X509KeyPair(cert.Certificate, cert.PrivateKey)
if err != nil {
- return E.From(err)
+ return err
}
expiries, err := getCertExpiries(&tlsCert)
if err != nil {
- return E.From(err)
+ return err
}
p.tlsCert = &tlsCert
p.certExpiries = expiries
@@ -123,14 +124,14 @@ func (p *Provider) ObtainCert() E.Error {
return nil
}
-func (p *Provider) LoadCert() E.Error {
+func (p *Provider) LoadCert() error {
cert, err := tls.LoadX509KeyPair(p.cfg.CertPath, p.cfg.KeyPath)
if err != nil {
- return E.Errorf("load SSL certificate: %w", err)
+ return fmt.Errorf("load SSL certificate: %w", err)
}
expiries, err := getCertExpiries(&cert)
if err != nil {
- return E.Errorf("parse SSL certificate: %w", err)
+ return fmt.Errorf("parse SSL certificate: %w", err)
}
p.tlsCert = &cert
p.certExpiries = expiries
@@ -171,7 +172,7 @@ func (p *Provider) ScheduleRenewal(parent task.Parent) {
continue
}
if err := p.renewIfNeeded(); err != nil {
- E.LogWarn("cert renew failed", err)
+ gperr.LogWarn("cert renew failed", err)
lastErrOn = time.Now()
continue
}
@@ -184,10 +185,10 @@ func (p *Provider) ScheduleRenewal(parent task.Parent) {
}()
}
-func (p *Provider) initClient() E.Error {
+func (p *Provider) initClient() error {
legoClient, err := lego.NewClient(p.legoCfg)
if err != nil {
- return E.From(err)
+ return err
}
generator := providersGenMap[p.cfg.Provider]
@@ -198,7 +199,7 @@ func (p *Provider) initClient() E.Error {
err = legoClient.Challenge.SetDNS01Provider(legoProvider)
if err != nil {
- return E.From(err)
+ return err
}
p.client = legoClient
@@ -273,7 +274,7 @@ func (p *Provider) certState() CertState {
return CertStateValid
}
-func (p *Provider) renewIfNeeded() E.Error {
+func (p *Provider) renewIfNeeded() error {
if p.cfg.Provider == ProviderLocal {
return nil
}
@@ -312,13 +313,13 @@ func providerGenerator[CT any, PT challenge.Provider](
defaultCfg func() *CT,
newProvider func(*CT) (PT, error),
) ProviderGenerator {
- return func(opt ProviderOpt) (challenge.Provider, E.Error) {
+ return func(opt ProviderOpt) (challenge.Provider, gperr.Error) {
cfg := defaultCfg()
err := U.Deserialize(opt, &cfg)
if err != nil {
return nil, err
}
p, pErr := newProvider(cfg)
- return p, E.From(pErr)
+ return p, gperr.Wrap(pErr)
}
}
diff --git a/internal/autocert/setup.go b/internal/autocert/setup.go
index 82e58ad..b436bed 100644
--- a/internal/autocert/setup.go
+++ b/internal/autocert/setup.go
@@ -1,16 +1,16 @@
package autocert
import (
+ "errors"
"os"
- E "github.com/yusing/go-proxy/internal/error"
"github.com/yusing/go-proxy/internal/logging"
"github.com/yusing/go-proxy/internal/utils/strutils"
)
-func (p *Provider) Setup() (err E.Error) {
+func (p *Provider) Setup() (err error) {
if err = p.LoadCert(); err != nil {
- if !err.Is(os.ErrNotExist) { // ignore if cert doesn't exist
+ if !errors.Is(err, os.ErrNotExist) { // ignore if cert doesn't exist
return err
}
logging.Debug().Msg("obtaining cert due to error loading cert")
diff --git a/internal/common/constants.go b/internal/common/constants.go
index 230a389..17e6190 100644
--- a/internal/common/constants.go
+++ b/internal/common/constants.go
@@ -4,12 +4,6 @@ import (
"time"
)
-const (
- ConnectionTimeout = 5 * time.Second
- DialTimeout = 3 * time.Second
- KeepAlive = 60 * time.Second
-)
-
// file, folder structure
const (
@@ -50,5 +44,3 @@ const (
StopTimeoutDefault = "30s"
StopMethodDefault = "stop"
)
-
-const HeaderCheckRedirect = "X-Goproxy-Check-Redirect"
diff --git a/internal/config/agent_pool.go b/internal/config/agent_pool.go
index 5088b37..9fe203d 100644
--- a/internal/config/agent_pool.go
+++ b/internal/config/agent_pool.go
@@ -2,7 +2,7 @@ package config
import (
"github.com/yusing/go-proxy/agent/pkg/agent"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/route/provider"
"github.com/yusing/go-proxy/internal/utils/functional"
)
@@ -29,12 +29,12 @@ func (cfg *Config) GetAgent(agentAddrOrDockerHost string) (*agent.AgentConfig, b
return GetAgent(agent.GetAgentAddrFromDockerHost(agentAddrOrDockerHost))
}
-func (cfg *Config) AddAgent(host string, ca agent.PEMPair, client agent.PEMPair) (int, E.Error) {
+func (cfg *Config) AddAgent(host string, ca agent.PEMPair, client agent.PEMPair) (int, gperr.Error) {
var agentCfg agent.AgentConfig
agentCfg.Addr = host
err := agentCfg.StartWithCerts(cfg.Task(), ca.Cert, client.Cert, client.Key)
if err != nil {
- return 0, err
+ return 0, gperr.Wrap(err, "failed to start agent")
}
provider := provider.NewAgentProvider(&agentCfg)
diff --git a/internal/config/config.go b/internal/config/config.go
index a0b6987..28fd5e6 100644
--- a/internal/config/config.go
+++ b/internal/config/config.go
@@ -14,9 +14,9 @@ import (
"github.com/yusing/go-proxy/internal/common"
config "github.com/yusing/go-proxy/internal/config/types"
"github.com/yusing/go-proxy/internal/entrypoint"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/logging"
- "github.com/yusing/go-proxy/internal/net/http/server"
+ "github.com/yusing/go-proxy/internal/net/gphttp/server"
"github.com/yusing/go-proxy/internal/notif"
proxy "github.com/yusing/go-proxy/internal/route/provider"
"github.com/yusing/go-proxy/internal/task"
@@ -64,7 +64,7 @@ func newConfig() *Config {
}
}
-func Load() (*Config, E.Error) {
+func Load() (*Config, gperr.Error) {
if config.HasInstance() {
panic(errors.New("config already loaded"))
}
@@ -84,8 +84,8 @@ func WatchChanges() {
t,
configEventFlushInterval,
OnConfigChange,
- func(err E.Error) {
- E.LogError("config reload error", err)
+ func(err gperr.Error) {
+ gperr.LogError("config reload error", err)
},
)
eventQueue.Start(cfgWatcher.Events(t.Context()))
@@ -109,7 +109,7 @@ func OnConfigChange(ev []events.Event) {
}
}
-func Reload() E.Error {
+func Reload() gperr.Error {
// avoid race between config change and API reload request
reloadMu.Lock()
defer reloadMu.Unlock()
@@ -118,7 +118,7 @@ func Reload() E.Error {
err := newCfg.load()
if err != nil {
newCfg.task.Finish(err)
- return E.New("using last config").With(err)
+ return gperr.New("using last config").With(err)
}
// cancel all current subtasks -> wait
@@ -133,10 +133,13 @@ func (cfg *Config) Value() *config.Config {
return cfg.value
}
-func (cfg *Config) Reload() E.Error {
+func (cfg *Config) Reload() gperr.Error {
return Reload()
}
+// AutoCertProvider returns the autocert provider.
+//
+// If the autocert provider is not configured, it returns nil.
func (cfg *Config) AutoCertProvider() *autocert.Provider {
return cfg.autocertProvider
}
@@ -163,7 +166,7 @@ func (cfg *Config) StartAutoCert() {
}
if err := autocert.Setup(); err != nil {
- E.LogFatal("autocert setup error", err)
+ gperr.LogFatal("autocert setup error", err)
} else {
autocert.ScheduleRenewal(cfg.task)
}
@@ -175,8 +178,8 @@ func (cfg *Config) StartProxyProviders() {
return p.Start(cfg.task)
})
- if err := E.Join(errs...); err != nil {
- E.LogError("route provider errors", err)
+ if err := gperr.Join(errs...); err != nil {
+ gperr.LogError("route provider errors", err)
}
}
@@ -210,21 +213,21 @@ func (cfg *Config) StartServers(opts ...*StartServersOptions) {
}
}
-func (cfg *Config) load() E.Error {
+func (cfg *Config) load() gperr.Error {
const errMsg = "config load error"
data, err := os.ReadFile(common.ConfigPath)
if err != nil {
- E.LogFatal(errMsg, err)
+ gperr.LogFatal(errMsg, err)
}
model := config.DefaultConfig()
if err := utils.DeserializeYAML(data, model); err != nil {
- E.LogFatal(errMsg, err)
+ gperr.LogFatal(errMsg, err)
}
// errors are non fatal below
- errs := E.NewBuilder(errMsg)
+ errs := gperr.NewBuilder(errMsg)
errs.Add(cfg.entrypoint.SetMiddlewares(model.Entrypoint.Middlewares))
errs.Add(cfg.entrypoint.SetAccessLogger(cfg.task, model.Entrypoint.AccessLog))
cfg.initNotification(model.Providers.Notification)
@@ -252,7 +255,7 @@ func (cfg *Config) initNotification(notifCfg []notif.NotificationConfig) {
}
}
-func (cfg *Config) initAutoCert(autocertCfg *autocert.AutocertConfig) (err E.Error) {
+func (cfg *Config) initAutoCert(autocertCfg *autocert.AutocertConfig) (err gperr.Error) {
if cfg.autocertProvider != nil {
return
}
@@ -261,9 +264,9 @@ func (cfg *Config) initAutoCert(autocertCfg *autocert.AutocertConfig) (err E.Err
return
}
-func (cfg *Config) errIfExists(p *proxy.Provider) E.Error {
+func (cfg *Config) errIfExists(p *proxy.Provider) gperr.Error {
if _, ok := cfg.providers.Load(p.String()); ok {
- return E.Errorf("provider %s already exists", p.String())
+ return gperr.Errorf("provider %s already exists", p.String())
}
return nil
}
@@ -272,9 +275,9 @@ func (cfg *Config) storeProvider(p *proxy.Provider) {
cfg.providers.Store(p.String(), p)
}
-func (cfg *Config) loadRouteProviders(providers *config.Providers) E.Error {
- errs := E.NewBuilder("route provider errors")
- results := E.NewBuilder("loaded route providers")
+func (cfg *Config) loadRouteProviders(providers *config.Providers) gperr.Error {
+ errs := gperr.NewBuilder("route provider errors")
+ results := gperr.NewBuilder("loaded route providers")
removeAllAgents()
@@ -297,7 +300,7 @@ func (cfg *Config) loadRouteProviders(providers *config.Providers) E.Error {
err = cfg.errIfExists(p)
}
if err != nil {
- errs.Add(E.PrependSubject(filename, err))
+ errs.Add(gperr.PrependSubject(filename, err))
continue
}
cfg.storeProvider(p)
diff --git a/internal/config/types/config.go b/internal/config/types/config.go
index 7788d78..60c766c 100644
--- a/internal/config/types/config.go
+++ b/internal/config/types/config.go
@@ -8,11 +8,10 @@ import (
"github.com/go-playground/validator/v10"
"github.com/yusing/go-proxy/agent/pkg/agent"
"github.com/yusing/go-proxy/internal/autocert"
- "github.com/yusing/go-proxy/internal/net/http/accesslog"
+ "github.com/yusing/go-proxy/internal/gperr"
+ "github.com/yusing/go-proxy/internal/net/gphttp/accesslog"
"github.com/yusing/go-proxy/internal/notif"
"github.com/yusing/go-proxy/internal/utils"
-
- E "github.com/yusing/go-proxy/internal/error"
)
type (
@@ -37,12 +36,12 @@ type (
ConfigInstance interface {
Value() *Config
- Reload() E.Error
+ Reload() gperr.Error
Statistics() map[string]any
RouteProviderList() []string
Context() context.Context
GetAgent(agentAddrOrDockerHost string) (*agent.AgentConfig, bool)
- AddAgent(host string, ca agent.PEMPair, client agent.PEMPair) (int, E.Error)
+ AddAgent(host string, ca agent.PEMPair, client agent.PEMPair) (int, gperr.Error)
ListAgents() []*agent.AgentConfig
}
)
@@ -79,7 +78,7 @@ func HasInstance() bool {
return instance != nil
}
-func Validate(data []byte) E.Error {
+func Validate(data []byte) gperr.Error {
var model Config
return utils.DeserializeYAML(data, &model)
}
diff --git a/internal/docker/idlewatcher/loading_page.go b/internal/docker/idlewatcher/loading_page.go
index 80913c7..b6e9860 100644
--- a/internal/docker/idlewatcher/loading_page.go
+++ b/internal/docker/idlewatcher/loading_page.go
@@ -6,7 +6,7 @@ import (
"strings"
"text/template"
- "github.com/yusing/go-proxy/internal/common"
+ "github.com/yusing/go-proxy/internal/net/gphttp/httpheaders"
)
type templateData struct {
@@ -23,11 +23,11 @@ func (w *Watcher) makeLoadingPageBody() []byte {
msg := w.ContainerName + " is starting..."
data := new(templateData)
- data.CheckRedirectHeader = common.HeaderCheckRedirect
+ data.CheckRedirectHeader = httpheaders.HeaderGoDoxyCheckRedirect
data.Title = w.ContainerName
data.Message = strings.ReplaceAll(msg, " ", " ")
- buf := bytes.NewBuffer(make([]byte, len(loadingPage)+len(data.Title)+len(data.Message)+len(common.HeaderCheckRedirect)))
+ buf := bytes.NewBuffer(make([]byte, len(loadingPage)+len(data.Title)+len(data.Message)+len(httpheaders.HeaderGoDoxyCheckRedirect)))
err := loadingPageTmpl.Execute(buf, data)
if err != nil { // should never happen in production
panic(err)
diff --git a/internal/docker/idlewatcher/types/config.go b/internal/docker/idlewatcher/types/config.go
index a813cec..c607bb6 100644
--- a/internal/docker/idlewatcher/types/config.go
+++ b/internal/docker/idlewatcher/types/config.go
@@ -7,7 +7,7 @@ import (
"time"
"github.com/yusing/go-proxy/internal/docker"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
)
type (
@@ -40,7 +40,7 @@ var validSignals = map[string]struct{}{
"INT": {}, "TERM": {}, "HUP": {}, "QUIT": {},
}
-func ValidateConfig(cont *docker.Container) (*Config, E.Error) {
+func ValidateConfig(cont *docker.Container) (*Config, gperr.Error) {
if cont == nil {
return nil, nil
}
@@ -54,14 +54,14 @@ func ValidateConfig(cont *docker.Container) (*Config, E.Error) {
}, nil
}
- errs := E.NewBuilder("invalid idlewatcher config")
+ errs := gperr.NewBuilder("invalid idlewatcher config")
- idleTimeout := E.Collect(errs, validateDurationPostitive, cont.IdleTimeout)
- wakeTimeout := E.Collect(errs, validateDurationPostitive, cont.WakeTimeout)
- stopTimeout := E.Collect(errs, validateDurationPostitive, cont.StopTimeout)
- stopMethod := E.Collect(errs, validateStopMethod, cont.StopMethod)
- signal := E.Collect(errs, validateSignal, cont.StopSignal)
- startEndpoint := E.Collect(errs, validateStartEndpoint, cont.StartEndpoint)
+ idleTimeout := gperr.Collect(errs, validateDurationPostitive, cont.IdleTimeout)
+ wakeTimeout := gperr.Collect(errs, validateDurationPostitive, cont.WakeTimeout)
+ stopTimeout := gperr.Collect(errs, validateDurationPostitive, cont.StopTimeout)
+ stopMethod := gperr.Collect(errs, validateStopMethod, cont.StopMethod)
+ signal := gperr.Collect(errs, validateSignal, cont.StopSignal)
+ startEndpoint := gperr.Collect(errs, validateStartEndpoint, cont.StartEndpoint)
if errs.HasError() {
return nil, errs.Error()
diff --git a/internal/docker/idlewatcher/waker.go b/internal/docker/idlewatcher/waker.go
index 6af2381..0b6fce9 100644
--- a/internal/docker/idlewatcher/waker.go
+++ b/internal/docker/idlewatcher/waker.go
@@ -5,9 +5,9 @@ import (
"time"
"github.com/yusing/go-proxy/internal/docker/idlewatcher/types"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/metrics"
- "github.com/yusing/go-proxy/internal/net/http/reverseproxy"
+ "github.com/yusing/go-proxy/internal/net/gphttp/reverseproxy"
net "github.com/yusing/go-proxy/internal/net/types"
route "github.com/yusing/go-proxy/internal/route/types"
"github.com/yusing/go-proxy/internal/task"
@@ -37,7 +37,7 @@ const (
// TODO: support stream
-func newWaker(parent task.Parent, route route.Route, rp *reverseproxy.ReverseProxy, stream net.Stream) (Waker, E.Error) {
+func newWaker(parent task.Parent, route route.Route, rp *reverseproxy.ReverseProxy, stream net.Stream) (Waker, gperr.Error) {
hcCfg := route.HealthCheckConfig()
hcCfg.Timeout = idleWakerCheckTimeout
@@ -48,7 +48,7 @@ func newWaker(parent task.Parent, route route.Route, rp *reverseproxy.ReversePro
task := parent.Subtask("idlewatcher." + route.TargetName())
watcher, err := registerWatcher(task, route, waker)
if err != nil {
- return nil, E.Errorf("register watcher: %w", err)
+ return nil, gperr.Errorf("register watcher: %w", err)
}
switch {
@@ -66,16 +66,16 @@ func newWaker(parent task.Parent, route route.Route, rp *reverseproxy.ReversePro
}
// lifetime should follow route provider.
-func NewHTTPWaker(parent task.Parent, route route.Route, rp *reverseproxy.ReverseProxy) (Waker, E.Error) {
+func NewHTTPWaker(parent task.Parent, route route.Route, rp *reverseproxy.ReverseProxy) (Waker, gperr.Error) {
return newWaker(parent, route, rp, nil)
}
-func NewStreamWaker(parent task.Parent, route route.Route, stream net.Stream) (Waker, E.Error) {
+func NewStreamWaker(parent task.Parent, route route.Route, stream net.Stream) (Waker, gperr.Error) {
return newWaker(parent, route, nil, stream)
}
// Start implements health.HealthMonitor.
-func (w *Watcher) Start(parent task.Parent) E.Error {
+func (w *Watcher) Start(parent task.Parent) gperr.Error {
w.task.OnCancel("route_cleanup", func() {
parent.Finish(w.task.FinishCause())
if w.metric != nil {
diff --git a/internal/docker/idlewatcher/waker_http.go b/internal/docker/idlewatcher/waker_http.go
index b3b7c9b..f3b1975 100644
--- a/internal/docker/idlewatcher/waker_http.go
+++ b/internal/docker/idlewatcher/waker_http.go
@@ -7,8 +7,8 @@ import (
"strconv"
"time"
- "github.com/yusing/go-proxy/internal/common"
- gphttp "github.com/yusing/go-proxy/internal/net/http"
+ gphttp "github.com/yusing/go-proxy/internal/net/gphttp"
+ "github.com/yusing/go-proxy/internal/net/gphttp/httpheaders"
"github.com/yusing/go-proxy/internal/watcher/health"
)
@@ -63,7 +63,7 @@ func (w *Watcher) wakeFromHTTP(rw http.ResponseWriter, r *http.Request) (shouldN
accept := gphttp.GetAccept(r.Header)
acceptHTML := (r.Method == http.MethodGet && accept.AcceptHTML() || r.RequestURI == "/" && accept.IsEmpty())
- isCheckRedirect := r.Header.Get(common.HeaderCheckRedirect) != ""
+ isCheckRedirect := r.Header.Get(httpheaders.HeaderGoDoxyCheckRedirect) != ""
if !isCheckRedirect && acceptHTML {
// Send a loading response to the client
body := w.makeLoadingPageBody()
diff --git a/internal/docker/idlewatcher/watcher.go b/internal/docker/idlewatcher/watcher.go
index bf35371..599579e 100644
--- a/internal/docker/idlewatcher/watcher.go
+++ b/internal/docker/idlewatcher/watcher.go
@@ -10,7 +10,7 @@ import (
"github.com/rs/zerolog"
D "github.com/yusing/go-proxy/internal/docker"
idlewatcher "github.com/yusing/go-proxy/internal/docker/idlewatcher/types"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/logging"
route "github.com/yusing/go-proxy/internal/route/types"
"github.com/yusing/go-proxy/internal/task"
@@ -180,7 +180,7 @@ func (w *Watcher) wakeIfStopped() error {
case "running":
return nil
default:
- return E.Errorf("unexpected container status: %s", status)
+ return gperr.Errorf("unexpected container status: %s", status)
}
}
@@ -213,7 +213,7 @@ func (w *Watcher) expires() time.Time {
return w.lastReset.Add(w.IdleTimeout)
}
-func (w *Watcher) getEventCh(dockerWatcher watcher.DockerWatcher) (eventCh <-chan events.Event, errCh <-chan E.Error) {
+func (w *Watcher) getEventCh(dockerWatcher watcher.DockerWatcher) (eventCh <-chan events.Event, errCh <-chan gperr.Error) {
eventCh, errCh = dockerWatcher.EventsWithOptions(w.Task().Context(), watcher.DockerListOptions{
Filters: watcher.NewDockerFilter(
watcher.DockerFilterContainer,
@@ -251,7 +251,7 @@ func (w *Watcher) watchUntilDestroy() (returnCause error) {
return w.task.FinishCause()
case err := <-dockerEventErrCh:
if !err.Is(context.Canceled) {
- E.LogError("idlewatcher error", err, &w.Logger)
+ gperr.LogError("idlewatcher error", err, &w.Logger)
}
return err
case e := <-dockerEventCh:
diff --git a/internal/docker/label.go b/internal/docker/label.go
index 2dead0a..73de823 100644
--- a/internal/docker/label.go
+++ b/internal/docker/label.go
@@ -1,17 +1,17 @@
package docker
import (
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/utils/strutils"
)
type LabelMap = map[string]any
-var ErrInvalidLabel = E.New("invalid label")
+var ErrInvalidLabel = gperr.New("invalid label")
-func ParseLabels(labels map[string]string) (LabelMap, E.Error) {
+func ParseLabels(labels map[string]string) (LabelMap, gperr.Error) {
nestedMap := make(LabelMap)
- errs := E.NewBuilder("labels error")
+ errs := gperr.NewBuilder("labels error")
for lbl, value := range labels {
parts := strutils.SplitRune(lbl, '.')
@@ -37,7 +37,7 @@ func ParseLabels(labels map[string]string) (LabelMap, E.Error) {
// Move deeper into the nested map
m, ok := currentMap[k].(LabelMap)
if !ok && currentMap[k] != "" {
- errs.Add(E.Errorf("expect mapping, got %T", currentMap[k]).Subject(lbl))
+ errs.Add(gperr.Errorf("expect mapping, got %T", currentMap[k]).Subject(lbl))
continue
} else if !ok {
m = make(LabelMap)
diff --git a/internal/entrypoint/entrypoint.go b/internal/entrypoint/entrypoint.go
index 3ab6dac..1a3a166 100644
--- a/internal/entrypoint/entrypoint.go
+++ b/internal/entrypoint/entrypoint.go
@@ -7,10 +7,10 @@ import (
"strings"
"github.com/yusing/go-proxy/internal/logging"
- gphttp "github.com/yusing/go-proxy/internal/net/http"
- "github.com/yusing/go-proxy/internal/net/http/accesslog"
- "github.com/yusing/go-proxy/internal/net/http/middleware"
- "github.com/yusing/go-proxy/internal/net/http/middleware/errorpage"
+ gphttp "github.com/yusing/go-proxy/internal/net/gphttp"
+ "github.com/yusing/go-proxy/internal/net/gphttp/accesslog"
+ "github.com/yusing/go-proxy/internal/net/gphttp/middleware"
+ "github.com/yusing/go-proxy/internal/net/gphttp/middleware/errorpage"
"github.com/yusing/go-proxy/internal/route/routes"
route "github.com/yusing/go-proxy/internal/route/types"
"github.com/yusing/go-proxy/internal/task"
diff --git a/internal/gperr/README.md b/internal/gperr/README.md
new file mode 100644
index 0000000..1ee390e
--- /dev/null
+++ b/internal/gperr/README.md
@@ -0,0 +1,106 @@
+# gperr
+
+gperr is an error interface that supports nested structure and subject highlighting.
+
+## Usage
+
+### gperr.Error
+
+The error interface.
+
+### gperr.New
+
+Like `errors.New`, but returns a `gperr.Error`.
+
+### gperr.Wrap
+
+Like `fmt.Errorf("%s: %w", message, err)`, but returns a `gperr.Error`.
+
+### gperr.Error.Subject
+
+Returns a new error with the subject prepended to the error message. The main subject is highlighted.
+
+```go
+err := gperr.New("error message")
+err = err.Subject("bar")
+err = err.Subject("foo")
+```
+
+Output:
+
+foo > bar: error message
+
+### gperr.Error.Subjectf
+
+Like `gperr.Error.Subject`, but formats the subject with `fmt.Sprintf`.
+
+### gperr.PrependSubject
+
+Prepends the subject to the error message like `gperr.Error.Subject`.
+
+```go
+err := gperr.New("error message")
+err = gperr.PrependSubject(err, "foo")
+err = gperr.PrependSubject(err, "bar")
+```
+
+Output:
+
+bar > foo: error message
+
+### gperr.Error.With
+
+Adds a new error to the error chain.
+
+```go
+err := gperr.New("error message")
+err = err.With(gperr.New("inner error"))
+err = err.With(gperr.New("inner error 2").With(gperr.New("inner inner error")))
+```
+
+Output:
+
+```
+error message:
+ • inner error
+ • inner error 2
+ • inner inner error
+```
+
+### gperr.Error.Withf
+
+Like `gperr.Error.With`, but formats the error with `fmt.Errorf`.
+
+### gperr.Error.Is
+
+Returns true if the error is equal to the given error.
+
+### gperr.Builder
+
+A builder for `gperr.Error`.
+
+```go
+builder := gperr.NewBuilder("foo")
+builder.Add(gperr.New("error message"))
+builder.Addf("error message: %s", "foo")
+builder.AddRange(gperr.New("error message 1"), gperr.New("error message 2"))
+```
+
+Output:
+
+```
+foo:
+ • error message
+ • error message: foo
+ • error message 1
+ • error message 2
+```
+
+### gperr.Builder.Build
+
+Builds a `gperr.Error` from the builder.
+
+## When to return gperr.Error
+
+- When you want to return multiple errors
+- When the error has a subject
diff --git a/internal/error/base.go b/internal/gperr/base.go
similarity index 98%
rename from internal/error/base.go
rename to internal/gperr/base.go
index 4668a11..96a36b3 100644
--- a/internal/error/base.go
+++ b/internal/gperr/base.go
@@ -1,4 +1,4 @@
-package err
+package gperr
import (
"encoding/json"
diff --git a/internal/error/builder.go b/internal/gperr/builder.go
similarity index 96%
rename from internal/error/builder.go
rename to internal/gperr/builder.go
index 6a23f25..4eeee60 100644
--- a/internal/error/builder.go
+++ b/internal/gperr/builder.go
@@ -1,4 +1,4 @@
-package err
+package gperr
import (
"fmt"
@@ -36,7 +36,7 @@ func (b *Builder) error() Error {
func (b *Builder) Error() Error {
if len(b.errs) == 1 {
- return From(b.errs[0])
+ return wrap(b.errs[0])
}
return b.error()
}
@@ -60,7 +60,7 @@ func (b *Builder) Add(err error) *Builder {
b.Lock()
defer b.Unlock()
- switch err := From(err).(type) {
+ switch err := wrap(err).(type) {
case *baseError:
b.errs = append(b.errs, err.Err)
case *nestedError:
diff --git a/internal/error/builder_test.go b/internal/gperr/builder_test.go
similarity index 94%
rename from internal/error/builder_test.go
rename to internal/gperr/builder_test.go
index 2975e4a..04aa326 100644
--- a/internal/error/builder_test.go
+++ b/internal/gperr/builder_test.go
@@ -1,4 +1,4 @@
-package err_test
+package gperr_test
import (
"context"
@@ -6,7 +6,7 @@ import (
"io"
"testing"
- . "github.com/yusing/go-proxy/internal/error"
+ . "github.com/yusing/go-proxy/internal/gperr"
. "github.com/yusing/go-proxy/internal/utils/testing"
)
diff --git a/internal/error/error.go b/internal/gperr/error.go
similarity index 98%
rename from internal/error/error.go
rename to internal/gperr/error.go
index 03e0079..6d3e70c 100644
--- a/internal/error/error.go
+++ b/internal/gperr/error.go
@@ -1,4 +1,4 @@
-package err
+package gperr
type Error interface {
error
diff --git a/internal/error/error_test.go b/internal/gperr/error_test.go
similarity index 96%
rename from internal/error/error_test.go
rename to internal/gperr/error_test.go
index ad3aca7..81d0139 100644
--- a/internal/error/error_test.go
+++ b/internal/gperr/error_test.go
@@ -1,4 +1,4 @@
-package err
+package gperr
import (
"errors"
@@ -44,7 +44,7 @@ func TestBaseWithExtra(t *testing.T) {
func TestBaseUnwrap(t *testing.T) {
err := errors.New("err")
- wrapped := From(err)
+ wrapped := Wrap(err)
ExpectError(t, err, errors.Unwrap(wrapped))
}
@@ -52,7 +52,7 @@ func TestBaseUnwrap(t *testing.T) {
func TestNestedUnwrap(t *testing.T) {
err := errors.New("err")
err2 := New("err2")
- wrapped := From(err).Subject("foo").With(err2.Subject("bar"))
+ wrapped := Wrap(err).Subject("foo").With(err2.Subject("bar"))
unwrapper, ok := wrapped.(interface{ Unwrap() []error })
ExpectTrue(t, ok)
@@ -64,7 +64,7 @@ func TestNestedUnwrap(t *testing.T) {
func TestErrorIs(t *testing.T) {
from := errors.New("error")
- err := From(from)
+ err := Wrap(from)
ExpectError(t, from, err)
ExpectTrue(t, err.Is(from))
diff --git a/internal/error/log.go b/internal/gperr/log.go
similarity index 50%
rename from internal/error/log.go
rename to internal/gperr/log.go
index 0729023..94c2d15 100644
--- a/internal/error/log.go
+++ b/internal/gperr/log.go
@@ -1,4 +1,4 @@
-package err
+package gperr
import (
"github.com/rs/zerolog"
@@ -6,42 +6,35 @@ import (
"github.com/yusing/go-proxy/internal/logging"
)
-func getLogger(logger ...*zerolog.Logger) *zerolog.Logger {
+func log(msg string, err error, level zerolog.Level, logger ...*zerolog.Logger) {
+ var l *zerolog.Logger
if len(logger) > 0 {
- return logger[0]
+ l = logger[0]
+ } else {
+ l = logging.GetLogger()
}
- return logging.GetLogger()
+ l.WithLevel(level).Msg(msg + ": " + err.Error())
}
-//go:inline
func LogFatal(msg string, err error, logger ...*zerolog.Logger) {
if common.IsDebug {
LogPanic(msg, err, logger...)
}
- getLogger(logger...).Fatal().Msg(err.Error())
+ log(msg, err, zerolog.FatalLevel, logger...)
}
-//go:inline
func LogError(msg string, err error, logger ...*zerolog.Logger) {
- getLogger(logger...).Error().Msg(err.Error())
+ log(msg, err, zerolog.ErrorLevel, logger...)
}
-//go:inline
func LogWarn(msg string, err error, logger ...*zerolog.Logger) {
- getLogger(logger...).Warn().Msg(err.Error())
+ log(msg, err, zerolog.WarnLevel, logger...)
}
-//go:inline
func LogPanic(msg string, err error, logger ...*zerolog.Logger) {
- getLogger(logger...).Panic().Msg(err.Error())
+ log(msg, err, zerolog.PanicLevel, logger...)
}
-//go:inline
-func LogInfo(msg string, err error, logger ...*zerolog.Logger) {
- getLogger(logger...).Info().Msg(err.Error())
-}
-
-//go:inline
func LogDebug(msg string, err error, logger ...*zerolog.Logger) {
- getLogger(logger...).Debug().Msg(err.Error())
+ log(msg, err, zerolog.DebugLevel, logger...)
}
diff --git a/internal/error/nested_error.go b/internal/gperr/nested_error.go
similarity index 97%
rename from internal/error/nested_error.go
rename to internal/gperr/nested_error.go
index e666a4f..dc97d87 100644
--- a/internal/error/nested_error.go
+++ b/internal/gperr/nested_error.go
@@ -1,4 +1,4 @@
-package err
+package gperr
import (
"errors"
@@ -99,7 +99,7 @@ func makeLines(errs []error, level int) []string {
}
lines := make([]string, 0, len(errs))
for _, err := range errs {
- switch err := From(err).(type) {
+ switch err := wrap(err).(type) {
case *nestedError:
if err.Err != nil {
lines = append(lines, makeLine(err.Err.Error(), level))
diff --git a/internal/error/subject.go b/internal/gperr/subject.go
similarity index 99%
rename from internal/error/subject.go
rename to internal/gperr/subject.go
index eac7499..293b648 100644
--- a/internal/error/subject.go
+++ b/internal/gperr/subject.go
@@ -1,4 +1,4 @@
-package err
+package gperr
import (
"encoding/json"
diff --git a/internal/error/utils.go b/internal/gperr/utils.go
similarity index 60%
rename from internal/error/utils.go
rename to internal/gperr/utils.go
index 8e36f83..4ac1d64 100644
--- a/internal/error/utils.go
+++ b/internal/gperr/utils.go
@@ -1,6 +1,8 @@
-package err
+package gperr
import (
+ "encoding/json"
+ "errors"
"fmt"
)
@@ -19,27 +21,50 @@ func Errorf(format string, args ...any) Error {
return &baseError{fmt.Errorf(format, args...)}
}
+// Wrap wraps message in front of the error message.
func Wrap(err error, message ...string) Error {
- if len(message) == 0 || message[0] == "" {
- return From(err)
+ if err == nil {
+ return nil
}
- return Errorf("%s: %w", message[0], err)
+ if len(message) == 0 || message[0] == "" {
+ return wrap(err)
+ }
+ //nolint:errorlint
+ switch err := err.(type) {
+ case *baseError:
+ err.Err = fmt.Errorf("%s: %w", message[0], err.Err)
+ return err
+ case *nestedError:
+ err.Err = fmt.Errorf("%s: %w", message[0], err.Err)
+ return err
+ }
+ return &baseError{fmt.Errorf("%s: %w", message[0], err)}
}
-func From(err error) Error {
+func wrap(err error) Error {
if err == nil {
return nil
}
//nolint:errorlint
switch err := err.(type) {
- case *baseError:
- return err
- case *nestedError:
+ case Error:
return err
}
return &baseError{err}
}
+func IsJSONMarshallable(err error) bool {
+ switch err := err.(type) {
+ case *nestedError, *withSubject:
+ return true
+ case *baseError:
+ return IsJSONMarshallable(err.Err)
+ default:
+ var v json.Marshaler
+ return errors.As(err, &v)
+ }
+}
+
func Join(errors ...error) Error {
n := 0
for _, err := range errors {
diff --git a/internal/gperr/utils_test.go b/internal/gperr/utils_test.go
new file mode 100644
index 0000000..7298f80
--- /dev/null
+++ b/internal/gperr/utils_test.go
@@ -0,0 +1,58 @@
+package gperr
+
+import (
+ "errors"
+ "testing"
+)
+
+type testErr struct{}
+
+func (e *testErr) Error() string {
+ return "test error"
+}
+
+func (e *testErr) MarshalJSON() ([]byte, error) {
+ return nil, nil
+}
+
+func TestIsJSONMarshallable(t *testing.T) {
+ tests := []struct {
+ name string
+ err error
+ want bool
+ }{
+ {
+ name: "testErr",
+ err: &testErr{},
+ want: true,
+ },
+ {
+ name: "baseError",
+ err: &baseError{},
+ want: true,
+ },
+ {
+ name: "nestedError",
+ err: &nestedError{},
+ want: true,
+ },
+ {
+ name: "withSubject",
+ err: &withSubject{},
+ want: true,
+ },
+ {
+ name: "standard error",
+ err: errors.New("test error"),
+ want: false,
+ },
+ }
+
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ if got := IsJSONMarshallable(test.err); got != test.want {
+ t.Errorf("IsJSONMarshallable(%v) = %v, want %v", test.err, got, test.want)
+ }
+ })
+ }
+}
diff --git a/internal/homepage/icon_url.go b/internal/homepage/icon_url.go
index f5265a4..f53060d 100644
--- a/internal/homepage/icon_url.go
+++ b/internal/homepage/icon_url.go
@@ -5,7 +5,7 @@ import (
"strings"
"github.com/yusing/go-proxy/internal"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
)
type (
@@ -31,7 +31,7 @@ const (
IconSourceSelfhSt
)
-var ErrInvalidIconURL = E.New("invalid icon url")
+var ErrInvalidIconURL = gperr.New("invalid icon url")
func NewSelfhStIconURL(reference, format string) *IconURL {
return &IconURL{
diff --git a/internal/logging/memlogger/mem_logger.go b/internal/logging/memlogger/mem_logger.go
index 5904b84..deff058 100644
--- a/internal/logging/memlogger/mem_logger.go
+++ b/internal/logging/memlogger/mem_logger.go
@@ -11,9 +11,10 @@ import (
"github.com/coder/websocket"
"github.com/rs/zerolog"
- "github.com/yusing/go-proxy/internal/api/v1/utils"
"github.com/yusing/go-proxy/internal/common"
"github.com/yusing/go-proxy/internal/logging"
+ "github.com/yusing/go-proxy/internal/net/gphttp"
+ "github.com/yusing/go-proxy/internal/net/gphttp/gpwebsocket"
"github.com/yusing/go-proxy/internal/task"
F "github.com/yusing/go-proxy/internal/utils/functional"
)
@@ -27,8 +28,9 @@ type memLogger struct {
sync.RWMutex
notifyLock sync.RWMutex
connChans F.Map[chan *logEntryRange, struct{}]
+ listeners F.Map[chan []byte, struct{}]
- bufPool sync.Pool // used in hook mode
+ bufPool sync.Pool
}
type MemLogger io.Writer
@@ -41,15 +43,16 @@ const (
maxMemLogSize = 16 * 1024
truncateSize = maxMemLogSize / 2
initialWriteChunkSize = 4 * 1024
- hookModeBufSize = 256
+ bufPoolSize = 256
)
var memLoggerInstance = &memLogger{
connChans: F.NewMapOf[chan *logEntryRange, struct{}](),
+ listeners: F.NewMapOf[chan []byte, struct{}](),
bufPool: sync.Pool{
New: func() any {
return &buffer{
- data: make([]byte, 0, hookModeBufSize),
+ data: make([]byte, 0, bufPoolSize),
}
},
},
@@ -92,6 +95,10 @@ func HandlerFunc() http.HandlerFunc {
return memLoggerInstance.ServeHTTP
}
+func Events() (<-chan []byte, func()) {
+ return memLoggerInstance.events()
+}
+
func (m *memLogger) truncateIfNeeded(n int) {
m.RLock()
needTruncate := m.Len()+n > maxMemLogSize
@@ -111,7 +118,7 @@ func (m *memLogger) truncateIfNeeded(n int) {
func (m *memLogger) notifyWS(pos, n int) {
if m.connChans.Size() > 0 {
- timeout := time.NewTimer(1 * time.Second)
+ timeout := time.NewTimer(2 * time.Second)
defer timeout.Stop()
m.notifyLock.RLock()
@@ -125,6 +132,19 @@ func (m *memLogger) notifyWS(pos, n int) {
return false
}
})
+ if m.listeners.Size() > 0 {
+ msg := make([]byte, n)
+ copy(msg, m.Buffer.Bytes()[pos:pos+n])
+ m.listeners.Range(func(ch chan []byte, _ struct{}) bool {
+ select {
+ case <-timeout.C:
+ logging.Warn().Msg("mem logger: timeout logging to channel")
+ return false
+ case ch <- msg:
+ return true
+ }
+ })
+ }
return
}
}
@@ -153,9 +173,9 @@ func (m *memLogger) Write(p []byte) (n int, err error) {
}
func (m *memLogger) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- conn, err := utils.InitiateWS(w, r)
+ conn, err := gpwebsocket.Initiate(w, r)
if err != nil {
- utils.HandleErr(w, r, err)
+ gphttp.ServerError(w, r, err)
return
}
@@ -172,13 +192,27 @@ func (m *memLogger) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}()
if err := m.wsInitial(r.Context(), conn); err != nil {
- utils.HandleErr(w, r, err)
+ gphttp.ServerError(w, r, err)
return
}
m.wsStreamLog(r.Context(), conn, logCh)
}
+func (m *memLogger) events() (<-chan []byte, func()) {
+ ch := make(chan []byte, 10)
+ m.notifyLock.Lock()
+ defer m.notifyLock.Unlock()
+ m.listeners.Store(ch, struct{}{})
+
+ return ch, func() {
+ m.notifyLock.Lock()
+ defer m.notifyLock.Unlock()
+ m.listeners.Delete(ch)
+ close(ch)
+ }
+}
+
func (m *memLogger) writeBytes(ctx context.Context, conn *websocket.Conn, b []byte) error {
return conn.Write(ctx, websocket.MessageText, b)
}
diff --git a/internal/metrics/period/handler.go b/internal/metrics/period/handler.go
index af6ead0..40f7cfe 100644
--- a/internal/metrics/period/handler.go
+++ b/internal/metrics/period/handler.go
@@ -7,9 +7,10 @@ import (
"github.com/coder/websocket"
"github.com/coder/websocket/wsjson"
- "github.com/yusing/go-proxy/internal/api/v1/utils"
metricsutils "github.com/yusing/go-proxy/internal/metrics/utils"
- "github.com/yusing/go-proxy/internal/net/http/httpheaders"
+ "github.com/yusing/go-proxy/internal/net/gphttp"
+ "github.com/yusing/go-proxy/internal/net/gphttp/gpwebsocket"
+ "github.com/yusing/go-proxy/internal/net/gphttp/httpheaders"
)
// ServeHTTP serves the data for the given period.
@@ -36,7 +37,7 @@ func (p *Poller[T, AggregateT]) ServeHTTP(w http.ResponseWriter, r *http.Request
if interval < minInterval {
interval = minInterval
}
- utils.PeriodicWS(w, r, interval, func(conn *websocket.Conn) error {
+ gpwebsocket.Periodic(w, r, interval, func(conn *websocket.Conn) error {
data, err := p.getRespData(r)
if err != nil {
return err
@@ -49,14 +50,14 @@ func (p *Poller[T, AggregateT]) ServeHTTP(w http.ResponseWriter, r *http.Request
} else {
data, err := p.getRespData(r)
if err != nil {
- utils.HandleErr(w, r, err)
+ gphttp.ServerError(w, r, err)
return
}
if data == nil {
http.Error(w, "no data", http.StatusNoContent)
return
}
- utils.RespondJSON(w, r, data)
+ gphttp.RespondJSON(w, r, data)
}
}
diff --git a/internal/metrics/period/poller.go b/internal/metrics/period/poller.go
index 7a2ef3e..3ff9da9 100644
--- a/internal/metrics/period/poller.go
+++ b/internal/metrics/period/poller.go
@@ -6,7 +6,7 @@ import (
"net/url"
"time"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/logging"
"github.com/yusing/go-proxy/internal/task"
)
@@ -84,7 +84,7 @@ func (p *Poller[T, AggregateT]) gatherErrs() (string, bool) {
if len(p.errs) == 0 {
return "", false
}
- errs := E.NewBuilder(fmt.Sprintf("poller %s has encountered %d errors in the last %s:", p.name, len(p.errs), gatherErrsInterval))
+ errs := gperr.NewBuilder(fmt.Sprintf("poller %s has encountered %d errors in the last %s:", p.name, len(p.errs), gatherErrsInterval))
for _, e := range p.errs {
errs.Addf("%w: %d times", e.err, e.count)
}
diff --git a/internal/metrics/systeminfo/system_info.go b/internal/metrics/systeminfo/system_info.go
index 4ef766b..27854d7 100644
--- a/internal/metrics/systeminfo/system_info.go
+++ b/internal/metrics/systeminfo/system_info.go
@@ -12,7 +12,7 @@ import (
"github.com/shirou/gopsutil/v4/net"
"github.com/shirou/gopsutil/v4/sensors"
"github.com/yusing/go-proxy/internal/common"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/logging"
"github.com/yusing/go-proxy/internal/metrics/period"
"github.com/yusing/go-proxy/internal/utils/strutils"
@@ -40,7 +40,7 @@ func _() { // check if this behavior is not changed
}
func getSystemInfo(ctx context.Context, lastResult *SystemInfo) (*SystemInfo, error) {
- errs := E.NewBuilder("failed to get system info")
+ errs := gperr.NewBuilder("failed to get system info")
var systemInfo SystemInfo
if !common.MetricsDisableCPU {
@@ -95,8 +95,8 @@ func getSystemInfo(ctx context.Context, lastResult *SystemInfo) (*SystemInfo, er
}
if errs.HasError() {
- allWarnings := E.NewBuilder("")
- allErrors := E.NewBuilder("failed to get system info")
+ allWarnings := gperr.NewBuilder("")
+ allErrors := gperr.NewBuilder("failed to get system info")
errs.ForEach(func(err error) {
// disk.Warnings has the same type
// all Warnings are alias of common.Warnings from "github.com/shirou/gopsutil/v4/internal/common"
diff --git a/internal/net/http/accesslog/access_logger.go b/internal/net/gphttp/accesslog/access_logger.go
similarity index 97%
rename from internal/net/http/accesslog/access_logger.go
rename to internal/net/gphttp/accesslog/access_logger.go
index 16c10d4..36e7486 100644
--- a/internal/net/http/accesslog/access_logger.go
+++ b/internal/net/gphttp/accesslog/access_logger.go
@@ -7,7 +7,7 @@ import (
"sync"
"time"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/logging"
"github.com/yusing/go-proxy/internal/task"
)
@@ -131,7 +131,7 @@ func (l *AccessLogger) Flush(force bool) {
}
func (l *AccessLogger) handleErr(err error) {
- E.LogError("failed to write access log", err)
+ gperr.LogError("failed to write access log", err)
}
func (l *AccessLogger) start() {
diff --git a/internal/net/http/accesslog/access_logger_test.go b/internal/net/gphttp/accesslog/access_logger_test.go
similarity index 98%
rename from internal/net/http/accesslog/access_logger_test.go
rename to internal/net/gphttp/accesslog/access_logger_test.go
index 2398ca7..012d8eb 100644
--- a/internal/net/http/accesslog/access_logger_test.go
+++ b/internal/net/gphttp/accesslog/access_logger_test.go
@@ -9,7 +9,7 @@ import (
"testing"
"time"
- . "github.com/yusing/go-proxy/internal/net/http/accesslog"
+ . "github.com/yusing/go-proxy/internal/net/gphttp/accesslog"
"github.com/yusing/go-proxy/internal/task"
. "github.com/yusing/go-proxy/internal/utils/testing"
)
diff --git a/internal/net/http/accesslog/config.go b/internal/net/gphttp/accesslog/config.go
similarity index 100%
rename from internal/net/http/accesslog/config.go
rename to internal/net/gphttp/accesslog/config.go
diff --git a/internal/net/http/accesslog/config_test.go b/internal/net/gphttp/accesslog/config_test.go
similarity index 97%
rename from internal/net/http/accesslog/config_test.go
rename to internal/net/gphttp/accesslog/config_test.go
index 125b501..e8de01d 100644
--- a/internal/net/http/accesslog/config_test.go
+++ b/internal/net/gphttp/accesslog/config_test.go
@@ -4,7 +4,7 @@ import (
"testing"
"github.com/yusing/go-proxy/internal/docker"
- . "github.com/yusing/go-proxy/internal/net/http/accesslog"
+ . "github.com/yusing/go-proxy/internal/net/gphttp/accesslog"
"github.com/yusing/go-proxy/internal/utils"
. "github.com/yusing/go-proxy/internal/utils/testing"
)
diff --git a/internal/net/http/accesslog/fields.go b/internal/net/gphttp/accesslog/fields.go
similarity index 100%
rename from internal/net/http/accesslog/fields.go
rename to internal/net/gphttp/accesslog/fields.go
diff --git a/internal/net/http/accesslog/fields_test.go b/internal/net/gphttp/accesslog/fields_test.go
similarity index 97%
rename from internal/net/http/accesslog/fields_test.go
rename to internal/net/gphttp/accesslog/fields_test.go
index feac44d..1cfa370 100644
--- a/internal/net/http/accesslog/fields_test.go
+++ b/internal/net/gphttp/accesslog/fields_test.go
@@ -3,7 +3,7 @@ package accesslog_test
import (
"testing"
- . "github.com/yusing/go-proxy/internal/net/http/accesslog"
+ . "github.com/yusing/go-proxy/internal/net/gphttp/accesslog"
. "github.com/yusing/go-proxy/internal/utils/testing"
)
diff --git a/internal/net/http/accesslog/file_logger.go b/internal/net/gphttp/accesslog/file_logger.go
similarity index 100%
rename from internal/net/http/accesslog/file_logger.go
rename to internal/net/gphttp/accesslog/file_logger.go
diff --git a/internal/net/http/accesslog/file_logger_test.go b/internal/net/gphttp/accesslog/file_logger_test.go
similarity index 100%
rename from internal/net/http/accesslog/file_logger_test.go
rename to internal/net/gphttp/accesslog/file_logger_test.go
diff --git a/internal/net/http/accesslog/filter.go b/internal/net/gphttp/accesslog/filter.go
similarity index 94%
rename from internal/net/http/accesslog/filter.go
rename to internal/net/gphttp/accesslog/filter.go
index 822101e..c0c3e29 100644
--- a/internal/net/http/accesslog/filter.go
+++ b/internal/net/gphttp/accesslog/filter.go
@@ -5,7 +5,7 @@ import (
"net/http"
"strings"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/net/types"
"github.com/yusing/go-proxy/internal/utils/strutils"
)
@@ -27,7 +27,7 @@ type (
CIDR struct{ types.CIDR }
)
-var ErrInvalidHTTPHeaderFilter = E.New("invalid http header filter")
+var ErrInvalidHTTPHeaderFilter = gperr.New("invalid http header filter")
func (f *LogFilter[T]) CheckKeep(req *http.Request, res *http.Response) bool {
if len(f.Values) == 0 {
diff --git a/internal/net/http/accesslog/filter_test.go b/internal/net/gphttp/accesslog/filter_test.go
similarity index 98%
rename from internal/net/http/accesslog/filter_test.go
rename to internal/net/gphttp/accesslog/filter_test.go
index 7160dce..a934a7b 100644
--- a/internal/net/http/accesslog/filter_test.go
+++ b/internal/net/gphttp/accesslog/filter_test.go
@@ -4,7 +4,7 @@ import (
"net/http"
"testing"
- . "github.com/yusing/go-proxy/internal/net/http/accesslog"
+ . "github.com/yusing/go-proxy/internal/net/gphttp/accesslog"
"github.com/yusing/go-proxy/internal/utils/strutils"
. "github.com/yusing/go-proxy/internal/utils/testing"
)
diff --git a/internal/net/http/accesslog/formatter.go b/internal/net/gphttp/accesslog/formatter.go
similarity index 100%
rename from internal/net/http/accesslog/formatter.go
rename to internal/net/gphttp/accesslog/formatter.go
diff --git a/internal/net/http/accesslog/mock_file.go b/internal/net/gphttp/accesslog/mock_file.go
similarity index 100%
rename from internal/net/http/accesslog/mock_file.go
rename to internal/net/gphttp/accesslog/mock_file.go
diff --git a/internal/net/http/accesslog/retention.go b/internal/net/gphttp/accesslog/retention.go
similarity index 96%
rename from internal/net/http/accesslog/retention.go
rename to internal/net/gphttp/accesslog/retention.go
index da31544..bf8b4c8 100644
--- a/internal/net/http/accesslog/retention.go
+++ b/internal/net/gphttp/accesslog/retention.go
@@ -7,7 +7,7 @@ import (
"strconv"
"time"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/utils/strutils"
)
@@ -19,8 +19,8 @@ type Retention struct {
const chunkSizeMax int64 = 128 * 1024 // 128KB
var (
- ErrInvalidSyntax = E.New("invalid syntax")
- ErrZeroValue = E.New("zero value")
+ ErrInvalidSyntax = gperr.New("invalid syntax")
+ ErrZeroValue = gperr.New("zero value")
)
// Syntax:
diff --git a/internal/net/http/accesslog/retention_test.go b/internal/net/gphttp/accesslog/retention_test.go
similarity index 96%
rename from internal/net/http/accesslog/retention_test.go
rename to internal/net/gphttp/accesslog/retention_test.go
index ea51fe2..ccb3b5d 100644
--- a/internal/net/http/accesslog/retention_test.go
+++ b/internal/net/gphttp/accesslog/retention_test.go
@@ -4,7 +4,7 @@ import (
"testing"
"time"
- . "github.com/yusing/go-proxy/internal/net/http/accesslog"
+ . "github.com/yusing/go-proxy/internal/net/gphttp/accesslog"
"github.com/yusing/go-proxy/internal/task"
"github.com/yusing/go-proxy/internal/utils/strutils"
. "github.com/yusing/go-proxy/internal/utils/testing"
diff --git a/internal/net/http/accesslog/status_code_range.go b/internal/net/gphttp/accesslog/status_code_range.go
similarity index 81%
rename from internal/net/http/accesslog/status_code_range.go
rename to internal/net/gphttp/accesslog/status_code_range.go
index 599f119..7ec94a2 100644
--- a/internal/net/http/accesslog/status_code_range.go
+++ b/internal/net/gphttp/accesslog/status_code_range.go
@@ -3,7 +3,7 @@ package accesslog
import (
"strconv"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/utils/strutils"
)
@@ -12,7 +12,7 @@ type StatusCodeRange struct {
End int
}
-var ErrInvalidStatusCodeRange = E.New("invalid status code range")
+var ErrInvalidStatusCodeRange = gperr.New("invalid status code range")
func (r *StatusCodeRange) Includes(code int) bool {
return r.Start <= code && code <= r.End
@@ -25,7 +25,7 @@ func (r *StatusCodeRange) Parse(v string) error {
case 1:
start, err := strconv.Atoi(split[0])
if err != nil {
- return E.From(err)
+ return gperr.Wrap(err)
}
r.Start = start
r.End = start
@@ -33,7 +33,7 @@ func (r *StatusCodeRange) Parse(v string) error {
case 2:
start, errStart := strconv.Atoi(split[0])
end, errEnd := strconv.Atoi(split[1])
- if err := E.Join(errStart, errEnd); err != nil {
+ if err := gperr.Join(errStart, errEnd); err != nil {
return err
}
r.Start = start
diff --git a/internal/api/v1/utils/utils.go b/internal/net/gphttp/body.go
similarity index 65%
rename from internal/api/v1/utils/utils.go
rename to internal/net/gphttp/body.go
index 48d4457..3a94023 100644
--- a/internal/api/v1/utils/utils.go
+++ b/internal/net/gphttp/body.go
@@ -1,7 +1,9 @@
-package utils
+package gphttp
import (
+ "context"
"encoding/json"
+ "errors"
"fmt"
"net/http"
@@ -10,7 +12,13 @@ import (
func WriteBody(w http.ResponseWriter, body []byte) {
if _, err := w.Write(body); err != nil {
- logging.Err(err).Msg("failed to write body")
+ switch {
+ case errors.Is(err, http.ErrHandlerTimeout),
+ errors.Is(err, context.DeadlineExceeded):
+ logging.Err(err).Msg("timeout writing body")
+ default:
+ logging.Err(err).Msg("failed to write body")
+ }
}
}
@@ -25,13 +33,13 @@ func RespondJSON(w http.ResponseWriter, r *http.Request, data any, code ...int)
case string:
_, err = w.Write([]byte(fmt.Sprintf("%q", data)))
case []byte:
- _, err = w.Write(data)
+ panic("use WriteBody instead")
default:
err = json.NewEncoder(w).Encode(data)
}
if err != nil {
- HandleErr(w, r, err)
+ LogError(r).Err(err).Msg("failed to encode json")
return false
}
return true
diff --git a/internal/net/http/content_type.go b/internal/net/gphttp/content_type.go
similarity index 98%
rename from internal/net/http/content_type.go
rename to internal/net/gphttp/content_type.go
index 3b4be65..dee78ff 100644
--- a/internal/net/http/content_type.go
+++ b/internal/net/gphttp/content_type.go
@@ -1,4 +1,4 @@
-package http
+package gphttp
import (
"mime"
diff --git a/internal/net/http/content_type_test.go b/internal/net/gphttp/content_type_test.go
similarity index 99%
rename from internal/net/http/content_type_test.go
rename to internal/net/gphttp/content_type_test.go
index ee4ea56..f5bba69 100644
--- a/internal/net/http/content_type_test.go
+++ b/internal/net/gphttp/content_type_test.go
@@ -1,4 +1,4 @@
-package http
+package gphttp
import (
"net/http"
diff --git a/internal/api/v1/utils/http_client.go b/internal/net/gphttp/default_client.go
similarity index 65%
rename from internal/api/v1/utils/http_client.go
rename to internal/net/gphttp/default_client.go
index 48d743b..dee455a 100644
--- a/internal/api/v1/utils/http_client.go
+++ b/internal/net/gphttp/default_client.go
@@ -1,22 +1,21 @@
-package utils
+package gphttp
import (
"crypto/tls"
"net"
"net/http"
-
- "github.com/yusing/go-proxy/internal/common"
+ "time"
)
var (
httpClient = &http.Client{
- Timeout: common.ConnectionTimeout,
+ Timeout: 5 * time.Second,
Transport: &http.Transport{
DisableKeepAlives: true,
ForceAttemptHTTP2: false,
DialContext: (&net.Dialer{
- Timeout: common.DialTimeout,
- KeepAlive: common.KeepAlive, // this is different from DisableKeepAlives
+ Timeout: 3 * time.Second,
+ KeepAlive: 60 * time.Second, // this is different from DisableKeepAlives
}).DialContext,
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
diff --git a/internal/net/gphttp/error.go b/internal/net/gphttp/error.go
new file mode 100644
index 0000000..060fac5
--- /dev/null
+++ b/internal/net/gphttp/error.go
@@ -0,0 +1,95 @@
+package gphttp
+
+import (
+ "context"
+ "encoding/json"
+ "errors"
+ "net/http"
+ "syscall"
+
+ "github.com/yusing/go-proxy/internal/gperr"
+ "github.com/yusing/go-proxy/internal/net/gphttp/httpheaders"
+)
+
+// ServerError is for handling server errors.
+//
+// It logs the error and returns http.StatusInternalServerError to the client.
+// Status code can be specified as an argument.
+func ServerError(w http.ResponseWriter, r *http.Request, err error, code ...int) {
+ switch {
+ case err == nil,
+ errors.Is(err, context.Canceled),
+ errors.Is(err, syscall.EPIPE),
+ errors.Is(err, syscall.ECONNRESET):
+ return
+ }
+ LogError(r).Msg(err.Error())
+ if httpheaders.IsWebsocket(r.Header) {
+ return
+ }
+ if len(code) == 0 {
+ code = []int{http.StatusInternalServerError}
+ }
+ http.Error(w, http.StatusText(code[0]), code[0])
+}
+
+// ClientError is for responding to client errors.
+//
+// It returns http.StatusBadRequest with reason to the client.
+// Status code can be specified as an argument.
+//
+// For JSON marshallable errors (e.g. gperr.Error), it returns the error details as JSON.
+// Otherwise, it returns the error details as plain text.
+func ClientError(w http.ResponseWriter, err error, code ...int) {
+ if len(code) == 0 {
+ code = []int{http.StatusBadRequest}
+ }
+ if gperr.IsJSONMarshallable(err) {
+ w.Header().Set("Content-Type", "application/json")
+ json.NewEncoder(w).Encode(err)
+ } else {
+ w.Header().Set("Content-Type", "text/plain; charset=utf-8")
+ }
+ http.Error(w, err.Error(), code[0])
+}
+
+// JSONError returns a JSON response of gperr.Error with the given status code.
+func JSONError(w http.ResponseWriter, err gperr.Error, code int) {
+ w.Header().Set("Content-Type", "application/json")
+ json.NewEncoder(w).Encode(err)
+ http.Error(w, err.Error(), code)
+}
+
+// BadRequest returns a Bad Request response with the given error message.
+func BadRequest(w http.ResponseWriter, err string, code ...int) {
+ if len(code) == 0 {
+ code = []int{http.StatusBadRequest}
+ }
+ http.Error(w, err, code[0])
+}
+
+// Unauthorized returns an Unauthorized response with the given error message.
+func Unauthorized(w http.ResponseWriter, err string) {
+ BadRequest(w, err, http.StatusUnauthorized)
+}
+
+// NotFound returns a Not Found response with the given error message.
+func NotFound(w http.ResponseWriter, err string) {
+ BadRequest(w, err, http.StatusNotFound)
+}
+
+func ErrMissingKey(k string) error {
+ return gperr.New(k + " is required")
+}
+
+func ErrInvalidKey(k string) error {
+ return gperr.New(k + " is invalid")
+}
+
+func ErrAlreadyExists(k, v string) error {
+ return gperr.Errorf("%s %q already exists", k, v)
+}
+
+func ErrNotFound(k, v string) error {
+ return gperr.Errorf("%s %q not found", k, v)
+}
diff --git a/internal/api/v1/utils/ws.go b/internal/net/gphttp/gpwebsocket/utils.go
similarity index 57%
rename from internal/api/v1/utils/ws.go
rename to internal/net/gphttp/gpwebsocket/utils.go
index aa2f985..cb67dd6 100644
--- a/internal/api/v1/utils/ws.go
+++ b/internal/net/gphttp/gpwebsocket/utils.go
@@ -1,4 +1,4 @@
-package utils
+package gpwebsocket
import (
"net/http"
@@ -7,8 +7,10 @@ import (
"github.com/coder/websocket"
"github.com/yusing/go-proxy/internal/common"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/logging"
- "github.com/yusing/go-proxy/internal/net/http/httpheaders"
+ "github.com/yusing/go-proxy/internal/net/gphttp"
+ "github.com/yusing/go-proxy/internal/net/gphttp/httpheaders"
)
func warnNoMatchDomains() {
@@ -17,7 +19,7 @@ func warnNoMatchDomains() {
var warnNoMatchDomainOnce sync.Once
-func InitiateWS(w http.ResponseWriter, r *http.Request) (*websocket.Conn, error) {
+func Initiate(w http.ResponseWriter, r *http.Request) (*websocket.Conn, error) {
var originPats []string
localAddresses := []string{"127.0.0.1", "10.0.*.*", "172.16.*.*", "192.168.*.*"}
@@ -42,17 +44,17 @@ func InitiateWS(w http.ResponseWriter, r *http.Request) (*websocket.Conn, error)
})
}
-func PeriodicWS(w http.ResponseWriter, r *http.Request, interval time.Duration, do func(conn *websocket.Conn) error) {
- conn, err := InitiateWS(w, r)
+func Periodic(w http.ResponseWriter, r *http.Request, interval time.Duration, do func(conn *websocket.Conn) error) {
+ conn, err := Initiate(w, r)
if err != nil {
- HandleErr(w, r, err)
+ gphttp.ServerError(w, r, err)
return
}
//nolint:errcheck
defer conn.CloseNow()
if err := do(conn); err != nil {
- HandleErr(w, r, err)
+ gphttp.ServerError(w, r, err)
return
}
@@ -65,9 +67,20 @@ func PeriodicWS(w http.ResponseWriter, r *http.Request, interval time.Duration,
return
case <-ticker.C:
if err := do(conn); err != nil {
- HandleErr(w, r, err)
+ gphttp.ServerError(w, r, err)
return
}
}
}
}
+
+// WriteText writes a text message to the websocket connection.
+// It returns true if the message was written successfully, false otherwise.
+// It logs an error if the message is not written successfully.
+func WriteText(r *http.Request, conn *websocket.Conn, msg string) bool {
+ if err := conn.Write(r.Context(), websocket.MessageText, []byte(msg)); err != nil {
+ gperr.LogError("failed to write text message", err)
+ return false
+ }
+ return true
+}
diff --git a/internal/net/http/httpheaders/sse.go b/internal/net/gphttp/httpheaders/sse.go
similarity index 100%
rename from internal/net/http/httpheaders/sse.go
rename to internal/net/gphttp/httpheaders/sse.go
diff --git a/internal/net/http/httpheaders/utils.go b/internal/net/gphttp/httpheaders/utils.go
similarity index 91%
rename from internal/net/http/httpheaders/utils.go
rename to internal/net/gphttp/httpheaders/utils.go
index 20e892b..00bed76 100644
--- a/internal/net/http/httpheaders/utils.go
+++ b/internal/net/gphttp/httpheaders/utils.go
@@ -17,13 +17,15 @@ const (
HeaderXForwardedURI = "X-Forwarded-Uri"
HeaderXRealIP = "X-Real-IP"
- HeaderUpstreamName = "X-GoDoxy-Upstream-Name"
- HeaderUpstreamScheme = "X-GoDoxy-Upstream-Scheme"
- HeaderUpstreamHost = "X-GoDoxy-Upstream-Host"
- HeaderUpstreamPort = "X-GoDoxy-Upstream-Port"
-
HeaderContentType = "Content-Type"
HeaderContentLength = "Content-Length"
+
+ HeaderUpstreamName = "X-Godoxy-Upstream-Name"
+ HeaderUpstreamScheme = "X-Godoxy-Upstream-Scheme"
+ HeaderUpstreamHost = "X-Godoxy-Upstream-Host"
+ HeaderUpstreamPort = "X-Godoxy-Upstream-Port"
+
+ HeaderGoDoxyCheckRedirect = "X-Godoxy-Check-Redirect"
)
// Hop-by-hop headers. These are removed when sent to the backend.
diff --git a/internal/net/http/httpheaders/websocket.go b/internal/net/gphttp/httpheaders/websocket.go
similarity index 100%
rename from internal/net/http/httpheaders/websocket.go
rename to internal/net/gphttp/httpheaders/websocket.go
diff --git a/internal/net/http/loadbalancer/ip_hash.go b/internal/net/gphttp/loadbalancer/ip_hash.go
similarity index 89%
rename from internal/net/http/loadbalancer/ip_hash.go
rename to internal/net/gphttp/loadbalancer/ip_hash.go
index 384f7cf..d8a54ed 100644
--- a/internal/net/http/loadbalancer/ip_hash.go
+++ b/internal/net/gphttp/loadbalancer/ip_hash.go
@@ -6,8 +6,8 @@ import (
"net/http"
"sync"
- E "github.com/yusing/go-proxy/internal/error"
- "github.com/yusing/go-proxy/internal/net/http/middleware"
+ "github.com/yusing/go-proxy/internal/gperr"
+ "github.com/yusing/go-proxy/internal/net/gphttp/middleware"
)
type ipHash struct {
@@ -23,10 +23,10 @@ func (lb *LoadBalancer) newIPHash() impl {
if len(lb.Options) == 0 {
return impl
}
- var err E.Error
+ var err gperr.Error
impl.realIP, err = middleware.RealIP.New(lb.Options)
if err != nil {
- E.LogError("invalid real_ip options, ignoring", err, &impl.l)
+ gperr.LogError("invalid real_ip options, ignoring", err, &impl.l)
}
return impl
}
diff --git a/internal/net/http/loadbalancer/least_conn.go b/internal/net/gphttp/loadbalancer/least_conn.go
similarity index 100%
rename from internal/net/http/loadbalancer/least_conn.go
rename to internal/net/gphttp/loadbalancer/least_conn.go
diff --git a/internal/net/http/loadbalancer/loadbalancer.go b/internal/net/gphttp/loadbalancer/loadbalancer.go
similarity index 95%
rename from internal/net/http/loadbalancer/loadbalancer.go
rename to internal/net/gphttp/loadbalancer/loadbalancer.go
index b453648..fa3e413 100644
--- a/internal/net/http/loadbalancer/loadbalancer.go
+++ b/internal/net/gphttp/loadbalancer/loadbalancer.go
@@ -6,10 +6,10 @@ import (
"time"
"github.com/rs/zerolog"
- "github.com/yusing/go-proxy/internal/common"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/logging"
- "github.com/yusing/go-proxy/internal/net/http/loadbalancer/types"
+ "github.com/yusing/go-proxy/internal/net/gphttp/httpheaders"
+ "github.com/yusing/go-proxy/internal/net/gphttp/loadbalancer/types"
"github.com/yusing/go-proxy/internal/route/routes"
"github.com/yusing/go-proxy/internal/task"
"github.com/yusing/go-proxy/internal/watcher/health"
@@ -54,7 +54,7 @@ func New(cfg *Config) *LoadBalancer {
}
// Start implements task.TaskStarter.
-func (lb *LoadBalancer) Start(parent task.Parent) E.Error {
+func (lb *LoadBalancer) Start(parent task.Parent) gperr.Error {
lb.startTime = time.Now()
lb.task = parent.Subtask("loadbalancer."+lb.Link, false)
parent.OnCancel("lb_remove_route", func() {
@@ -227,7 +227,7 @@ func (lb *LoadBalancer) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
http.Error(rw, "Service unavailable", http.StatusServiceUnavailable)
return
}
- if r.Header.Get(common.HeaderCheckRedirect) != "" {
+ if r.Header.Get(httpheaders.HeaderGoDoxyCheckRedirect) != "" {
// wake all servers
for _, srv := range srvs {
if err := srv.TryWake(); err != nil {
diff --git a/internal/net/http/loadbalancer/loadbalancer_test.go b/internal/net/gphttp/loadbalancer/loadbalancer_test.go
similarity index 95%
rename from internal/net/http/loadbalancer/loadbalancer_test.go
rename to internal/net/gphttp/loadbalancer/loadbalancer_test.go
index 25199b5..03f2bfc 100644
--- a/internal/net/http/loadbalancer/loadbalancer_test.go
+++ b/internal/net/gphttp/loadbalancer/loadbalancer_test.go
@@ -3,7 +3,7 @@ package loadbalancer
import (
"testing"
- "github.com/yusing/go-proxy/internal/net/http/loadbalancer/types"
+ "github.com/yusing/go-proxy/internal/net/gphttp/loadbalancer/types"
. "github.com/yusing/go-proxy/internal/utils/testing"
)
diff --git a/internal/net/http/loadbalancer/round_robin.go b/internal/net/gphttp/loadbalancer/round_robin.go
similarity index 100%
rename from internal/net/http/loadbalancer/round_robin.go
rename to internal/net/gphttp/loadbalancer/round_robin.go
diff --git a/internal/net/http/loadbalancer/types.go b/internal/net/gphttp/loadbalancer/types.go
similarity index 72%
rename from internal/net/http/loadbalancer/types.go
rename to internal/net/gphttp/loadbalancer/types.go
index 36b45ad..2a83a8f 100644
--- a/internal/net/http/loadbalancer/types.go
+++ b/internal/net/gphttp/loadbalancer/types.go
@@ -1,7 +1,7 @@
package loadbalancer
import (
- "github.com/yusing/go-proxy/internal/net/http/loadbalancer/types"
+ "github.com/yusing/go-proxy/internal/net/gphttp/loadbalancer/types"
)
type (
diff --git a/internal/net/http/loadbalancer/types/config.go b/internal/net/gphttp/loadbalancer/types/config.go
similarity index 100%
rename from internal/net/http/loadbalancer/types/config.go
rename to internal/net/gphttp/loadbalancer/types/config.go
diff --git a/internal/net/http/loadbalancer/types/mode.go b/internal/net/gphttp/loadbalancer/types/mode.go
similarity index 100%
rename from internal/net/http/loadbalancer/types/mode.go
rename to internal/net/gphttp/loadbalancer/types/mode.go
diff --git a/internal/net/http/loadbalancer/types/server.go b/internal/net/gphttp/loadbalancer/types/server.go
similarity index 100%
rename from internal/net/http/loadbalancer/types/server.go
rename to internal/net/gphttp/loadbalancer/types/server.go
diff --git a/internal/net/http/loadbalancer/types/weight.go b/internal/net/gphttp/loadbalancer/types/weight.go
similarity index 100%
rename from internal/net/http/loadbalancer/types/weight.go
rename to internal/net/gphttp/loadbalancer/types/weight.go
diff --git a/internal/api/v1/utils/logging.go b/internal/net/gphttp/logging.go
similarity index 97%
rename from internal/api/v1/utils/logging.go
rename to internal/net/gphttp/logging.go
index 6f06e31..cfb67f0 100644
--- a/internal/api/v1/utils/logging.go
+++ b/internal/net/gphttp/logging.go
@@ -1,4 +1,4 @@
-package utils
+package gphttp
import (
"net/http"
diff --git a/internal/net/http/methods.go b/internal/net/gphttp/methods.go
similarity index 95%
rename from internal/net/http/methods.go
rename to internal/net/gphttp/methods.go
index caca564..6e49202 100644
--- a/internal/net/http/methods.go
+++ b/internal/net/gphttp/methods.go
@@ -1,4 +1,4 @@
-package http
+package gphttp
import "net/http"
diff --git a/internal/net/http/middleware/cidr_whitelist.go b/internal/net/gphttp/middleware/cidr_whitelist.go
similarity index 97%
rename from internal/net/http/middleware/cidr_whitelist.go
rename to internal/net/gphttp/middleware/cidr_whitelist.go
index e123c86..6b9271f 100644
--- a/internal/net/http/middleware/cidr_whitelist.go
+++ b/internal/net/gphttp/middleware/cidr_whitelist.go
@@ -5,7 +5,7 @@ import (
"net/http"
"github.com/go-playground/validator/v10"
- gphttp "github.com/yusing/go-proxy/internal/net/http"
+ gphttp "github.com/yusing/go-proxy/internal/net/gphttp"
"github.com/yusing/go-proxy/internal/net/types"
"github.com/yusing/go-proxy/internal/utils"
F "github.com/yusing/go-proxy/internal/utils/functional"
diff --git a/internal/net/http/middleware/cidr_whitelist_test.go b/internal/net/gphttp/middleware/cidr_whitelist_test.go
similarity index 96%
rename from internal/net/http/middleware/cidr_whitelist_test.go
rename to internal/net/gphttp/middleware/cidr_whitelist_test.go
index 64fc9e8..a8c7cee 100644
--- a/internal/net/http/middleware/cidr_whitelist_test.go
+++ b/internal/net/gphttp/middleware/cidr_whitelist_test.go
@@ -7,7 +7,7 @@ import (
"strings"
"testing"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/utils"
. "github.com/yusing/go-proxy/internal/utils/testing"
)
@@ -61,7 +61,7 @@ func TestCIDRWhitelistValidation(t *testing.T) {
}
func TestCIDRWhitelist(t *testing.T) {
- errs := E.NewBuilder("")
+ errs := gperr.NewBuilder("")
mids := BuildMiddlewaresFromYAML("", testCIDRWhitelistCompose, errs)
ExpectNoError(t, errs.Error())
deny = mids["deny@file"]
diff --git a/internal/net/http/middleware/cloudflare_real_ip.go b/internal/net/gphttp/middleware/cloudflare_real_ip.go
similarity index 100%
rename from internal/net/http/middleware/cloudflare_real_ip.go
rename to internal/net/gphttp/middleware/cloudflare_real_ip.go
diff --git a/internal/net/http/middleware/custom_error_page.go b/internal/net/gphttp/middleware/custom_error_page.go
similarity index 92%
rename from internal/net/http/middleware/custom_error_page.go
rename to internal/net/gphttp/middleware/custom_error_page.go
index 2c50f02..76110be 100644
--- a/internal/net/http/middleware/custom_error_page.go
+++ b/internal/net/gphttp/middleware/custom_error_page.go
@@ -9,9 +9,9 @@ import (
"strings"
"github.com/yusing/go-proxy/internal/logging"
- gphttp "github.com/yusing/go-proxy/internal/net/http"
- "github.com/yusing/go-proxy/internal/net/http/httpheaders"
- "github.com/yusing/go-proxy/internal/net/http/middleware/errorpage"
+ gphttp "github.com/yusing/go-proxy/internal/net/gphttp"
+ "github.com/yusing/go-proxy/internal/net/gphttp/httpheaders"
+ "github.com/yusing/go-proxy/internal/net/gphttp/middleware/errorpage"
)
type customErrorPage struct{}
diff --git a/internal/net/http/middleware/errorpage/error_page.go b/internal/net/gphttp/middleware/errorpage/error_page.go
similarity index 95%
rename from internal/net/http/middleware/errorpage/error_page.go
rename to internal/net/gphttp/middleware/errorpage/error_page.go
index 2fb09e1..a1acec6 100644
--- a/internal/net/http/middleware/errorpage/error_page.go
+++ b/internal/net/gphttp/middleware/errorpage/error_page.go
@@ -7,7 +7,7 @@ import (
"sync"
"github.com/yusing/go-proxy/internal/common"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/logging"
"github.com/yusing/go-proxy/internal/task"
U "github.com/yusing/go-proxy/internal/utils"
@@ -90,7 +90,7 @@ func watchDir() {
loadContent()
}
case err := <-errCh:
- E.LogError("error watching error page directory", err)
+ gperr.LogError("error watching error page directory", err)
}
}
}
diff --git a/internal/net/http/middleware/metrics_logger/metrics_logger.go b/internal/net/gphttp/middleware/metrics_logger/metrics_logger.go
similarity index 100%
rename from internal/net/http/middleware/metrics_logger/metrics_logger.go
rename to internal/net/gphttp/middleware/metrics_logger/metrics_logger.go
diff --git a/internal/net/http/middleware/metrics_logger/metrics_response_writer.go b/internal/net/gphttp/middleware/metrics_logger/metrics_response_writer.go
similarity index 100%
rename from internal/net/http/middleware/metrics_logger/metrics_response_writer.go
rename to internal/net/gphttp/middleware/metrics_logger/metrics_response_writer.go
diff --git a/internal/net/http/middleware/middleware.go b/internal/net/gphttp/middleware/middleware.go
similarity index 91%
rename from internal/net/http/middleware/middleware.go
rename to internal/net/gphttp/middleware/middleware.go
index b206d26..9a36fe5 100644
--- a/internal/net/http/middleware/middleware.go
+++ b/internal/net/gphttp/middleware/middleware.go
@@ -7,15 +7,15 @@ import (
"sort"
"strings"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/logging"
- gphttp "github.com/yusing/go-proxy/internal/net/http"
- "github.com/yusing/go-proxy/internal/net/http/reverseproxy"
+ gphttp "github.com/yusing/go-proxy/internal/net/gphttp"
+ "github.com/yusing/go-proxy/internal/net/gphttp/reverseproxy"
"github.com/yusing/go-proxy/internal/utils"
)
type (
- Error = E.Error
+ Error = gperr.Error
ReverseProxy = reverseproxy.ReverseProxy
ProxyRequest = reverseproxy.ProxyRequest
@@ -103,7 +103,7 @@ func (m *Middleware) setup() {
}
}
-func (m *Middleware) apply(optsRaw OptionsRaw) E.Error {
+func (m *Middleware) apply(optsRaw OptionsRaw) gperr.Error {
if len(optsRaw) == 0 {
return nil
}
@@ -132,10 +132,10 @@ func (m *Middleware) finalize() error {
return nil
}
-func (m *Middleware) New(optsRaw OptionsRaw) (*Middleware, E.Error) {
+func (m *Middleware) New(optsRaw OptionsRaw) (*Middleware, gperr.Error) {
if m.construct == nil { // likely a middleware from compose
if len(optsRaw) != 0 {
- return nil, E.New("additional options not allowed for middleware ").Subject(m.name)
+ return nil, gperr.New("additional options not allowed for middleware ").Subject(m.name)
}
return m, nil
}
@@ -145,7 +145,7 @@ func (m *Middleware) New(optsRaw OptionsRaw) (*Middleware, E.Error) {
return nil, err
}
if err := mid.finalize(); err != nil {
- return nil, E.From(err)
+ return nil, gperr.Wrap(err)
}
return mid, nil
}
@@ -196,7 +196,7 @@ func (m *Middleware) ServeHTTP(next http.HandlerFunc, w http.ResponseWriter, r *
next(w, r)
}
-func PatchReverseProxy(rp *ReverseProxy, middlewaresMap map[string]OptionsRaw) (err E.Error) {
+func PatchReverseProxy(rp *ReverseProxy, middlewaresMap map[string]OptionsRaw) (err gperr.Error) {
var middlewares []*Middleware
middlewares, err = compileMiddlewares(middlewaresMap)
if err != nil {
diff --git a/internal/net/http/middleware/middleware_builder.go b/internal/net/gphttp/middleware/middleware_builder.go
similarity index 79%
rename from internal/net/http/middleware/middleware_builder.go
rename to internal/net/gphttp/middleware/middleware_builder.go
index 8ea5403..c7be596 100644
--- a/internal/net/http/middleware/middleware_builder.go
+++ b/internal/net/gphttp/middleware/middleware_builder.go
@@ -6,13 +6,13 @@ import (
"path"
"sort"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"gopkg.in/yaml.v3"
)
-var ErrMissingMiddlewareUse = E.New("missing middleware 'use' field")
+var ErrMissingMiddlewareUse = gperr.New("missing middleware 'use' field")
-func BuildMiddlewaresFromComposeFile(filePath string, eb *E.Builder) map[string]*Middleware {
+func BuildMiddlewaresFromComposeFile(filePath string, eb *gperr.Builder) map[string]*Middleware {
fileContent, err := os.ReadFile(filePath)
if err != nil {
eb.Add(err)
@@ -21,7 +21,7 @@ func BuildMiddlewaresFromComposeFile(filePath string, eb *E.Builder) map[string]
return BuildMiddlewaresFromYAML(path.Base(filePath), fileContent, eb)
}
-func BuildMiddlewaresFromYAML(source string, data []byte, eb *E.Builder) map[string]*Middleware {
+func BuildMiddlewaresFromYAML(source string, data []byte, eb *gperr.Builder) map[string]*Middleware {
var rawMap map[string][]map[string]any
err := yaml.Unmarshal(data, &rawMap)
if err != nil {
@@ -40,11 +40,11 @@ func BuildMiddlewaresFromYAML(source string, data []byte, eb *E.Builder) map[str
return middlewares
}
-func compileMiddlewares(middlewaresMap map[string]OptionsRaw) ([]*Middleware, E.Error) {
+func compileMiddlewares(middlewaresMap map[string]OptionsRaw) ([]*Middleware, gperr.Error) {
middlewares := make([]*Middleware, 0, len(middlewaresMap))
- errs := E.NewBuilder("middlewares compile error")
- invalidOpts := E.NewBuilder("options compile error")
+ errs := gperr.NewBuilder("middlewares compile error")
+ invalidOpts := gperr.NewBuilder("options compile error")
for name, opts := range middlewaresMap {
m, err := Get(name)
@@ -68,7 +68,7 @@ func compileMiddlewares(middlewaresMap map[string]OptionsRaw) ([]*Middleware, E.
return middlewares, errs.Error()
}
-func BuildMiddlewareFromMap(name string, middlewaresMap map[string]OptionsRaw) (*Middleware, E.Error) {
+func BuildMiddlewareFromMap(name string, middlewaresMap map[string]OptionsRaw) (*Middleware, gperr.Error) {
compiled, err := compileMiddlewares(middlewaresMap)
if err != nil {
return nil, err
@@ -77,8 +77,8 @@ func BuildMiddlewareFromMap(name string, middlewaresMap map[string]OptionsRaw) (
}
// TODO: check conflict or duplicates.
-func BuildMiddlewareFromChainRaw(name string, defs []map[string]any) (*Middleware, E.Error) {
- chainErr := E.NewBuilder("")
+func BuildMiddlewareFromChainRaw(name string, defs []map[string]any) (*Middleware, gperr.Error) {
+ chainErr := gperr.NewBuilder("")
chain := make([]*Middleware, 0, len(defs))
for i, def := range defs {
if def["use"] == nil || def["use"] == "" {
diff --git a/internal/net/http/middleware/middleware_builder_test.go b/internal/net/gphttp/middleware/middleware_builder_test.go
similarity index 85%
rename from internal/net/http/middleware/middleware_builder_test.go
rename to internal/net/gphttp/middleware/middleware_builder_test.go
index 2c9828c..08e8402 100644
--- a/internal/net/http/middleware/middleware_builder_test.go
+++ b/internal/net/gphttp/middleware/middleware_builder_test.go
@@ -5,7 +5,7 @@ import (
"encoding/json"
"testing"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
. "github.com/yusing/go-proxy/internal/utils/testing"
)
@@ -13,7 +13,7 @@ import (
var testMiddlewareCompose []byte
func TestBuild(t *testing.T) {
- errs := E.NewBuilder("")
+ errs := gperr.NewBuilder("")
middlewares := BuildMiddlewaresFromYAML("", testMiddlewareCompose, errs)
ExpectNoError(t, errs.Error())
Must(json.MarshalIndent(middlewares, "", " "))
diff --git a/internal/net/http/middleware/middleware_chain.go b/internal/net/gphttp/middleware/middleware_chain.go
similarity index 90%
rename from internal/net/http/middleware/middleware_chain.go
rename to internal/net/gphttp/middleware/middleware_chain.go
index 932d278..cf1258b 100644
--- a/internal/net/http/middleware/middleware_chain.go
+++ b/internal/net/gphttp/middleware/middleware_chain.go
@@ -4,7 +4,7 @@ import (
"net/http"
"github.com/yusing/go-proxy/internal/common"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
)
type middlewareChain struct {
@@ -51,10 +51,10 @@ func (m *middlewareChain) modifyResponse(resp *http.Response) error {
if len(m.modResps) == 0 {
return nil
}
- errs := E.NewBuilder("modify response errors")
+ errs := gperr.NewBuilder("modify response errors")
for i, mr := range m.modResps {
if err := mr.modifyResponse(resp); err != nil {
- errs.Add(E.From(err).Subjectf("%d", i))
+ errs.Add(gperr.Wrap(err).Subjectf("%d", i))
}
}
return errs.Error()
diff --git a/internal/net/http/middleware/middleware_test.go b/internal/net/gphttp/middleware/middleware_test.go
similarity index 100%
rename from internal/net/http/middleware/middleware_test.go
rename to internal/net/gphttp/middleware/middleware_test.go
diff --git a/internal/net/http/middleware/middlewares.go b/internal/net/gphttp/middleware/middlewares.go
similarity index 86%
rename from internal/net/http/middleware/middlewares.go
rename to internal/net/gphttp/middleware/middlewares.go
index a5050be..184de94 100644
--- a/internal/net/http/middleware/middlewares.go
+++ b/internal/net/gphttp/middleware/middlewares.go
@@ -4,7 +4,7 @@ import (
"path"
"github.com/yusing/go-proxy/internal/common"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/logging"
"github.com/yusing/go-proxy/internal/utils"
"github.com/yusing/go-proxy/internal/utils/strutils"
@@ -35,8 +35,8 @@ var allMiddlewares = map[string]*Middleware{
}
var (
- ErrUnknownMiddleware = E.New("unknown middleware")
- ErrDuplicatedMiddleware = E.New("duplicated middleware")
+ ErrUnknownMiddleware = gperr.New("unknown middleware")
+ ErrDuplicatedMiddleware = gperr.New("duplicated middleware")
)
func Get(name string) (*Middleware, Error) {
@@ -54,14 +54,14 @@ func All() map[string]*Middleware {
}
func LoadComposeFiles() {
- errs := E.NewBuilder("middleware compile errors")
+ errs := gperr.NewBuilder("middleware compile errors")
middlewareDefs, err := utils.ListFiles(common.MiddlewareComposeBasePath, 0)
if err != nil {
logging.Err(err).Msg("failed to list middleware definitions")
return
}
for _, defFile := range middlewareDefs {
- voidErrs := E.NewBuilder("") // ignore these errors, will be added in next step
+ voidErrs := gperr.NewBuilder("") // ignore these errors, will be added in next step
mws := BuildMiddlewaresFromComposeFile(defFile, voidErrs)
if len(mws) == 0 {
continue
@@ -99,6 +99,6 @@ func LoadComposeFiles() {
}
}
if errs.HasError() {
- E.LogError(errs.About(), errs.Error())
+ gperr.LogError(errs.About(), errs.Error())
}
}
diff --git a/internal/net/http/middleware/modify_request.go b/internal/net/gphttp/middleware/modify_request.go
similarity index 100%
rename from internal/net/http/middleware/modify_request.go
rename to internal/net/gphttp/middleware/modify_request.go
diff --git a/internal/net/http/middleware/modify_request_test.go b/internal/net/gphttp/middleware/modify_request_test.go
similarity index 100%
rename from internal/net/http/middleware/modify_request_test.go
rename to internal/net/gphttp/middleware/modify_request_test.go
diff --git a/internal/net/http/middleware/modify_response.go b/internal/net/gphttp/middleware/modify_response.go
similarity index 100%
rename from internal/net/http/middleware/modify_response.go
rename to internal/net/gphttp/middleware/modify_response.go
diff --git a/internal/net/http/middleware/modify_response_test.go b/internal/net/gphttp/middleware/modify_response_test.go
similarity index 100%
rename from internal/net/http/middleware/modify_response_test.go
rename to internal/net/gphttp/middleware/modify_response_test.go
diff --git a/internal/net/http/middleware/oidc.go b/internal/net/gphttp/middleware/oidc.go
similarity index 94%
rename from internal/net/http/middleware/oidc.go
rename to internal/net/gphttp/middleware/oidc.go
index 3af1ca3..128f4a0 100644
--- a/internal/net/http/middleware/oidc.go
+++ b/internal/net/gphttp/middleware/oidc.go
@@ -6,7 +6,7 @@ import (
"sync/atomic"
"github.com/yusing/go-proxy/internal/api/v1/auth"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
)
type oidcMiddleware struct {
@@ -24,7 +24,7 @@ var OIDC = NewMiddleware[oidcMiddleware]()
func (amw *oidcMiddleware) finalize() error {
if !auth.IsOIDCEnabled() {
- return E.New("OIDC not enabled but OIDC middleware is used")
+ return gperr.New("OIDC not enabled but OIDC middleware is used")
}
return nil
}
diff --git a/internal/net/http/middleware/rate_limit.go b/internal/net/gphttp/middleware/rate_limit.go
similarity index 100%
rename from internal/net/http/middleware/rate_limit.go
rename to internal/net/gphttp/middleware/rate_limit.go
diff --git a/internal/net/http/middleware/rate_limit_test.go b/internal/net/gphttp/middleware/rate_limit_test.go
similarity index 100%
rename from internal/net/http/middleware/rate_limit_test.go
rename to internal/net/gphttp/middleware/rate_limit_test.go
diff --git a/internal/net/http/middleware/real_ip.go b/internal/net/gphttp/middleware/real_ip.go
similarity index 97%
rename from internal/net/http/middleware/real_ip.go
rename to internal/net/gphttp/middleware/real_ip.go
index f1925fb..ed11d12 100644
--- a/internal/net/http/middleware/real_ip.go
+++ b/internal/net/gphttp/middleware/real_ip.go
@@ -4,7 +4,7 @@ import (
"net"
"net/http"
- "github.com/yusing/go-proxy/internal/net/http/httpheaders"
+ "github.com/yusing/go-proxy/internal/net/gphttp/httpheaders"
"github.com/yusing/go-proxy/internal/net/types"
)
diff --git a/internal/net/http/middleware/real_ip_test.go b/internal/net/gphttp/middleware/real_ip_test.go
similarity index 96%
rename from internal/net/http/middleware/real_ip_test.go
rename to internal/net/gphttp/middleware/real_ip_test.go
index 5b4d809..372862d 100644
--- a/internal/net/http/middleware/real_ip_test.go
+++ b/internal/net/gphttp/middleware/real_ip_test.go
@@ -6,7 +6,7 @@ import (
"strings"
"testing"
- "github.com/yusing/go-proxy/internal/net/http/httpheaders"
+ "github.com/yusing/go-proxy/internal/net/gphttp/httpheaders"
"github.com/yusing/go-proxy/internal/net/types"
. "github.com/yusing/go-proxy/internal/utils/testing"
)
diff --git a/internal/net/http/middleware/redirect_http.go b/internal/net/gphttp/middleware/redirect_http.go
similarity index 100%
rename from internal/net/http/middleware/redirect_http.go
rename to internal/net/gphttp/middleware/redirect_http.go
diff --git a/internal/net/http/middleware/redirect_http_test.go b/internal/net/gphttp/middleware/redirect_http_test.go
similarity index 100%
rename from internal/net/http/middleware/redirect_http_test.go
rename to internal/net/gphttp/middleware/redirect_http_test.go
diff --git a/internal/net/http/middleware/set_upstream_headers.go b/internal/net/gphttp/middleware/set_upstream_headers.go
similarity index 86%
rename from internal/net/http/middleware/set_upstream_headers.go
rename to internal/net/gphttp/middleware/set_upstream_headers.go
index 488b1c5..434c4cd 100644
--- a/internal/net/http/middleware/set_upstream_headers.go
+++ b/internal/net/gphttp/middleware/set_upstream_headers.go
@@ -3,8 +3,8 @@ package middleware
import (
"net/http"
- "github.com/yusing/go-proxy/internal/net/http/httpheaders"
- "github.com/yusing/go-proxy/internal/net/http/reverseproxy"
+ "github.com/yusing/go-proxy/internal/net/gphttp/httpheaders"
+ "github.com/yusing/go-proxy/internal/net/gphttp/reverseproxy"
)
// internal use only.
diff --git a/internal/net/http/middleware/test_data/cidr_whitelist_test.yml b/internal/net/gphttp/middleware/test_data/cidr_whitelist_test.yml
similarity index 100%
rename from internal/net/http/middleware/test_data/cidr_whitelist_test.yml
rename to internal/net/gphttp/middleware/test_data/cidr_whitelist_test.yml
diff --git a/internal/net/http/middleware/test_data/middleware_compose.yml b/internal/net/gphttp/middleware/test_data/middleware_compose.yml
similarity index 100%
rename from internal/net/http/middleware/test_data/middleware_compose.yml
rename to internal/net/gphttp/middleware/test_data/middleware_compose.yml
diff --git a/internal/net/http/middleware/test_data/sample_headers.json b/internal/net/gphttp/middleware/test_data/sample_headers.json
similarity index 100%
rename from internal/net/http/middleware/test_data/sample_headers.json
rename to internal/net/gphttp/middleware/test_data/sample_headers.json
diff --git a/internal/net/http/middleware/test_utils.go b/internal/net/gphttp/middleware/test_utils.go
similarity index 94%
rename from internal/net/http/middleware/test_utils.go
rename to internal/net/gphttp/middleware/test_utils.go
index 0adb1a5..2bd208b 100644
--- a/internal/net/http/middleware/test_utils.go
+++ b/internal/net/gphttp/middleware/test_utils.go
@@ -9,8 +9,8 @@ import (
"net/http/httptest"
"github.com/yusing/go-proxy/internal/common"
- E "github.com/yusing/go-proxy/internal/error"
- "github.com/yusing/go-proxy/internal/net/http/reverseproxy"
+ "github.com/yusing/go-proxy/internal/gperr"
+ "github.com/yusing/go-proxy/internal/net/gphttp/reverseproxy"
"github.com/yusing/go-proxy/internal/net/types"
. "github.com/yusing/go-proxy/internal/utils/testing"
)
@@ -122,7 +122,7 @@ func (args *testArgs) bodyReader() io.Reader {
return nil
}
-func newMiddlewareTest(middleware *Middleware, args *testArgs) (*TestResult, E.Error) {
+func newMiddlewareTest(middleware *Middleware, args *testArgs) (*TestResult, gperr.Error) {
if args == nil {
args = new(testArgs)
}
@@ -136,7 +136,7 @@ func newMiddlewareTest(middleware *Middleware, args *testArgs) (*TestResult, E.E
return newMiddlewaresTest([]*Middleware{mid}, args)
}
-func newMiddlewaresTest(middlewares []*Middleware, args *testArgs) (*TestResult, E.Error) {
+func newMiddlewaresTest(middlewares []*Middleware, args *testArgs) (*TestResult, gperr.Error) {
if args == nil {
args = new(testArgs)
}
@@ -163,7 +163,7 @@ func newMiddlewaresTest(middlewares []*Middleware, args *testArgs) (*TestResult,
data, err := io.ReadAll(resp.Body)
if err != nil {
- return nil, E.From(err)
+ return nil, gperr.Wrap(err)
}
return &TestResult{
diff --git a/internal/net/http/middleware/trace.go b/internal/net/gphttp/middleware/trace.go
similarity index 96%
rename from internal/net/http/middleware/trace.go
rename to internal/net/gphttp/middleware/trace.go
index a4ebcc7..4c9550a 100644
--- a/internal/net/http/middleware/trace.go
+++ b/internal/net/gphttp/middleware/trace.go
@@ -4,7 +4,7 @@ import (
"net/http"
"sync"
- "github.com/yusing/go-proxy/internal/net/http/httpheaders"
+ "github.com/yusing/go-proxy/internal/net/gphttp/httpheaders"
)
type (
diff --git a/internal/net/http/middleware/tracer.go b/internal/net/gphttp/middleware/tracer.go
similarity index 100%
rename from internal/net/http/middleware/tracer.go
rename to internal/net/gphttp/middleware/tracer.go
diff --git a/internal/net/http/middleware/vars.go b/internal/net/gphttp/middleware/vars.go
similarity index 98%
rename from internal/net/http/middleware/vars.go
rename to internal/net/gphttp/middleware/vars.go
index 20e716c..472ca72 100644
--- a/internal/net/http/middleware/vars.go
+++ b/internal/net/gphttp/middleware/vars.go
@@ -7,7 +7,7 @@ import (
"strconv"
"strings"
- "github.com/yusing/go-proxy/internal/net/http/httpheaders"
+ "github.com/yusing/go-proxy/internal/net/gphttp/httpheaders"
)
type (
diff --git a/internal/net/http/middleware/x_forwarded.go b/internal/net/gphttp/middleware/x_forwarded.go
similarity index 93%
rename from internal/net/http/middleware/x_forwarded.go
rename to internal/net/gphttp/middleware/x_forwarded.go
index 7958a3d..a2de34b 100644
--- a/internal/net/http/middleware/x_forwarded.go
+++ b/internal/net/gphttp/middleware/x_forwarded.go
@@ -5,7 +5,7 @@ import (
"net/http"
"strings"
- "github.com/yusing/go-proxy/internal/net/http/httpheaders"
+ "github.com/yusing/go-proxy/internal/net/gphttp/httpheaders"
)
type (
diff --git a/internal/net/http/modify_response_writer.go b/internal/net/gphttp/modify_response_writer.go
similarity index 99%
rename from internal/net/http/modify_response_writer.go
rename to internal/net/gphttp/modify_response_writer.go
index a8c7b89..41f846d 100644
--- a/internal/net/http/modify_response_writer.go
+++ b/internal/net/gphttp/modify_response_writer.go
@@ -1,7 +1,7 @@
// Modified from Traefik Labs's MIT-licensed code (https://github.com/traefik/traefik/blob/master/pkg/middlewares/response_modifier.go)
// Copyright (c) 2020-2024 Traefik Labs
-package http
+package gphttp
import (
"bufio"
diff --git a/internal/net/http/reverseproxy/reverse_proxy_mod.go b/internal/net/gphttp/reverseproxy/reverse_proxy_mod.go
similarity index 99%
rename from internal/net/http/reverseproxy/reverse_proxy_mod.go
rename to internal/net/gphttp/reverseproxy/reverse_proxy_mod.go
index f3f0b7b..221aa74 100644
--- a/internal/net/http/reverseproxy/reverse_proxy_mod.go
+++ b/internal/net/gphttp/reverseproxy/reverse_proxy_mod.go
@@ -26,8 +26,8 @@ import (
"github.com/rs/zerolog"
"github.com/yusing/go-proxy/internal/logging"
- "github.com/yusing/go-proxy/internal/net/http/accesslog"
- "github.com/yusing/go-proxy/internal/net/http/httpheaders"
+ "github.com/yusing/go-proxy/internal/net/gphttp/accesslog"
+ "github.com/yusing/go-proxy/internal/net/gphttp/httpheaders"
"github.com/yusing/go-proxy/internal/net/types"
U "github.com/yusing/go-proxy/internal/utils"
"golang.org/x/net/http/httpguts"
diff --git a/internal/net/http/serve_mux.go b/internal/net/gphttp/serve_mux.go
similarity index 97%
rename from internal/net/http/serve_mux.go
rename to internal/net/gphttp/serve_mux.go
index 0e487b6..902c0e2 100644
--- a/internal/net/http/serve_mux.go
+++ b/internal/net/gphttp/serve_mux.go
@@ -1,4 +1,4 @@
-package http
+package gphttp
import "net/http"
diff --git a/internal/net/http/server/error.go b/internal/net/gphttp/server/error.go
similarity index 100%
rename from internal/net/http/server/error.go
rename to internal/net/gphttp/server/error.go
diff --git a/internal/net/http/server/server.go b/internal/net/gphttp/server/server.go
similarity index 100%
rename from internal/net/http/server/server.go
rename to internal/net/gphttp/server/server.go
diff --git a/internal/net/http/status_code.go b/internal/net/gphttp/status_code.go
similarity index 93%
rename from internal/net/http/status_code.go
rename to internal/net/gphttp/status_code.go
index 8235805..25977df 100644
--- a/internal/net/http/status_code.go
+++ b/internal/net/gphttp/status_code.go
@@ -1,4 +1,4 @@
-package http
+package gphttp
import "net/http"
diff --git a/internal/net/http/transport.go b/internal/net/gphttp/transport.go
similarity index 98%
rename from internal/net/http/transport.go
rename to internal/net/gphttp/transport.go
index 84e294f..d633ee6 100644
--- a/internal/net/http/transport.go
+++ b/internal/net/gphttp/transport.go
@@ -1,4 +1,4 @@
-package http
+package gphttp
import (
"crypto/tls"
diff --git a/internal/notif/base.go b/internal/notif/base.go
index 5af0df1..a1db3af 100644
--- a/internal/notif/base.go
+++ b/internal/notif/base.go
@@ -6,7 +6,7 @@ import (
"net/url"
"strings"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
)
type ProviderBase struct {
@@ -16,12 +16,12 @@ type ProviderBase struct {
}
var (
- ErrMissingToken = E.New("token is required")
- ErrURLMissingScheme = E.New("url missing scheme, expect 'http://' or 'https://'")
+ ErrMissingToken = gperr.New("token is required")
+ ErrURLMissingScheme = gperr.New("url missing scheme, expect 'http://' or 'https://'")
)
// Validate implements the utils.CustomValidator interface.
-func (base *ProviderBase) Validate() E.Error {
+func (base *ProviderBase) Validate() gperr.Error {
if base.Token == "" {
return ErrMissingToken
}
@@ -30,7 +30,7 @@ func (base *ProviderBase) Validate() E.Error {
}
u, err := url.Parse(base.URL)
if err != nil {
- return E.Wrap(err)
+ return gperr.Wrap(err)
}
base.URL = u.String()
return nil
@@ -63,7 +63,7 @@ func (base *ProviderBase) SetHeaders(logMsg *LogMessage, headers http.Header) {
func (base *ProviderBase) makeRespError(resp *http.Response) error {
body, err := io.ReadAll(resp.Body)
if err == nil {
- return E.Errorf("%s status %d: %s", base.Name, resp.StatusCode, body)
+ return gperr.Errorf("%s status %d: %s", base.Name, resp.StatusCode, body)
}
- return E.Errorf("%s status %d", base.Name, resp.StatusCode)
+ return gperr.Errorf("%s status %d", base.Name, resp.StatusCode)
}
diff --git a/internal/notif/config.go b/internal/notif/config.go
index c9c29cd..1f35cdb 100644
--- a/internal/notif/config.go
+++ b/internal/notif/config.go
@@ -1,7 +1,7 @@
package notif
import (
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/utils"
)
@@ -11,13 +11,13 @@ type NotificationConfig struct {
}
var (
- ErrMissingNotifProvider = E.New("missing notification provider")
- ErrInvalidNotifProviderType = E.New("invalid notification provider type")
- ErrUnknownNotifProvider = E.New("unknown notification provider")
+ ErrMissingNotifProvider = gperr.New("missing notification provider")
+ ErrInvalidNotifProviderType = gperr.New("invalid notification provider type")
+ ErrUnknownNotifProvider = gperr.New("unknown notification provider")
)
// UnmarshalMap implements MapUnmarshaler.
-func (cfg *NotificationConfig) UnmarshalMap(m map[string]any) (err E.Error) {
+func (cfg *NotificationConfig) UnmarshalMap(m map[string]any) (err gperr.Error) {
// extract provider name
providerName := m["provider"]
switch providerName := providerName.(type) {
diff --git a/internal/notif/dispatcher.go b/internal/notif/dispatcher.go
index c8431b2..7b9788e 100644
--- a/internal/notif/dispatcher.go
+++ b/internal/notif/dispatcher.go
@@ -2,7 +2,7 @@ package notif
import (
"github.com/rs/zerolog"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/logging"
"github.com/yusing/go-proxy/internal/task"
F "github.com/yusing/go-proxy/internal/utils/functional"
@@ -89,14 +89,14 @@ func (disp *Dispatcher) dispatch(msg *LogMessage) {
task := disp.task.Subtask("dispatcher")
defer task.Finish("notif dispatched")
- errs := E.NewBuilder(dispatchErr)
+ errs := gperr.NewBuilder(dispatchErr)
disp.providers.RangeAllParallel(func(p Provider) {
if err := notifyProvider(task.Context(), p, msg); err != nil {
- errs.Add(E.PrependSubject(p.GetName(), err))
+ errs.Add(gperr.PrependSubject(p.GetName(), err))
}
})
if errs.HasError() {
- E.LogError(errs.About(), errs.Error())
+ gperr.LogError(errs.About(), errs.Error())
} else {
logging.Debug().Str("title", msg.Title).Msgf("dispatched notif")
}
diff --git a/internal/notif/ntfy.go b/internal/notif/ntfy.go
index 42b97f7..6e10725 100644
--- a/internal/notif/ntfy.go
+++ b/internal/notif/ntfy.go
@@ -7,7 +7,7 @@ import (
"strings"
"github.com/rs/zerolog"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
)
// See https://docs.ntfy.sh/publish
@@ -24,22 +24,22 @@ const (
NtfyStylePlain NtfyStyle = "plain"
)
-func (n *Ntfy) Validate() E.Error {
+func (n *Ntfy) Validate() gperr.Error {
if n.URL == "" {
- return E.New("url is required")
+ return gperr.New("url is required")
}
if n.Topic == "" {
- return E.New("topic is required")
+ return gperr.New("topic is required")
}
if n.Topic[0] == '/' {
- return E.New("topic should not start with a slash")
+ return gperr.New("topic should not start with a slash")
}
switch n.Style {
case "":
n.Style = NtfyStyleMarkdown
case NtfyStyleMarkdown, NtfyStylePlain:
default:
- return E.Errorf("invalid style, expecting %q or %q, got %q", NtfyStyleMarkdown, NtfyStylePlain, n.Style)
+ return gperr.Errorf("invalid style, expecting %q or %q, got %q", NtfyStyleMarkdown, NtfyStylePlain, n.Style)
}
return nil
}
diff --git a/internal/notif/providers.go b/internal/notif/providers.go
index 0de2a2c..953fb3b 100644
--- a/internal/notif/providers.go
+++ b/internal/notif/providers.go
@@ -6,8 +6,8 @@ import (
"net/http"
"time"
- E "github.com/yusing/go-proxy/internal/error"
- gphttp "github.com/yusing/go-proxy/internal/net/http"
+ "github.com/yusing/go-proxy/internal/gperr"
+ gphttp "github.com/yusing/go-proxy/internal/net/gphttp"
"github.com/yusing/go-proxy/internal/utils"
)
@@ -26,7 +26,7 @@ type (
makeRespError(resp *http.Response) error
}
- ProviderCreateFunc func(map[string]any) (Provider, E.Error)
+ ProviderCreateFunc func(map[string]any) (Provider, gperr.Error)
ProviderConfig map[string]any
)
@@ -39,7 +39,7 @@ const (
func notifyProvider(ctx context.Context, provider Provider, msg *LogMessage) error {
body, err := provider.MakeBody(msg)
if err != nil {
- return E.PrependSubject(provider.GetName(), err)
+ return gperr.PrependSubject(provider.GetName(), err)
}
ctx, cancel := context.WithTimeout(ctx, 2*time.Second)
@@ -52,7 +52,7 @@ func notifyProvider(ctx context.Context, provider Provider, msg *LogMessage) err
body,
)
if err != nil {
- return E.PrependSubject(provider.GetName(), err)
+ return gperr.PrependSubject(provider.GetName(), err)
}
req.Header.Set("Content-Type", provider.GetMIMEType())
@@ -63,7 +63,7 @@ func notifyProvider(ctx context.Context, provider Provider, msg *LogMessage) err
resp, err := http.DefaultClient.Do(req)
if err != nil {
- return E.PrependSubject(provider.GetName(), err)
+ return gperr.PrependSubject(provider.GetName(), err)
}
defer resp.Body.Close()
diff --git a/internal/notif/webhook.go b/internal/notif/webhook.go
index 806b5f9..13fd23c 100644
--- a/internal/notif/webhook.go
+++ b/internal/notif/webhook.go
@@ -8,7 +8,7 @@ import (
"net/http"
"strings"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
)
type Webhook struct {
@@ -27,7 +27,7 @@ var webhookTemplates = map[string]string{
"discord": discordPayload,
}
-func (webhook *Webhook) Validate() E.Error {
+func (webhook *Webhook) Validate() gperr.Error {
if err := webhook.ProviderBase.Validate(); err != nil && !err.Is(ErrMissingToken) {
return err
}
@@ -37,16 +37,16 @@ func (webhook *Webhook) Validate() E.Error {
webhook.MIMEType = "application/json"
case "application/json", "application/x-www-form-urlencoded", "text/plain":
default:
- return E.New("invalid mime_type, expect empty, 'application/json', 'application/x-www-form-urlencoded' or 'text/plain'")
+ return gperr.New("invalid mime_type, expect empty, 'application/json', 'application/x-www-form-urlencoded' or 'text/plain'")
}
switch webhook.Template {
case "":
if webhook.MIMEType == "application/json" && !json.Valid([]byte(webhook.Payload)) {
- return E.New("invalid payload, expect valid JSON")
+ return gperr.New("invalid payload, expect valid JSON")
}
if webhook.Payload == "" {
- return E.New("invalid payload, expect non-empty")
+ return gperr.New("invalid payload, expect non-empty")
}
case "discord":
webhook.ColorMode = "dec"
@@ -56,7 +56,7 @@ func (webhook *Webhook) Validate() E.Error {
webhook.Payload = discordPayload
}
default:
- return E.New("invalid template, expect empty or 'discord'")
+ return gperr.New("invalid template, expect empty or 'discord'")
}
switch webhook.Method {
@@ -64,7 +64,7 @@ func (webhook *Webhook) Validate() E.Error {
webhook.Method = http.MethodPost
case http.MethodGet, http.MethodPost, http.MethodPut:
default:
- return E.New("invalid method, expect empty, 'GET', 'POST' or 'PUT'")
+ return gperr.New("invalid method, expect empty, 'GET', 'POST' or 'PUT'")
}
switch webhook.ColorMode {
@@ -72,7 +72,7 @@ func (webhook *Webhook) Validate() E.Error {
webhook.ColorMode = "hex"
case "hex", "dec":
default:
- return E.New("invalid color_mode, expect empty, 'hex' or 'dec'")
+ return gperr.New("invalid color_mode, expect empty, 'hex' or 'dec'")
}
return nil
diff --git a/internal/route/fileserver.go b/internal/route/fileserver.go
index e407d9b..ed75e9b 100644
--- a/internal/route/fileserver.go
+++ b/internal/route/fileserver.go
@@ -6,16 +6,15 @@ import (
"path/filepath"
"github.com/yusing/go-proxy/internal/common"
- gphttp "github.com/yusing/go-proxy/internal/net/http"
- "github.com/yusing/go-proxy/internal/net/http/accesslog"
- "github.com/yusing/go-proxy/internal/net/http/middleware"
- metricslogger "github.com/yusing/go-proxy/internal/net/http/middleware/metrics_logger"
+ "github.com/yusing/go-proxy/internal/gperr"
+ gphttp "github.com/yusing/go-proxy/internal/net/gphttp"
+ "github.com/yusing/go-proxy/internal/net/gphttp/accesslog"
+ "github.com/yusing/go-proxy/internal/net/gphttp/middleware"
+ metricslogger "github.com/yusing/go-proxy/internal/net/gphttp/middleware/metrics_logger"
"github.com/yusing/go-proxy/internal/route/routes"
"github.com/yusing/go-proxy/internal/task"
"github.com/yusing/go-proxy/internal/watcher/health"
"github.com/yusing/go-proxy/internal/watcher/health/monitor"
-
- E "github.com/yusing/go-proxy/internal/error"
)
type (
@@ -35,12 +34,12 @@ func handler(root string) http.Handler {
return http.FileServer(http.Dir(root))
}
-func NewFileServer(base *Route) (*FileServer, E.Error) {
+func NewFileServer(base *Route) (*FileServer, gperr.Error) {
s := &FileServer{Route: base}
s.Root = filepath.Clean(s.Root)
if !path.IsAbs(s.Root) {
- return nil, E.New("`root` must be an absolute path")
+ return nil, gperr.New("`root` must be an absolute path")
}
s.handler = handler(s.Root)
@@ -57,7 +56,7 @@ func NewFileServer(base *Route) (*FileServer, E.Error) {
}
// Start implements task.TaskStarter.
-func (s *FileServer) Start(parent task.Parent) E.Error {
+func (s *FileServer) Start(parent task.Parent) gperr.Error {
s.task = parent.Subtask("fileserver."+s.TargetName(), false)
pathPatterns := s.PathPatterns
@@ -66,7 +65,7 @@ func (s *FileServer) Start(parent task.Parent) E.Error {
case len(pathPatterns) == 1 && pathPatterns[0] == "/":
default:
mux := gphttp.NewServeMux()
- patErrs := E.NewBuilder("invalid path pattern(s)")
+ patErrs := gperr.NewBuilder("invalid path pattern(s)")
for _, p := range pathPatterns {
patErrs.Add(mux.Handle(p, s.handler))
}
@@ -88,7 +87,7 @@ func (s *FileServer) Start(parent task.Parent) E.Error {
s.accessLogger, err = accesslog.NewFileAccessLogger(s.task, s.AccessLog)
if err != nil {
s.task.Finish(err)
- return E.Wrap(err)
+ return gperr.Wrap(err)
}
}
diff --git a/internal/route/provider/agent.go b/internal/route/provider/agent.go
index 85acec9..c4dd88d 100644
--- a/internal/route/provider/agent.go
+++ b/internal/route/provider/agent.go
@@ -3,7 +3,7 @@ package provider
import (
"github.com/rs/zerolog"
"github.com/yusing/go-proxy/agent/pkg/agent"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/route"
"github.com/yusing/go-proxy/internal/watcher"
)
@@ -25,7 +25,7 @@ func (p *AgentProvider) IsExplicitOnly() bool {
return p.docker.IsExplicitOnly()
}
-func (p *AgentProvider) loadRoutesImpl() (route.Routes, E.Error) {
+func (p *AgentProvider) loadRoutesImpl() (route.Routes, gperr.Error) {
return p.docker.loadRoutesImpl()
}
diff --git a/internal/route/provider/docker.go b/internal/route/provider/docker.go
index 2bbc4b7..e08cfc8 100755
--- a/internal/route/provider/docker.go
+++ b/internal/route/provider/docker.go
@@ -8,7 +8,7 @@ import (
"github.com/rs/zerolog"
"github.com/yusing/go-proxy/internal/common"
"github.com/yusing/go-proxy/internal/docker"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/logging"
"github.com/yusing/go-proxy/internal/route"
U "github.com/yusing/go-proxy/internal/utils"
@@ -27,7 +27,7 @@ const (
aliasRefPrefixAlt = '$'
)
-var ErrAliasRefIndexOutOfRange = E.New("index out of range")
+var ErrAliasRefIndexOutOfRange = gperr.New("index out of range")
func DockerProviderImpl(name, dockerHost string) ProviderImpl {
if dockerHost == common.DockerHostFromEnv {
@@ -60,13 +60,13 @@ func (p *DockerProvider) NewWatcher() watcher.Watcher {
return watcher.NewDockerWatcher(p.dockerHost)
}
-func (p *DockerProvider) loadRoutesImpl() (route.Routes, E.Error) {
+func (p *DockerProvider) loadRoutesImpl() (route.Routes, gperr.Error) {
containers, err := docker.ListContainers(p.dockerHost)
if err != nil {
- return nil, E.From(err)
+ return nil, gperr.Wrap(err)
}
- errs := E.NewBuilder("")
+ errs := gperr.NewBuilder("")
routes := make(route.Routes)
for _, c := range containers {
@@ -93,7 +93,7 @@ func (p *DockerProvider) loadRoutesImpl() (route.Routes, E.Error) {
// Returns a list of proxy entries for a container.
// Always non-nil.
-func (p *DockerProvider) routesFromContainerLabels(container *docker.Container) (route.Routes, E.Error) {
+func (p *DockerProvider) routesFromContainerLabels(container *docker.Container) (route.Routes, gperr.Error) {
if !container.IsExplicit && p.IsExplicitOnly() {
return nil, nil
}
@@ -109,7 +109,7 @@ func (p *DockerProvider) routesFromContainerLabels(container *docker.Container)
}
}
- errs := E.NewBuilder("label errors")
+ errs := gperr.NewBuilder("label errors")
m, err := docker.ParseLabels(container.Labels)
errs.Add(err)
@@ -118,7 +118,7 @@ func (p *DockerProvider) routesFromContainerLabels(container *docker.Container)
for alias, entryMapAny := range m {
if len(alias) == 0 {
- errs.Add(E.New("empty alias"))
+ errs.Add(gperr.New("empty alias"))
continue
}
@@ -132,7 +132,7 @@ func (p *DockerProvider) routesFromContainerLabels(container *docker.Container)
panic(fmt.Errorf("invalid entry map type %T", entryMapAny))
}
if err := yaml.Unmarshal([]byte(yamlStr), &entryMap); err != nil {
- errs.Add(E.From(err).Subject(alias))
+ errs.Add(gperr.Wrap(err).Subject(alias))
continue
}
}
diff --git a/internal/route/provider/event_handler.go b/internal/route/provider/event_handler.go
index 3dccc0f..5035d58 100644
--- a/internal/route/provider/event_handler.go
+++ b/internal/route/provider/event_handler.go
@@ -1,7 +1,7 @@
package provider
import (
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/route"
"github.com/yusing/go-proxy/internal/route/provider/types"
"github.com/yusing/go-proxy/internal/task"
@@ -11,19 +11,19 @@ import (
type EventHandler struct {
provider *Provider
- errs *E.Builder
- added *E.Builder
- removed *E.Builder
- updated *E.Builder
+ errs *gperr.Builder
+ added *gperr.Builder
+ removed *gperr.Builder
+ updated *gperr.Builder
}
func (p *Provider) newEventHandler() *EventHandler {
return &EventHandler{
provider: p,
- errs: E.NewBuilder("event errors"),
- added: E.NewBuilder("added"),
- removed: E.NewBuilder("removed"),
- updated: E.NewBuilder("updated"),
+ errs: gperr.NewBuilder("event errors"),
+ added: gperr.NewBuilder("added"),
+ removed: gperr.NewBuilder("removed"),
+ updated: gperr.NewBuilder("updated"),
}
}
@@ -100,7 +100,7 @@ func (handler *EventHandler) Update(parent task.Parent, oldRoute *route.Route, n
}
func (handler *EventHandler) Log() {
- results := E.NewBuilder("event occurred")
+ results := gperr.NewBuilder("event occurred")
results.AddFrom(handler.added, false)
results.AddFrom(handler.removed, false)
results.AddFrom(handler.updated, false)
diff --git a/internal/route/provider/file.go b/internal/route/provider/file.go
index 8d2e208..79855b9 100644
--- a/internal/route/provider/file.go
+++ b/internal/route/provider/file.go
@@ -7,7 +7,7 @@ import (
"github.com/rs/zerolog"
"github.com/yusing/go-proxy/internal/common"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/logging"
"github.com/yusing/go-proxy/internal/route"
"github.com/yusing/go-proxy/internal/utils"
@@ -33,12 +33,12 @@ func FileProviderImpl(filename string) (ProviderImpl, error) {
return impl, nil
}
-func validate(data []byte) (routes route.Routes, err E.Error) {
+func validate(data []byte) (routes route.Routes, err gperr.Error) {
err = utils.DeserializeYAML(data, &routes)
return
}
-func Validate(data []byte) (err E.Error) {
+func Validate(data []byte) (err gperr.Error) {
_, err = validate(data)
return
}
@@ -59,16 +59,16 @@ func (p *FileProvider) Logger() *zerolog.Logger {
return &p.l
}
-func (p *FileProvider) loadRoutesImpl() (route.Routes, E.Error) {
+func (p *FileProvider) loadRoutesImpl() (route.Routes, gperr.Error) {
data, err := os.ReadFile(p.path)
if err != nil {
- return nil, E.Wrap(err)
+ return nil, gperr.Wrap(err)
}
routes, err := validate(data)
if err != nil && len(routes) == 0 {
- return nil, E.Wrap(err)
+ return nil, gperr.Wrap(err)
}
- return routes, E.Wrap(err)
+ return routes, gperr.Wrap(err)
}
func (p *FileProvider) NewWatcher() W.Watcher {
diff --git a/internal/route/provider/provider.go b/internal/route/provider/provider.go
index 78cb4a4..6894879 100644
--- a/internal/route/provider/provider.go
+++ b/internal/route/provider/provider.go
@@ -8,7 +8,7 @@ import (
"github.com/rs/zerolog"
"github.com/yusing/go-proxy/agent/pkg/agent"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/route"
"github.com/yusing/go-proxy/internal/route/provider/types"
"github.com/yusing/go-proxy/internal/task"
@@ -29,7 +29,7 @@ type (
fmt.Stringer
ShortName() string
IsExplicitOnly() bool
- loadRoutesImpl() (route.Routes, E.Error)
+ loadRoutesImpl() (route.Routes, gperr.Error)
NewWatcher() W.Watcher
Logger() *zerolog.Logger
}
@@ -86,7 +86,7 @@ func (p *Provider) MarshalText() ([]byte, error) {
return []byte(p.String()), nil
}
-func (p *Provider) startRoute(parent task.Parent, r *route.Route) E.Error {
+func (p *Provider) startRoute(parent task.Parent, r *route.Route) gperr.Error {
err := r.Start(parent)
if err != nil {
delete(p.routes, r.Alias)
@@ -97,10 +97,10 @@ func (p *Provider) startRoute(parent task.Parent, r *route.Route) E.Error {
}
// Start implements task.TaskStarter.
-func (p *Provider) Start(parent task.Parent) E.Error {
+func (p *Provider) Start(parent task.Parent) gperr.Error {
t := parent.Subtask("provider."+p.String(), false)
- errs := E.NewBuilder("routes error")
+ errs := gperr.NewBuilder("routes error")
for _, r := range p.routes {
errs.Add(p.startRoute(t, r))
}
@@ -114,8 +114,8 @@ func (p *Provider) Start(parent task.Parent) E.Error {
handler.Handle(t, events)
handler.Log()
},
- func(err E.Error) {
- E.LogError("event error", err, p.Logger())
+ func(err gperr.Error) {
+ gperr.LogError("event error", err, p.Logger())
},
)
eventQueue.Start(p.watcher.Events(t.Context()))
@@ -137,12 +137,12 @@ func (p *Provider) GetRoute(alias string) (r *route.Route, ok bool) {
return
}
-func (p *Provider) loadRoutes() (routes route.Routes, err E.Error) {
+func (p *Provider) loadRoutes() (routes route.Routes, err gperr.Error) {
routes, err = p.loadRoutesImpl()
if err != nil && len(routes) == 0 {
return route.Routes{}, err
}
- errs := E.NewBuilder("routes error")
+ errs := gperr.NewBuilder("routes error")
errs.Add(err)
// check for exclusion
// set alias and provider, then validate
@@ -161,7 +161,7 @@ func (p *Provider) loadRoutes() (routes route.Routes, err E.Error) {
return routes, errs.Error()
}
-func (p *Provider) LoadRoutes() (err E.Error) {
+func (p *Provider) LoadRoutes() (err gperr.Error) {
p.routes, err = p.loadRoutes()
return
}
diff --git a/internal/route/reverse_proxy.go b/internal/route/reverse_proxy.go
index 5af3774..7500122 100755
--- a/internal/route/reverse_proxy.go
+++ b/internal/route/reverse_proxy.go
@@ -10,15 +10,15 @@ import (
"github.com/yusing/go-proxy/internal/common"
"github.com/yusing/go-proxy/internal/docker"
"github.com/yusing/go-proxy/internal/docker/idlewatcher"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/logging"
- gphttp "github.com/yusing/go-proxy/internal/net/http"
- "github.com/yusing/go-proxy/internal/net/http/accesslog"
- "github.com/yusing/go-proxy/internal/net/http/loadbalancer"
- loadbalance "github.com/yusing/go-proxy/internal/net/http/loadbalancer/types"
- "github.com/yusing/go-proxy/internal/net/http/middleware"
- metricslogger "github.com/yusing/go-proxy/internal/net/http/middleware/metrics_logger"
- "github.com/yusing/go-proxy/internal/net/http/reverseproxy"
+ gphttp "github.com/yusing/go-proxy/internal/net/gphttp"
+ "github.com/yusing/go-proxy/internal/net/gphttp/accesslog"
+ "github.com/yusing/go-proxy/internal/net/gphttp/loadbalancer"
+ loadbalance "github.com/yusing/go-proxy/internal/net/gphttp/loadbalancer/types"
+ "github.com/yusing/go-proxy/internal/net/gphttp/middleware"
+ metricslogger "github.com/yusing/go-proxy/internal/net/gphttp/middleware/metrics_logger"
+ "github.com/yusing/go-proxy/internal/net/gphttp/reverseproxy"
"github.com/yusing/go-proxy/internal/route/routes"
"github.com/yusing/go-proxy/internal/task"
"github.com/yusing/go-proxy/internal/watcher/health"
@@ -41,7 +41,7 @@ type (
// var globalMux = http.NewServeMux() // TODO: support regex subdomain matching.
-func NewReverseProxyRoute(base *Route) (*ReveseProxyRoute, E.Error) {
+func NewReverseProxyRoute(base *Route) (*ReveseProxyRoute, gperr.Error) {
httpConfig := base.HTTPConfig
proxyURL := base.ProxyURL
@@ -96,9 +96,9 @@ func (r *ReveseProxyRoute) String() string {
}
// Start implements task.TaskStarter.
-func (r *ReveseProxyRoute) Start(parent task.Parent) E.Error {
+func (r *ReveseProxyRoute) Start(parent task.Parent) gperr.Error {
if existing, ok := routes.GetHTTPRoute(r.TargetName()); ok {
- return E.Errorf("route already exists: from provider %s and %s", existing.ProviderName(), r.ProviderName())
+ return gperr.Errorf("route already exists: from provider %s and %s", existing.ProviderName(), r.ProviderName())
}
r.task = parent.Subtask("http."+r.TargetName(), false)
@@ -130,7 +130,7 @@ func (r *ReveseProxyRoute) Start(parent task.Parent) E.Error {
r.rp.AccessLogger, err = accesslog.NewFileAccessLogger(r.task, r.AccessLog)
if err != nil {
r.task.Finish(err)
- return E.From(err)
+ return gperr.Wrap(err)
}
}
@@ -146,7 +146,7 @@ func (r *ReveseProxyRoute) Start(parent task.Parent) E.Error {
Str("route", r.TargetName()).
Msg("`path_patterns` for reverse proxy is deprecated. Use `rules` instead.")
mux := gphttp.NewServeMux()
- patErrs := E.NewBuilder("invalid path pattern(s)")
+ patErrs := gperr.NewBuilder("invalid path pattern(s)")
for _, p := range pathPatterns {
patErrs.Add(mux.HandleFunc(p, r.rp.HandlerFunc))
}
diff --git a/internal/route/route.go b/internal/route/route.go
index 871d333..2ae9edb 100644
--- a/internal/route/route.go
+++ b/internal/route/route.go
@@ -8,6 +8,7 @@ import (
"github.com/yusing/go-proxy/internal"
"github.com/yusing/go-proxy/internal/docker"
idlewatcher "github.com/yusing/go-proxy/internal/docker/idlewatcher/types"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/homepage"
net "github.com/yusing/go-proxy/internal/net/types"
"github.com/yusing/go-proxy/internal/task"
@@ -16,9 +17,8 @@ import (
dockertypes "github.com/docker/docker/api/types"
"github.com/yusing/go-proxy/internal/common"
- E "github.com/yusing/go-proxy/internal/error"
- "github.com/yusing/go-proxy/internal/net/http/accesslog"
- loadbalance "github.com/yusing/go-proxy/internal/net/http/loadbalancer/types"
+ "github.com/yusing/go-proxy/internal/net/gphttp/accesslog"
+ loadbalance "github.com/yusing/go-proxy/internal/net/gphttp/loadbalancer/types"
"github.com/yusing/go-proxy/internal/route/rules"
"github.com/yusing/go-proxy/internal/route/types"
"github.com/yusing/go-proxy/internal/utils"
@@ -67,14 +67,14 @@ func (r Routes) Contains(alias string) bool {
return ok
}
-func (r *Route) Validate() (err E.Error) {
+func (r *Route) Validate() (err gperr.Error) {
if r.isValidated {
return nil
}
r.isValidated = true
r.Finalize()
- errs := E.NewBuilder("entry validation failed")
+ errs := gperr.NewBuilder("entry validation failed")
switch r.Scheme {
case types.SchemeFileServer:
@@ -88,14 +88,14 @@ func (r *Route) Validate() (err E.Error) {
}
fallthrough
case types.SchemeTCP, types.SchemeUDP:
- r.LisURL = E.Collect(errs, net.ParseURL, fmt.Sprintf("%s://:%d", r.Scheme, r.Port.Listening))
+ r.LisURL = gperr.Collect(errs, net.ParseURL, fmt.Sprintf("%s://:%d", r.Scheme, r.Port.Listening))
fallthrough
default:
if r.LoadBalance != nil && r.LoadBalance.Link == "" {
r.LoadBalance = nil
}
- r.ProxyURL = E.Collect(errs, net.ParseURL, fmt.Sprintf("%s://%s:%d", r.Scheme, r.Host, r.Port.Proxy))
- r.Idlewatcher = E.Collect(errs, idlewatcher.ValidateConfig, r.Container)
+ r.ProxyURL = gperr.Collect(errs, net.ParseURL, fmt.Sprintf("%s://%s:%d", r.Scheme, r.Host, r.Port.Proxy))
+ r.Idlewatcher = gperr.Collect(errs, idlewatcher.ValidateConfig, r.Container)
}
if !r.UseHealthCheck() && (r.UseLoadBalance() || r.UseIdleWatcher()) {
@@ -120,9 +120,9 @@ func (r *Route) Validate() (err E.Error) {
return err
}
-func (r *Route) Start(parent task.Parent) (err E.Error) {
+func (r *Route) Start(parent task.Parent) (err gperr.Error) {
if r.impl == nil {
- return E.New("route not initialized")
+ return gperr.New("route not initialized")
}
return r.impl.Start(parent)
}
diff --git a/internal/route/rules/do.go b/internal/route/rules/do.go
index 6490987..f00c20d 100644
--- a/internal/route/rules/do.go
+++ b/internal/route/rules/do.go
@@ -6,9 +6,9 @@ import (
"strconv"
"strings"
- E "github.com/yusing/go-proxy/internal/error"
- gphttp "github.com/yusing/go-proxy/internal/net/http"
- "github.com/yusing/go-proxy/internal/net/http/reverseproxy"
+ "github.com/yusing/go-proxy/internal/gperr"
+ gphttp "github.com/yusing/go-proxy/internal/net/gphttp"
+ "github.com/yusing/go-proxy/internal/net/gphttp/reverseproxy"
"github.com/yusing/go-proxy/internal/net/types"
"github.com/yusing/go-proxy/internal/utils/strutils"
)
@@ -47,7 +47,7 @@ var commands = map[string]struct {
"to": "the path to rewrite to, must start with /",
},
},
- validate: func(args []string) (any, E.Error) {
+ validate: func(args []string) (any, gperr.Error) {
if len(args) != 2 {
return nil, ErrExpectTwoArgs
}
@@ -109,7 +109,7 @@ var commands = map[string]struct {
"text": "the error message to return",
},
},
- validate: func(args []string) (any, E.Error) {
+ validate: func(args []string) (any, gperr.Error) {
if len(args) != 2 {
return nil, ErrExpectTwoArgs
}
@@ -137,7 +137,7 @@ var commands = map[string]struct {
"realm": "the authentication realm",
},
},
- validate: func(args []string) (any, E.Error) {
+ validate: func(args []string) (any, gperr.Error) {
if len(args) == 1 {
return args[0], nil
}
@@ -176,7 +176,7 @@ var commands = map[string]struct {
"value": "the value to set",
},
},
- validate: func(args []string) (any, E.Error) {
+ validate: func(args []string) (any, gperr.Error) {
return validateModField(ModFieldSet, args)
},
build: func(args any) CommandHandler {
@@ -191,7 +191,7 @@ var commands = map[string]struct {
"value": "the value to add",
},
},
- validate: func(args []string) (any, E.Error) {
+ validate: func(args []string) (any, gperr.Error) {
return validateModField(ModFieldAdd, args)
},
build: func(args any) CommandHandler {
@@ -205,7 +205,7 @@ var commands = map[string]struct {
"field": "the field to remove",
},
},
- validate: func(args []string) (any, E.Error) {
+ validate: func(args []string) (any, gperr.Error) {
return validateModField(ModFieldRemove, args)
},
build: func(args any) CommandHandler {
diff --git a/internal/route/rules/errors.go b/internal/route/rules/errors.go
index d30093c..ec9e86e 100644
--- a/internal/route/rules/errors.go
+++ b/internal/route/rules/errors.go
@@ -1,18 +1,20 @@
package rules
-import E "github.com/yusing/go-proxy/internal/error"
+import (
+ "github.com/yusing/go-proxy/internal/gperr"
+)
var (
- ErrUnterminatedQuotes = E.New("unterminated quotes")
- ErrUnsupportedEscapeChar = E.New("unsupported escape char")
- ErrUnknownDirective = E.New("unknown directive")
- ErrInvalidArguments = E.New("invalid arguments")
- ErrInvalidOnTarget = E.New("invalid `rule.on` target")
- ErrInvalidCommandSequence = E.New("invalid command sequence")
- ErrInvalidSetTarget = E.New("invalid `rule.set` target")
+ ErrUnterminatedQuotes = gperr.New("unterminated quotes")
+ ErrUnsupportedEscapeChar = gperr.New("unsupported escape char")
+ ErrUnknownDirective = gperr.New("unknown directive")
+ ErrInvalidArguments = gperr.New("invalid arguments")
+ ErrInvalidOnTarget = gperr.New("invalid `rule.on` target")
+ ErrInvalidCommandSequence = gperr.New("invalid command sequence")
+ ErrInvalidSetTarget = gperr.New("invalid `rule.set` target")
- ErrExpectNoArg = E.Wrap(ErrInvalidArguments, "expect no arg")
- ErrExpectOneArg = E.Wrap(ErrInvalidArguments, "expect 1 arg")
- ErrExpectTwoArgs = E.Wrap(ErrInvalidArguments, "expect 2 args")
- ErrExpectKVOptionalV = E.Wrap(ErrInvalidArguments, "expect 'key' or 'key value'")
+ ErrExpectNoArg = gperr.Wrap(ErrInvalidArguments, "expect no arg")
+ ErrExpectOneArg = gperr.Wrap(ErrInvalidArguments, "expect 1 arg")
+ ErrExpectTwoArgs = gperr.Wrap(ErrInvalidArguments, "expect 2 args")
+ ErrExpectKVOptionalV = gperr.Wrap(ErrInvalidArguments, "expect 'key' or 'key value'")
)
diff --git a/internal/route/rules/on.go b/internal/route/rules/on.go
index e0b1837..8c9e29f 100644
--- a/internal/route/rules/on.go
+++ b/internal/route/rules/on.go
@@ -3,7 +3,7 @@ package rules
import (
"net/http"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/net/types"
"github.com/yusing/go-proxy/internal/utils/strutils"
)
@@ -240,7 +240,7 @@ func (on *RuleOn) Parse(v string) error {
lines := strutils.SplitLine(v)
checkAnd := make(CheckMatchAll, 0, len(lines))
- errs := E.NewBuilder("rule.on syntax errors")
+ errs := gperr.NewBuilder("rule.on syntax errors")
for i, line := range lines {
if line == "" {
continue
@@ -265,11 +265,11 @@ func (on *RuleOn) MarshalText() ([]byte, error) {
return []byte(on.String()), nil
}
-func parseOn(line string) (Checker, E.Error) {
+func parseOn(line string) (Checker, gperr.Error) {
ors := strutils.SplitRune(line, '|')
if len(ors) > 1 {
- errs := E.NewBuilder("rule.on syntax errors")
+ errs := gperr.NewBuilder("rule.on syntax errors")
checkOr := make(CheckMatchSingle, len(ors))
for i, or := range ors {
curCheckers, err := parseOn(or)
diff --git a/internal/route/rules/on_test.go b/internal/route/rules/on_test.go
index 7c671ce..fb60ffc 100644
--- a/internal/route/rules/on_test.go
+++ b/internal/route/rules/on_test.go
@@ -7,7 +7,7 @@ import (
"net/url"
"testing"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
. "github.com/yusing/go-proxy/internal/utils/testing"
"golang.org/x/crypto/bcrypt"
)
@@ -16,7 +16,7 @@ func TestParseOn(t *testing.T) {
tests := []struct {
name string
input string
- wantErr E.Error
+ wantErr gperr.Error
}{
// header
{
diff --git a/internal/route/rules/parser.go b/internal/route/rules/parser.go
index 7ebc689..dc317b0 100644
--- a/internal/route/rules/parser.go
+++ b/internal/route/rules/parser.go
@@ -4,7 +4,7 @@ import (
"bytes"
"unicode"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
)
var escapedChars = map[rune]rune{
@@ -23,7 +23,7 @@ var escapedChars = map[rune]rune{
//
// error 403 "Forbidden 'foo' 'bar'"
// error 403 Forbidden\ \"foo\"\ \"bar\".
-func parse(v string) (subject string, args []string, err E.Error) {
+func parse(v string) (subject string, args []string, err gperr.Error) {
buf := bytes.NewBuffer(make([]byte, 0, len(v)))
escaped := false
diff --git a/internal/route/rules/parser_test.go b/internal/route/rules/parser_test.go
index f43f284..b5743ae 100644
--- a/internal/route/rules/parser_test.go
+++ b/internal/route/rules/parser_test.go
@@ -4,7 +4,7 @@ import (
"strconv"
"testing"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
. "github.com/yusing/go-proxy/internal/utils/testing"
)
@@ -14,7 +14,7 @@ func TestParser(t *testing.T) {
input string
subject string
args []string
- wantErr E.Error
+ wantErr gperr.Error
}{
{
name: "basic",
diff --git a/internal/route/rules/validate.go b/internal/route/rules/validate.go
index e894309..58a7dd8 100644
--- a/internal/route/rules/validate.go
+++ b/internal/route/rules/validate.go
@@ -6,13 +6,13 @@ import (
"path"
"strings"
- E "github.com/yusing/go-proxy/internal/error"
- gphttp "github.com/yusing/go-proxy/internal/net/http"
+ "github.com/yusing/go-proxy/internal/gperr"
+ gphttp "github.com/yusing/go-proxy/internal/net/gphttp"
"github.com/yusing/go-proxy/internal/net/types"
)
type (
- ValidateFunc func(args []string) (any, E.Error)
+ ValidateFunc func(args []string) (any, gperr.Error)
Tuple[T1, T2 any] struct {
First T1
Second T2
@@ -29,7 +29,7 @@ func (t *Tuple[T1, T2]) String() string {
}
// toStrTuple returns *StrTuple.
-func toStrTuple(args []string) (any, E.Error) {
+func toStrTuple(args []string) (any, gperr.Error) {
if len(args) != 2 {
return nil, ErrExpectTwoArgs
}
@@ -37,7 +37,7 @@ func toStrTuple(args []string) (any, E.Error) {
}
// toKVOptionalV returns *StrTuple that value is optional.
-func toKVOptionalV(args []string) (any, E.Error) {
+func toKVOptionalV(args []string) (any, gperr.Error) {
switch len(args) {
case 1:
return &StrTuple{args[0], ""}, nil
@@ -49,7 +49,7 @@ func toKVOptionalV(args []string) (any, E.Error) {
}
// validateURL returns types.URL with the URL validated.
-func validateURL(args []string) (any, E.Error) {
+func validateURL(args []string) (any, gperr.Error) {
if len(args) != 1 {
return nil, ErrExpectOneArg
}
@@ -61,7 +61,7 @@ func validateURL(args []string) (any, E.Error) {
}
// validateAbsoluteURL returns types.URL with the URL validated.
-func validateAbsoluteURL(args []string) (any, E.Error) {
+func validateAbsoluteURL(args []string) (any, gperr.Error) {
if len(args) != 1 {
return nil, ErrExpectOneArg
}
@@ -79,7 +79,7 @@ func validateAbsoluteURL(args []string) (any, E.Error) {
}
// validateCIDR returns types.CIDR with the CIDR validated.
-func validateCIDR(args []string) (any, E.Error) {
+func validateCIDR(args []string) (any, gperr.Error) {
if len(args) != 1 {
return nil, ErrExpectOneArg
}
@@ -94,7 +94,7 @@ func validateCIDR(args []string) (any, E.Error) {
}
// validateURLPath returns string with the path validated.
-func validateURLPath(args []string) (any, E.Error) {
+func validateURLPath(args []string) (any, gperr.Error) {
if len(args) != 1 {
return nil, ErrExpectOneArg
}
@@ -112,8 +112,8 @@ func validateURLPath(args []string) (any, E.Error) {
}
// validateURLPaths returns []string with each element validated.
-func validateURLPaths(paths []string) (any, E.Error) {
- errs := E.NewBuilder("invalid url paths")
+func validateURLPaths(paths []string) (any, gperr.Error) {
+ errs := gperr.NewBuilder("invalid url paths")
for i, p := range paths {
val, err := validateURLPath([]string{p})
if err != nil {
@@ -129,7 +129,7 @@ func validateURLPaths(paths []string) (any, E.Error) {
}
// validateFSPath returns string with the path validated.
-func validateFSPath(args []string) (any, E.Error) {
+func validateFSPath(args []string) (any, gperr.Error) {
if len(args) != 1 {
return nil, ErrExpectOneArg
}
@@ -141,7 +141,7 @@ func validateFSPath(args []string) (any, E.Error) {
}
// validateMethod returns string with the method validated.
-func validateMethod(args []string) (any, E.Error) {
+func validateMethod(args []string) (any, gperr.Error) {
if len(args) != 1 {
return nil, ErrExpectOneArg
}
@@ -153,7 +153,7 @@ func validateMethod(args []string) (any, E.Error) {
}
// validateUserBCryptPassword returns *HashedCrendential with the password validated.
-func validateUserBCryptPassword(args []string) (any, E.Error) {
+func validateUserBCryptPassword(args []string) (any, gperr.Error) {
if len(args) != 2 {
return nil, ErrExpectTwoArgs
}
@@ -161,7 +161,7 @@ func validateUserBCryptPassword(args []string) (any, E.Error) {
}
// validateModField returns CommandHandler with the field validated.
-func validateModField(mod FieldModifier, args []string) (CommandHandler, E.Error) {
+func validateModField(mod FieldModifier, args []string) (CommandHandler, gperr.Error) {
setField, ok := modFields[args[0]]
if !ok {
return nil, ErrInvalidSetTarget.Subject(args[0])
diff --git a/internal/route/stream.go b/internal/route/stream.go
index 3ec3112..7f4c206 100755
--- a/internal/route/stream.go
+++ b/internal/route/stream.go
@@ -7,7 +7,7 @@ import (
"github.com/rs/zerolog"
"github.com/yusing/go-proxy/internal/docker"
"github.com/yusing/go-proxy/internal/docker/idlewatcher"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/logging"
net "github.com/yusing/go-proxy/internal/net/types"
"github.com/yusing/go-proxy/internal/route/routes"
@@ -30,7 +30,7 @@ type StreamRoute struct {
l zerolog.Logger
}
-func NewStreamRoute(base *Route) (route.Route, E.Error) {
+func NewStreamRoute(base *Route) (route.Route, gperr.Error) {
// TODO: support non-coherent scheme
return &StreamRoute{
Route: base,
@@ -46,9 +46,9 @@ func (r *StreamRoute) String() string {
}
// Start implements task.TaskStarter.
-func (r *StreamRoute) Start(parent task.Parent) E.Error {
+func (r *StreamRoute) Start(parent task.Parent) gperr.Error {
if existing, ok := routes.GetStreamRoute(r.TargetName()); ok {
- return E.Errorf("route already exists: from provider %s and %s", existing.ProviderName(), r.ProviderName())
+ return gperr.Errorf("route already exists: from provider %s and %s", existing.ProviderName(), r.ProviderName())
}
r.task = parent.Subtask("stream." + r.TargetName())
r.Stream = NewStream(r)
@@ -81,14 +81,14 @@ func (r *StreamRoute) Start(parent task.Parent) E.Error {
if err := r.Stream.Setup(); err != nil {
r.task.Finish(err)
- return E.From(err)
+ return gperr.Wrap(err)
}
r.l.Info().Int("port", r.Port.Listening).Msg("listening")
if r.HealthMon != nil {
if err := r.HealthMon.Start(r.task); err != nil {
- E.LogWarn("health monitor error", err, &r.l)
+ gperr.LogWarn("health monitor error", err, &r.l)
}
}
@@ -128,7 +128,7 @@ func (r *StreamRoute) acceptConnections() {
select {
case <-r.task.Context().Done():
default:
- E.LogError("accept connection error", err, &r.l)
+ gperr.LogError("accept connection error", err, &r.l)
}
r.task.Finish(err)
return
@@ -139,7 +139,7 @@ func (r *StreamRoute) acceptConnections() {
go func() {
err := r.Stream.Handle(conn)
if err != nil && !errors.Is(err, context.Canceled) {
- E.LogError("handle connection error", err, &r.l)
+ gperr.LogError("handle connection error", err, &r.l)
}
}()
}
diff --git a/internal/route/types/port.go b/internal/route/types/port.go
index 89ce88f..57c08fd 100644
--- a/internal/route/types/port.go
+++ b/internal/route/types/port.go
@@ -3,7 +3,7 @@ package types
import (
"strconv"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/utils/strutils"
)
@@ -13,8 +13,8 @@ type Port struct {
}
var (
- ErrInvalidPortSyntax = E.New("invalid port syntax, expect [listening_port:]target_port")
- ErrPortOutOfRange = E.New("port out of range")
+ ErrInvalidPortSyntax = gperr.New("invalid port syntax, expect [listening_port:]target_port")
+ ErrPortOutOfRange = gperr.New("port out of range")
)
// Parse implements strutils.Parser.
@@ -28,7 +28,7 @@ func (p *Port) Parse(v string) (err error) {
var err2 error
p.Listening, err = strconv.Atoi(parts[0])
p.Proxy, err2 = strconv.Atoi(parts[1])
- err = E.Join(err, err2)
+ err = gperr.Join(err, err2)
default:
return ErrInvalidPortSyntax.Subject(v)
}
diff --git a/internal/route/types/route.go b/internal/route/types/route.go
index 87a027d..2fe2ed3 100644
--- a/internal/route/types/route.go
+++ b/internal/route/types/route.go
@@ -11,7 +11,7 @@ import (
"github.com/yusing/go-proxy/internal/task"
"github.com/yusing/go-proxy/internal/watcher/health"
- loadbalance "github.com/yusing/go-proxy/internal/net/http/loadbalancer/types"
+ loadbalance "github.com/yusing/go-proxy/internal/net/gphttp/loadbalancer/types"
)
type (
diff --git a/internal/route/types/scheme.go b/internal/route/types/scheme.go
index 6830c6e..cbb4ce2 100644
--- a/internal/route/types/scheme.go
+++ b/internal/route/types/scheme.go
@@ -1,12 +1,12 @@
package types
import (
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
)
type Scheme string
-var ErrInvalidScheme = E.New("invalid scheme")
+var ErrInvalidScheme = gperr.New("invalid scheme")
const (
SchemeHTTP Scheme = "http"
@@ -16,7 +16,7 @@ const (
SchemeFileServer Scheme = "fileserver"
)
-func (s Scheme) Validate() E.Error {
+func (s Scheme) Validate() gperr.Error {
switch s {
case SchemeHTTP, SchemeHTTPS,
SchemeTCP, SchemeUDP, SchemeFileServer:
diff --git a/internal/route/udp_forwarder.go b/internal/route/udp_forwarder.go
index d33b91b..62149af 100644
--- a/internal/route/udp_forwarder.go
+++ b/internal/route/udp_forwarder.go
@@ -6,7 +6,7 @@ import (
"net"
"sync"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/logging"
"github.com/yusing/go-proxy/internal/net/types"
F "github.com/yusing/go-proxy/internal/utils/functional"
@@ -192,7 +192,7 @@ func (w *UDPForwarder) Handle(streamConn types.StreamConn) error {
}
func (w *UDPForwarder) Close() error {
- errs := E.NewBuilder("errors closing udp conn")
+ errs := gperr.NewBuilder("errors closing udp conn")
w.mu.Lock()
defer w.mu.Unlock()
w.connMap.RangeAll(func(key string, conn *UDPConn) {
diff --git a/internal/task/task.go b/internal/task/task.go
index 19a5f8a..2421a13 100644
--- a/internal/task/task.go
+++ b/internal/task/task.go
@@ -8,7 +8,7 @@ import (
"time"
"github.com/yusing/go-proxy/internal/common"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/logging"
"github.com/yusing/go-proxy/internal/utils/strutils"
)
@@ -19,7 +19,7 @@ type (
// and returns an error if it fails to start.
//
// callerSubtask.Finish must be called when start fails or the object is finished.
- Start(parent Parent) E.Error
+ Start(parent Parent) gperr.Error
Task() *Task
}
TaskFinisher interface {
diff --git a/internal/utils/io.go b/internal/utils/io.go
index 10e526d..6a5b6cf 100644
--- a/internal/utils/io.go
+++ b/internal/utils/io.go
@@ -8,7 +8,7 @@ import (
"sync"
"syscall"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
)
// TODO: move to "utils/io".
@@ -90,10 +90,10 @@ func NewBidirectionalPipe(ctx context.Context, rw1 io.ReadWriteCloser, rw2 io.Re
}
}
-func (p BidirectionalPipe) Start() E.Error {
+func (p BidirectionalPipe) Start() gperr.Error {
var wg sync.WaitGroup
wg.Add(2)
- b := E.NewBuilder("bidirectional pipe error")
+ b := gperr.NewBuilder("bidirectional pipe error")
go func() {
b.Add(p.pSrcDst.Start())
wg.Done()
diff --git a/internal/utils/serialization.go b/internal/utils/serialization.go
index 6830efd..0cc4f98 100644
--- a/internal/utils/serialization.go
+++ b/internal/utils/serialization.go
@@ -11,7 +11,7 @@ import (
"time"
"github.com/go-playground/validator/v10"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/utils/functional"
"github.com/yusing/go-proxy/internal/utils/strutils"
"gopkg.in/yaml.v3"
@@ -20,15 +20,15 @@ import (
type SerializedObject = map[string]any
type MapUnmarshaller interface {
- UnmarshalMap(m map[string]any) E.Error
+ UnmarshalMap(m map[string]any) gperr.Error
}
var (
- ErrInvalidType = E.New("invalid type")
- ErrNilValue = E.New("nil")
- ErrUnsettable = E.New("unsettable")
- ErrUnsupportedConversion = E.New("unsupported conversion")
- ErrUnknownField = E.New("unknown field")
+ ErrInvalidType = gperr.New("invalid type")
+ ErrNilValue = gperr.New("nil")
+ ErrUnsettable = gperr.New("unsettable")
+ ErrUnsupportedConversion = gperr.New("unsupported conversion")
+ ErrUnknownField = gperr.New("unknown field")
)
var (
@@ -89,8 +89,8 @@ func extractFields(t reflect.Type) (all, anonymous []reflect.StructField) {
return fields, anonymous
}
-func ValidateWithFieldTags(s any) E.Error {
- errs := E.NewBuilder("validate error")
+func ValidateWithFieldTags(s any) gperr.Error {
+ errs := gperr.NewBuilder("validate error")
err := validate.Struct(s)
var valErrs validator.ValidationErrors
if errors.As(err, &valErrs) {
@@ -107,13 +107,13 @@ func ValidateWithFieldTags(s any) E.Error {
return errs.Error()
}
-func ValidateWithCustomValidator(v reflect.Value) E.Error {
+func ValidateWithCustomValidator(v reflect.Value) gperr.Error {
isStruct := false
for {
switch v.Kind() {
case reflect.Pointer, reflect.Interface:
if v.IsNil() {
- return E.Errorf("validate: v is %w", ErrNilValue)
+ return gperr.Errorf("validate: v is %w", ErrNilValue)
}
if validate, ok := v.Interface().(CustomValidator); ok {
return validate.Validate()
@@ -134,14 +134,14 @@ func ValidateWithCustomValidator(v reflect.Value) E.Error {
}
}
-func dive(dst reflect.Value) (v reflect.Value, t reflect.Type, err E.Error) {
+func dive(dst reflect.Value) (v reflect.Value, t reflect.Type, err gperr.Error) {
dstT := dst.Type()
for {
switch dst.Kind() {
case reflect.Pointer, reflect.Interface:
if dst.IsNil() {
if !dst.CanSet() {
- err = E.Errorf("dive: dst is %w and is not settable", ErrNilValue)
+ err = gperr.Errorf("dive: dst is %w and is not settable", ErrNilValue)
return
}
dst.Set(New(dstT.Elem()))
@@ -158,7 +158,7 @@ func dive(dst reflect.Value) (v reflect.Value, t reflect.Type, err E.Error) {
case reflect.Slice:
dst.Set(reflect.MakeSlice(dstT, 0, 0))
default:
- err = E.Errorf("deserialize: %w for dst %s", ErrInvalidType, dstT.String())
+ err = gperr.Errorf("deserialize: %w for dst %s", ErrInvalidType, dstT.String())
return
}
}
@@ -180,7 +180,7 @@ func dive(dst reflect.Value) (v reflect.Value, t reflect.Type, err E.Error) {
// If the target value is a map[string]any the SerializedObject will be deserialized into the map.
//
// The function returns an error if the target value is not a struct or a map[string]any, or if there is an error during deserialization.
-func Deserialize(src SerializedObject, dst any) (err E.Error) {
+func Deserialize(src SerializedObject, dst any) (err gperr.Error) {
dstV := reflect.ValueOf(dst)
dstT := dstV.Type()
@@ -189,7 +189,7 @@ func Deserialize(src SerializedObject, dst any) (err E.Error) {
dstV.Set(reflect.Zero(dstT))
return nil
}
- return E.Errorf("deserialize: src is %w and dst is not settable\n%s", ErrNilValue, debug.Stack())
+ return gperr.Errorf("deserialize: src is %w and dst is not settable\n%s", ErrNilValue, debug.Stack())
}
if dstT.Implements(mapUnmarshalerType) {
@@ -209,7 +209,7 @@ func Deserialize(src SerializedObject, dst any) (err E.Error) {
// convert target fields to lower no-snake
// then check if the field of data is in the target
- errs := E.NewBuilder("deserialize error")
+ errs := gperr.NewBuilder("deserialize error")
switch dstV.Kind() {
case reflect.Struct, reflect.Interface:
@@ -302,9 +302,9 @@ func isIntFloat(t reflect.Kind) bool {
//
// Returns:
// - error: the error occurred during conversion, or nil if no error occurred.
-func Convert(src reflect.Value, dst reflect.Value) E.Error {
+func Convert(src reflect.Value, dst reflect.Value) gperr.Error {
if !dst.IsValid() {
- return E.Errorf("convert: dst is %w", ErrNilValue)
+ return gperr.Errorf("convert: dst is %w", ErrNilValue)
}
if !src.IsValid() {
@@ -312,7 +312,7 @@ func Convert(src reflect.Value, dst reflect.Value) E.Error {
dst.Set(reflect.Zero(dst.Type()))
return nil
}
- return E.Errorf("convert: src is %w", ErrNilValue)
+ return gperr.Errorf("convert: src is %w", ErrNilValue)
}
srcT := src.Type()
@@ -379,7 +379,7 @@ func Convert(src reflect.Value, dst reflect.Value) E.Error {
if dstT.Kind() != reflect.Slice {
return ErrUnsupportedConversion.Subject(dstT.String() + " to " + srcT.String())
}
- sliceErrs := E.NewBuilder("slice conversion errors")
+ sliceErrs := gperr.NewBuilder("slice conversion errors")
newSlice := reflect.MakeSlice(dstT, src.Len(), src.Len())
i := 0
for j, v := range src.Seq2() {
@@ -401,7 +401,7 @@ func Convert(src reflect.Value, dst reflect.Value) E.Error {
return ErrUnsupportedConversion.Subjectf("%s to %s", srcT, dstT)
}
-func ConvertString(src string, dst reflect.Value) (convertible bool, convErr E.Error) {
+func ConvertString(src string, dst reflect.Value) (convertible bool, convErr gperr.Error) {
convertible = true
dstT := dst.Type()
if dst.Kind() == reflect.Ptr {
@@ -423,7 +423,7 @@ func ConvertString(src string, dst reflect.Value) (convertible bool, convErr E.E
}
d, err := time.ParseDuration(src)
if err != nil {
- return true, E.From(err)
+ return true, gperr.Wrap(err)
}
dst.Set(reflect.ValueOf(d))
return
@@ -443,14 +443,14 @@ func ConvertString(src string, dst reflect.Value) (convertible bool, convErr E.E
i, err = strconv.ParseFloat(src, dstT.Bits())
}
if err != nil {
- return true, E.From(err)
+ return true, gperr.Wrap(err)
}
dst.Set(reflect.ValueOf(i).Convert(dstT))
return
}
// check if (*T).Convertor is implemented
if parser, ok := dst.Addr().Interface().(strutils.Parser); ok {
- return true, E.From(parser.Parse(src))
+ return true, gperr.Wrap(parser.Parse(src))
}
// yaml like
var tmp any
@@ -462,7 +462,7 @@ func ConvertString(src string, dst reflect.Value) (convertible bool, convErr E.E
if !isMultiline && src[0] != '-' {
values := strutils.CommaSeperatedList(src)
dst.Set(reflect.MakeSlice(dst.Type(), len(values), len(values)))
- errs := E.NewBuilder("invalid slice values")
+ errs := gperr.NewBuilder("invalid slice values")
for i, v := range values {
err := Convert(reflect.ValueOf(v), dst.Index(i))
if err != nil {
@@ -477,14 +477,14 @@ func ConvertString(src string, dst reflect.Value) (convertible bool, convErr E.E
sl := make([]any, 0)
err := yaml.Unmarshal([]byte(src), &sl)
if err != nil {
- return true, E.From(err)
+ return true, gperr.Wrap(err)
}
tmp = sl
case reflect.Map, reflect.Struct:
rawMap := make(SerializedObject)
err := yaml.Unmarshal([]byte(src), &rawMap)
if err != nil {
- return true, E.From(err)
+ return true, gperr.Wrap(err)
}
tmp = rawMap
default:
@@ -493,17 +493,17 @@ func ConvertString(src string, dst reflect.Value) (convertible bool, convErr E.E
return true, Convert(reflect.ValueOf(tmp), dst)
}
-func DeserializeYAML[T any](data []byte, target *T) E.Error {
+func DeserializeYAML[T any](data []byte, target *T) gperr.Error {
m := make(map[string]any)
if err := yaml.Unmarshal(data, m); err != nil {
- return E.From(err)
+ return gperr.Wrap(err)
}
return Deserialize(m, target)
}
-func DeserializeYAMLMap[V any](data []byte) (_ functional.Map[string, V], err E.Error) {
+func DeserializeYAMLMap[V any](data []byte) (_ functional.Map[string, V], err gperr.Error) {
m := make(map[string]any)
- if err = E.From(yaml.Unmarshal(data, m)); err != nil {
+ if err = gperr.Wrap(yaml.Unmarshal(data, m)); err != nil {
return
}
m2 := make(map[string]V, len(m))
diff --git a/internal/utils/validation.go b/internal/utils/validation.go
index 32db124..490c348 100644
--- a/internal/utils/validation.go
+++ b/internal/utils/validation.go
@@ -2,15 +2,15 @@ package utils
import (
"github.com/go-playground/validator/v10"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
)
var validate = validator.New()
-var ErrValidationError = E.New("validation error")
+var ErrValidationError = gperr.New("validation error")
type CustomValidator interface {
- Validate() E.Error
+ Validate() gperr.Error
}
func Validator() *validator.Validate {
diff --git a/internal/watcher/directory_watcher.go b/internal/watcher/directory_watcher.go
index 171d59e..45cca6a 100644
--- a/internal/watcher/directory_watcher.go
+++ b/internal/watcher/directory_watcher.go
@@ -8,7 +8,7 @@ import (
"github.com/fsnotify/fsnotify"
"github.com/rs/zerolog"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/logging"
"github.com/yusing/go-proxy/internal/task"
"github.com/yusing/go-proxy/internal/watcher/events"
@@ -24,7 +24,7 @@ type DirWatcher struct {
mu sync.Mutex
eventCh chan Event
- errCh chan E.Error
+ errCh chan gperr.Error
task *task.Task
}
@@ -55,14 +55,14 @@ func NewDirectoryWatcher(parent task.Parent, dirPath string) *DirWatcher {
w: w,
fwMap: make(map[string]*fileWatcher),
eventCh: make(chan Event),
- errCh: make(chan E.Error),
+ errCh: make(chan gperr.Error),
task: parent.Subtask("dir_watcher(" + dirPath + ")"),
}
go helper.start()
return helper
}
-func (h *DirWatcher) Events(_ context.Context) (<-chan Event, <-chan E.Error) {
+func (h *DirWatcher) Events(_ context.Context) (<-chan Event, <-chan gperr.Error) {
return h.eventCh, h.errCh
}
@@ -78,7 +78,7 @@ func (h *DirWatcher) Add(relPath string) Watcher {
s = &fileWatcher{
relPath: relPath,
eventCh: make(chan Event),
- errCh: make(chan E.Error),
+ errCh: make(chan gperr.Error),
}
h.fwMap[relPath] = s
return s
@@ -162,7 +162,7 @@ func (h *DirWatcher) start() {
return
}
select {
- case h.errCh <- E.From(err):
+ case h.errCh <- gperr.Wrap(err):
default:
}
}
diff --git a/internal/watcher/docker_watcher.go b/internal/watcher/docker_watcher.go
index 647357e..89b8a0d 100644
--- a/internal/watcher/docker_watcher.go
+++ b/internal/watcher/docker_watcher.go
@@ -7,7 +7,7 @@ import (
docker_events "github.com/docker/docker/api/types/events"
"github.com/docker/docker/api/types/filters"
D "github.com/yusing/go-proxy/internal/docker"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/watcher/events"
)
@@ -61,7 +61,7 @@ func NewDockerWatcherWithClient(client *D.SharedClient) DockerWatcher {
}
}
-func (w DockerWatcher) Events(ctx context.Context) (<-chan Event, <-chan E.Error) {
+func (w DockerWatcher) Events(ctx context.Context) (<-chan Event, <-chan gperr.Error) {
return w.EventsWithOptions(ctx, optionsDefault)
}
@@ -71,9 +71,9 @@ func (w DockerWatcher) Close() {
}
}
-func (w DockerWatcher) EventsWithOptions(ctx context.Context, options DockerListOptions) (<-chan Event, <-chan E.Error) {
+func (w DockerWatcher) EventsWithOptions(ctx context.Context, options DockerListOptions) (<-chan Event, <-chan gperr.Error) {
eventCh := make(chan Event, 100)
- errCh := make(chan E.Error, 10)
+ errCh := make(chan gperr.Error, 10)
go func() {
defer func() {
@@ -89,7 +89,7 @@ func (w DockerWatcher) EventsWithOptions(ctx context.Context, options DockerList
retryTicker := time.NewTicker(dockerWatcherRetryInterval)
for err != nil {
attempts++
- errCh <- E.Errorf("docker connection attempt #%d: %w", attempts, err)
+ errCh <- gperr.Errorf("docker connection attempt #%d: %w", attempts, err)
select {
case <-ctx.Done():
retryTicker.Stop()
@@ -126,7 +126,7 @@ func (w DockerWatcher) EventsWithOptions(ctx context.Context, options DockerList
if err == nil {
continue
}
- errCh <- E.From(err)
+ errCh <- gperr.Wrap(err)
select {
case <-ctx.Done():
return
diff --git a/internal/watcher/events/event_queue.go b/internal/watcher/events/event_queue.go
index 563c8cd..276a2d9 100644
--- a/internal/watcher/events/event_queue.go
+++ b/internal/watcher/events/event_queue.go
@@ -5,7 +5,7 @@ import (
"time"
"github.com/yusing/go-proxy/internal/common"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/task"
)
@@ -19,7 +19,7 @@ type (
onError OnErrorFunc
}
OnFlushFunc = func(events []Event)
- OnErrorFunc = func(err E.Error)
+ OnErrorFunc = func(err gperr.Error)
)
const eventQueueCapacity = 10
@@ -50,13 +50,13 @@ func NewEventQueue(queueTask *task.Task, flushInterval time.Duration, onFlush On
}
}
-func (e *EventQueue) Start(eventCh <-chan Event, errCh <-chan E.Error) {
+func (e *EventQueue) Start(eventCh <-chan Event, errCh <-chan gperr.Error) {
origOnFlush := e.onFlush
// recover panic in onFlush when in production mode
e.onFlush = func(events []Event) {
defer func() {
if err := recover(); err != nil {
- e.onError(E.New("recovered panic in onFlush").
+ e.onError(gperr.New("recovered panic in onFlush").
Withf("%v", err).
Subject(e.task.Name()))
if common.IsDebug {
diff --git a/internal/watcher/file_watcher.go b/internal/watcher/file_watcher.go
index a53025d..41989a1 100644
--- a/internal/watcher/file_watcher.go
+++ b/internal/watcher/file_watcher.go
@@ -3,15 +3,15 @@ package watcher
import (
"context"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
)
type fileWatcher struct {
relPath string
eventCh chan Event
- errCh chan E.Error
+ errCh chan gperr.Error
}
-func (fw *fileWatcher) Events(ctx context.Context) (<-chan Event, <-chan E.Error) {
+func (fw *fileWatcher) Events(ctx context.Context) (<-chan Event, <-chan gperr.Error) {
return fw.eventCh, fw.errCh
}
diff --git a/internal/watcher/health/monitor/monitor.go b/internal/watcher/health/monitor/monitor.go
index 0d76877..86d13f9 100644
--- a/internal/watcher/health/monitor/monitor.go
+++ b/internal/watcher/health/monitor/monitor.go
@@ -6,7 +6,7 @@ import (
"fmt"
"time"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/logging"
"github.com/yusing/go-proxy/internal/metrics"
"github.com/yusing/go-proxy/internal/net/types"
@@ -57,9 +57,9 @@ func (mon *monitor) ContextWithTimeout(cause string) (ctx context.Context, cance
}
// Start implements task.TaskStarter.
-func (mon *monitor) Start(parent task.Parent) E.Error {
+func (mon *monitor) Start(parent task.Parent) gperr.Error {
if mon.config.Interval <= 0 {
- return E.From(ErrNegativeInterval)
+ return gperr.Wrap(ErrNegativeInterval)
}
mon.service = parent.Name()
diff --git a/internal/watcher/watcher.go b/internal/watcher/watcher.go
index e33cd55..1c51ec8 100644
--- a/internal/watcher/watcher.go
+++ b/internal/watcher/watcher.go
@@ -3,12 +3,12 @@ package watcher
import (
"context"
- E "github.com/yusing/go-proxy/internal/error"
+ "github.com/yusing/go-proxy/internal/gperr"
"github.com/yusing/go-proxy/internal/watcher/events"
)
type Event = events.Event
type Watcher interface {
- Events(ctx context.Context) (<-chan Event, <-chan E.Error)
+ Events(ctx context.Context) (<-chan Event, <-chan gperr.Error)
}