Server.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. package dynamicproxy
  2. import (
  3. "fmt"
  4. "net/http"
  5. "os"
  6. "strings"
  7. "imuslab.com/zoraxy/mod/geodb"
  8. )
  9. /*
  10. Server.go
  11. Main server for dynamic proxy core
  12. Routing Handler Priority (High to Low)
  13. - Blacklist
  14. - Whitelist
  15. - Redirectable
  16. - Subdomain Routing
  17. - Vitrual Directory Routing
  18. */
  19. func (h *ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  20. /*
  21. General Access Check
  22. */
  23. //Check if this ip is in blacklist
  24. clientIpAddr := geodb.GetRequesterIP(r)
  25. if h.Parent.Option.GeodbStore.IsBlacklisted(clientIpAddr) {
  26. w.Header().Set("Content-Type", "text/html; charset=utf-8")
  27. w.WriteHeader(http.StatusForbidden)
  28. template, err := os.ReadFile("./web/forbidden.html")
  29. if err != nil {
  30. w.Write([]byte("403 - Forbidden"))
  31. } else {
  32. w.Write(template)
  33. }
  34. h.logRequest(r, false, 403, "blacklist", "")
  35. return
  36. }
  37. //Check if this ip is in whitelist
  38. if !h.Parent.Option.GeodbStore.IsWhitelisted(clientIpAddr) {
  39. w.Header().Set("Content-Type", "text/html; charset=utf-8")
  40. w.WriteHeader(http.StatusForbidden)
  41. template, err := os.ReadFile("./web/forbidden.html")
  42. if err != nil {
  43. w.Write([]byte("403 - Forbidden"))
  44. } else {
  45. w.Write(template)
  46. }
  47. h.logRequest(r, false, 403, "whitelist", "")
  48. return
  49. }
  50. /*
  51. Redirection Routing
  52. */
  53. //Check if this is a redirection url
  54. if h.Parent.Option.RedirectRuleTable.IsRedirectable(r) {
  55. statusCode := h.Parent.Option.RedirectRuleTable.HandleRedirect(w, r)
  56. h.logRequest(r, statusCode != 500, statusCode, "redirect", "")
  57. return
  58. }
  59. //Check if there are external routing rule matches.
  60. //If yes, route them via external rr
  61. matchedRoutingRule := h.Parent.GetMatchingRoutingRule(r)
  62. if matchedRoutingRule != nil {
  63. //Matching routing rule found. Let the sub-router handle it
  64. matchedRoutingRule.Route(w, r)
  65. return
  66. }
  67. //Extract request host to see if it is virtual directory or subdomain
  68. domainOnly := r.Host
  69. if strings.Contains(r.Host, ":") {
  70. hostPath := strings.Split(r.Host, ":")
  71. domainOnly = hostPath[0]
  72. }
  73. /*
  74. Subdomain Routing
  75. */
  76. if strings.Contains(r.Host, ".") {
  77. //This might be a subdomain. See if there are any subdomain proxy router for this
  78. sep := h.Parent.getSubdomainProxyEndpointFromHostname(domainOnly)
  79. if sep != nil {
  80. if sep.RequireBasicAuth {
  81. err := h.handleBasicAuthRouting(w, r, sep)
  82. if err != nil {
  83. return
  84. }
  85. }
  86. h.subdomainRequest(w, r, sep)
  87. return
  88. }
  89. }
  90. /*
  91. Virtual Directory Routing
  92. */
  93. //Clean up the request URI
  94. proxyingPath := strings.TrimSpace(r.RequestURI)
  95. targetProxyEndpoint := h.Parent.getTargetProxyEndpointFromRequestURI(proxyingPath)
  96. if targetProxyEndpoint != nil {
  97. if targetProxyEndpoint.RequireBasicAuth {
  98. err := h.handleBasicAuthRouting(w, r, targetProxyEndpoint)
  99. if err != nil {
  100. return
  101. }
  102. }
  103. h.proxyRequest(w, r, targetProxyEndpoint)
  104. } else if !strings.HasSuffix(proxyingPath, "/") {
  105. potentialProxtEndpoint := h.Parent.getTargetProxyEndpointFromRequestURI(proxyingPath + "/")
  106. fmt.Println(strings.HasSuffix(proxyingPath, "/"))
  107. if potentialProxtEndpoint != nil {
  108. //Missing tailing slash. Redirect to target proxy endpoint
  109. http.Redirect(w, r, r.RequestURI+"/", http.StatusTemporaryRedirect)
  110. } else {
  111. //Passthrough the request to root
  112. h.proxyRequest(w, r, h.Parent.Root)
  113. }
  114. } else {
  115. //No routing rules found. Route to root.
  116. h.proxyRequest(w, r, h.Parent.Root)
  117. }
  118. }