当前位置:   article > 正文

go开源webssh终端源码main.go分析

go开源webssh终端源码main.go分析

1.地址:  

https://github.com/Jrohy/webssh.git

2.添加中文注释地址:

https://github.com/tonyimax/webssh_cn.git

main.go分析

主包名:main

package main //主包名

依赖包加载

  1. //导入依赖包
  2. import (
  3. "embed" //可执行文件资源嵌入
  4. "flag" //标志变量
  5. "fmt" //格式化
  6. "github.com/gin-contrib/gzip" //压缩库
  7. "github.com/gin-gonic/gin" //网页框架
  8. "io/fs" //文件系统
  9. "net/http" //http通信
  10. "os" //系统信息
  11. "strconv" //字符串转换
  12. "strings" //字符串
  13. "time" //时间
  14. "webssh/controller" //websocket通信
  15. )
在可执行文件中嵌入文件夹dist
//go:embed web/dist/*

访问集成文件夹文件系统

var f embed.FS //集成文件集合,取go:embed中文件夹中文件与文件夹列表
变量声明
  1. var (
  2. //整形标志声明,用于储存整形指针
  3. port = flag.Int("p", //标志名
  4. 5032, //标志值
  5. "服务运行端口") //标志描述
  6. v = flag.Bool("v", false, "显示版本号")
  7. authInfo = flag.String("a", "", "开启账号密码登录验证, '-a user:pass'的格式传参")
  8. //普通变量声明
  9. timeout int //连接超时
  10. savePass bool //保存密码
  11. version string //版本号
  12. buildDate string //编译时间
  13. goVersion string //go版本号
  14. gitVersion string //git版本号
  15. username string //用户名
  16. password string //密码
  17. )

初始化函数分析

func init() {}

初始化变量为标志

  1. //初始化timeout变量为标志
  2. flag.IntVar(&timeout, //标志指针
  3. "t", //标志名
  4. 120, //标志值
  5. "ssh连接超时时间(min)") //标志描述
  6. //初始化savePass变量为标志
  7. flag.BoolVar(&savePass, //标志指针
  8. "s", //标志名
  9. true, //标志值
  10. "保存ssh密码") //标志描述
  11. flag.StringVar(&version,
  12. "ver",
  13. "v1.0.0",
  14. "程序版本号")
  15. flag.StringVar(&goVersion,
  16. "gover",
  17. "v1.22",
  18. "go版本号")
  19. flag.StringVar(&gitVersion,
  20. "gitver",
  21. "2.45.2",
  22. "git版本号")
  23. flag.StringVar(&buildDate,
  24. "d",
  25. time.Now().String(),
  26. "编译日期")

操作环境变量

  1. //查找环境变量savePass
  2. if envVal, ok := os.LookupEnv("savePass"); ok {
  3. //转换环境变量值为Bool值
  4. if b, err := strconv.ParseBool(envVal); err == nil {
  5. savePass = b //如果环境变量有值保存到savePass
  6. }
  7. }
  8. //读取环境变量用户验证信息
  9. if envVal, ok := os.LookupEnv("authInfo"); ok {
  10. *authInfo = envVal
  11. }
  12. //读取环境变量通信端口信息
  13. if envVal, ok := os.LookupEnv("port"); ok {
  14. //转换为整数
  15. if b, err := strconv.Atoi(envVal); err == nil {
  16. *port = b
  17. }
  18. }
  19. //必须在标志定义之后及程序访问之前调用
  20. flag.Parse()

参数检测

  1. //如果有-v参数,显示版本号信息
  2. if *v {
  3. fmt.Printf("Version: %s\n\n", version)
  4. fmt.Printf("BuildDate: %s\n\n", buildDate)
  5. fmt.Printf("GoVersion: %s\n\n", goVersion)
  6. fmt.Printf("GitVersion: %s\n\n", gitVersion)
  7. os.Exit(0)
  8. }

