github.com/voedger/voedger@v0.0.0-20240520144910-273e84102129/pkg/sys/it/reverseproxy_test.go (about) 1 /* 2 * Copyright (c) 2021-present unTill Pro, Ltd. 3 */ 4 5 package sys_it 6 7 import ( 8 "context" 9 "errors" 10 "io" 11 "net" 12 "net/http" 13 "sync" 14 "testing" 15 16 "github.com/stretchr/testify/require" 17 18 coreutils "github.com/voedger/voedger/pkg/utils" 19 it "github.com/voedger/voedger/pkg/vit" 20 ) 21 22 func TestBasicUsage_ReverseProxy(t *testing.T) { 23 require := require.New(t) 24 vit := it.NewVIT(t, &it.SharedConfig_App1) 25 defer vit.TearDown() 26 27 targetListener, err := net.Listen("tcp", coreutils.ServerAddress(it.TestServicePort)) 28 require.NoError(err) 29 errs := make(chan error) 30 targetHandler := targetHandler{t, &sync.Mutex{}, "", ""} 31 targetServer := http.Server{ 32 Handler: &targetHandler, 33 } 34 go func() { 35 errs <- targetServer.Serve(targetListener) 36 }() 37 38 body := `world` 39 40 cases := map[string]string{ 41 "grafana/foo": "/grafana/foo", 42 "grafana/foo/bar/": "/grafana/foo/bar/", 43 "grafana-rewrite/foo": "/rewritten/foo", 44 "unknown/foo": "/not-found/unknown/foo", 45 46 // https://dev.untill.com/projects/#!627070 47 "api/untill/airs-bp//c.air.StoreSubscriptionProfile": "/not-found/api/untill/airs-bp//c.air.StoreSubscriptionProfile", 48 } 49 50 for srcURL, expectedURLPath := range cases { 51 targetHandler.setExpectedURLPath(expectedURLPath) 52 53 // resp := vit.PostFree(fmt.Sprintf("http://127.0.0.1:%s/%s", vit.IFederation.URL().Port(), srcURL), body) 54 resp := vit.POST(srcURL, body) 55 require.Equal(`hello world`, resp.Body) // guarantees that expectedURLPath is checked by the handler 56 } 57 58 t.Run("route domain", func(t *testing.T) { 59 targetHandler.setExpectedURLPath("/grafana/foo/") 60 targetHandler.setExpectedHost("127.0.0.1") 61 // resp := vit.PostFree(fmt.Sprintf("http://localhost:%s/grafana/foo/?Datadfsdfsdfsdfdf", vit.IFederation.URL().Port()), body) 62 resp := vit.POST("grafana/foo/?Datadfsdfsdfsdfdf", body) 63 require.Equal(`hello world`, resp.Body) 64 }) 65 66 // stop everything 67 require.NoError(targetServer.Shutdown(context.Background())) 68 err = <-errs 69 if !errors.Is(err, http.ErrServerClosed) { 70 t.Fatal(err) 71 } 72 targetListener.Close() 73 74 } 75 76 type targetHandler struct { 77 t *testing.T 78 lock sync.Locker 79 expectedURLPath string 80 expectedHost string 81 } 82 83 func (h *targetHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { 84 rw.WriteHeader(http.StatusOK) 85 body, err := io.ReadAll(req.Body) 86 require.NoError(h.t, err) 87 req.Close = true 88 req.Body.Close() 89 if len(h.expectedHost) > 0 { 90 require.Contains(h.t, req.Host, h.expectedHost) // check localhost->127.0.0.1 translation by RouteDomains rule 91 } 92 require.Equal(h.t, h.getExpectedURLPath(), req.URL.Path) 93 require.Equal(h.t, http.MethodPost, req.Method, req.URL.Path) 94 _, err = rw.Write([]byte("hello " + string(body))) // test will be failed in case of any error 95 require.NoError(h.t, err) 96 } 97 98 func (h *targetHandler) setExpectedHost(expectedHost string) { 99 h.lock.Lock() 100 h.expectedHost = expectedHost 101 h.lock.Unlock() 102 } 103 104 func (h *targetHandler) setExpectedURLPath(expectedURLPath string) { 105 h.lock.Lock() 106 h.expectedURLPath = expectedURLPath 107 h.lock.Unlock() 108 } 109 func (h *targetHandler) getExpectedURLPath() string { 110 h.lock.Lock() 111 defer h.lock.Unlock() 112 return h.expectedURLPath 113 } 114 115 // func TestHTTPS(t *testing.T) { 116 // testApp := setUp(t, withCmdLineArgs("--router-port", strconv.Itoa(router.HTTPSPort), "--router-http01-challenge-host", "rtrtyry")) 117 // defer tearDown(testApp) 118 119 // resp := postURL(t, fmt.Sprintf("https://localhost:%d/unknown", router.HTTPSPort), nil) 120 // defer resp.Body.Close() 121 122 // respBody := readOK(t, resp) 123 // log.Println(string(respBody)) 124 // }