github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/pkg/baseurl/server.go (about) 1 package baseurl 2 3 import ( 4 "fmt" 5 "log" 6 "net/http" 7 "net/http/httputil" 8 "net/url" 9 "strings" 10 "time" 11 12 "github.com/pyroscope-io/pyroscope/pkg/config" 13 "github.com/sirupsen/logrus" 14 ) 15 16 var upstream string 17 var baseURL string 18 var listenAddr string 19 20 // newProxy takes target host and creates a reverse proxy 21 func newProxy(targetHost string) (http.Handler, error) { 22 target, err := url.Parse(targetHost) 23 if err != nil { 24 return nil, err 25 } 26 27 p := httputil.NewSingleHostReverseProxy(target) 28 p.Director = func(r *http.Request) { 29 logrus.Info("before: ", r.URL.String()) 30 r.URL.Scheme = target.Scheme 31 r.URL.Host = target.Host 32 logrus.Info("target.Host", target.Host) 33 r.URL.Path = strings.ReplaceAll(r.URL.Path, target.Path, "") 34 r.URL.RawPath = strings.ReplaceAll(r.URL.RawPath, target.Path, "") 35 logrus.Info("after: ", r.URL.String()) 36 } 37 38 f := func(w http.ResponseWriter, r *http.Request) { 39 if !strings.HasPrefix(r.URL.Path, target.Path) { 40 w.WriteHeader(http.StatusNotFound) 41 w.Write([]byte(fmt.Sprintf("Please visit pyroscope at %s", target.Path))) 42 return 43 } 44 p.ServeHTTP(w, r) 45 } 46 return http.HandlerFunc(f), nil 47 } 48 49 func Start(cfg *config.Server) { 50 proxy, err := newProxy("http://localhost" + cfg.APIBindAddr + cfg.BaseURL) 51 52 if err != nil { 53 panic(err) 54 } 55 56 logger := logrus.New() 57 w := logger.Writer() 58 server := &http.Server{ 59 Addr: cfg.BaseURLBindAddr, 60 Handler: proxy, 61 ReadTimeout: 10 * time.Second, 62 WriteTimeout: 15 * time.Second, 63 IdleTimeout: 30 * time.Second, 64 MaxHeaderBytes: 1 << 20, 65 66 ErrorLog: log.New(w, "", 0), 67 } 68 69 server.ListenAndServe() 70 }