用户名与密码参数分割 (-a user:pass'的格式传参)

  1. if *authInfo != "" {
  2. //分割用户名与密码
  3. accountInfo := strings.Split(*authInfo, ":")
  4. //非空判断
  5. if len(accountInfo) != 2 ||
  6. accountInfo[0] == "" ||
  7. accountInfo[1] == "" {
  8. fmt.Println("请按'user:pass'的格式来传参或设置环境变量, 且账号密码都不能为空!")
  9. os.Exit(0)
  10. }
  11. //保存用户名与密码
  12. username, password = accountInfo[0], accountInfo[1]
  13. }

静态路由函数分析

func staticRouter(router *gin.Engine) {}

创建用户键值对

  1. //创建账户map
  2. accountList := map[string]string{
  3. username: password,
  4. }

授权并写页面

  1. //授权路由
  2. //传入用户列表{用户:密码}
  3. authorized := router.Group("/", gin.BasicAuth(accountList))
  4. authorized.GET("", func(c *gin.Context) {
  5. //读取主页面
  6. indexHTML, _ := f.ReadFile("web/dist/" + "index.html")
  7. //向上下文写入主页面
  8. c.Writer.Write(indexHTML)
  9. })

http操作静态资源

  1. staticFs, _ := fs.Sub(f, "web/dist/static")
  2. router.StaticFS("/static", http.FS(staticFs))

main主函数分析

func main() {}

设置http服务参数并启用路由

  1. //取web引擎实例
  2. server := gin.Default()
  3. //设置可信代理
  4. server.SetTrustedProxies(nil)
  5. //使用压缩中间件,支持资源压缩功能
  6. server.Use(gzip.Gzip(gzip.DefaultCompression))
  7. //启动路由
  8. staticRouter(server)

HTTP服务操作:

  1. //HTTP服务操作
  2. //GET操作,连接终端websocket
  3. server.GET("/term", func(c *gin.Context) {
  4. //调用终端websocket
  5. controller.TermWs(c, time.Duration(timeout)*time.Minute)
  6. })
  7. //GET操作,SSH服务检测
  8. server.GET("/check", func(c *gin.Context) {
  9. //检测SSH服务
  10. responseBody := controller.CheckSSH(c)
  11. //保存连接密码
  12. responseBody.Data = map[string]interface{}{
  13. "savePass": savePass,
  14. }
  15. //渲染JSON数据及HTTP状态码给客户端
  16. c.JSON(200, responseBody)
  17. })

文件资源操作:

  1. //文件资源操作
  2. file := server.Group("/file")
  3. {
  4. //请求文件列表
  5. file.GET("/list", func(c *gin.Context) {
  6. c.JSON(200, controller.FileList(c))
  7. })
  8. //下载文件
  9. file.GET("/download", func(c *gin.Context) {
  10. controller.DownloadFile(c)
  11. })
  12. //上传文件
  13. file.POST("/upload", func(c *gin.Context) {
  14. c.JSON(200, controller.UploadFile(c))
  15. })
  16. //上传/下载进度处理
  17. file.GET("/progress", func(c *gin.Context) {
  18. controller.UploadProgressWs(c)
  19. })
  20. }

启动HTTP服务

  1. //启动HTTP服务
  2. server.Run(fmt.Sprintf(":%d", *port))

启动成功输出 如下日志:

  1. [GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
  2. [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
  3. - using env: export GIN_MODE=release
  4. - using code: gin.SetMode(gin.ReleaseMode)
  5. [GIN-debug] GET / --> main.staticRouter.func2 (4 handlers)
  6. [GIN-debug] GET /static/*filepath --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (4 handlers)
  7. [GIN-debug] HEAD /static/*filepath --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (4 handlers)
  8. [GIN-debug] GET /term --> main.main.func1 (4 handlers)
  9. [GIN-debug] GET /check --> main.main.func2 (4 handlers)
  10. [GIN-debug] GET /file/list --> main.main.func3 (4 handlers)
  11. [GIN-debug] GET /file/download --> main.main.func4 (4 handlers)
  12. [GIN-debug] POST /file/upload --> main.main.func5 (4 handlers)
  13. [GIN-debug] GET /file/progress --> main.main.func6 (4 handlers)
  14. [GIN-debug] Listening and serving HTTP on :5032

main.go

  1. package main //主包名
  2. //导入依赖包
  3. import (
  4. "embed" //可执行文件资源嵌入
  5. "flag" //标志变量
  6. "fmt" //格式化
  7. "github.com/gin-contrib/gzip" //压缩库
  8. "github.com/gin-gonic/gin" //网页框架
  9. "io/fs" //文件系统
  10. "net/http" //http通信
  11. "os" //系统信息
  12. "strconv" //字符串转换
  13. "strings" //字符串
  14. "time" //时间
  15. "webssh/controller" //websocket通信
  16. )
  17. // 在可执行文件中嵌入文件夹dist
  18. //
  19. //go:embed web/dist/*
  20. var f embed.FS //集成文件集合,取go:embed中文件夹中文件与文件夹列表
  21. // 变量声明
  22. var (
  23. //整形标志声明,用于储存整形指针
  24. port = flag.Int("p", //标志名
  25. 5032, //标志值
  26. "服务运行端口") //标志描述
  27. v = flag.Bool("v", false, "显示版本号")
  28. authInfo = flag.String("a", "", "开启账号密码登录验证, '-a user:pass'的格式传参")
  29. //普通变量声明
  30. timeout int //连接超时
  31. savePass bool //保存密码
  32. version string //版本号
  33. buildDate string //编译时间
  34. goVersion string //go版本号
  35. gitVersion string //git版本号
  36. username string //用户名
  37. password string //密码
  38. )
  39. // 初始化
  40. func init() {
  41. //初始化timeout变量为标志
  42. flag.IntVar(&timeout, //标志指针
  43. "t", //标志名
  44. 120, //标志值
  45. "ssh连接超时时间(min)") //标志描述
  46. //初始化savePass变量为标志
  47. flag.BoolVar(&savePass, //标志指针
  48. "s", //标志名
  49. true, //标志值
  50. "保存ssh密码") //标志描述
  51. flag.StringVar(&version,
  52. "ver",
  53. "v1.0.0",
  54. "程序版本号")
  55. flag.StringVar(&goVersion,
  56. "gover",
  57. "v1.22",
  58. "go版本号")
  59. flag.StringVar(&gitVersion,
  60. "gitver",
  61. "2.45.2",
  62. "git版本号")
  63. flag.StringVar(&buildDate,
  64. "d",
  65. time.Now().String(),
  66. "编译日期")
  67. //查找环境变量savePass
  68. if envVal, ok := os.LookupEnv("savePass"); ok {
  69. //转换环境变量值为Bool值
  70. if b, err := strconv.ParseBool(envVal); err == nil {
  71. savePass = b //如果环境变量有值保存到savePass
  72. }
  73. }
  74. //读取环境变量用户验证信息
  75. if envVal, ok := os.LookupEnv("authInfo"); ok {
  76. *authInfo = envVal
  77. }
  78. //读取环境变量通信端口信息
  79. if envVal, ok := os.LookupEnv("port"); ok {
  80. //转换为整数
  81. if b, err := strconv.Atoi(envVal); err == nil {
  82. *port = b
  83. }
  84. }
  85. //必须在标志定义之后及程序访问之前调用
  86. flag.Parse()
  87. //如果有-v参数,显示版本号信息
  88. if *v {
  89. fmt.Printf("Version: %s\n\n", version)
  90. fmt.Printf("BuildDate: %s\n\n", buildDate)
  91. fmt.Printf("GoVersion: %s\n\n", goVersion)
  92. fmt.Printf("GitVersion: %s\n\n", gitVersion)
  93. os.Exit(0)
  94. }
  95. if *authInfo != "" {
  96. //分割用户名与密码
  97. accountInfo := strings.Split(*authInfo, ":")
  98. //非空判断
  99. if len(accountInfo) != 2 ||
  100. accountInfo[0] == "" ||
  101. accountInfo[1] == "" {
  102. fmt.Println("请按'user:pass'的格式来传参或设置环境变量, 且账号密码都不能为空!")
  103. os.Exit(0)
  104. }
  105. //保存用户名与密码
  106. username, password = accountInfo[0], accountInfo[1]
  107. }
  108. }
  109. // 启动静态路由
  110. func staticRouter(router *gin.Engine) {
  111. //如果密码不为空
  112. if password != "" {
  113. //创建账户map
  114. accountList := map[string]string{
  115. username: password,
  116. }
  117. //授权路由
  118. //传入用户列表{用户:密码}
  119. authorized := router.Group("/", gin.BasicAuth(accountList))
  120. authorized.GET("", func(c *gin.Context) {
  121. //读取主页面
  122. indexHTML, _ := f.ReadFile("web/dist/" + "index.html")
  123. //向上下文写入主页面
  124. c.Writer.Write(indexHTML)
  125. })
  126. } else {
  127. router.GET("/", func(c *gin.Context) {
  128. indexHTML, _ := f.ReadFile("web/dist/" + "index.html")
  129. c.Writer.Write(indexHTML)
  130. })
  131. }
  132. //http操作静态资源
  133. staticFs, _ := fs.Sub(f, "web/dist/static")
  134. router.StaticFS("/static", http.FS(staticFs))
  135. }
  136. func main() {
  137. //取web引擎实例
  138. server := gin.Default()
  139. //设置可信代理
  140. server.SetTrustedProxies(nil)
  141. //使用压缩中间件,支持资源压缩功能
  142. server.Use(gzip.Gzip(gzip.DefaultCompression))
  143. //启动路由
  144. staticRouter(server)
  145. //HTTP服务操作
  146. //GET操作,连接终端websocket
  147. server.GET("/term", func(c *gin.Context) {
  148. //调用终端websocket
  149. controller.TermWs(c, time.Duration(timeout)*time.Minute)
  150. })
  151. //GET操作,SSH服务检测
  152. server.GET("/check", func(c *gin.Context) {
  153. //检测SSH服务
  154. responseBody := controller.CheckSSH(c)
  155. //保存连接密码
  156. responseBody.Data = map[string]interface{}{
  157. "savePass": savePass,
  158. }
  159. //渲染JSON数据及HTTP状态码给客户端
  160. c.JSON(200, responseBody)
  161. })
  162. //文件资源操作
  163. file := server.Group("/file")
  164. {
  165. //请求文件列表
  166. file.GET("/list", func(c *gin.Context) {
  167. c.JSON(200, controller.FileList(c))
  168. })
  169. //下载文件
  170. file.GET("/download", func(c *gin.Context) {
  171. controller.DownloadFile(c)
  172. })
  173. //上传文件
  174. file.POST("/upload", func(c *gin.Context) {
  175. c.JSON(200, controller.UploadFile(c))
  176. })
  177. //上传/下载进度处理
  178. file.GET("/progress", func(c *gin.Context) {
  179. controller.UploadProgressWs(c)
  180. })
  181. }
  182. //启动HTTP服务
  183. server.Run(fmt.Sprintf(":%d", *port))
  184. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/代码探险家/article/detail/797277
推荐阅读
  

闽ICP备14008679号