vdir.go 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. package main
  2. /*
  3. Vdir.go
  4. This script handle virtual directory functions
  5. in global scopes
  6. Author: tobychui
  7. */
  8. import (
  9. "encoding/json"
  10. "net/http"
  11. "strings"
  12. "imuslab.com/zoraxy/mod/dynamicproxy"
  13. "imuslab.com/zoraxy/mod/utils"
  14. )
  15. // List the Virtual directory under given proxy rule
  16. func ReverseProxyListVdir(w http.ResponseWriter, r *http.Request) {
  17. eptype, err := utils.PostPara(r, "type") //Support root and host
  18. if err != nil {
  19. utils.SendErrorResponse(w, "type not defined")
  20. return
  21. }
  22. var targetEndpoint *dynamicproxy.ProxyEndpoint
  23. if eptype == "host" {
  24. endpoint, err := utils.PostPara(r, "ep")
  25. if err != nil {
  26. utils.SendErrorResponse(w, "endpoint not defined")
  27. return
  28. }
  29. targetEndpoint, err = dynamicProxyRouter.LoadProxy(endpoint)
  30. if err != nil {
  31. utils.SendErrorResponse(w, "target endpoint not found")
  32. return
  33. }
  34. } else if eptype == "root" {
  35. targetEndpoint = dynamicProxyRouter.Root
  36. } else {
  37. utils.SendErrorResponse(w, "invalid type given")
  38. return
  39. }
  40. //Parse result to json
  41. vdirs := targetEndpoint.VirtualDirectories
  42. if targetEndpoint.VirtualDirectories == nil {
  43. //Avoid returning null to front-end
  44. vdirs = []*dynamicproxy.VirtualDirectoryEndpoint{}
  45. }
  46. js, _ := json.Marshal(vdirs)
  47. utils.SendJSONResponse(w, string(js))
  48. }
  49. // Add Virtual Directory to a host
  50. func ReverseProxyAddVdir(w http.ResponseWriter, r *http.Request) {
  51. eptype, err := utils.PostPara(r, "type") //Support root and host
  52. if err != nil {
  53. utils.SendErrorResponse(w, "type not defined")
  54. return
  55. }
  56. matchingPath, err := utils.PostPara(r, "path")
  57. if err != nil {
  58. utils.SendErrorResponse(w, "matching path not defined")
  59. return
  60. }
  61. //Must start with /
  62. if !strings.HasPrefix(matchingPath, "/") {
  63. matchingPath = "/" + matchingPath
  64. }
  65. domain, err := utils.PostPara(r, "domain")
  66. if err != nil {
  67. utils.SendErrorResponse(w, "target domain not defined")
  68. return
  69. }
  70. reqTLSStr, err := utils.PostPara(r, "reqTLS")
  71. if err != nil {
  72. //Assume false
  73. reqTLSStr = "false"
  74. }
  75. reqTLS := (reqTLSStr == "true")
  76. skipValidStr, err := utils.PostPara(r, "skipValid")
  77. if err != nil {
  78. //Assume false
  79. skipValidStr = "false"
  80. }
  81. skipValid := (skipValidStr == "true")
  82. //Load the target proxy endpoint from runtime
  83. var targetProxyEndpoint *dynamicproxy.ProxyEndpoint
  84. if eptype == "root" {
  85. //Check if root is running at reverse proxy mode
  86. if dynamicProxyRouter.Root.DefaultSiteOption != dynamicproxy.DefaultSite_ReverseProxy {
  87. utils.SendErrorResponse(w, "virtual directory can only be added to root router under proxy mode")
  88. return
  89. }
  90. targetProxyEndpoint = dynamicProxyRouter.Root
  91. } else if eptype == "host" {
  92. endpointID, err := utils.PostPara(r, "endpoint")
  93. if err != nil {
  94. utils.SendErrorResponse(w, "endpoint not defined")
  95. return
  96. }
  97. loadedEndpoint, err := dynamicProxyRouter.LoadProxy(endpointID)
  98. if err != nil {
  99. utils.SendErrorResponse(w, "selected proxy host not exists")
  100. return
  101. }
  102. targetProxyEndpoint = loadedEndpoint
  103. } else {
  104. utils.SendErrorResponse(w, "invalid proxy type given")
  105. return
  106. }
  107. // Create a virtual directory entry base on the above info
  108. newVirtualDirectoryRouter := dynamicproxy.VirtualDirectoryEndpoint{
  109. MatchingPath: matchingPath,
  110. Domain: domain,
  111. RequireTLS: reqTLS,
  112. SkipCertValidations: skipValid,
  113. }
  114. //Add Virtual Directory Rule to this Proxy Endpoint
  115. activatedProxyEndpoint, err := targetProxyEndpoint.AddVirtualDirectoryRule(&newVirtualDirectoryRouter)
  116. if err != nil {
  117. utils.SendErrorResponse(w, err.Error())
  118. return
  119. }
  120. //Save it to file
  121. SaveReverseProxyConfig(activatedProxyEndpoint)
  122. // Update uptime monitor
  123. UpdateUptimeMonitorTargets()
  124. utils.SendOK(w)
  125. }
  126. func ReverseProxyDeleteVdir(w http.ResponseWriter, r *http.Request) {
  127. eptype, err := utils.PostPara(r, "type") //Support root and host
  128. if err != nil {
  129. utils.SendErrorResponse(w, "type not defined")
  130. return
  131. }
  132. vdir, err := utils.PostPara(r, "vdir")
  133. if err != nil {
  134. utils.SendErrorResponse(w, "vdir matching key not defined")
  135. return
  136. }
  137. var targetEndpoint *dynamicproxy.ProxyEndpoint
  138. if eptype == "root" {
  139. targetEndpoint = dynamicProxyRouter.Root
  140. } else if eptype == "host" {
  141. //Proxy rule
  142. matchingPath, err := utils.PostPara(r, "path")
  143. if err != nil {
  144. utils.SendErrorResponse(w, "matching path not defined")
  145. return
  146. }
  147. ept, err := dynamicProxyRouter.LoadProxy(matchingPath)
  148. if err != nil {
  149. utils.SendErrorResponse(w, "target proxy rule not found")
  150. return
  151. }
  152. targetEndpoint = ept
  153. } else {
  154. utils.SendErrorResponse(w, "invalid endpoint type")
  155. return
  156. }
  157. //Delete the Vdir from endpoint
  158. err = targetEndpoint.RemoveVirtualDirectoryRuleByMatchingPath(vdir)
  159. if err != nil {
  160. utils.SendErrorResponse(w, err.Error())
  161. return
  162. }
  163. err = SaveReverseProxyConfig(targetEndpoint)
  164. if err != nil {
  165. SystemWideLogger.PrintAndLog("Config", "Fail to write vdir rules update to config file", err)
  166. utils.SendErrorResponse(w, "unable to write changes to file")
  167. return
  168. }
  169. UpdateUptimeMonitorTargets()
  170. utils.SendOK(w)
  171. }
  172. // Handle update of reverse proxy vdir rules
  173. func ReverseProxyEditVdir(w http.ResponseWriter, r *http.Request) {
  174. eptype, err := utils.PostPara(r, "type") //Support root and host
  175. if err != nil {
  176. utils.SendErrorResponse(w, "type not defined")
  177. return
  178. }
  179. vdir, err := utils.PostPara(r, "vdir")
  180. if err != nil {
  181. utils.SendErrorResponse(w, "vdir matching key not defined")
  182. return
  183. }
  184. domain, err := utils.PostPara(r, "domain")
  185. if err != nil {
  186. utils.SendErrorResponse(w, "target domain not defined")
  187. return
  188. }
  189. reqTLSStr, err := utils.PostPara(r, "reqTLS")
  190. if err != nil {
  191. //Assume false
  192. reqTLSStr = "false"
  193. }
  194. reqTLS := (reqTLSStr == "true")
  195. skipValidStr, err := utils.PostPara(r, "skipValid")
  196. if err != nil {
  197. //Assume false
  198. skipValidStr = "false"
  199. }
  200. skipValid := (skipValidStr == "true")
  201. var targetEndpoint *dynamicproxy.ProxyEndpoint
  202. if eptype == "root" {
  203. targetEndpoint = dynamicProxyRouter.Root
  204. } else if eptype == "host" {
  205. //Proxy rule
  206. matchingPath, err := utils.PostPara(r, "path")
  207. if err != nil {
  208. utils.SendErrorResponse(w, "matching path not defined")
  209. return
  210. }
  211. ept, err := dynamicProxyRouter.LoadProxy(matchingPath)
  212. if err != nil {
  213. utils.SendErrorResponse(w, "target proxy rule not found")
  214. return
  215. }
  216. targetEndpoint = ept
  217. } else {
  218. utils.SendErrorResponse(w, "invalid endpoint type given")
  219. return
  220. }
  221. //Check if the target vdir exists
  222. if targetEndpoint.GetVirtualDirectoryRuleByMatchingPath(vdir) == nil {
  223. utils.SendErrorResponse(w, "target virtual directory rule not exists")
  224. return
  225. }
  226. //Overwrite the target endpoint
  227. newVdirRule := dynamicproxy.VirtualDirectoryEndpoint{
  228. MatchingPath: vdir,
  229. Domain: domain,
  230. RequireTLS: reqTLS,
  231. SkipCertValidations: skipValid,
  232. Disabled: false,
  233. }
  234. targetEndpoint.RemoveVirtualDirectoryRuleByMatchingPath(vdir)
  235. activatedProxyEndpoint, err := targetEndpoint.AddVirtualDirectoryRule(&newVdirRule)
  236. if err != nil {
  237. utils.SendErrorResponse(w, err.Error())
  238. return
  239. }
  240. //Save changes to file
  241. SaveReverseProxyConfig(activatedProxyEndpoint)
  242. UpdateUptimeMonitorTargets()
  243. utils.SendOK(w)
  244. }