mirror of https://github.com/fatedier/frp.git
added a 30s timeout for frpc subcommands to avoid long delays (#4359)
This commit is contained in:
parent
e8045194cd
commit
ae73ec2fed
|
@ -9,11 +9,6 @@
|
|||
|
||||
<h3 align="center">Gold Sponsors</h3>
|
||||
<!--gold sponsors start-->
|
||||
<p align="center">
|
||||
<a href="https://lokal.so/?utm_campaign=github_repo&utm_medium=referral&utm_content=frp&utm_source=github" target="_blank">
|
||||
<img width="420px" src="https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/sponsor_lokal.png">
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://workos.com/?utm_campaign=github_repo&utm_medium=referral&utm_content=frp&utm_source=github" target="_blank">
|
||||
<img width="420px" src="https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/sponsor_workos.png">
|
||||
|
|
|
@ -11,11 +11,6 @@ frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP
|
|||
|
||||
<h3 align="center">Gold Sponsors</h3>
|
||||
<!--gold sponsors start-->
|
||||
<p align="center">
|
||||
<a href="https://lokal.so/?utm_campaign=github_repo&utm_medium=referral&utm_content=frp&utm_source=github" target="_blank">
|
||||
<img width="420px" src="https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/sponsor_lokal.png">
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://workos.com/?utm_campaign=github_repo&utm_medium=referral&utm_content=frp&utm_source=github" target="_blank">
|
||||
<img width="420px" src="https://raw.githubusercontent.com/fatedier/frp/dev/doc/pic/sponsor_workos.png">
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
### Features
|
||||
|
||||
* Added a new plugin `tls2raw`: Enables TLS termination and forwarding of decrypted raw traffic to local service.
|
||||
* Added a default timeout of 30 seconds for the frpc subcommands to prevent commands from being stuck for a long time due to network issues.
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fixed the issue that when `loginFailExit = false`, the frpc stop command cannot be stopped correctly if the server is not successfully connected after startup.
|
||||
|
|
|
@ -15,9 +15,11 @@
|
|||
package sub
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/rodaine/table"
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -27,24 +29,24 @@ import (
|
|||
clientsdk "github.com/fatedier/frp/pkg/sdk/client"
|
||||
)
|
||||
|
||||
var adminAPITimeout = 30 * time.Second
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(NewAdminCommand(
|
||||
"reload",
|
||||
"Hot-Reload frpc configuration",
|
||||
ReloadHandler,
|
||||
))
|
||||
commands := []struct {
|
||||
name string
|
||||
description string
|
||||
handler func(*v1.ClientCommonConfig) error
|
||||
}{
|
||||
{"reload", "Hot-Reload frpc configuration", ReloadHandler},
|
||||
{"status", "Overview of all proxies status", StatusHandler},
|
||||
{"stop", "Stop the running frpc", StopHandler},
|
||||
}
|
||||
|
||||
rootCmd.AddCommand(NewAdminCommand(
|
||||
"status",
|
||||
"Overview of all proxies status",
|
||||
StatusHandler,
|
||||
))
|
||||
|
||||
rootCmd.AddCommand(NewAdminCommand(
|
||||
"stop",
|
||||
"Stop the running frpc",
|
||||
StopHandler,
|
||||
))
|
||||
for _, cmdConfig := range commands {
|
||||
cmd := NewAdminCommand(cmdConfig.name, cmdConfig.description, cmdConfig.handler)
|
||||
cmd.Flags().DurationVar(&adminAPITimeout, "api-timeout", adminAPITimeout, "Timeout for admin API calls")
|
||||
rootCmd.AddCommand(cmd)
|
||||
}
|
||||
}
|
||||
|
||||
func NewAdminCommand(name, short string, handler func(*v1.ClientCommonConfig) error) *cobra.Command {
|
||||
|
@ -73,7 +75,9 @@ func NewAdminCommand(name, short string, handler func(*v1.ClientCommonConfig) er
|
|||
func ReloadHandler(clientCfg *v1.ClientCommonConfig) error {
|
||||
client := clientsdk.New(clientCfg.WebServer.Addr, clientCfg.WebServer.Port)
|
||||
client.SetAuth(clientCfg.WebServer.User, clientCfg.WebServer.Password)
|
||||
if err := client.Reload(strictConfigMode); err != nil {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), adminAPITimeout)
|
||||
defer cancel()
|
||||
if err := client.Reload(ctx, strictConfigMode); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("reload success")
|
||||
|
@ -83,7 +87,9 @@ func ReloadHandler(clientCfg *v1.ClientCommonConfig) error {
|
|||
func StatusHandler(clientCfg *v1.ClientCommonConfig) error {
|
||||
client := clientsdk.New(clientCfg.WebServer.Addr, clientCfg.WebServer.Port)
|
||||
client.SetAuth(clientCfg.WebServer.User, clientCfg.WebServer.Password)
|
||||
res, err := client.GetAllProxyStatus()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), adminAPITimeout)
|
||||
defer cancel()
|
||||
res, err := client.GetAllProxyStatus(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -109,7 +115,9 @@ func StatusHandler(clientCfg *v1.ClientCommonConfig) error {
|
|||
func StopHandler(clientCfg *v1.ClientCommonConfig) error {
|
||||
client := clientsdk.New(clientCfg.WebServer.Addr, clientCfg.WebServer.Port)
|
||||
client.SetAuth(clientCfg.WebServer.User, clientCfg.WebServer.Password)
|
||||
if err := client.Stop(); err != nil {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), adminAPITimeout)
|
||||
defer cancel()
|
||||
if err := client.Stop(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("stop success")
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
|
@ -31,8 +32,8 @@ func (c *Client) SetAuth(user, pwd string) {
|
|||
c.authPwd = pwd
|
||||
}
|
||||
|
||||
func (c *Client) GetProxyStatus(name string) (*client.ProxyStatusResp, error) {
|
||||
req, err := http.NewRequest("GET", "http://"+c.address+"/api/status", nil)
|
||||
func (c *Client) GetProxyStatus(ctx context.Context, name string) (*client.ProxyStatusResp, error) {
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", "http://"+c.address+"/api/status", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -54,8 +55,8 @@ func (c *Client) GetProxyStatus(name string) (*client.ProxyStatusResp, error) {
|
|||
return nil, fmt.Errorf("no proxy status found")
|
||||
}
|
||||
|
||||
func (c *Client) GetAllProxyStatus() (client.StatusResp, error) {
|
||||
req, err := http.NewRequest("GET", "http://"+c.address+"/api/status", nil)
|
||||
func (c *Client) GetAllProxyStatus(ctx context.Context) (client.StatusResp, error) {
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", "http://"+c.address+"/api/status", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -70,7 +71,7 @@ func (c *Client) GetAllProxyStatus() (client.StatusResp, error) {
|
|||
return allStatus, nil
|
||||
}
|
||||
|
||||
func (c *Client) Reload(strictMode bool) error {
|
||||
func (c *Client) Reload(ctx context.Context, strictMode bool) error {
|
||||
v := url.Values{}
|
||||
if strictMode {
|
||||
v.Set("strictConfig", "true")
|
||||
|
@ -79,7 +80,7 @@ func (c *Client) Reload(strictMode bool) error {
|
|||
if len(v) > 0 {
|
||||
queryStr = "?" + v.Encode()
|
||||
}
|
||||
req, err := http.NewRequest("GET", "http://"+c.address+"/api/reload"+queryStr, nil)
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", "http://"+c.address+"/api/reload"+queryStr, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -87,8 +88,8 @@ func (c *Client) Reload(strictMode bool) error {
|
|||
return err
|
||||
}
|
||||
|
||||
func (c *Client) Stop() error {
|
||||
req, err := http.NewRequest("POST", "http://"+c.address+"/api/stop", nil)
|
||||
func (c *Client) Stop(ctx context.Context) error {
|
||||
req, err := http.NewRequestWithContext(ctx, "POST", "http://"+c.address+"/api/stop", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -96,16 +97,16 @@ func (c *Client) Stop() error {
|
|||
return err
|
||||
}
|
||||
|
||||
func (c *Client) GetConfig() (string, error) {
|
||||
req, err := http.NewRequest("GET", "http://"+c.address+"/api/config", nil)
|
||||
func (c *Client) GetConfig(ctx context.Context) (string, error) {
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", "http://"+c.address+"/api/config", nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return c.do(req)
|
||||
}
|
||||
|
||||
func (c *Client) UpdateConfig(content string) error {
|
||||
req, err := http.NewRequest("PUT", "http://"+c.address+"/api/config", strings.NewReader(content))
|
||||
func (c *Client) UpdateConfig(ctx context.Context, content string) error {
|
||||
req, err := http.NewRequestWithContext(ctx, "PUT", "http://"+c.address+"/api/config", strings.NewReader(content))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
package version
|
||||
|
||||
var version = "0.59.0"
|
||||
var version = "0.60.0"
|
||||
|
||||
func Full() string {
|
||||
return version
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package basic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -54,7 +55,7 @@ var _ = ginkgo.Describe("[Feature: ClientManage]", func() {
|
|||
framework.NewRequestExpect(f).Port(p3Port).Ensure()
|
||||
|
||||
client := f.APIClientForFrpc(adminPort)
|
||||
conf, err := client.GetConfig()
|
||||
conf, err := client.GetConfig(context.Background())
|
||||
framework.ExpectNoError(err)
|
||||
|
||||
newP2Port := f.AllocPort()
|
||||
|
@ -65,10 +66,10 @@ var _ = ginkgo.Describe("[Feature: ClientManage]", func() {
|
|||
newClientConf = newClientConf[:p3Index]
|
||||
}
|
||||
|
||||
err = client.UpdateConfig(newClientConf)
|
||||
err = client.UpdateConfig(context.Background(), newClientConf)
|
||||
framework.ExpectNoError(err)
|
||||
|
||||
err = client.Reload(true)
|
||||
err = client.Reload(context.Background(), true)
|
||||
framework.ExpectNoError(err)
|
||||
time.Sleep(time.Second)
|
||||
|
||||
|
@ -120,7 +121,7 @@ var _ = ginkgo.Describe("[Feature: ClientManage]", func() {
|
|||
framework.NewRequestExpect(f).Port(testPort).Ensure()
|
||||
|
||||
client := f.APIClientForFrpc(adminPort)
|
||||
err := client.Stop()
|
||||
err := client.Stop(context.Background())
|
||||
framework.ExpectNoError(err)
|
||||
|
||||
time.Sleep(3 * time.Second)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package basic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
|
@ -101,7 +102,7 @@ var _ = ginkgo.Describe("[Feature: Server Manager]", func() {
|
|||
client := f.APIClientForFrpc(adminPort)
|
||||
|
||||
// tcp random port
|
||||
status, err := client.GetProxyStatus("tcp")
|
||||
status, err := client.GetProxyStatus(context.Background(), "tcp")
|
||||
framework.ExpectNoError(err)
|
||||
|
||||
_, portStr, err := net.SplitHostPort(status.RemoteAddr)
|
||||
|
@ -112,7 +113,7 @@ var _ = ginkgo.Describe("[Feature: Server Manager]", func() {
|
|||
framework.NewRequestExpect(f).Port(port).Ensure()
|
||||
|
||||
// udp random port
|
||||
status, err = client.GetProxyStatus("udp")
|
||||
status, err = client.GetProxyStatus(context.Background(), "udp")
|
||||
framework.ExpectNoError(err)
|
||||
|
||||
_, portStr, err = net.SplitHostPort(status.RemoteAddr)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package basic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -57,7 +58,7 @@ var _ = ginkgo.Describe("[Feature: ClientManage]", func() {
|
|||
framework.NewRequestExpect(f).Port(p3Port).Ensure()
|
||||
|
||||
client := f.APIClientForFrpc(adminPort)
|
||||
conf, err := client.GetConfig()
|
||||
conf, err := client.GetConfig(context.Background())
|
||||
framework.ExpectNoError(err)
|
||||
|
||||
newP2Port := f.AllocPort()
|
||||
|
@ -68,10 +69,10 @@ var _ = ginkgo.Describe("[Feature: ClientManage]", func() {
|
|||
newClientConf = newClientConf[:p3Index]
|
||||
}
|
||||
|
||||
err = client.UpdateConfig(newClientConf)
|
||||
err = client.UpdateConfig(context.Background(), newClientConf)
|
||||
framework.ExpectNoError(err)
|
||||
|
||||
err = client.Reload(true)
|
||||
err = client.Reload(context.Background(), true)
|
||||
framework.ExpectNoError(err)
|
||||
time.Sleep(time.Second)
|
||||
|
||||
|
@ -124,7 +125,7 @@ var _ = ginkgo.Describe("[Feature: ClientManage]", func() {
|
|||
framework.NewRequestExpect(f).Port(testPort).Ensure()
|
||||
|
||||
client := f.APIClientForFrpc(adminPort)
|
||||
err := client.Stop()
|
||||
err := client.Stop(context.Background())
|
||||
framework.ExpectNoError(err)
|
||||
|
||||
time.Sleep(3 * time.Second)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package basic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/onsi/ginkgo/v2"
|
||||
|
@ -72,7 +73,7 @@ var _ = ginkgo.Describe("[Feature: Config]", func() {
|
|||
|
||||
client := f.APIClientForFrpc(adminPort)
|
||||
checkProxyFn := func(name string, localPort, remotePort int) {
|
||||
status, err := client.GetProxyStatus(name)
|
||||
status, err := client.GetProxyStatus(context.Background(), name)
|
||||
framework.ExpectNoError(err)
|
||||
|
||||
framework.ExpectContainSubstring(status.LocalAddr, fmt.Sprintf(":%d", localPort))
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package basic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
|
@ -112,7 +113,7 @@ var _ = ginkgo.Describe("[Feature: Server Manager]", func() {
|
|||
client := f.APIClientForFrpc(adminPort)
|
||||
|
||||
// tcp random port
|
||||
status, err := client.GetProxyStatus("tcp")
|
||||
status, err := client.GetProxyStatus(context.Background(), "tcp")
|
||||
framework.ExpectNoError(err)
|
||||
|
||||
_, portStr, err := net.SplitHostPort(status.RemoteAddr)
|
||||
|
@ -123,7 +124,7 @@ var _ = ginkgo.Describe("[Feature: Server Manager]", func() {
|
|||
framework.NewRequestExpect(f).Port(port).Ensure()
|
||||
|
||||
// udp random port
|
||||
status, err = client.GetProxyStatus("udp")
|
||||
status, err = client.GetProxyStatus(context.Background(), "udp")
|
||||
framework.ExpectNoError(err)
|
||||
|
||||
_, portStr, err = net.SplitHostPort(status.RemoteAddr)
|
||||
|
|
Loading…
Reference in New Issue