dashboard_api.go 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. // Copyright 2017 fatedier, fatedier@gmail.com
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package server
  15. import (
  16. "encoding/json"
  17. "net/http"
  18. "github.com/fatedier/frp/g"
  19. "github.com/fatedier/frp/models/config"
  20. "github.com/fatedier/frp/models/consts"
  21. "github.com/fatedier/frp/utils/log"
  22. "github.com/fatedier/frp/utils/version"
  23. "github.com/julienschmidt/httprouter"
  24. )
  25. type GeneralResponse struct {
  26. Code int64 `json:"code"`
  27. Msg string `json:"msg"`
  28. }
  29. // api/serverinfo
  30. type ServerInfoResp struct {
  31. GeneralResponse
  32. Version string `json:"version"`
  33. BindPort int `json:"bind_port"`
  34. BindUdpPort int `json:"bind_udp_port"`
  35. VhostHttpPort int `json:"vhost_http_port"`
  36. VhostHttpsPort int `json:"vhost_https_port"`
  37. KcpBindPort int `json:"kcp_bind_port"`
  38. AuthTimeout int64 `json:"auth_timeout"`
  39. SubdomainHost string `json:"subdomain_host"`
  40. MaxPoolCount int64 `json:"max_pool_count"`
  41. MaxPortsPerClient int64 `json:"max_ports_per_client"`
  42. HeartBeatTimeout int64 `json:"heart_beat_timeout"`
  43. TotalTrafficIn int64 `json:"total_traffic_in"`
  44. TotalTrafficOut int64 `json:"total_traffic_out"`
  45. CurConns int64 `json:"cur_conns"`
  46. ClientCounts int64 `json:"client_counts"`
  47. ProxyTypeCounts map[string]int64 `json:"proxy_type_count"`
  48. }
  49. func apiServerInfo(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
  50. var (
  51. buf []byte
  52. res ServerInfoResp
  53. )
  54. defer func() {
  55. log.Info("Http response [/api/serverinfo]: code [%d]", res.Code)
  56. }()
  57. log.Info("Http request: [/api/serverinfo]")
  58. cfg := &g.GlbServerCfg.ServerCommonConf
  59. serverStats := StatsGetServer()
  60. res = ServerInfoResp{
  61. Version: version.Full(),
  62. BindPort: cfg.BindPort,
  63. BindUdpPort: cfg.BindUdpPort,
  64. VhostHttpPort: cfg.VhostHttpPort,
  65. VhostHttpsPort: cfg.VhostHttpsPort,
  66. KcpBindPort: cfg.KcpBindPort,
  67. AuthTimeout: cfg.AuthTimeout,
  68. SubdomainHost: cfg.SubDomainHost,
  69. MaxPoolCount: cfg.MaxPoolCount,
  70. MaxPortsPerClient: cfg.MaxPortsPerClient,
  71. HeartBeatTimeout: cfg.HeartBeatTimeout,
  72. TotalTrafficIn: serverStats.TotalTrafficIn,
  73. TotalTrafficOut: serverStats.TotalTrafficOut,
  74. CurConns: serverStats.CurConns,
  75. ClientCounts: serverStats.ClientCounts,
  76. ProxyTypeCounts: serverStats.ProxyTypeCounts,
  77. }
  78. buf, _ = json.Marshal(&res)
  79. w.Write(buf)
  80. }
  81. // Get proxy info.
  82. type ProxyStatsInfo struct {
  83. Name string `json:"name"`
  84. Conf config.ProxyConf `json:"conf"`
  85. TodayTrafficIn int64 `json:"today_traffic_in"`
  86. TodayTrafficOut int64 `json:"today_traffic_out"`
  87. CurConns int64 `json:"cur_conns"`
  88. LastStartTime string `json:"last_start_time"`
  89. LastCloseTime string `json:"last_close_time"`
  90. Status string `json:"status"`
  91. }
  92. type GetProxyInfoResp struct {
  93. GeneralResponse
  94. Proxies []*ProxyStatsInfo `json:"proxies"`
  95. }
  96. // api/proxy/tcp
  97. func apiProxyTcp(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
  98. var (
  99. buf []byte
  100. res GetProxyInfoResp
  101. )
  102. defer func() {
  103. log.Info("Http response [/api/proxy/tcp]: code [%d]", res.Code)
  104. }()
  105. log.Info("Http request: [/api/proxy/tcp]")
  106. res.Proxies = getProxyStatsByType(consts.TcpProxy)
  107. buf, _ = json.Marshal(&res)
  108. w.Write(buf)
  109. }
  110. // api/proxy/udp
  111. func apiProxyUdp(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
  112. var (
  113. buf []byte
  114. res GetProxyInfoResp
  115. )
  116. defer func() {
  117. log.Info("Http response [/api/proxy/udp]: code [%d]", res.Code)
  118. }()
  119. log.Info("Http request: [/api/proxy/udp]")
  120. res.Proxies = getProxyStatsByType(consts.UdpProxy)
  121. buf, _ = json.Marshal(&res)
  122. w.Write(buf)
  123. }
  124. // api/proxy/http
  125. func apiProxyHttp(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
  126. var (
  127. buf []byte
  128. res GetProxyInfoResp
  129. )
  130. defer func() {
  131. log.Info("Http response [/api/proxy/http]: code [%d]", res.Code)
  132. }()
  133. log.Info("Http request: [/api/proxy/http]")
  134. res.Proxies = getProxyStatsByType(consts.HttpProxy)
  135. buf, _ = json.Marshal(&res)
  136. w.Write(buf)
  137. }
  138. // api/proxy/https
  139. func apiProxyHttps(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
  140. var (
  141. buf []byte
  142. res GetProxyInfoResp
  143. )
  144. defer func() {
  145. log.Info("Http response [/api/proxy/https]: code [%d]", res.Code)
  146. }()
  147. log.Info("Http request: [/api/proxy/https]")
  148. res.Proxies = getProxyStatsByType(consts.HttpsProxy)
  149. buf, _ = json.Marshal(&res)
  150. w.Write(buf)
  151. }
  152. func getProxyStatsByType(proxyType string) (proxyInfos []*ProxyStatsInfo) {
  153. proxyStats := StatsGetProxiesByType(proxyType)
  154. proxyInfos = make([]*ProxyStatsInfo, 0, len(proxyStats))
  155. for _, ps := range proxyStats {
  156. proxyInfo := &ProxyStatsInfo{}
  157. if pxy, ok := ServerService.pxyManager.GetByName(ps.Name); ok {
  158. proxyInfo.Conf = pxy.GetConf()
  159. proxyInfo.Status = consts.Online
  160. } else {
  161. proxyInfo.Status = consts.Offline
  162. }
  163. proxyInfo.Name = ps.Name
  164. proxyInfo.TodayTrafficIn = ps.TodayTrafficIn
  165. proxyInfo.TodayTrafficOut = ps.TodayTrafficOut
  166. proxyInfo.CurConns = ps.CurConns
  167. proxyInfo.LastStartTime = ps.LastStartTime
  168. proxyInfo.LastCloseTime = ps.LastCloseTime
  169. proxyInfos = append(proxyInfos, proxyInfo)
  170. }
  171. return
  172. }
  173. // Get proxy info by name.
  174. type GetProxyStatsResp struct {
  175. GeneralResponse
  176. Name string `json:"name"`
  177. Conf config.ProxyConf `json:"conf"`
  178. TodayTrafficIn int64 `json:"today_traffic_in"`
  179. TodayTrafficOut int64 `json:"today_traffic_out"`
  180. CurConns int64 `json:"cur_conns"`
  181. LastStartTime string `json:"last_start_time"`
  182. LastCloseTime string `json:"last_close_time"`
  183. Status string `json:"status"`
  184. }
  185. // api/proxy/tcp/:name
  186. func apiProxyTcpByName(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
  187. var (
  188. buf []byte
  189. res GetProxyStatsResp
  190. )
  191. name := params.ByName("name")
  192. defer func() {
  193. log.Info("Http response [/api/proxy/tcp/:name]: code [%d]", res.Code)
  194. }()
  195. log.Info("Http request: [/api/proxy/tcp/:name]")
  196. res = getProxyStatsByTypeAndName(consts.TcpProxy, name)
  197. buf, _ = json.Marshal(&res)
  198. w.Write(buf)
  199. }
  200. // api/proxy/udp/:name
  201. func apiProxyUdpByName(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
  202. var (
  203. buf []byte
  204. res GetProxyStatsResp
  205. )
  206. name := params.ByName("name")
  207. defer func() {
  208. log.Info("Http response [/api/proxy/udp/:name]: code [%d]", res.Code)
  209. }()
  210. log.Info("Http request: [/api/proxy/udp/:name]")
  211. res = getProxyStatsByTypeAndName(consts.UdpProxy, name)
  212. buf, _ = json.Marshal(&res)
  213. w.Write(buf)
  214. }
  215. // api/proxy/http/:name
  216. func apiProxyHttpByName(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
  217. var (
  218. buf []byte
  219. res GetProxyStatsResp
  220. )
  221. name := params.ByName("name")
  222. defer func() {
  223. log.Info("Http response [/api/proxy/http/:name]: code [%d]", res.Code)
  224. }()
  225. log.Info("Http request: [/api/proxy/http/:name]")
  226. res = getProxyStatsByTypeAndName(consts.HttpProxy, name)
  227. buf, _ = json.Marshal(&res)
  228. w.Write(buf)
  229. }
  230. // api/proxy/https/:name
  231. func apiProxyHttpsByName(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
  232. var (
  233. buf []byte
  234. res GetProxyStatsResp
  235. )
  236. name := params.ByName("name")
  237. defer func() {
  238. log.Info("Http response [/api/proxy/https/:name]: code [%d]", res.Code)
  239. }()
  240. log.Info("Http request: [/api/proxy/https/:name]")
  241. res = getProxyStatsByTypeAndName(consts.HttpsProxy, name)
  242. buf, _ = json.Marshal(&res)
  243. w.Write(buf)
  244. }
  245. func getProxyStatsByTypeAndName(proxyType string, proxyName string) (proxyInfo GetProxyStatsResp) {
  246. proxyInfo.Name = proxyName
  247. ps := StatsGetProxiesByTypeAndName(proxyType, proxyName)
  248. if ps == nil {
  249. proxyInfo.Code = 1
  250. proxyInfo.Msg = "no proxy info found"
  251. } else {
  252. if pxy, ok := ServerService.pxyManager.GetByName(proxyName); ok {
  253. proxyInfo.Conf = pxy.GetConf()
  254. proxyInfo.Status = consts.Online
  255. } else {
  256. proxyInfo.Status = consts.Offline
  257. }
  258. proxyInfo.TodayTrafficIn = ps.TodayTrafficIn
  259. proxyInfo.TodayTrafficOut = ps.TodayTrafficOut
  260. proxyInfo.CurConns = ps.CurConns
  261. proxyInfo.LastStartTime = ps.LastStartTime
  262. proxyInfo.LastCloseTime = ps.LastCloseTime
  263. }
  264. return
  265. }
  266. // api/proxy/traffic/:name
  267. type GetProxyTrafficResp struct {
  268. GeneralResponse
  269. Name string `json:"name"`
  270. TrafficIn []int64 `json:"traffic_in"`
  271. TrafficOut []int64 `json:"traffic_out"`
  272. }
  273. func apiProxyTraffic(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
  274. var (
  275. buf []byte
  276. res GetProxyTrafficResp
  277. )
  278. name := params.ByName("name")
  279. defer func() {
  280. log.Info("Http response [/api/proxy/traffic/:name]: code [%d]", res.Code)
  281. }()
  282. log.Info("Http request: [/api/proxy/traffic/:name]")
  283. res.Name = name
  284. proxyTrafficInfo := StatsGetProxyTraffic(name)
  285. if proxyTrafficInfo == nil {
  286. res.Code = 1
  287. res.Msg = "no proxy info found"
  288. } else {
  289. res.TrafficIn = proxyTrafficInfo.TrafficIn
  290. res.TrafficOut = proxyTrafficInfo.TrafficOut
  291. }
  292. buf, _ = json.Marshal(&res)
  293. w.Write(buf)
  294. }