added golangci-linting, refactor, simplified error msgs and fixed some error handling

This commit is contained in:
yusing
2024-10-10 11:52:09 +08:00
parent d91b66ae87
commit da04a0dff4
63 changed files with 690 additions and 410 deletions

View File

@@ -5,7 +5,7 @@ import (
"net/http"
v1 "github.com/yusing/go-proxy/internal/api/v1"
"github.com/yusing/go-proxy/internal/api/v1/error_page"
"github.com/yusing/go-proxy/internal/api/v1/errorpage"
. "github.com/yusing/go-proxy/internal/api/v1/utils"
"github.com/yusing/go-proxy/internal/common"
"github.com/yusing/go-proxy/internal/config"
@@ -36,11 +36,11 @@ func NewHandler(cfg *config.Config) http.Handler {
mux.HandleFunc("PUT", "/v1/file/{filename...}", v1.SetFileContent)
mux.HandleFunc("GET", "/v1/stats", wrap(cfg, v1.Stats))
mux.HandleFunc("GET", "/v1/stats/ws", wrap(cfg, v1.StatsWS))
mux.HandleFunc("GET", "/v1/error_page", error_page.GetHandleFunc())
mux.HandleFunc("GET", "/v1/error_page", errorpage.GetHandleFunc())
return mux
}
// allow only requests to API server with host matching common.APIHTTPAddr
// allow only requests to API server with host matching common.APIHTTPAddr.
func checkHost(f http.HandlerFunc) http.HandlerFunc {
if common.IsDebug {
return f
@@ -48,8 +48,7 @@ func checkHost(f http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if r.Host != common.APIHTTPAddr {
Logger.Warnf("invalid request to API server with host: %s, expect %s", r.Host, common.APIHTTPAddr)
w.WriteHeader(http.StatusForbidden)
w.Write([]byte("invalid request"))
http.Error(w, "invalid request", http.StatusForbidden)
return
}
f(w, r)

View File

@@ -5,7 +5,7 @@ import (
"net/http"
"strings"
U "github.com/yusing/go-proxy/internal/api/v1/utils"
. "github.com/yusing/go-proxy/internal/api/v1/utils"
"github.com/yusing/go-proxy/internal/config"
R "github.com/yusing/go-proxy/internal/route"
)
@@ -13,7 +13,7 @@ import (
func CheckHealth(cfg *config.Config, w http.ResponseWriter, r *http.Request) {
target := r.FormValue("target")
if target == "" {
U.HandleErr(w, r, U.ErrMissingKey("target"), http.StatusBadRequest)
HandleErr(w, r, ErrMissingKey("target"), http.StatusBadRequest)
return
}
@@ -22,7 +22,7 @@ func CheckHealth(cfg *config.Config, w http.ResponseWriter, r *http.Request) {
switch {
case route == nil:
U.HandleErr(w, r, U.ErrNotFound("target", target), http.StatusNotFound)
HandleErr(w, r, ErrNotFound("target", target), http.StatusNotFound)
return
case route.Type() == R.RouteTypeReverseProxy:
ok = IsSiteHealthy(route.URL().String())

View File

@@ -1,4 +1,4 @@
package error_page
package errorpage
import (
"context"
@@ -7,7 +7,7 @@ import (
"path"
"sync"
api "github.com/yusing/go-proxy/internal/api/v1/utils"
. "github.com/yusing/go-proxy/internal/api/v1/utils"
"github.com/yusing/go-proxy/internal/common"
U "github.com/yusing/go-proxy/internal/utils"
F "github.com/yusing/go-proxy/internal/utils/functional"
@@ -17,6 +17,11 @@ import (
const errPagesBasePath = common.ErrorPagesBasePath
var (
dirWatcher W.Watcher
fileContentMap = F.NewMapOf[string, []byte]()
)
var setup = sync.OnceFunc(func() {
dirWatcher = W.NewDirectoryWatcher(context.Background(), errPagesBasePath)
loadContent()
@@ -27,7 +32,7 @@ func GetStaticFile(filename string) ([]byte, bool) {
return fileContentMap.Load(filename)
}
// try <statusCode>.html -> 404.html -> not ok
// try <statusCode>.html -> 404.html -> not ok.
func GetErrorPageByStatus(statusCode int) (content []byte, ok bool) {
content, ok = fileContentMap.Load(fmt.Sprintf("%d.html", statusCode))
if !ok && statusCode != 404 {
@@ -39,7 +44,7 @@ func GetErrorPageByStatus(statusCode int) (content []byte, ok bool) {
func loadContent() {
files, err := U.ListFiles(errPagesBasePath, 0)
if err != nil {
api.Logger.Error(err)
Logger.Error(err)
return
}
for _, file := range files {
@@ -48,11 +53,11 @@ func loadContent() {
}
content, err := os.ReadFile(file)
if err != nil {
api.Logger.Errorf("failed to read error page resource %s: %s", file, err)
Logger.Errorf("failed to read error page resource %s: %s", file, err)
continue
}
file = path.Base(file)
api.Logger.Infof("error page resource %s loaded", file)
Logger.Infof("error page resource %s loaded", file)
fileContentMap.Store(file, content)
}
}
@@ -72,17 +77,14 @@ func watchDir() {
loadContent()
case events.ActionFileDeleted:
fileContentMap.Delete(filename)
api.Logger.Infof("error page resource %s deleted", filename)
Logger.Infof("error page resource %s deleted", filename)
case events.ActionFileRenamed:
api.Logger.Infof("error page resource %s deleted", filename)
Logger.Infof("error page resource %s deleted", filename)
fileContentMap.Delete(filename)
loadContent()
}
case err := <-errCh:
api.Logger.Errorf("error watching error page directory: %s", err)
Logger.Errorf("error watching error page directory: %s", err)
}
}
}
var dirWatcher W.Watcher
var fileContentMap = F.NewMapOf[string, []byte]()

View File

@@ -1,6 +1,10 @@
package error_page
package errorpage
import "net/http"
import (
"net/http"
. "github.com/yusing/go-proxy/internal/api/v1/utils"
)
func GetHandleFunc() http.HandlerFunc {
setup()
@@ -21,5 +25,7 @@ func serveHTTP(w http.ResponseWriter, r *http.Request) {
http.Error(w, "404 not found", http.StatusNotFound)
return
}
w.Write(content)
if _, err := w.Write(content); err != nil {
HandleErr(w, r, err)
}
}

View File

@@ -24,7 +24,7 @@ func GetFileContent(w http.ResponseWriter, r *http.Request) {
U.HandleErr(w, r, err)
return
}
w.Write(content)
U.WriteBody(w, content)
}
func SetFileContent(w http.ResponseWriter, r *http.Request) {
@@ -47,11 +47,11 @@ func SetFileContent(w http.ResponseWriter, r *http.Request) {
}
if validateErr != nil {
U.RespondJson(w, validateErr.JSONObject(), http.StatusBadRequest)
U.RespondJSON(w, r, validateErr.JSONObject(), http.StatusBadRequest)
return
}
err = os.WriteFile(path.Join(common.ConfigBasePath, filename), content, 0644)
err = os.WriteFile(path.Join(common.ConfigBasePath, filename), content, 0o644)
if err != nil {
U.HandleErr(w, r, err)
return

View File

@@ -1,7 +1,11 @@
package v1
import "net/http"
import (
"net/http"
. "github.com/yusing/go-proxy/internal/api/v1/utils"
)
func Index(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("API ready"))
WriteBody(w, []byte("API ready"))
}

View File

@@ -55,7 +55,7 @@ func listRoutes(cfg *config.Config, w http.ResponseWriter, r *http.Request) {
}
}
U.HandleErr(w, r, U.RespondJson(w, routes))
U.RespondJSON(w, r, routes)
}
func listConfigFiles(w http.ResponseWriter, r *http.Request) {
@@ -67,21 +67,21 @@ func listConfigFiles(w http.ResponseWriter, r *http.Request) {
for i := range files {
files[i] = strings.TrimPrefix(files[i], common.ConfigBasePath+"/")
}
U.HandleErr(w, r, U.RespondJson(w, files))
U.RespondJSON(w, r, files)
}
func listMiddlewareTrace(w http.ResponseWriter, r *http.Request) {
U.HandleErr(w, r, U.RespondJson(w, middleware.GetAllTrace()))
U.RespondJSON(w, r, middleware.GetAllTrace())
}
func listMiddlewares(w http.ResponseWriter, r *http.Request) {
U.HandleErr(w, r, U.RespondJson(w, middleware.All()))
U.RespondJSON(w, r, middleware.All())
}
func listMatchDomains(cfg *config.Config, w http.ResponseWriter, r *http.Request) {
U.HandleErr(w, r, U.RespondJson(w, cfg.Value().MatchDomains))
U.RespondJSON(w, r, cfg.Value().MatchDomains)
}
func listHomepageConfig(cfg *config.Config, w http.ResponseWriter, r *http.Request) {
U.HandleErr(w, r, U.RespondJson(w, cfg.HomepageConfig()))
U.RespondJSON(w, r, cfg.HomepageConfig())
}

View File

@@ -9,7 +9,7 @@ import (
func Reload(cfg *config.Config, w http.ResponseWriter, r *http.Request) {
if err := cfg.Reload(); err != nil {
U.RespondJson(w, err.JSONObject(), http.StatusInternalServerError)
U.RespondJSON(w, r, err.JSONObject(), http.StatusInternalServerError)
} else {
w.WriteHeader(http.StatusOK)
}

View File

@@ -5,18 +5,17 @@ import (
"net/http"
"time"
"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/common"
"github.com/yusing/go-proxy/internal/config"
"github.com/yusing/go-proxy/internal/server"
"github.com/yusing/go-proxy/internal/utils"
"github.com/coder/websocket"
"github.com/coder/websocket/wsjson"
)
func Stats(cfg *config.Config, w http.ResponseWriter, r *http.Request) {
U.HandleErr(w, r, U.RespondJson(w, getStats(cfg)))
U.RespondJSON(w, r, getStats(cfg))
}
func StatsWS(cfg *config.Config, w http.ResponseWriter, r *http.Request) {
@@ -42,6 +41,7 @@ func StatsWS(cfg *config.Config, w http.ResponseWriter, r *http.Request) {
U.Logger.Errorf("/stats/ws failed to upgrade websocket: %s", err)
return
}
/* trunk-ignore(golangci-lint/errcheck) */
defer conn.CloseNow()
ctx, cancel := context.WithCancel(context.Background())

View File

@@ -8,20 +8,22 @@ import (
"github.com/yusing/go-proxy/internal/common"
)
var HTTPClient = &http.Client{
Timeout: common.ConnectionTimeout,
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
DisableKeepAlives: true,
ForceAttemptHTTP2: true,
DialContext: (&net.Dialer{
Timeout: common.DialTimeout,
KeepAlive: common.KeepAlive, // this is different from DisableKeepAlives
}).DialContext,
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
}
var (
HTTPClient = &http.Client{
Timeout: common.ConnectionTimeout,
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
DisableKeepAlives: true,
ForceAttemptHTTP2: true,
DialContext: (&net.Dialer{
Timeout: common.DialTimeout,
KeepAlive: common.KeepAlive, // this is different from DisableKeepAlives
}).DialContext,
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
}
var Get = HTTPClient.Get
var Post = HTTPClient.Post
var Head = HTTPClient.Head
Get = HTTPClient.Get
Post = HTTPClient.Post
Head = HTTPClient.Head
)

View File

@@ -5,16 +5,26 @@ import (
"net/http"
)
func RespondJson(w http.ResponseWriter, data any, code ...int) error {
func WriteBody(w http.ResponseWriter, body []byte) {
if _, err := w.Write(body); err != nil {
HandleErr(w, nil, err)
}
}
func RespondJSON(w http.ResponseWriter, r *http.Request, data any, code ...int) bool {
if len(code) > 0 {
w.WriteHeader(code[0])
}
w.Header().Set("Content-Type", "application/json")
j, err := json.MarshalIndent(data, "", " ")
if err != nil {
return err
} else {
w.Write(j)
HandleErr(w, r, err)
return false
}
return nil
_, err = w.Write(j)
if err != nil {
HandleErr(w, r, err)
return false
}
return true
}

View File

@@ -3,9 +3,10 @@ package v1
import (
"net/http"
. "github.com/yusing/go-proxy/internal/api/v1/utils"
"github.com/yusing/go-proxy/pkg"
)
func GetVersion(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(pkg.GetVersion()))
WriteBody(w, []byte(pkg.GetVersion()))
}