dashboard_api.go 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  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. // 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) {
  50. var (
  51. buf []byte
  52. res ServerInfoResp
  53. )
  54. defer func() {
  55. log.Info("Http response [%s]: code [%d]", r.URL.Path, res.Code)
  56. }()
  57. log.Info("Http request: [%s]", r.URL.Path)
  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. type BaseOutConf struct {
  82. config.BaseProxyConf
  83. }
  84. type TcpOutConf struct {
  85. BaseOutConf
  86. RemotePort int `json:"remote_port"`
  87. }
  88. type UdpOutConf struct {
  89. BaseOutConf
  90. RemotePort int `json:"remote_port"`
  91. }
  92. type HttpOutConf struct {
  93. BaseOutConf
  94. config.DomainConf
  95. Locations []string `json:"locations"`
  96. HostHeaderRewrite string `json:"host_header_rewrite"`
  97. }
  98. type HttpsOutConf struct {
  99. BaseOutConf
  100. config.DomainConf
  101. }
  102. type StcpOutConf struct {
  103. BaseOutConf
  104. }
  105. type XtcpOutConf struct {
  106. BaseOutConf
  107. }
  108. func getConfByType(proxyType string) interface{} {
  109. switch proxyType {
  110. case consts.TcpProxy:
  111. return &TcpOutConf{}
  112. case consts.UdpProxy:
  113. return &UdpOutConf{}
  114. case consts.HttpProxy:
  115. return &HttpOutConf{}
  116. case consts.HttpsProxy:
  117. return &HttpsOutConf{}
  118. case consts.StcpProxy:
  119. return &StcpOutConf{}
  120. case consts.XtcpProxy:
  121. return &XtcpOutConf{}
  122. default:
  123. return nil
  124. }
  125. }
  126. // Get proxy info.
  127. type ProxyStatsInfo struct {
  128. Name string `json:"name"`
  129. Conf interface{} `json:"conf"`
  130. TodayTrafficIn int64 `json:"today_traffic_in"`
  131. TodayTrafficOut int64 `json:"today_traffic_out"`
  132. CurConns int64 `json:"cur_conns"`
  133. LastStartTime string `json:"last_start_time"`
  134. LastCloseTime string `json:"last_close_time"`
  135. Status string `json:"status"`
  136. }
  137. type GetProxyInfoResp struct {
  138. GeneralResponse
  139. Proxies []*ProxyStatsInfo `json:"proxies"`
  140. }
  141. // api/proxy/:type
  142. func apiProxyByType(w http.ResponseWriter, r *http.Request) {
  143. var (
  144. buf []byte
  145. res GetProxyInfoResp
  146. )
  147. params := mux.Vars(r)
  148. proxyType := params["type"]
  149. defer func() {
  150. log.Info("Http response [%s]: code [%d]", r.URL.Path, res.Code)
  151. log.Info(r.URL.Path)
  152. log.Info(r.URL.RawPath)
  153. }()
  154. log.Info("Http request: [%s]", r.URL.Path)
  155. res.Proxies = getProxyStatsByType(proxyType)
  156. buf, _ = json.Marshal(&res)
  157. w.Write(buf)
  158. }
  159. func getProxyStatsByType(proxyType string) (proxyInfos []*ProxyStatsInfo) {
  160. proxyStats := StatsGetProxiesByType(proxyType)
  161. proxyInfos = make([]*ProxyStatsInfo, 0, len(proxyStats))
  162. for _, ps := range proxyStats {
  163. proxyInfo := &ProxyStatsInfo{}
  164. if pxy, ok := ServerService.pxyManager.GetByName(ps.Name); ok {
  165. content, err := json.Marshal(pxy.GetConf())
  166. if err != nil {
  167. log.Warn("marshal proxy [%s] conf info error: %v", ps.Name, err)
  168. continue
  169. }
  170. proxyInfo.Conf = getConfByType(ps.Type)
  171. if err = json.Unmarshal(content, &proxyInfo.Conf); err != nil {
  172. log.Warn("unmarshal proxy [%s] conf info error: %v", ps.Name, err)
  173. continue
  174. }
  175. proxyInfo.Status = consts.Online
  176. } else {
  177. proxyInfo.Status = consts.Offline
  178. }
  179. proxyInfo.Name = ps.Name
  180. proxyInfo.TodayTrafficIn = ps.TodayTrafficIn
  181. proxyInfo.TodayTrafficOut = ps.TodayTrafficOut
  182. proxyInfo.CurConns = ps.CurConns
  183. proxyInfo.LastStartTime = ps.LastStartTime
  184. proxyInfo.LastCloseTime = ps.LastCloseTime
  185. proxyInfos = append(proxyInfos, proxyInfo)
  186. }
  187. return
  188. }
  189. // Get proxy info by name.
  190. type GetProxyStatsResp struct {
  191. GeneralResponse
  192. Name string `json:"name"`
  193. Conf interface{} `json:"conf"`
  194. TodayTrafficIn int64 `json:"today_traffic_in"`
  195. TodayTrafficOut int64 `json:"today_traffic_out"`
  196. CurConns int64 `json:"cur_conns"`
  197. LastStartTime string `json:"last_start_time"`
  198. LastCloseTime string `json:"last_close_time"`
  199. Status string `json:"status"`
  200. }
  201. // api/proxy/:type/:name
  202. func apiProxyByTypeAndName(w http.ResponseWriter, r *http.Request) {
  203. var (
  204. buf []byte
  205. res GetProxyStatsResp
  206. )
  207. params := mux.Vars(r)
  208. proxyType := params["type"]
  209. name := params["name"]
  210. defer func() {
  211. log.Info("Http response [%s]: code [%d]", r.URL.Path, res.Code)
  212. }()
  213. log.Info("Http request: [%s]", r.URL.Path)
  214. res = getProxyStatsByTypeAndName(proxyType, name)
  215. buf, _ = json.Marshal(&res)
  216. w.Write(buf)
  217. }
  218. func getProxyStatsByTypeAndName(proxyType string, proxyName string) (proxyInfo GetProxyStatsResp) {
  219. proxyInfo.Name = proxyName
  220. ps := StatsGetProxiesByTypeAndName(proxyType, proxyName)
  221. if ps == nil {
  222. proxyInfo.Code = 1
  223. proxyInfo.Msg = "no proxy info found"
  224. } else {
  225. if pxy, ok := ServerService.pxyManager.GetByName(proxyName); ok {
  226. content, err := json.Marshal(pxy.GetConf())
  227. if err != nil {
  228. log.Warn("marshal proxy [%s] conf info error: %v", ps.Name, err)
  229. proxyInfo.Code = 2
  230. proxyInfo.Msg = "parse conf error"
  231. return
  232. }
  233. proxyInfo.Conf = getConfByType(ps.Type)
  234. if err = json.Unmarshal(content, &proxyInfo.Conf); err != nil {
  235. log.Warn("unmarshal proxy [%s] conf info error: %v", ps.Name, err)
  236. proxyInfo.Code = 2
  237. proxyInfo.Msg = "parse conf error"
  238. return
  239. }
  240. proxyInfo.Status = consts.Online
  241. } else {
  242. proxyInfo.Status = consts.Offline
  243. }
  244. proxyInfo.TodayTrafficIn = ps.TodayTrafficIn
  245. proxyInfo.TodayTrafficOut = ps.TodayTrafficOut
  246. proxyInfo.CurConns = ps.CurConns
  247. proxyInfo.LastStartTime = ps.LastStartTime
  248. proxyInfo.LastCloseTime = ps.LastCloseTime
  249. }
  250. return
  251. }
  252. // api/traffic/:name
  253. type GetProxyTrafficResp struct {
  254. GeneralResponse
  255. Name string `json:"name"`
  256. TrafficIn []int64 `json:"traffic_in"`
  257. TrafficOut []int64 `json:"traffic_out"`
  258. }
  259. func apiProxyTraffic(w http.ResponseWriter, r *http.Request) {
  260. var (
  261. buf []byte
  262. res GetProxyTrafficResp
  263. )
  264. params := mux.Vars(r)
  265. name := params["name"]
  266. defer func() {
  267. log.Info("Http response [%s]: code [%d]", r.URL.Path, res.Code)
  268. }()
  269. log.Info("Http request: [%s]", r.URL.Path)
  270. res.Name = name
  271. proxyTrafficInfo := StatsGetProxyTraffic(name)
  272. if proxyTrafficInfo == nil {
  273. res.Code = 1
  274. res.Msg = "no proxy info found"
  275. } else {
  276. res.TrafficIn = proxyTrafficInfo.TrafficIn
  277. res.TrafficOut = proxyTrafficInfo.TrafficOut
  278. }
  279. buf, _ = json.Marshal(&res)
  280. w.Write(buf)
  281. }