赞
踩
1.地址:
https://github.com/Jrohy/webssh.git
2.添加中文注释地址:
https://github.com/tonyimax/webssh_cn.git
main.go分析
主包名:main
package main //主包名
依赖包加载
- //导入依赖包
- import (
- "embed" //可执行文件资源嵌入
- "flag" //标志变量
- "fmt" //格式化
- "github.com/gin-contrib/gzip" //压缩库
- "github.com/gin-gonic/gin" //网页框架
- "io/fs" //文件系统
- "net/http" //http通信
- "os" //系统信息
- "strconv" //字符串转换
- "strings" //字符串
- "time" //时间
- "webssh/controller" //websocket通信
- )
在可执行文件中嵌入文件夹dist
//go:embed web/dist/*
访问集成文件夹文件系统
var f embed.FS //集成文件集合,取go:embed中文件夹中文件与文件夹列表
变量声明
- var (
- //整形标志声明,用于储存整形指针
- port = flag.Int("p", //标志名
- 5032, //标志值
- "服务运行端口") //标志描述
- v = flag.Bool("v", false, "显示版本号")
- authInfo = flag.String("a", "", "开启账号密码登录验证, '-a user:pass'的格式传参")
- //普通变量声明
- timeout int //连接超时
- savePass bool //保存密码
- version string //版本号
- buildDate string //编译时间
- goVersion string //go版本号
- gitVersion string //git版本号
- username string //用户名
- password string //密码
- )
初始化函数分析
func init() {}
初始化变量为标志
- //初始化timeout变量为标志
- flag.IntVar(&timeout, //标志指针
- "t", //标志名
- 120, //标志值
- "ssh连接超时时间(min)") //标志描述
- //初始化savePass变量为标志
- flag.BoolVar(&savePass, //标志指针
- "s", //标志名
- true, //标志值
- "保存ssh密码") //标志描述
- flag.StringVar(&version,
- "ver",
- "v1.0.0",
- "程序版本号")
- flag.StringVar(&goVersion,
- "gover",
- "v1.22",
- "go版本号")
- flag.StringVar(&gitVersion,
- "gitver",
- "2.45.2",
- "git版本号")
- flag.StringVar(&buildDate,
- "d",
- time.Now().String(),
- "编译日期")
操作环境变量
- //查找环境变量savePass
- if envVal, ok := os.LookupEnv("savePass"); ok {
- //转换环境变量值为Bool值
- if b, err := strconv.ParseBool(envVal); err == nil {
- savePass = b //如果环境变量有值保存到savePass
- }
- }
- //读取环境变量用户验证信息
- if envVal, ok := os.LookupEnv("authInfo"); ok {
- *authInfo = envVal
- }
- //读取环境变量通信端口信息
- if envVal, ok := os.LookupEnv("port"); ok {
- //转换为整数
- if b, err := strconv.Atoi(envVal); err == nil {
- *port = b
- }
- }
- //必须在标志定义之后及程序访问之前调用
- flag.Parse()
参数检测
- //如果有-v参数,显示版本号信息
- if *v {
- fmt.Printf("Version: %s\n\n", version)
- fmt.Printf("BuildDate: %s\n\n", buildDate)
- fmt.Printf("GoVersion: %s\n\n", goVersion)
- fmt.Printf("GitVersion: %s\n\n", gitVersion)
- os.Exit(0)
- }
用户名与密码参数分割 (-a user:pass'的格式传参)
- if *authInfo != "" {
- //分割用户名与密码
- accountInfo := strings.Split(*authInfo, ":")
- //非空判断
- if len(accountInfo) != 2 ||
- accountInfo[0] == "" ||
- accountInfo[1] == "" {
- fmt.Println("请按'user:pass'的格式来传参或设置环境变量, 且账号密码都不能为空!")
- os.Exit(0)
- }
- //保存用户名与密码
- username, password = accountInfo[0], accountInfo[1]
- }
静态路由函数分析
func staticRouter(router *gin.Engine) {}
创建用户键值对
- //创建账户map
- accountList := map[string]string{
- username: password,
- }
授权并写页面
- //授权路由
- //传入用户列表{用户:密码}
- authorized := router.Group("/", gin.BasicAuth(accountList))
- authorized.GET("", func(c *gin.Context) {
- //读取主页面
- indexHTML, _ := f.ReadFile("web/dist/" + "index.html")
- //向上下文写入主页面
- c.Writer.Write(indexHTML)
- })
http操作静态资源
- staticFs, _ := fs.Sub(f, "web/dist/static")
- router.StaticFS("/static", http.FS(staticFs))
main主函数分析
func main() {}
设置http服务参数并启用路由
- //取web引擎实例
- server := gin.Default()
- //设置可信代理
- server.SetTrustedProxies(nil)
- //使用压缩中间件,支持资源压缩功能
- server.Use(gzip.Gzip(gzip.DefaultCompression))
- //启动路由
- staticRouter(server)
HTTP服务操作:
- //HTTP服务操作
- //GET操作,连接终端websocket
- server.GET("/term", func(c *gin.Context) {
- //调用终端websocket
- controller.TermWs(c, time.Duration(timeout)*time.Minute)
- })
- //GET操作,SSH服务检测
- server.GET("/check", func(c *gin.Context) {
- //检测SSH服务
- responseBody := controller.CheckSSH(c)
- //保存连接密码
- responseBody.Data = map[string]interface{}{
- "savePass": savePass,
- }
- //渲染JSON数据及HTTP状态码给客户端
- c.JSON(200, responseBody)
- })
文件资源操作:
- //文件资源操作
- file := server.Group("/file")
- {
- //请求文件列表
- file.GET("/list", func(c *gin.Context) {
- c.JSON(200, controller.FileList(c))
- })
- //下载文件
- file.GET("/download", func(c *gin.Context) {
- controller.DownloadFile(c)
- })
- //上传文件
- file.POST("/upload", func(c *gin.Context) {
- c.JSON(200, controller.UploadFile(c))
- })
- //上传/下载进度处理
- file.GET("/progress", func(c *gin.Context) {
- controller.UploadProgressWs(c)
- })
- }
启动HTTP服务
- //启动HTTP服务
- server.Run(fmt.Sprintf(":%d", *port))
启动成功输出 如下日志:
- [GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
-
- [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- - using env: export GIN_MODE=release
- - using code: gin.SetMode(gin.ReleaseMode)
-
- [GIN-debug] GET / --> main.staticRouter.func2 (4 handlers)
- [GIN-debug] GET /static/*filepath --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (4 handlers)
- [GIN-debug] HEAD /static/*filepath --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (4 handlers)
- [GIN-debug] GET /term --> main.main.func1 (4 handlers)
- [GIN-debug] GET /check --> main.main.func2 (4 handlers)
- [GIN-debug] GET /file/list --> main.main.func3 (4 handlers)
- [GIN-debug] GET /file/download --> main.main.func4 (4 handlers)
- [GIN-debug] POST /file/upload --> main.main.func5 (4 handlers)
- [GIN-debug] GET /file/progress --> main.main.func6 (4 handlers)
- [GIN-debug] Listening and serving HTTP on :5032
main.go
- package main //主包名
- //导入依赖包
- import (
- "embed" //可执行文件资源嵌入
- "flag" //标志变量
- "fmt" //格式化
- "github.com/gin-contrib/gzip" //压缩库
- "github.com/gin-gonic/gin" //网页框架
- "io/fs" //文件系统
- "net/http" //http通信
- "os" //系统信息
- "strconv" //字符串转换
- "strings" //字符串
- "time" //时间
- "webssh/controller" //websocket通信
- )
-
- // 在可执行文件中嵌入文件夹dist
- //
- //go:embed web/dist/*
- var f embed.FS //集成文件集合,取go:embed中文件夹中文件与文件夹列表
- // 变量声明
- var (
- //整形标志声明,用于储存整形指针
- port = flag.Int("p", //标志名
- 5032, //标志值
- "服务运行端口") //标志描述
- v = flag.Bool("v", false, "显示版本号")
- authInfo = flag.String("a", "", "开启账号密码登录验证, '-a user:pass'的格式传参")
- //普通变量声明
- timeout int //连接超时
- savePass bool //保存密码
- version string //版本号
- buildDate string //编译时间
- goVersion string //go版本号
- gitVersion string //git版本号
- username string //用户名
- password string //密码
- )
-
- // 初始化
- func init() {
- //初始化timeout变量为标志
- flag.IntVar(&timeout, //标志指针
- "t", //标志名
- 120, //标志值
- "ssh连接超时时间(min)") //标志描述
- //初始化savePass变量为标志
- flag.BoolVar(&savePass, //标志指针
- "s", //标志名
- true, //标志值
- "保存ssh密码") //标志描述
- flag.StringVar(&version,
- "ver",
- "v1.0.0",
- "程序版本号")
- flag.StringVar(&goVersion,
- "gover",
- "v1.22",
- "go版本号")
- flag.StringVar(&gitVersion,
- "gitver",
- "2.45.2",
- "git版本号")
- flag.StringVar(&buildDate,
- "d",
- time.Now().String(),
- "编译日期")
- //查找环境变量savePass
- if envVal, ok := os.LookupEnv("savePass"); ok {
- //转换环境变量值为Bool值
- if b, err := strconv.ParseBool(envVal); err == nil {
- savePass = b //如果环境变量有值保存到savePass
- }
- }
- //读取环境变量用户验证信息
- if envVal, ok := os.LookupEnv("authInfo"); ok {
- *authInfo = envVal
- }
- //读取环境变量通信端口信息
- if envVal, ok := os.LookupEnv("port"); ok {
- //转换为整数
- if b, err := strconv.Atoi(envVal); err == nil {
- *port = b
- }
- }
- //必须在标志定义之后及程序访问之前调用
- flag.Parse()
- //如果有-v参数,显示版本号信息
- if *v {
- fmt.Printf("Version: %s\n\n", version)
- fmt.Printf("BuildDate: %s\n\n", buildDate)
- fmt.Printf("GoVersion: %s\n\n", goVersion)
- fmt.Printf("GitVersion: %s\n\n", gitVersion)
- os.Exit(0)
- }
- if *authInfo != "" {
- //分割用户名与密码
- accountInfo := strings.Split(*authInfo, ":")
- //非空判断
- if len(accountInfo) != 2 ||
- accountInfo[0] == "" ||
- accountInfo[1] == "" {
- fmt.Println("请按'user:pass'的格式来传参或设置环境变量, 且账号密码都不能为空!")
- os.Exit(0)
- }
- //保存用户名与密码
- username, password = accountInfo[0], accountInfo[1]
- }
- }
-
- // 启动静态路由
- func staticRouter(router *gin.Engine) {
- //如果密码不为空
- if password != "" {
- //创建账户map
- accountList := map[string]string{
- username: password,
- }
- //授权路由
- //传入用户列表{用户:密码}
- authorized := router.Group("/", gin.BasicAuth(accountList))
- authorized.GET("", func(c *gin.Context) {
- //读取主页面
- indexHTML, _ := f.ReadFile("web/dist/" + "index.html")
- //向上下文写入主页面
- c.Writer.Write(indexHTML)
- })
- } else {
- router.GET("/", func(c *gin.Context) {
- indexHTML, _ := f.ReadFile("web/dist/" + "index.html")
- c.Writer.Write(indexHTML)
- })
- }
- //http操作静态资源
- staticFs, _ := fs.Sub(f, "web/dist/static")
- router.StaticFS("/static", http.FS(staticFs))
- }
-
- func main() {
- //取web引擎实例
- server := gin.Default()
- //设置可信代理
- server.SetTrustedProxies(nil)
- //使用压缩中间件,支持资源压缩功能
- server.Use(gzip.Gzip(gzip.DefaultCompression))
- //启动路由
- staticRouter(server)
-
- //HTTP服务操作
- //GET操作,连接终端websocket
- server.GET("/term", func(c *gin.Context) {
- //调用终端websocket
- controller.TermWs(c, time.Duration(timeout)*time.Minute)
- })
- //GET操作,SSH服务检测
- server.GET("/check", func(c *gin.Context) {
- //检测SSH服务
- responseBody := controller.CheckSSH(c)
- //保存连接密码
- responseBody.Data = map[string]interface{}{
- "savePass": savePass,
- }
- //渲染JSON数据及HTTP状态码给客户端
- c.JSON(200, responseBody)
- })
- //文件资源操作
- file := server.Group("/file")
- {
- //请求文件列表
- file.GET("/list", func(c *gin.Context) {
- c.JSON(200, controller.FileList(c))
- })
- //下载文件
- file.GET("/download", func(c *gin.Context) {
- controller.DownloadFile(c)
- })
- //上传文件
- file.POST("/upload", func(c *gin.Context) {
- c.JSON(200, controller.UploadFile(c))
- })
- //上传/下载进度处理
- file.GET("/progress", func(c *gin.Context) {
- controller.UploadProgressWs(c)
- })
- }
- //启动HTTP服务
- server.Run(fmt.Sprintf(":%d", *port))
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。