Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2a1f949c13 | ||
|
|
959e274063 | ||
|
|
b6a2bd37b1 | ||
|
|
3e60c9913a | ||
|
|
fd7f3f4029 | ||
|
|
2705a5d444 | ||
|
|
556055cfcb | ||
|
|
67a0d06944 |
@@ -54,10 +54,11 @@ function build() {
|
|||||||
cp -R "$ROOT"/www "$DIST"/
|
cp -R "$ROOT"/www "$DIST"/
|
||||||
cp -R "$ROOT"/pages "$DIST"/
|
cp -R "$ROOT"/pages "$DIST"/
|
||||||
|
|
||||||
# we support TOA on linux/amd64 only
|
# we support TOA on linux only
|
||||||
if [ "$OS" == "linux" ] && [ "$ARCH" == "amd64" ]
|
if [ "$OS" == "linux" ] && [ -f "${ROOT}/edge-toa/edge-toa-${ARCH}" ]
|
||||||
then
|
then
|
||||||
cp -R "$ROOT"/edge-toa "$DIST"
|
mkdir "$DIST/edge-toa"
|
||||||
|
cp "${ROOT}/edge-toa/edge-toa-${ARCH}" "$DIST/edge-toa/edge-toa"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "building ..."
|
echo "building ..."
|
||||||
|
|||||||
Binary file not shown.
@@ -1,7 +1,7 @@
|
|||||||
package teaconst
|
package teaconst
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Version = "1.2.2"
|
Version = "1.2.3"
|
||||||
|
|
||||||
ProductName = "Edge Node"
|
ProductName = "Edge Node"
|
||||||
ProcessName = "edge-node"
|
ProcessName = "edge-node"
|
||||||
|
|||||||
@@ -129,9 +129,8 @@ func (this *ClientConn) Read(b []byte) (n int, err error) {
|
|||||||
// 检测是否为超时错误
|
// 检测是否为超时错误
|
||||||
var isTimeout = err != nil && os.IsTimeout(err)
|
var isTimeout = err != nil && os.IsTimeout(err)
|
||||||
var isHandshakeError = isTimeout && !this.hasRead
|
var isHandshakeError = isTimeout && !this.hasRead
|
||||||
if isTimeout {
|
|
||||||
_ = this.SetLinger(0)
|
if err != nil {
|
||||||
} else {
|
|
||||||
_ = this.SetLinger(nodeconfigs.DefaultTCPLinger)
|
_ = this.SetLinger(nodeconfigs.DefaultTCPLinger)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
"github.com/TeaOSLab/EdgeNode/internal/goman"
|
"github.com/TeaOSLab/EdgeNode/internal/goman"
|
||||||
"github.com/TeaOSLab/EdgeNode/internal/remotelogs"
|
|
||||||
"github.com/pires/go-proxyproto"
|
"github.com/pires/go-proxyproto"
|
||||||
"golang.org/x/net/http2"
|
"golang.org/x/net/http2"
|
||||||
"net"
|
"net"
|
||||||
@@ -132,14 +131,8 @@ func (this *HTTPClientPool) Client(req *HTTPRequest,
|
|||||||
var transport = &HTTPClientTransport{
|
var transport = &HTTPClientTransport{
|
||||||
Transport: &http.Transport{
|
Transport: &http.Transport{
|
||||||
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
|
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||||
// 支持TOA的连接
|
|
||||||
conn, err := this.handleTOA(req, ctx, network, originAddr, connectionTimeout)
|
|
||||||
if conn != nil || err != nil {
|
|
||||||
return conn, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 普通的连接
|
// 普通的连接
|
||||||
conn, err = (&net.Dialer{
|
conn, err := (&net.Dialer{
|
||||||
Timeout: connectionTimeout,
|
Timeout: connectionTimeout,
|
||||||
KeepAlive: 1 * time.Minute,
|
KeepAlive: 1 * time.Minute,
|
||||||
}).DialContext(ctx, network, originAddr)
|
}).DialContext(ctx, network, originAddr)
|
||||||
@@ -215,38 +208,6 @@ func (this *HTTPClientPool) cleanClients() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 支持TOA
|
|
||||||
func (this *HTTPClientPool) handleTOA(req *HTTPRequest, ctx context.Context, network string, originAddr string, connectionTimeout time.Duration) (net.Conn, error) {
|
|
||||||
// TODO 每个服务读取自身所属集群的TOA设置
|
|
||||||
var toaConfig = sharedTOAManager.Config()
|
|
||||||
if toaConfig != nil && toaConfig.IsOn {
|
|
||||||
var retries = 3
|
|
||||||
for i := 1; i <= retries; i++ {
|
|
||||||
var port = int(toaConfig.RandLocalPort())
|
|
||||||
// TODO 思考是否支持X-Real-IP/X-Forwarded-IP
|
|
||||||
err := sharedTOAManager.SendMsg("add:" + strconv.Itoa(port) + ":" + req.requestRemoteAddr(true))
|
|
||||||
if err != nil {
|
|
||||||
remotelogs.Error("TOA", "add failed: "+err.Error())
|
|
||||||
} else {
|
|
||||||
dialer := net.Dialer{
|
|
||||||
Timeout: connectionTimeout,
|
|
||||||
KeepAlive: 1 * time.Minute,
|
|
||||||
LocalAddr: &net.TCPAddr{
|
|
||||||
Port: port,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
conn, err := dialer.DialContext(ctx, network, originAddr)
|
|
||||||
// TODO 需要在合适的时机删除TOA记录
|
|
||||||
if err == nil || i == retries {
|
|
||||||
return conn, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 支持PROXY Protocol
|
// 支持PROXY Protocol
|
||||||
func (this *HTTPClientPool) handlePROXYProtocol(conn net.Conn, req *HTTPRequest, proxyProtocol *serverconfigs.ProxyProtocolConfig) error {
|
func (this *HTTPClientPool) handlePROXYProtocol(conn net.Conn, req *HTTPRequest, proxyProtocol *serverconfigs.ProxyProtocolConfig) error {
|
||||||
if proxyProtocol != nil && proxyProtocol.IsOn && (proxyProtocol.Version == serverconfigs.ProxyProtocolVersion1 || proxyProtocol.Version == serverconfigs.ProxyProtocolVersion2) {
|
if proxyProtocol != nil && proxyProtocol.IsOn && (proxyProtocol.Version == serverconfigs.ProxyProtocolVersion1 || proxyProtocol.Version == serverconfigs.ProxyProtocolVersion2) {
|
||||||
|
|||||||
@@ -38,8 +38,13 @@ func (this *HTTPRequest) doCacheRead(useStale bool) (shouldStop bool) {
|
|||||||
|
|
||||||
// 添加 X-Cache Header
|
// 添加 X-Cache Header
|
||||||
var addStatusHeader = this.web.Cache.AddStatusHeader
|
var addStatusHeader = this.web.Cache.AddStatusHeader
|
||||||
|
var cacheBypassDescription = ""
|
||||||
if addStatusHeader {
|
if addStatusHeader {
|
||||||
defer func() {
|
defer func() {
|
||||||
|
if len(cacheBypassDescription) > 0 {
|
||||||
|
this.writer.Header().Set("X-Cache", cacheBypassDescription)
|
||||||
|
return
|
||||||
|
}
|
||||||
var cacheStatus = this.varMapping["cache.status"]
|
var cacheStatus = this.varMapping["cache.status"]
|
||||||
if cacheStatus != "HIT" {
|
if cacheStatus != "HIT" {
|
||||||
this.writer.Header().Set("X-Cache", cacheStatus)
|
this.writer.Header().Set("X-Cache", cacheStatus)
|
||||||
@@ -94,6 +99,7 @@ func (this *HTTPRequest) doCacheRead(useStale bool) (shouldStop bool) {
|
|||||||
// 校验请求
|
// 校验请求
|
||||||
if !this.cacheRef.MatchRequest(this.RawReq) {
|
if !this.cacheRef.MatchRequest(this.RawReq) {
|
||||||
this.cacheRef = nil
|
this.cacheRef = nil
|
||||||
|
cacheBypassDescription = "BYPASS, not match"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,6 +112,7 @@ func (this *HTTPRequest) doCacheRead(useStale bool) (shouldStop bool) {
|
|||||||
if this.cacheRef.EnableRequestCachePragma {
|
if this.cacheRef.EnableRequestCachePragma {
|
||||||
if this.RawReq.Header.Get("Cache-Control") == "no-cache" || this.RawReq.Header.Get("Pragma") == "no-cache" {
|
if this.RawReq.Header.Get("Cache-Control") == "no-cache" || this.RawReq.Header.Get("Pragma") == "no-cache" {
|
||||||
this.cacheRef = nil
|
this.cacheRef = nil
|
||||||
|
cacheBypassDescription = "BYPASS, Cache-Control or Pragma"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -119,6 +126,7 @@ func (this *HTTPRequest) doCacheRead(useStale bool) (shouldStop bool) {
|
|||||||
var key = this.Format(this.cacheRef.Key)
|
var key = this.Format(this.cacheRef.Key)
|
||||||
if len(key) == 0 {
|
if len(key) == 0 {
|
||||||
this.cacheRef = nil
|
this.cacheRef = nil
|
||||||
|
cacheBypassDescription = "BYPASS, empty key"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var method = this.Method()
|
var method = this.Method()
|
||||||
@@ -134,6 +142,7 @@ func (this *HTTPRequest) doCacheRead(useStale bool) (shouldStop bool) {
|
|||||||
var storage = caches.SharedManager.FindStorageWithPolicy(cachePolicy.Id)
|
var storage = caches.SharedManager.FindStorageWithPolicy(cachePolicy.Id)
|
||||||
if storage == nil {
|
if storage == nil {
|
||||||
this.cacheRef = nil
|
this.cacheRef = nil
|
||||||
|
cacheBypassDescription = "BYPASS, no policy found"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.writer.cacheStorage = storage
|
this.writer.cacheStorage = storage
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (this *HTTPRequest) doCheckUserAgent() (shouldStop bool) {
|
func (this *HTTPRequest) doCheckUserAgent() (shouldStop bool) {
|
||||||
if this.web.UserAgent == nil {
|
if this.web.UserAgent == nil || !this.web.UserAgent.IsOn {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,3 +15,7 @@ func (this *Node) reloadIPLibrary() {
|
|||||||
func (this *Node) notifyPlusChange() error {
|
func (this *Node) notifyPlusChange() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *Node) execTOAChangedTask() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -90,6 +90,8 @@ func (this *Node) execTask(rpcClient *rpc.RPCClient, task *pb.NodeTask) error {
|
|||||||
err = this.execUpdatingServersTask(rpcClient)
|
err = this.execUpdatingServersTask(rpcClient)
|
||||||
case "plusChanged":
|
case "plusChanged":
|
||||||
err = this.notifyPlusChange()
|
err = this.notifyPlusChange()
|
||||||
|
case "toaChanged":
|
||||||
|
err = this.execTOAChangedTask()
|
||||||
default:
|
default:
|
||||||
remotelogs.Error("NODE", "task '"+types.String(task.Id)+"', type '"+task.Type+"' has not been handled")
|
remotelogs.Error("NODE", "task '"+types.String(task.Id)+"', type '"+task.Type+"' has not been handled")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,117 +1,31 @@
|
|||||||
|
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
//go:build !plus
|
||||||
|
|
||||||
package nodes
|
package nodes
|
||||||
|
|
||||||
import (
|
import "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||||
"errors"
|
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
|
||||||
teaconst "github.com/TeaOSLab/EdgeNode/internal/const"
|
|
||||||
"github.com/TeaOSLab/EdgeNode/internal/events"
|
|
||||||
"github.com/TeaOSLab/EdgeNode/internal/goman"
|
|
||||||
"github.com/TeaOSLab/EdgeNode/internal/remotelogs"
|
|
||||||
executils "github.com/TeaOSLab/EdgeNode/internal/utils/exec"
|
|
||||||
"github.com/iwind/TeaGo/Tea"
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
var sharedTOAManager = NewTOAManager()
|
var sharedTOAManager = NewTOAManager()
|
||||||
|
|
||||||
func init() {
|
|
||||||
if !teaconst.IsMain {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
events.On(events.EventReload, func() {
|
|
||||||
err := sharedTOAManager.Run(sharedNodeConfig.TOA)
|
|
||||||
if err != nil {
|
|
||||||
remotelogs.Error("TOA", err.Error())
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
type TOAManager struct {
|
type TOAManager struct {
|
||||||
config *nodeconfigs.TOAConfig
|
|
||||||
pid int
|
|
||||||
conn net.Conn
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTOAManager() *TOAManager {
|
func NewTOAManager() *TOAManager {
|
||||||
return &TOAManager{}
|
return &TOAManager{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *TOAManager) Run(config *nodeconfigs.TOAConfig) error {
|
func (this *TOAManager) Apply(config *nodeconfigs.TOAConfig) error {
|
||||||
this.config = config
|
|
||||||
|
|
||||||
if this.pid > 0 {
|
|
||||||
remotelogs.Println("TOA", "stopping ...")
|
|
||||||
err := this.Quit()
|
|
||||||
if err != nil {
|
|
||||||
remotelogs.Error("TOA", "quit error: "+err.Error())
|
|
||||||
}
|
|
||||||
if this.conn != nil {
|
|
||||||
_ = this.conn.Close()
|
|
||||||
}
|
|
||||||
this.conn = nil
|
|
||||||
this.pid = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
if !config.IsOn {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
binPath := Tea.Root + "/edge-toa/edge-toa" // TODO 可以做成配置
|
|
||||||
_, err := os.Stat(binPath)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
remotelogs.Println("TOA", "starting ...")
|
|
||||||
remotelogs.Println("TOA", "args: "+strings.Join(config.AsArgs(), " "))
|
|
||||||
cmd := executils.NewCmd(binPath, config.AsArgs()...)
|
|
||||||
err = cmd.Start()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
var process = cmd.Process()
|
|
||||||
if process == nil {
|
|
||||||
return errors.New("start failed")
|
|
||||||
}
|
|
||||||
this.pid = process.Pid
|
|
||||||
|
|
||||||
goman.New(func() {
|
|
||||||
_ = cmd.Wait()
|
|
||||||
})
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *TOAManager) Config() *nodeconfigs.TOAConfig {
|
func (this *TOAManager) Config() *nodeconfigs.TOAConfig {
|
||||||
return this.config
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *TOAManager) Quit() error {
|
func (this *TOAManager) Quit() error {
|
||||||
return this.SendMsg("quit:0")
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *TOAManager) SendMsg(msg string) error {
|
func (this *TOAManager) SendMsg(msg string) error {
|
||||||
if this.config == nil {
|
return nil
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if this.conn != nil {
|
|
||||||
_, err := this.conn.Write([]byte(msg + "\n"))
|
|
||||||
if err != nil {
|
|
||||||
_ = this.conn.Close()
|
|
||||||
this.conn = nil
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
conn, err := net.DialTimeout("unix", this.config.SockFile(), 1*time.Second)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
this.conn = conn
|
|
||||||
_, err = this.conn.Write([]byte(msg + "\n"))
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
package nodes
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestTOAManager_Run(t *testing.T) {
|
|
||||||
manager := NewTOAManager()
|
|
||||||
err := manager.Run(&nodeconfigs.TOAConfig{
|
|
||||||
IsOn: true,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
t.Log("ok")
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user