dynamicproxy.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. package dynamicproxy
  2. import (
  3. "log"
  4. "net/http"
  5. "net/url"
  6. "strconv"
  7. "sync"
  8. "imuslab.com/arozos/mod/network/reverseproxy"
  9. )
  10. /*
  11. Allow users to setup manual proxying for specific path
  12. */
  13. type Router struct {
  14. ListenPort int
  15. ProxyEndpoints *sync.Map
  16. root *ProxyEndpoint
  17. mux http.Handler
  18. useTLS bool
  19. }
  20. type RouterOption struct {
  21. Port int
  22. }
  23. type ProxyEndpoint struct {
  24. Root string
  25. Domain string
  26. RequireTLS bool
  27. Proxy *reverseproxy.ReverseProxy
  28. }
  29. type ProxyHandler struct {
  30. Parent *Router
  31. }
  32. func NewDynamicProxy(port int) (*Router, error) {
  33. newSyncMap := sync.Map{}
  34. thisRouter := Router{
  35. ListenPort: port,
  36. ProxyEndpoints: &newSyncMap,
  37. useTLS: false,
  38. }
  39. thisRouter.mux = &ProxyHandler{
  40. Parent: &thisRouter,
  41. }
  42. return &thisRouter, nil
  43. }
  44. //Start the dynamic routing
  45. func (router *Router) StartProxyService() {
  46. go func() {
  47. err := http.ListenAndServe(":"+strconv.Itoa(router.ListenPort), router.mux)
  48. log.Println("[DynamicProxy] " + err.Error())
  49. }()
  50. }
  51. /*
  52. Add an URL into a custom proxy services
  53. */
  54. func (router *Router) AddProxyService(rootname string, domain string, requireTLS bool) error {
  55. if domain[len(domain)-1:] == "/" {
  56. domain = domain[:len(domain)-1]
  57. }
  58. webProxyEndpoint := domain
  59. if requireTLS {
  60. webProxyEndpoint = "https://" + webProxyEndpoint
  61. } else {
  62. webProxyEndpoint = "http://" + webProxyEndpoint
  63. }
  64. //Create a new proxy agent for this root
  65. path, err := url.Parse(webProxyEndpoint)
  66. if err != nil {
  67. return err
  68. }
  69. proxy := reverseproxy.NewReverseProxy(path)
  70. router.ProxyEndpoints.Store(rootname, &ProxyEndpoint{
  71. Root: rootname,
  72. Domain: domain,
  73. RequireTLS: requireTLS,
  74. Proxy: proxy,
  75. })
  76. return nil
  77. }
  78. /*
  79. Add an default router for the proxy server
  80. */
  81. func (router *Router) SetRootProxy(proxyLocation string, requireTLS bool) error {
  82. if proxyLocation[len(proxyLocation)-1:] == "/" {
  83. proxyLocation = proxyLocation[:len(proxyLocation)-1]
  84. }
  85. webProxyEndpoint := proxyLocation
  86. if requireTLS {
  87. webProxyEndpoint = "https://" + webProxyEndpoint
  88. } else {
  89. webProxyEndpoint = "http://" + webProxyEndpoint
  90. }
  91. //Create a new proxy agent for this root
  92. path, err := url.Parse(webProxyEndpoint)
  93. if err != nil {
  94. return err
  95. }
  96. proxy := reverseproxy.NewReverseProxy(path)
  97. rootEndpoint := ProxyEndpoint{
  98. Root: "/",
  99. Domain: proxyLocation,
  100. RequireTLS: requireTLS,
  101. Proxy: proxy,
  102. }
  103. router.root = &rootEndpoint
  104. return nil
  105. }
  106. //Do all the main routing in here
  107. func (h *ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  108. targetProxyEndpoint := h.Parent.getTargetProxyEndpointFromRequestURI(r.RequestURI)
  109. log.Println(targetProxyEndpoint)
  110. if targetProxyEndpoint != nil {
  111. h.proxyRequest(w, r, targetProxyEndpoint)
  112. } else {
  113. h.proxyRequest(w, r, h.Parent.root)
  114. }
  115. }