1
0

dashboard_api.go 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  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/gorilla/mux"
  24. )
  25. type GeneralResponse struct {
  26. Code int64 `json:"code"`
  27. Msg string `json:"msg"`
  28. }
  29. type ServerInfoResp struct {
  30. GeneralResponse
  31. Version string `json:"version"`
  32. BindPort int `json:"bind_port"`
  33. BindUdpPort int `json:"bind_udp_port"`
  34. VhostHttpPort int `json:"vhost_http_port"`
  35. VhostHttpsPort int `json:"vhost_https_port"`
  36. KcpBindPort int `json:"kcp_bind_port"`
  37. SubdomainHost string `json:"subdomain_host"`
  38. MaxPoolCount int64 `json:"max_pool_count"`
  39. MaxPortsPerClient int64 `json:"max_ports_per_client"`
  40. HeartBeatTimeout int64 `json:"heart_beat_timeout"`
  41. TotalTrafficIn int64 `json:"total_traffic_in"`
  42. TotalTrafficOut int64 `json:"total_traffic_out"`
  43. CurConns int64 `json:"cur_conns"`
  44. ClientCounts int64 `json:"client_counts"`
  45. ProxyTypeCounts map[string]int64 `json:"proxy_type_count"`
  46. }
  47. // api/serverinfo
  48. func (svr *Service) ApiServerInfo(w http.ResponseWriter, r *http.Request) {
  49. var (
  50. buf []byte
  51. res ServerInfoResp
  52. )
  53. defer func() {
  54. log.Info("Http response [%s]: code [%d]", r.URL.Path, res.Code)
  55. }()
  56. log.Info("Http request: [%s]", r.URL.Path)
  57. cfg := &g.GlbServerCfg.ServerCommonConf
  58. serverStats := svr.statsCollector.GetServer()
  59. res = ServerInfoResp{
  60. Version: version.Full(),
  61. BindPort: cfg.BindPort,
  62. BindUdpPort: cfg.BindUdpPort,
  63. VhostHttpPort: cfg.VhostHttpPort,
  64. VhostHttpsPort: cfg.VhostHttpsPort,
  65. KcpBindPort: cfg.KcpBindPort,
  66. SubdomainHost: cfg.SubDomainHost,
  67. MaxPoolCount: cfg.MaxPoolCount,
  68. MaxPortsPerClient: cfg.MaxPortsPerClient,
  69. HeartBeatTimeout: cfg.HeartBeatTimeout,
  70. TotalTrafficIn: serverStats.TotalTrafficIn,
  71. TotalTrafficOut: serverStats.TotalTrafficOut,
  72. CurConns: serverStats.CurConns,
  73. ClientCounts: serverStats.ClientCounts,
  74. ProxyTypeCounts: serverStats.ProxyTypeCounts,
  75. }
  76. buf, _ = json.Marshal(&res)
  77. w.Write(buf)
  78. }
  79. type BaseOutConf struct {
  80. config.BaseProxyConf
  81. }
  82. type TcpOutConf struct {
  83. BaseOutConf
  84. RemotePort int `json:"remote_port"`
  85. }
  86. type UdpOutConf struct {
  87. BaseOutConf
  88. RemotePort int `json:"remote_port"`
  89. }
  90. type HttpOutConf struct {
  91. BaseOutConf
  92. config.DomainConf
  93. Locations []string `json:"locations"`
  94. HostHeaderRewrite string `json:"host_header_rewrite"`
  95. }
  96. type HttpsOutConf struct {
  97. BaseOutConf
  98. config.DomainConf
  99. }
  100. type StcpOutConf struct {
  101. BaseOutConf
  102. }
  103. type XtcpOutConf struct {
  104. BaseOutConf
  105. }
  106. func getConfByType(proxyType string) interface{} {
  107. switch proxyType {
  108. case consts.TcpProxy:
  109. return &TcpOutConf{}
  110. case consts.UdpProxy:
  111. return &UdpOutConf{}
  112. case consts.HttpProxy:
  113. return &HttpOutConf{}
  114. case consts.HttpsProxy:
  115. return &HttpsOutConf{}
  116. case consts.StcpProxy:
  117. return &StcpOutConf{}
  118. case consts.XtcpProxy:
  119. return &XtcpOutConf{}
  120. default:
  121. return nil
  122. }
  123. }
  124. // Get proxy info.
  125. type ProxyStatsInfo struct {
  126. Name string `json:"name"`
  127. Conf interface{} `json:"conf"`
  128. TodayTrafficIn int64 `json:"today_traffic_in"`
  129. TodayTrafficOut int64 `json:"today_traffic_out"`
  130. CurConns int64 `json:"cur_conns"`
  131. LastStartTime string `json:"last_start_time"`
  132. LastCloseTime string `json:"last_close_time"`
  133. Status string `json:"status"`
  134. }
  135. type GetProxyInfoResp struct {
  136. GeneralResponse
  137. Proxies []*ProxyStatsInfo `json:"proxies"`
  138. }
  139. // api/proxy/:type
  140. func (svr *Service) ApiProxyByType(w http.ResponseWriter, r *http.Request) {
  141. var (
  142. buf []byte
  143. res GetProxyInfoResp
  144. )
  145. params := mux.Vars(r)
  146. proxyType := params["type"]
  147. defer func() {
  148. log.Info("Http response [%s]: code [%d]", r.URL.Path, res.Code)
  149. log.Info(r.URL.Path)
  150. log.Info(r.URL.RawPath)
  151. }()
  152. log.Info("Http request: [%s]", r.URL.Path)
  153. res.Proxies = svr.getProxyStatsByType(proxyType)
  154. buf, _ = json.Marshal(&res)
  155. w.Write(buf)
  156. }
  157. func (svr *Service) getProxyStatsByType(proxyType string) (proxyInfos []*ProxyStatsInfo) {
  158. proxyStats := svr.statsCollector.GetProxiesByType(proxyType)
  159. proxyInfos = make([]*ProxyStatsInfo, 0, len(proxyStats))
  160. for _, ps := range proxyStats {
  161. proxyInfo := &ProxyStatsInfo{}
  162. if pxy, ok := svr.pxyManager.GetByName(ps.Name); ok {
  163. content, err := json.Marshal(pxy.GetConf())
  164. if err != nil {
  165. log.Warn("marshal proxy [%s] conf info error: %v", ps.Name, err)
  166. continue
  167. }
  168. proxyInfo.Conf = getConfByType(ps.Type)
  169. if err = json.Unmarshal(content, &proxyInfo.Conf); err != nil {
  170. log.Warn("unmarshal proxy [%s] conf info error: %v", ps.Name, err)
  171. continue
  172. }
  173. proxyInfo.Status = consts.Online
  174. } else {
  175. proxyInfo.Status = consts.Offline
  176. }
  177. proxyInfo.Name = ps.Name
  178. proxyInfo.TodayTrafficIn = ps.TodayTrafficIn
  179. proxyInfo.TodayTrafficOut = ps.TodayTrafficOut
  180. proxyInfo.CurConns = ps.CurConns
  181. proxyInfo.LastStartTime = ps.LastStartTime
  182. proxyInfo.LastCloseTime = ps.LastCloseTime
  183. proxyInfos = append(proxyInfos, proxyInfo)
  184. }
  185. return
  186. }
  187. // Get proxy info by name.
  188. type GetProxyStatsResp struct {
  189. GeneralResponse
  190. Name string `json:"name"`
  191. Conf interface{} `json:"conf"`
  192. TodayTrafficIn int64 `json:"today_traffic_in"`
  193. TodayTrafficOut int64 `json:"today_traffic_out"`
  194. CurConns int64 `json:"cur_conns"`
  195. LastStartTime string `json:"last_start_time"`
  196. LastCloseTime string `json:"last_close_time"`
  197. Status string `json:"status"`
  198. }
  199. // api/proxy/:type/:name
  200. func (svr *Service) ApiProxyByTypeAndName(w http.ResponseWriter, r *http.Request) {
  201. var (
  202. buf []byte
  203. res GetProxyStatsResp
  204. )
  205. params := mux.Vars(r)
  206. proxyType := params["type"]
  207. name := params["name"]
  208. defer func() {
  209. log.Info("Http response [%s]: code [%d]", r.URL.Path, res.Code)
  210. }()
  211. log.Info("Http request: [%s]", r.URL.Path)
  212. res = svr.getProxyStatsByTypeAndName(proxyType, name)
  213. buf, _ = json.Marshal(&res)
  214. w.Write(buf)
  215. }
  216. func (svr *Service) getProxyStatsByTypeAndName(proxyType string, proxyName string) (proxyInfo GetProxyStatsResp) {
  217. proxyInfo.Name = proxyName
  218. ps := svr.statsCollector.GetProxiesByTypeAndName(proxyType, proxyName)
  219. if ps == nil {
  220. proxyInfo.Code = 1
  221. proxyInfo.Msg = "no proxy info found"
  222. } else {
  223. if pxy, ok := svr.pxyManager.GetByName(proxyName); ok {
  224. content, err := json.Marshal(pxy.GetConf())
  225. if err != nil {
  226. log.Warn("marshal proxy [%s] conf info error: %v", ps.Name, err)
  227. proxyInfo.Code = 2
  228. proxyInfo.Msg = "parse conf error"
  229. return
  230. }
  231. proxyInfo.Conf = getConfByType(ps.Type)
  232. if err = json.Unmarshal(content, &proxyInfo.Conf); err != nil {
  233. log.Warn("unmarshal proxy [%s] conf info error: %v", ps.Name, err)
  234. proxyInfo.Code = 2
  235. proxyInfo.Msg = "parse conf error"
  236. return
  237. }
  238. proxyInfo.Status = consts.Online
  239. } else {
  240. proxyInfo.Status = consts.Offline
  241. }
  242. proxyInfo.TodayTrafficIn = ps.TodayTrafficIn
  243. proxyInfo.TodayTrafficOut = ps.TodayTrafficOut
  244. proxyInfo.CurConns = ps.CurConns
  245. proxyInfo.LastStartTime = ps.LastStartTime
  246. proxyInfo.LastCloseTime = ps.LastCloseTime
  247. }
  248. return
  249. }
  250. // api/traffic/:name
  251. type GetProxyTrafficResp struct {
  252. GeneralResponse
  253. Name string `json:"name"`
  254. TrafficIn []int64 `json:"traffic_in"`
  255. TrafficOut []int64 `json:"traffic_out"`
  256. }
  257. func (svr *Service) ApiProxyTraffic(w http.ResponseWriter, r *http.Request) {
  258. var (
  259. buf []byte
  260. res GetProxyTrafficResp
  261. )
  262. params := mux.Vars(r)
  263. name := params["name"]
  264. defer func() {
  265. log.Info("Http response [%s]: code [%d]", r.URL.Path, res.Code)
  266. }()
  267. log.Info("Http request: [%s]", r.URL.Path)
  268. res.Name = name
  269. proxyTrafficInfo := svr.statsCollector.GetProxyTraffic(name)
  270. if proxyTrafficInfo == nil {
  271. res.Code = 1
  272. res.Msg = "no proxy info found"
  273. } else {
  274. res.TrafficIn = proxyTrafficInfo.TrafficIn
  275. res.TrafficOut = proxyTrafficInfo.TrafficOut
  276. }
  277. buf, _ = json.Marshal(&res)
  278. w.Write(buf)
  279. }