vdir.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  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") //Support root and host
  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. //Append the virtual directory entry to the endpoint
  115. targetProxyEndpoint.VirtualDirectories = append(targetProxyEndpoint.VirtualDirectories, &newVirtualDirectoryRouter)
  116. //Prepare to replace the current routing rule
  117. readyRoutingRule, err := dynamicProxyRouter.PrepareProxyRoute(targetProxyEndpoint)
  118. if err != nil {
  119. utils.SendErrorResponse(w, err.Error())
  120. return
  121. }
  122. if eptype == "root" {
  123. //Replace the root router
  124. dynamicProxyRouter.Root = readyRoutingRule
  125. } else {
  126. targetProxyEndpoint.Remove()
  127. dynamicProxyRouter.AddProxyRouteToRuntime(readyRoutingRule)
  128. }
  129. //Save it to file
  130. SaveReverseProxyConfig(targetProxyEndpoint)
  131. // Update uptime monitor
  132. UpdateUptimeMonitorTargets()
  133. utils.SendOK(w)
  134. }
  135. func ReverseProxyDeleteVdir(w http.ResponseWriter, r *http.Request) {
  136. eptype, err := utils.PostPara(r, "type") //Support root and host
  137. if err != nil {
  138. utils.SendErrorResponse(w, "type not defined")
  139. return
  140. }
  141. vdir, err := utils.PostPara(r, "vdir")
  142. if err != nil {
  143. utils.SendErrorResponse(w, "vdir matching key not defined")
  144. return
  145. }
  146. var targetEndpoint *dynamicproxy.ProxyEndpoint
  147. if eptype == "root" {
  148. targetEndpoint = dynamicProxyRouter.Root
  149. } else if eptype == "host" {
  150. //Proxy rule
  151. matchingPath, err := utils.PostPara(r, "path")
  152. if err != nil {
  153. utils.SendErrorResponse(w, "matching path not defined")
  154. return
  155. }
  156. ept, err := dynamicProxyRouter.LoadProxy(matchingPath)
  157. if err != nil {
  158. utils.SendErrorResponse(w, "target proxy rule not found")
  159. return
  160. }
  161. targetEndpoint = ept
  162. } else {
  163. utils.SendErrorResponse(w, "invalid endpoint type")
  164. return
  165. }
  166. //Load the vdir from endpoint
  167. err = targetEndpoint.RemoveVirtualDirectoryRuleByMatchingPath(vdir)
  168. if err != nil {
  169. utils.SendErrorResponse(w, err.Error())
  170. return
  171. }
  172. err = SaveReverseProxyConfig(targetEndpoint)
  173. if err != nil {
  174. SystemWideLogger.PrintAndLog("Config", "Fail to write vdir rules update to config file", err)
  175. utils.SendErrorResponse(w, "unable to write changes to file")
  176. return
  177. }
  178. utils.SendOK(w)
  179. }
  180. func ReverseProxyEditVdir(w http.ResponseWriter, r *http.Request) {
  181. }