mirror of
https://github.com/bolucat/Archive.git
synced 2025-12-24 13:28:37 +08:00
Update On Sat Jun 15 20:30:11 CEST 2024
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
"listen": "127.0.0.1:1234",
|
||||
"listen_type": "raw",
|
||||
"transport_type": "raw",
|
||||
"label": "relay1",
|
||||
"label": "iperf3",
|
||||
"tcp_remotes": ["0.0.0.0:5201"]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -116,7 +116,7 @@ func MustStartComponents(mainCtx context.Context, cfg *config.Config) {
|
||||
}()
|
||||
|
||||
if cfg.NeedStartWebServer() {
|
||||
webS, err := web.NewServer(cfg, rs, rs.Cmgr)
|
||||
webS, err := web.NewServer(cfg, rs, rs, rs.Cmgr)
|
||||
if err != nil {
|
||||
cliLogger.Fatalf("NewWebServer meet err=%s", err.Error())
|
||||
}
|
||||
|
||||
14
echo/internal/glue/interface.go
Normal file
14
echo/internal/glue/interface.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package glue
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
type Reloader interface {
|
||||
Reload(force bool) error
|
||||
}
|
||||
|
||||
type HealthChecker interface {
|
||||
// get relay by ID and check the connection health
|
||||
HealthCheck(ctx context.Context, RelayID string) error
|
||||
}
|
||||
19
echo/internal/relay/health_check.go
Normal file
19
echo/internal/relay/health_check.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package relay
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/Ehco1996/ehco/internal/glue"
|
||||
)
|
||||
|
||||
var _ glue.HealthChecker = (*Server)(nil)
|
||||
|
||||
func (r *Server) HealthCheck(ctx context.Context, relayID string) error {
|
||||
rs, ok := r.relayM.Load(relayID)
|
||||
if !ok {
|
||||
return fmt.Errorf("label for relay: %s not found,can not health check", relayID)
|
||||
}
|
||||
inner, _ := rs.(*Relay)
|
||||
return inner.relayServer.HealthCheck(ctx)
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
package relay
|
||||
|
||||
import (
|
||||
"github.com/Ehco1996/ehco/internal/glue"
|
||||
"github.com/Ehco1996/ehco/internal/relay/conf"
|
||||
"github.com/Ehco1996/ehco/internal/reloader"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// make sure Server implements the reloader.Reloader interface
|
||||
var _ reloader.Reloader = (*Server)(nil)
|
||||
var _ glue.Reloader = (*Server)(nil)
|
||||
|
||||
func (s *Server) Reload(force bool) error {
|
||||
// k:name v: *Config
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
package reloader
|
||||
|
||||
type Reloader interface {
|
||||
Reload(force bool) error
|
||||
}
|
||||
@@ -24,15 +24,21 @@ type baseTransporter struct {
|
||||
|
||||
cmgr cmgr.Cmgr
|
||||
tCPRemotes lb.RoundRobin
|
||||
relayer RelayClient
|
||||
}
|
||||
|
||||
func NewBaseTransporter(cfg *conf.Config, cmgr cmgr.Cmgr) *baseTransporter {
|
||||
func NewBaseTransporter(cfg *conf.Config, cmgr cmgr.Cmgr) (*baseTransporter, error) {
|
||||
relayer, err := newRelayClient(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &baseTransporter{
|
||||
cfg: cfg,
|
||||
cmgr: cmgr,
|
||||
tCPRemotes: cfg.ToTCPRemotes(),
|
||||
l: zap.S().Named(cfg.GetLoggerName()),
|
||||
}
|
||||
relayer: relayer,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (b *baseTransporter) GetTCPListenAddr() (*net.TCPAddr, error) {
|
||||
@@ -94,3 +100,7 @@ func (b *baseTransporter) RelayTCPConn(c net.Conn, handshakeF TCPHandShakeF) err
|
||||
defer b.cmgr.RemoveConnection(relayConn)
|
||||
return relayConn.Transport(remote.Label)
|
||||
}
|
||||
|
||||
func (b *baseTransporter) HealthCheck(ctx context.Context) error {
|
||||
return b.relayer.HealthCheck(ctx, b.GetRemote().Clone())
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package transporter
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/Ehco1996/ehco/internal/cmgr"
|
||||
@@ -12,39 +14,45 @@ import (
|
||||
type TCPHandShakeF func(remote *lb.Node) (net.Conn, error)
|
||||
|
||||
type RelayClient interface {
|
||||
HealthCheck(ctx context.Context, remote *lb.Node) error
|
||||
TCPHandShake(remote *lb.Node) (net.Conn, error)
|
||||
RelayTCPConn(c net.Conn, handshakeF TCPHandShakeF) error
|
||||
}
|
||||
|
||||
func newRelayClient(base *baseTransporter) (RelayClient, error) {
|
||||
switch base.cfg.TransportType {
|
||||
func newRelayClient(cfg *conf.Config) (RelayClient, error) {
|
||||
switch cfg.TransportType {
|
||||
case constant.RelayTypeRaw:
|
||||
return newRawClient(base)
|
||||
case constant.RelayTypeWS:
|
||||
return newWsClient(base)
|
||||
case constant.RelayTypeMWS:
|
||||
return newMwsClient(base)
|
||||
case constant.RelayTypeWSS:
|
||||
return newWssClient(base)
|
||||
case constant.RelayTypeMWSS:
|
||||
return newMwssClient(base)
|
||||
return newRawClient(cfg)
|
||||
case constant.RelayTypeMTCP:
|
||||
return newMtcpClient(base)
|
||||
return newMtcpClient(cfg)
|
||||
case constant.RelayTypeWS:
|
||||
return newWsClient(cfg)
|
||||
case constant.RelayTypeMWS:
|
||||
return newMwsClient(cfg)
|
||||
case constant.RelayTypeWSS:
|
||||
return newWssClient(cfg)
|
||||
case constant.RelayTypeMWSS:
|
||||
return newMwssClient(cfg)
|
||||
default:
|
||||
panic("unsupported transport type" + base.cfg.TransportType)
|
||||
return nil, fmt.Errorf("unsupported transport type" + cfg.TransportType)
|
||||
}
|
||||
}
|
||||
|
||||
type RelayServer interface {
|
||||
ListenAndServe() error
|
||||
Close() error
|
||||
HealthCheck(ctx context.Context) error
|
||||
}
|
||||
|
||||
func NewRelayServer(cfg *conf.Config, cmgr cmgr.Cmgr) (RelayServer, error) {
|
||||
base := NewBaseTransporter(cfg, cmgr)
|
||||
base, err := NewBaseTransporter(cfg, cmgr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch cfg.ListenType {
|
||||
case constant.RelayTypeRaw:
|
||||
return newRawServer(base)
|
||||
case constant.RelayTypeMTCP:
|
||||
return newMtcpServer(base)
|
||||
case constant.RelayTypeWS:
|
||||
return newWsServer(base)
|
||||
case constant.RelayTypeMWS:
|
||||
@@ -53,8 +61,6 @@ func NewRelayServer(cfg *conf.Config, cmgr cmgr.Cmgr) (RelayServer, error) {
|
||||
return newWssServer(base)
|
||||
case constant.RelayTypeMWSS:
|
||||
return newMwssServer(base)
|
||||
case constant.RelayTypeMTCP:
|
||||
return newMtcpServer(base)
|
||||
default:
|
||||
panic("unsupported transport type" + cfg.ListenType)
|
||||
}
|
||||
|
||||
@@ -2,12 +2,15 @@
|
||||
package transporter
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/Ehco1996/ehco/internal/constant"
|
||||
"github.com/Ehco1996/ehco/internal/metrics"
|
||||
"github.com/Ehco1996/ehco/internal/relay/conf"
|
||||
"github.com/Ehco1996/ehco/pkg/lb"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -16,15 +19,16 @@ var (
|
||||
)
|
||||
|
||||
type RawClient struct {
|
||||
*baseTransporter
|
||||
|
||||
dialer *net.Dialer
|
||||
cfg *conf.Config
|
||||
l *zap.SugaredLogger
|
||||
}
|
||||
|
||||
func newRawClient(base *baseTransporter) (*RawClient, error) {
|
||||
func newRawClient(cfg *conf.Config) (*RawClient, error) {
|
||||
r := &RawClient{
|
||||
baseTransporter: base,
|
||||
dialer: &net.Dialer{Timeout: constant.DialTimeOut},
|
||||
l: zap.S().Named("raw"),
|
||||
cfg: cfg,
|
||||
dialer: &net.Dialer{Timeout: constant.DialTimeOut},
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
@@ -41,11 +45,22 @@ func (raw *RawClient) TCPHandShake(remote *lb.Node) (net.Conn, error) {
|
||||
return rc, nil
|
||||
}
|
||||
|
||||
func (raw *RawClient) HealthCheck(ctx context.Context, remote *lb.Node) error {
|
||||
l := zap.S().Named("health-check")
|
||||
l.Infof("start send req to %s", remote.Address)
|
||||
c, err := raw.TCPHandShake(remote)
|
||||
if err != nil {
|
||||
l.Errorf("send req to %s meet error:%s", remote.Address, err)
|
||||
return err
|
||||
}
|
||||
c.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
type RawServer struct {
|
||||
*baseTransporter
|
||||
localTCPAddr *net.TCPAddr
|
||||
lis *net.TCPListener
|
||||
relayer RelayClient
|
||||
}
|
||||
|
||||
func newRawServer(base *baseTransporter) (*RawServer, error) {
|
||||
@@ -57,15 +72,10 @@ func newRawServer(base *baseTransporter) (*RawServer, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
relayer, err := newRelayClient(base)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &RawServer{
|
||||
lis: lis,
|
||||
baseTransporter: base,
|
||||
localTCPAddr: addr,
|
||||
relayer: relayer,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -6,8 +6,10 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/xtaci/smux"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/Ehco1996/ehco/internal/metrics"
|
||||
"github.com/Ehco1996/ehco/internal/relay/conf"
|
||||
"github.com/Ehco1996/ehco/pkg/lb"
|
||||
)
|
||||
|
||||
@@ -21,13 +23,13 @@ type MtcpClient struct {
|
||||
muxTP *smuxTransporter
|
||||
}
|
||||
|
||||
func newMtcpClient(base *baseTransporter) (*MtcpClient, error) {
|
||||
raw, err := newRawClient(base)
|
||||
func newMtcpClient(cfg *conf.Config) (*MtcpClient, error) {
|
||||
raw, err := newRawClient(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c := &MtcpClient{RawClient: raw}
|
||||
c.muxTP = NewSmuxTransporter(raw.l.Named("mtcp"), c.initNewSession)
|
||||
c.muxTP = NewSmuxTransporter(zap.S().Named("mtcp"), c.initNewSession)
|
||||
return c, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/Ehco1996/ehco/internal/conn"
|
||||
"github.com/Ehco1996/ehco/internal/constant"
|
||||
"github.com/Ehco1996/ehco/internal/metrics"
|
||||
"github.com/Ehco1996/ehco/internal/relay/conf"
|
||||
"github.com/Ehco1996/ehco/internal/web"
|
||||
"github.com/Ehco1996/ehco/pkg/lb"
|
||||
)
|
||||
@@ -23,15 +24,16 @@ var (
|
||||
)
|
||||
|
||||
type WsClient struct {
|
||||
*baseTransporter
|
||||
|
||||
dialer *ws.Dialer
|
||||
cfg *conf.Config
|
||||
l *zap.SugaredLogger
|
||||
}
|
||||
|
||||
func newWsClient(base *baseTransporter) (*WsClient, error) {
|
||||
func newWsClient(cfg *conf.Config) (*WsClient, error) {
|
||||
s := &WsClient{
|
||||
baseTransporter: base,
|
||||
dialer: &ws.Dialer{Timeout: constant.DialTimeOut},
|
||||
cfg: cfg,
|
||||
l: zap.S().Named(cfg.TransportType),
|
||||
dialer: &ws.Dialer{Timeout: constant.DialTimeOut},
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
@@ -53,12 +55,23 @@ func (s *WsClient) TCPHandShake(remote *lb.Node) (net.Conn, error) {
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (s *WsClient) HealthCheck(ctx context.Context, remote *lb.Node) error {
|
||||
l := zap.S().Named("health-check")
|
||||
l.Infof("start send req to %s", remote.Address)
|
||||
c, err := s.TCPHandShake(remote)
|
||||
if err != nil {
|
||||
l.Errorf("send req to %s meet error:%s", remote.Address, err)
|
||||
return err
|
||||
}
|
||||
c.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
type WsServer struct {
|
||||
*baseTransporter
|
||||
|
||||
e *echo.Echo
|
||||
httpServer *http.Server
|
||||
relayer RelayClient
|
||||
}
|
||||
|
||||
func newWsServer(base *baseTransporter) (*WsServer, error) {
|
||||
@@ -79,11 +92,6 @@ func newWsServer(base *baseTransporter) (*WsServer, error) {
|
||||
e.GET(base.cfg.GetWSHandShakePath(), echo.WrapHandler(http.HandlerFunc(s.HandleRequest)))
|
||||
|
||||
s.e = e
|
||||
relayer, err := newRelayClient(base)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.relayer = relayer
|
||||
return s, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"github.com/xtaci/smux"
|
||||
|
||||
"github.com/Ehco1996/ehco/internal/metrics"
|
||||
"github.com/Ehco1996/ehco/internal/relay/conf"
|
||||
"github.com/Ehco1996/ehco/pkg/lb"
|
||||
)
|
||||
|
||||
@@ -29,8 +30,8 @@ type MwsClient struct {
|
||||
muxTP *smuxTransporter
|
||||
}
|
||||
|
||||
func newMwsClient(base *baseTransporter) (*MwsClient, error) {
|
||||
wc, err := newWssClient(base)
|
||||
func newMwsClient(cfg *conf.Config) (*MwsClient, error) {
|
||||
wc, err := newWssClient(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package transporter
|
||||
|
||||
import (
|
||||
"github.com/Ehco1996/ehco/internal/relay/conf"
|
||||
mytls "github.com/Ehco1996/ehco/internal/tls"
|
||||
)
|
||||
|
||||
@@ -13,8 +14,8 @@ type WssClient struct {
|
||||
*WsClient
|
||||
}
|
||||
|
||||
func newWssClient(base *baseTransporter) (*WssClient, error) {
|
||||
wc, err := newWsClient(base)
|
||||
func newWssClient(cfg *conf.Config) (*WssClient, error) {
|
||||
wc, err := newWsClient(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"github.com/xtaci/smux"
|
||||
|
||||
"github.com/Ehco1996/ehco/internal/metrics"
|
||||
"github.com/Ehco1996/ehco/internal/relay/conf"
|
||||
"github.com/Ehco1996/ehco/pkg/lb"
|
||||
)
|
||||
|
||||
@@ -29,8 +30,8 @@ type MwssClient struct {
|
||||
muxTP *smuxTransporter
|
||||
}
|
||||
|
||||
func newMwssClient(base *baseTransporter) (*MwssClient, error) {
|
||||
wc, err := newWssClient(base)
|
||||
func newMwssClient(cfg *conf.Config) (*MwssClient, error) {
|
||||
wc, err := newWssClient(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
const defaultPageSize = 10
|
||||
const defaultPageSize = 20
|
||||
|
||||
func MakeIndexF() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -51,13 +51,15 @@ func (s *Server) HandleClashProxyProvider(c echo.Context) error {
|
||||
}
|
||||
|
||||
func (s *Server) handleClashProxyProvider(c echo.Context, subName string, grouped bool) error {
|
||||
if s.relayServerReloader != nil {
|
||||
if err := s.relayServerReloader.Reload(true); err != nil {
|
||||
if s.Reloader != nil {
|
||||
if err := s.Reloader.Reload(true); err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
} else {
|
||||
s.l.Debugf("relayServerReloader is nil this should not happen")
|
||||
s.l.Debugf("Reloader is nil this should not happen")
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "should not happen error happen :)")
|
||||
}
|
||||
|
||||
clashSubList, err := s.cfg.GetClashSubList()
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
|
||||
@@ -81,11 +83,10 @@ func (s *Server) handleClashProxyProvider(c echo.Context, subName string, groupe
|
||||
}
|
||||
|
||||
func (s *Server) HandleReload(c echo.Context) error {
|
||||
if s.relayServerReloader == nil {
|
||||
if s.Reloader == nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "reload not support")
|
||||
}
|
||||
|
||||
err := s.relayServerReloader.Reload(true)
|
||||
err := s.Reloader.Reload(true)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
@@ -97,6 +98,18 @@ func (s *Server) HandleReload(c echo.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Server) HandleHealthCheck(c echo.Context) error {
|
||||
relayLabel := c.QueryParam("relay_label")
|
||||
if relayLabel == "" {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "relay_label is required")
|
||||
}
|
||||
if err := s.HealthCheck(c.Request().Context(), relayLabel); err != nil {
|
||||
res := CommonResp{Message: err.Error()}
|
||||
return c.JSON(http.StatusBadRequest, res)
|
||||
}
|
||||
return c.JSON(http.StatusOK, CommonResp{Message: "connect success"})
|
||||
}
|
||||
|
||||
func (s *Server) CurrentConfig(c echo.Context) error {
|
||||
ret, err := json.Marshal(s.cfg)
|
||||
if err != nil {
|
||||
|
||||
@@ -17,21 +17,23 @@ import (
|
||||
|
||||
"github.com/Ehco1996/ehco/internal/cmgr"
|
||||
"github.com/Ehco1996/ehco/internal/config"
|
||||
"github.com/Ehco1996/ehco/internal/glue"
|
||||
"github.com/Ehco1996/ehco/internal/metrics"
|
||||
"github.com/Ehco1996/ehco/internal/reloader"
|
||||
)
|
||||
|
||||
//go:embed templates/*.html
|
||||
var templatesFS embed.FS
|
||||
|
||||
type Server struct {
|
||||
glue.Reloader
|
||||
glue.HealthChecker
|
||||
|
||||
e *echo.Echo
|
||||
addr string
|
||||
l *zap.SugaredLogger
|
||||
cfg *config.Config
|
||||
|
||||
relayServerReloader reloader.Reloader
|
||||
connMgr cmgr.Cmgr
|
||||
connMgr cmgr.Cmgr
|
||||
}
|
||||
|
||||
type echoTemplate struct {
|
||||
@@ -42,7 +44,11 @@ func (t *echoTemplate) Render(w io.Writer, name string, data interface{}, c echo
|
||||
return t.templates.ExecuteTemplate(w, name, data)
|
||||
}
|
||||
|
||||
func NewServer(cfg *config.Config, relayReloader reloader.Reloader, connMgr cmgr.Cmgr) (*Server, error) {
|
||||
func NewServer(
|
||||
cfg *config.Config,
|
||||
relayReloader glue.Reloader,
|
||||
healthChecker glue.HealthChecker,
|
||||
connMgr cmgr.Cmgr) (*Server, error) {
|
||||
l := zap.S().Named("web")
|
||||
|
||||
templates := template.Must(template.ParseFS(templatesFS, "templates/*.html"))
|
||||
@@ -79,12 +85,14 @@ func NewServer(cfg *config.Config, relayReloader reloader.Reloader, connMgr cmgr
|
||||
return nil, err
|
||||
}
|
||||
s := &Server{
|
||||
e: e,
|
||||
l: l,
|
||||
cfg: cfg,
|
||||
connMgr: connMgr,
|
||||
relayServerReloader: relayReloader,
|
||||
addr: net.JoinHostPort(cfg.WebHost, fmt.Sprintf("%d", cfg.WebPort)),
|
||||
Reloader: relayReloader,
|
||||
HealthChecker: healthChecker,
|
||||
|
||||
e: e,
|
||||
l: l,
|
||||
cfg: cfg,
|
||||
connMgr: connMgr,
|
||||
addr: net.JoinHostPort(cfg.WebHost, fmt.Sprintf("%d", cfg.WebPort)),
|
||||
}
|
||||
|
||||
// register handler
|
||||
@@ -99,7 +107,7 @@ func NewServer(cfg *config.Config, relayReloader reloader.Reloader, connMgr cmgr
|
||||
api := e.Group("/api/v1")
|
||||
api.GET("/config/", s.CurrentConfig)
|
||||
api.POST("/config/reload/", s.HandleReload)
|
||||
|
||||
api.GET("/health_check/", s.HandleHealthCheck)
|
||||
return s, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/1.0.0/css/bulma.min.css">
|
||||
<meta name="description" content="ehco web">
|
||||
<meta name="keywords" content="ehco-relay">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/1.0.1/css/bulma.min.css">
|
||||
<title>Connections</title>
|
||||
</head>
|
||||
<body>
|
||||
@@ -57,9 +59,9 @@
|
||||
{{if gt .CurrentPage 1}}
|
||||
<li><a class="pagination-link" href="?conn_type={{.ConnType}}&page=1&page_size={{.PageSize}}">1</a></li>
|
||||
{{end}}
|
||||
<li><span class="pagination-ellipsis">…</span></li>
|
||||
<li><span class="pagination-ellipsis">…</span></li>
|
||||
<li><a class="pagination-link is-current" aria-label="Page {{.CurrentPage}}" aria-current="page">{{.CurrentPage}}</a></li>
|
||||
<li><span class="pagination-ellipsis">…</span></li>
|
||||
<li><span class="pagination-ellipsis">…</span></li>
|
||||
{{if lt .CurrentPage .TotalPage}}
|
||||
<li><a class="pagination-link" href="?conn_type={{.ConnType}}&page={{.TotalPage}}&page_size={{.PageSize}}">{{.TotalPage}}</a></li>
|
||||
{{end}}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="description" content="ehco web" />
|
||||
<meta name="keywords" content="ehco-relay" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
@@ -18,7 +20,6 @@
|
||||
<h1 class="title has-text-centered">
|
||||
ehco is a network relay tool and a typo :)
|
||||
</h1>
|
||||
|
||||
<!-- Build Info Card -->
|
||||
<div class="card">
|
||||
<header class="card-header">
|
||||
@@ -38,7 +39,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Stylish Links Card -->
|
||||
<div class="card">
|
||||
<header class="card-header">
|
||||
@@ -82,7 +82,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- Clash Providers card -->
|
||||
{{if .SubConfigs}}
|
||||
{{ if .SubConfigs }}
|
||||
<div class="card">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title has-text-centered">
|
||||
@@ -92,7 +92,7 @@
|
||||
<div class="card-content">
|
||||
<div class="content">
|
||||
<ul>
|
||||
{{range .SubConfigs}}
|
||||
{{ range .SubConfigs }}
|
||||
<li>
|
||||
<a
|
||||
class="button is-info is-light"
|
||||
@@ -108,12 +108,11 @@
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
{{end}}
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
{{ end }}
|
||||
<!-- Reload Config Button -->
|
||||
<div class="has-text-centered">
|
||||
<button
|
||||
@@ -125,7 +124,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<div class="hero-foot">
|
||||
<footer class="footer">
|
||||
@@ -137,7 +135,6 @@
|
||||
</footer>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
$("#reloadButton").click(function () {
|
||||
|
||||
5
echo/internal/web/types.go
Normal file
5
echo/internal/web/types.go
Normal file
@@ -0,0 +1,5 @@
|
||||
package web
|
||||
|
||||
type CommonResp struct {
|
||||
Message string `json:"msg"`
|
||||
}
|
||||
Reference in New Issue
Block a user