--- /dev/null
+main/main
+main/main.exe
import (
"crypto/md5"
+ "crypto/tls"
"encoding/json"
"fmt"
"sync"
lock sync.RWMutex
Addr string `json:"addr"`
TLS struct {
- Pub string `json:"pub"`
- Key string `json:"key"`
+ Config *tls.Config `json:"-"`
+ Pub string `json:"pub"`
+ Key string `json:"key"`
} `json:"tls"`
MatchRule string `json:"matchRule"`
Routes []Route `json:"routes"`
go 1.21.4
-require github.com/gorilla/websocket v1.5.1
+require (
+ github.com/gorilla/websocket v1.5.1
+ github.com/qydysky/part v0.28.20231209070216
+)
require (
- github.com/andybalholm/brotli v1.0.6 // indirect
+ github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
- github.com/klauspost/compress v1.17.3 // indirect
- github.com/miekg/dns v1.1.57 // indirect
- github.com/qydysky/part v0.28.20231203041727 // indirect
+ github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
- github.com/thedevsaddam/gojsonq/v2 v2.5.2 // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect
- golang.org/x/mod v0.14.0 // indirect
golang.org/x/net v0.18.0 // indirect
golang.org/x/sys v0.14.0 // indirect
golang.org/x/text v0.14.0 // indirect
- golang.org/x/tools v0.15.0 // indirect
+ gopkg.in/yaml.v3 v3.0.1 // indirect
)
-replace github.com/qydysky/part => ../part
+// replace github.com/qydysky/part => ../part
-github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
-github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI=
github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
-github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
+github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
+github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
-github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI=
-github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
-github.com/klauspost/compress v1.17.3 h1:qkRjuerhUU1EmXLYGkSH6EZL+vPSxIrYjLNAK4slzwA=
-github.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
-github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI=
-github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
-github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM=
-github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk=
-github.com/qydysky/part v0.27.17 h1:hYSOjnkV0jIf/tSLBmqEAXfkprEhwySQrVWRtrZxuXE=
-github.com/qydysky/part v0.27.17/go.mod h1:IEMpGB0NBl6MklZmoenSpS5ChhaIL79JYFo6mF1UkAU=
-github.com/qydysky/part v0.28.1 h1:VkG9hnN7176v55InlxVFzD4Pxac5X4oHfG5Z7DBwgkk=
-github.com/qydysky/part v0.28.1/go.mod h1:NyKyjpBCSjcHtKlC+fL5lCidm57UCnwEgufiBDs5yxA=
-github.com/qydysky/part v0.28.20231202005014 h1:/txeAjH2FdMPPX1BfcLtd5ArWAG1DcP/Rg4CeT73EjE=
-github.com/qydysky/part v0.28.20231202005014/go.mod h1:NyKyjpBCSjcHtKlC+fL5lCidm57UCnwEgufiBDs5yxA=
+github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
+github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
+github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
+github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
+github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
+github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/qydysky/part v0.28.20231209070216 h1:1hnOxnsd4sTBTA/nF2pLhyL+0DidpwHo5H08S1D7xHE=
+github.com/qydysky/part v0.28.20231209070216/go.mod h1:NyKyjpBCSjcHtKlC+fL5lCidm57UCnwEgufiBDs5yxA=
+github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
+github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
-github.com/thedevsaddam/gojsonq/v2 v2.5.2 h1:CoMVaYyKFsVj6TjU6APqAhAvC07hTI6IQen8PHzHYY0=
-github.com/thedevsaddam/gojsonq/v2 v2.5.2/go.mod h1:bv6Xa7kWy82uT0LnXPE2SzGqTj33TAEeR560MdJkiXs=
-github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM=
-github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI=
+github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
-github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms=
-github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4=
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
-github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
-github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
-golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
-golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
-golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
-golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg=
golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
-golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
-golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y=
-golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4=
golang.org/x/tools v0.15.0 h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8=
golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+lukechampine.com/uint128 v1.3.0 h1:cDdUVfRwDUDovz610ABgFD17nXD4/uDgVHl2sC3+sbo=
+lukechampine.com/uint128 v1.3.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
+modernc.org/cc/v3 v3.41.0 h1:QoR1Sn3YWlmA1T4vLaKZfawdVtSiGx8H+cEojbC7v1Q=
+modernc.org/cc/v3 v3.41.0/go.mod h1:Ni4zjJYJ04CDOhG7dn640WGfwBzfE0ecX8TyMB0Fv0Y=
+modernc.org/ccgo/v3 v3.16.15 h1:KbDR3ZAVU+wiLyMESPtbtE/Add4elztFyfsWoNTgxS0=
+modernc.org/ccgo/v3 v3.16.15/go.mod h1:yT7B+/E2m43tmMOT51GMoM98/MtHIcQQSleGnddkUNI=
+modernc.org/libc v1.34.4 h1:r9+5s4wNeoCsB8CuJE67UB4N07ernbvrcry9O3MLWtQ=
+modernc.org/libc v1.34.4/go.mod h1:YAXkAZ8ktnkCKaN9sw/UDeUVkGYJ/YquGO4FTi5nmHE=
+modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
+modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
+modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E=
+modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E=
+modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
+modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
+modernc.org/sqlite v1.27.0 h1:MpKAHoyYB7xqcwnUwkuD+npwEa0fojF0B5QRbN+auJ8=
+modernc.org/sqlite v1.27.0/go.mod h1:Qxpazz0zH8Z1xCFyi5GSL3FzbtZ3fvbjmywNogldEW0=
+modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=
+modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0=
+modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
+modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
import (
"context"
+ "crypto/tls"
"encoding/json"
"errors"
"fmt"
"github.com/gorilla/websocket"
pctx "github.com/qydysky/part/ctx"
- pfile "github.com/qydysky/part/file"
- plog "github.com/qydysky/part/log"
pweb "github.com/qydysky/part/web"
)
+type Logger interface {
+ Error(msg string, args ...any)
+ Debug(msg string, args ...any)
+ Info(msg string, args ...any)
+ Warn(msg string, args ...any)
+}
+
+type File interface {
+ Read(data []byte) (int, error)
+}
+
// 加载
-func LoadPeriod(ctx context.Context, buf []byte, configF *pfile.File, configS *Config, logger *plog.Log_interface) {
- if e := loadConfig(buf, configF, configS, logger); e != nil {
- logger.L(`E:`, "配置加载", e)
+func LoadPeriod(ctx context.Context, buf []byte, configF File, configS *Config, logger Logger) error {
+ if e := loadConfig(buf, configF, configS); e != nil {
+ logger.Error(`E:`, "配置加载", e)
+ return e
}
// 定时加载config
go func() {
for {
select {
case <-time.After(time.Second * 10):
- if e := loadConfig(buf, configF, configS, logger); e != nil {
- logger.L(`E:`, "配置加载", e)
+ if e := loadConfig(buf, configF, configS); e != nil {
+ logger.Error(`E:`, "配置加载", e)
}
case <-ctx1.Done():
return
}
}
}()
+ return nil
}
// 测试
-func Test(ctx context.Context, port int, logger *plog.Log_interface) {
+func Test(ctx context.Context, port int, logger Logger) {
if port == 0 {
return
}
- logger = logger.Base("测试")
ctx1, done1 := pctx.WaitCtx(ctx)
defer done1()
- logger.L(`I:`, "启动", fmt.Sprintf("127.0.0.1:%d", port))
+ logger.Info(`I:`, "启动", fmt.Sprintf("127.0.0.1:%d", port))
s := pweb.New(&http.Server{
Addr: fmt.Sprintf("127.0.0.1:%d", port),
WriteTimeout: time.Second * time.Duration(10),
}
// 转发
-func Run(ctx context.Context, configSP *Config, logger *plog.Log_interface) {
- logger = logger.Base("转发")
+func Run(ctx context.Context, configSP *Config, logger Logger) {
// 根ctx
ctx, cancle := pctx.WithWait(ctx, 0, time.Minute)
defer func() {
if errors.Is(cancle(), pctx.ErrWaitTo) {
- logger.L(`E:`, "退出超时")
+ logger.Error(`E:`, "退出超时")
}
}()
// 路由
routeP := pweb.WebPath{}
- logger.L(`I:`, "启动...")
- defer logger.L(`I:`, "退出,等待1min连接关闭...")
+ logger.Info(`I:`, "启动...")
+ defer logger.Info(`I:`, "退出,等待1min连接关闭...")
// config对象初次加载
if e := applyConfig(ctx, configSP, &routeP, logger); e != nil {
var matchfunc func(path string) (func(w http.ResponseWriter, r *http.Request), bool)
switch configSP.MatchRule {
case "prefix":
- logger.L(`I:`, "匹配规则", "prefix")
+ logger.Info(`I:`, "匹配规则", "prefix")
matchfunc = routeP.LoadPerfix
case "all":
- logger.L(`I:`, "匹配规则", "all")
+ logger.Info(`I:`, "匹配规则", "all")
matchfunc = routeP.Load
default:
- logger.L(`E:`, "匹配规则", "无效")
+ logger.Error(`E:`, "匹配规则", "无效")
return
}
Addr: configSP.Addr,
}
+ if configSP.TLS.Config != nil {
+ httpSer.TLSConfig = configSP.TLS.Config.Clone()
+ }
+
syncWeb := pweb.NewSyncMap(&httpSer, &routeP, matchfunc)
defer syncWeb.Shutdown()
}
}
-func loadConfig(buf []byte, configF *pfile.File, configS *Config, logger *plog.Log_interface) error {
+func loadConfig(buf []byte, configF File, configS *Config) error {
if i, e := configF.Read(buf); e != nil && !errors.Is(e, io.EOF) {
- logger.L(`E:`, `读取配置`, e)
return e
} else if i == cap(buf) {
- logger.L(`E:`, `读取配置`, `buf full`)
return errors.New(`buf full`)
} else {
configS.lock.Lock()
defer configS.lock.Unlock()
if e := json.Unmarshal(buf[:i], configS); e != nil {
- logger.L(`E:`, `读取配置`, e)
return e
}
+
+ if configS.TLS.Key != "" && configS.TLS.Pub != "" {
+ if cert, e := tls.LoadX509KeyPair(configS.TLS.Pub, configS.TLS.Key); e != nil {
+ return e
+ } else {
+ configS.TLS.Config = &tls.Config{
+ Certificates: []tls.Certificate{cert},
+ NextProtos: []string{"h2", "http/1.1"},
+ }
+ }
+ }
}
return nil
}
-func applyConfig(ctx context.Context, configS *Config, routeP *pweb.WebPath, logger *plog.Log_interface) error {
+func applyConfig(ctx context.Context, configS *Config, routeP *pweb.WebPath, logger Logger) error {
configS.lock.RLock()
defer configS.lock.RUnlock()
}
if len(route.Back) == 0 {
- logger.L(`I:`, "移除路由", path)
+ logger.Info(`I:`, "移除路由", path)
routeP.Store(path, nil)
continue
}
backArray := route.GenBack()
if len(backArray) == 0 {
- logger.L(`I:`, "移除路由", path)
+ logger.Info(`I:`, "移除路由", path)
routeP.Store(path, nil)
continue
}
- logger.L(`I:`, "路由更新", path)
+ logger.Info(`I:`, "路由更新", path)
routeP.Store(path, func(w http.ResponseWriter, r *http.Request) {
ctx1, done1 := pctx.WaitCtx(ctx)
}
}
if backI == int64(len(backArray)) {
- pweb.WithStatusCode(w, http.StatusServiceUnavailable)
- logger.L(`E:`, fmt.Sprintf("%s=> 全部后端失效", path))
+ w.WriteHeader(http.StatusServiceUnavailable)
+ logger.Error(`E:`, fmt.Sprintf("%s=> 全部后端失效", path))
return
}
}
- logger.L(`T:`, fmt.Sprintf("%s=>%s", path, backArray[backI].Name))
+ logger.Error(`T:`, fmt.Sprintf("%s=>%s", path, backArray[backI].Name))
var e error
if r.Header.Get("Upgrade") == "websocket" {
e = httpDealer(ctx1, w, r, path, backArray[backI], logger)
}
if e != nil {
- logger.L(`W:`, fmt.Sprintf("%s=>%s %v", path, backArray[backI].Name, e))
- backArray[backI].Disable()
- if !errors.Is(e, ErrCopy) && ErrRedirect {
- w.Header().Set("Location", r.URL.String())
- w.WriteHeader(http.StatusTemporaryRedirect)
+ logger.Warn(`W:`, fmt.Sprintf("%s=>%s %v", path, backArray[backI].Name, e))
+ switch e {
+ case ErrCopy:
+ backArray[backI].Disable()
+ return
+ case ErrHeaderCheckFail:
+ w.WriteHeader(http.StatusForbidden)
+ return
+ default:
+ backArray[backI].Disable()
+ if ErrRedirect {
+ w.Header().Set("Location", r.URL.String())
+ w.WriteHeader(http.StatusTemporaryRedirect)
+ }
}
}
})
ErrHeaderCheckFail = errors.New("ErrHeaderCheckFail")
)
-func httpDealer(ctx context.Context, w http.ResponseWriter, r *http.Request, routePath string, back *Back, logger *plog.Log_interface) error {
+func httpDealer(ctx context.Context, w http.ResponseWriter, r *http.Request, routePath string, back *Back, logger Logger) error {
url := back.To
if back.PathAdd {
url += r.URL.String()
case `del`:
req.Header.Del(v.Key)
default:
- logger.L(`W:`, fmt.Sprintf("%s=>%s 无效ReqHeader %v", routePath, back.Name, v))
+ logger.Warn(`W:`, fmt.Sprintf("%s=>%s 无效ReqHeader %v", routePath, back.Name, v))
}
}
client := http.Client{}
case `del`:
w.Header().Del(v.Key)
default:
- logger.L(`W:`, fmt.Sprintf("%s=>%s 无效ResHeader %v", routePath, back.Name, v))
+ logger.Warn(`W:`, fmt.Sprintf("%s=>%s 无效ResHeader %v", routePath, back.Name, v))
}
}
defer resp.Body.Close()
if _, e = io.Copy(w, resp.Body); e != nil {
- logger.L(`E:`, fmt.Sprintf("%s=>%s %v", routePath, back.Name, e))
+ logger.Error(`E:`, fmt.Sprintf("%s=>%s %v", routePath, back.Name, e))
return ErrCopy
}
return nil
}
-func wsDealer(ctx context.Context, w http.ResponseWriter, r *http.Request, routePath string, back *Back, logger *plog.Log_interface) error {
+func wsDealer(ctx context.Context, w http.ResponseWriter, r *http.Request, routePath string, back *Back, logger Logger) error {
url := back.To
if back.PathAdd {
url += r.URL.String()
case `del`:
reqHeader.Del(v.Key)
default:
- logger.L(`W:`, fmt.Sprintf("%s=>%s 无效ReqHeader %v", routePath, back.Name, v))
+ logger.Warn(`W:`, fmt.Sprintf("%s=>%s 无效ReqHeader %v", routePath, back.Name, v))
}
}
if res, resp, e := websocket.DefaultDialer.Dial(url, reqHeader); e != nil {
case `del`:
resp.Header.Del(v.Key)
default:
- logger.L(`W:`, fmt.Sprintf("%s=>%s 无效ResHeader %v", routePath, back.Name, v))
+ logger.Warn(`W:`, fmt.Sprintf("%s=>%s 无效ResHeader %v", routePath, back.Name, v))
}
}
resc.Close()
}()
if e := <-fin; e != nil {
- logger.L(`E:`, fmt.Sprintf("%s=>%s %v", routePath, back.Name, e))
+ logger.Error(`E:`, fmt.Sprintf("%s=>%s %v", routePath, back.Name, e))
return ErrCopy
}
return nil
--- /dev/null
+-----BEGIN CERTIFICATE-----
+MIIDAzCCAeugAwIBAgIQbcQ26qWCtfHvKNO9C3rvqzANBgkqhkiG9w0BAQsFADAS
+MRAwDgYDVQQKEwdBY21lIENvMB4XDTIzMTIwOTA1NTc0MVoXDTI0MTIwODA1NTc0
+MVowEjEQMA4GA1UEChMHQWNtZSBDbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBAPerzWf6QgJGkTKdt5CzQ0ycaUcdr32EfwStrnpPZSkOvpftvSnS2OJu
+7/dD3dSrchnXF9EZgEqtLZCA1W3EBzQvbMjZsDBUQBTI0PEumBG8/hfaC4SA2LFH
+voogQnFjh0o4Tm/Hn5eefITBZtAQspBH/zvj4bx16nRsuh0G7LmGAl9w0OhsN8Hc
+05iImxmJUW2Jl1eKN1V7WilAs3GCRVxVJnsJZvyEFwLxq2xuGthgTpgwWzzl4na0
+mTksWI5ko+kLX9yD4g9/hB8FGJYiaUTI3htwZVNsLQHa7kdmLgpyRr+eBWObaf2T
+oTNb2fS5xGeRyvKVExMHZTvOHo86WoMCAwEAAaNVMFMwDgYDVR0PAQH/BAQDAgWg
+MBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwHgYDVR0RBBcwFYIT
+MTkyLjE2OC4zMS4xMDE6OTAwOTANBgkqhkiG9w0BAQsFAAOCAQEATZiyFEP5VV4w
+PNzgdPN51EKAIlxwuxDGv9U2Zr/Pr2Yd2XioHCvR3q6qn73NQUWSviFtB6XW8N5y
+S/RPEH+Kvi0S3/40l0yM7cmbr6nyC36gaVHNSFZKDB6b4f5rrABl7H4s0Mnr/oUx
+mYUXyPF9br++PD+UJm2W0JTlXH3D43IivuyVLaBo+bBXTV/FjsG/39BycICO0W2q
+gWEkz5K55W6gYKwaZ6MFdwqBjjrXhVxQeBCKe4IzSJ9U/xNKfuszJUKwnilcArXY
+nY0pWJ5e94Wjulr5nd/xPvC6eEXYRapkmfVS6glDfjz+PBgRIjjENZpR0/5g4cvT
+JfOL6RM0gw==
+-----END CERTIFICATE-----
--- /dev/null
+-----BEGIN PRIVATE KEY-----
+MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQD3q81n+kICRpEy
+nbeQs0NMnGlHHa99hH8Era56T2UpDr6X7b0p0tjibu/3Q93Uq3IZ1xfRGYBKrS2Q
+gNVtxAc0L2zI2bAwVEAUyNDxLpgRvP4X2guEgNixR76KIEJxY4dKOE5vx5+XnnyE
+wWbQELKQR/874+G8dep0bLodBuy5hgJfcNDobDfB3NOYiJsZiVFtiZdXijdVe1op
+QLNxgkVcVSZ7CWb8hBcC8atsbhrYYE6YMFs85eJ2tJk5LFiOZKPpC1/cg+IPf4Qf
+BRiWImlEyN4bcGVTbC0B2u5HZi4Kcka/ngVjm2n9k6EzW9n0ucRnkcrylRMTB2U7
+zh6POlqDAgMBAAECggEBALUZMdQS4Qtq8CbTvnMXMWGmiTCQG08rf/k6ynby8SRp
+fKH5G7WmUCKaPetO+7jTOFZ+uhKSlAWGxeeA3Q8rJJ1bBC+FRdjA8i6AfI+uo1Ft
+IVrtfDiCQnC25jN3zT2+KiHyNCB2FlM2dxRXmscPPpJTouT3B4vXqP1Ct4AcHSK1
+02ufVJaZGOxPwqlaYV1mQaUG9wh1O8/YJFfB5w36unh/I8DfosXjoAmMnjsgRXbD
+XbDlbzIHENrZ6hj2yMNxLeH2NjGxmGsCHBJqCnjWUOMSA1pHLiogB3+fep4wdrxn
+fNdffCaMclTp7M28JPp6qy06lnwhkkDDds2vKCJWUhkCgYEA/bfpIHurP1O+1qe2
+wskj5ETwkN7bEvO4yx1VsmIB/IgHdeHGSAbnzw1SDYBzNSe5sSTzr6HZryS7S8y2
+kXD1f+Qnk4Hm+VGVyvCCcLzKUnIByGXnHBIrAq7RoQ69HK+aCuIVOIm+FijI0FK6
+vVw1LdVV3NwDAYmBQigP75cg9QUCgYEA+eX4WnyGgj5+aID4ratF6xZFYMGlPeEh
+7kU+Ns7tOVt41jvf2aBiqqo8vZt4t5e4VRsNyY/T6p1EWVDeXgzY3szowUJFHbYN
+SRRofDW3RtCgFcQueRYvb9PIHEM0kS6UIDMBs0yp5OUMBf77y7qLNtiiRqgh7K94
+eWOY4r67p+cCgYEAzBZc23k/JgCKWQatl3/OdDcUP6RUGqmb8x6UqZn2uRj+z08e
+fR+45a90WlIB2jcrQphTwOpzPVRRqMZx8QopIIf5Yckzb0e2M3lFo8PpB2qXjoiR
+392pZU4UZ/aAHowOYES+By2djxuddR2nAt0iFc0udSsw69Kc/AdX0kUCCLUCgYB4
+OgXUMtjbzIkwaew6UY5f3eUe+cswDCIw6itWXxOOZs2p9EBsCVeu2BxE9ImNenb6
+qvtlH8dKtsLtXZS+Ftw3xMmuQN3Tv4SAxkrGh2lXroN2NV5Obzf/SxqZTlP6DTjC
+jQeiZZ3PO8sfD1/A0kyr5GmeKMG5h2okrKAfZrgNvQKBgQCHXfrCOAmR3SvmmIew
+YnUlIzSUMJL72jw9oPnTOde204YnqkDu/ZNMMta7WaAlfv7E31rfxxGBC8JaC2ko
+S44xAb/pdHn9UzX/64OcE22ftkldO51L2g+BruopMfOwZjCVGLdS5B7OJkFJ84oy
+L5sJ5Jm1T++wQZx5mPanipQfpg==
+-----END PRIVATE KEY-----
// 获取config路径
configP := flag.String("c", "main.json", "config")
testP := flag.Int("t", 0, "test port")
- _ = flag.Bool("q", true, "no warn,error log")
+ _ = flag.Bool("q", false, "no warn,error log")
flag.Parse()
// 日志初始化
var buf = make([]byte, 1<<16)
// 加载配置
- pfront.LoadPeriod(ctx, buf, configF, &configS, logger)
+ if e := pfront.LoadPeriod(ctx, buf, configF, &configS, logger); e != nil {
+ return
+ }
// 测试响应
- go pfront.Test(ctx, *testP, logger)
+ go pfront.Test(ctx, *testP, logger.Base("测试"))
- go pfront.Run(ctx, &configS, logger)
+ go pfront.Run(ctx, &configS, logger.Base("转发"))
// ctrl+c退出
var interrupt = make(chan os.Signal, 2)
{
"addr":"0.0.0.0:9009",
"tls": {
- "pub":"",
- "key":""
+ "pub":"cert.pem",
+ "key":"key.pem"
},
"matchRule": "prefix",
"routes":[
"path": "/1",
"errRedirect": true,
"back": [
- {
- "name": "test",
- "to": "http://127.0.0.1:13001",
- "weight": 1,
- "pathAdd": false,
- "errBanSec": 10,
- "resHeader":[
- {
- "action": "set",
- "key": "KEY",
- "value": "asf"
- }
- ]
- },
{
"name": "test",
"to": "http://127.0.0.1:13000",
{
"action": "set",
"key": "KEY",
- "value": "asf1"
+ "value": "asf"
}
]
}