Files
terminal/server/api/tools_api.go
T

162 lines
3.8 KiB
Go

package api
import (
"bufio"
"bytes"
"fmt"
"io"
"net"
"net/http"
"os/exec"
"runtime"
"strconv"
"strings"
"time"
"github.com/labstack/echo/v4"
"golang.org/x/text/encoding/simplifiedchinese"
"golang.org/x/text/transform"
)
type ToolsApi struct{}
func (api ToolsApi) TcpingEndpoint(c echo.Context) error {
host := c.QueryParam("host")
port := c.QueryParam("port")
attemptsStr := c.QueryParam("attempts")
attempts := 4
if attemptsStr != "" {
attempts, _ = strconv.Atoi(attemptsStr)
}
c.Response().Header().Set("Content-Type", "text/event-stream")
c.Response().Header().Set("Cache-Control", "no-cache")
c.Response().Header().Set("Connection", "keep-alive")
flusher, ok := c.Response().Writer.(http.Flusher)
if !ok {
return echo.NewHTTPError(500, "Streaming unsupported")
}
for i := 0; i < attempts; i++ {
start := time.Now()
conn, err := net.DialTimeout("tcp", host+":"+port, 5*time.Second)
elapsed := time.Since(start)
var result string
if err != nil {
result = fmt.Sprintf("TCP ping %s:%s - Failed: %v", host, port, err)
} else {
conn.Close()
result = fmt.Sprintf("TCP ping %s:%s - Connected, time=%v", host, port, elapsed.Round(time.Millisecond))
}
fmt.Fprintf(c.Response(), "data: %s\n\n", result)
flusher.Flush()
if i < attempts-1 {
time.Sleep(1 * time.Second)
}
}
fmt.Fprintf(c.Response(), "event: done\ndata: completed\n\n")
flusher.Flush()
return nil
}
func (api ToolsApi) PingEndpoint(c echo.Context) error {
host := c.QueryParam("host")
attemptsStr := c.QueryParam("attempts")
attempts := 4
if attemptsStr != "" {
attempts, _ = strconv.Atoi(attemptsStr)
}
c.Response().Header().Set("Content-Type", "text/event-stream")
c.Response().Header().Set("Cache-Control", "no-cache")
c.Response().Header().Set("Connection", "keep-alive")
flusher, ok := c.Response().Writer.(http.Flusher)
if !ok {
return echo.NewHTTPError(500, "Streaming unsupported")
}
var cmd *exec.Cmd
if runtime.GOOS == "windows" {
cmd = exec.Command("ping", "-n", strconv.Itoa(attempts), host)
} else {
cmd = exec.Command("ping", "-c", strconv.Itoa(attempts), host)
}
stdout, err := cmd.StdoutPipe()
if err != nil {
fmt.Fprintf(c.Response(), "data: Error: %v\n\n", err)
flusher.Flush()
return nil
}
if err := cmd.Start(); err != nil {
fmt.Fprintf(c.Response(), "data: Error: %v\n\n", err)
flusher.Flush()
return nil
}
var reader io.Reader = stdout
if runtime.GOOS == "windows" {
reader = transform.NewReader(stdout, simplifiedchinese.GBK.NewDecoder())
}
scanner := bufio.NewScanner(reader)
for scanner.Scan() {
line := scanner.Text()
if strings.TrimSpace(line) != "" {
fmt.Fprintf(c.Response(), "data: %s\n\n", line)
flusher.Flush()
}
}
_ = cmd.Wait()
fmt.Fprintf(c.Response(), "event: done\ndata: completed\n\n")
flusher.Flush()
return nil
}
func (api ToolsApi) TelnetEndpoint(c echo.Context) error {
host := c.QueryParam("host")
port := c.QueryParam("port")
c.Response().Header().Set("Content-Type", "text/event-stream")
c.Response().Header().Set("Cache-Control", "no-cache")
c.Response().Header().Set("Connection", "keep-alive")
flusher, ok := c.Response().Writer.(http.Flusher)
if !ok {
return echo.NewHTTPError(500, "Streaming unsupported")
}
start := time.Now()
conn, err := net.DialTimeout("tcp", host+":"+port, 10*time.Second)
elapsed := time.Since(start)
var result bytes.Buffer
if err != nil {
result.WriteString(fmt.Sprintf("Telnet %s:%s - Connection failed: %v", host, port, err))
} else {
conn.Close()
result.WriteString(fmt.Sprintf("Telnet %s:%s - Connected successfully in %v", host, port, elapsed.Round(time.Millisecond)))
}
fmt.Fprintf(c.Response(), "data: %s\n\n", result.String())
flusher.Flush()
fmt.Fprintf(c.Response(), "event: done\ndata: completed\n\n")
flusher.Flush()
return nil
}