blob: 733ca46934d903c604f97fa37e03107ffd7cf473 [file] [log] [blame]
Filip Tehlarb15a0002022-11-10 12:34:17 +01001package main
2
Filip Tehlarc204c872022-12-21 08:59:16 +01003import (
Matus Fabian82ad9662024-06-04 19:00:00 +02004 "bytes"
Filip Tehlar8df3de42023-01-27 13:14:34 +01005 "fmt"
Matus Fabianba9ea132024-07-12 11:07:17 +02006 "github.com/onsi/gomega/ghttp"
Matus Fabian2d1f0e62024-06-06 11:24:36 +02007 "github.com/onsi/gomega/gmeasure"
8 "io"
Matus Fabiand086a362024-06-27 13:20:10 +02009 "net"
Matus Fabianb7a9ed72024-05-10 16:20:40 +020010 "net/http"
Matus Fabiand086a362024-06-27 13:20:10 +020011 "net/http/httptrace"
12 "os"
Matus Fabiand46e6742024-07-31 16:08:40 +020013 "strconv"
Matus Fabian5c4c1b62024-06-28 16:11:04 +020014 "sync"
Adrian Villincee15aa2024-03-14 11:42:55 -040015 "time"
16
Adrian Villin4677d922024-06-14 09:32:39 +020017 . "fd.io/hs-test/infra"
Matus Fabian5c4c1b62024-06-28 16:11:04 +020018 . "github.com/onsi/ginkgo/v2"
Filip Tehlarc204c872022-12-21 08:59:16 +010019)
20
Adrian Villincee15aa2024-03-14 11:42:55 -040021func init() {
Adrian Villin4677d922024-06-14 09:32:39 +020022 RegisterVethTests(HttpCliTest, HttpCliConnectErrorTest)
Matus Fabianba9ea132024-07-12 11:07:17 +020023 RegisterSoloVethTests(HttpClientGetMemLeakTest)
Matus Fabiand086a362024-06-27 13:20:10 +020024 RegisterNoTopoTests(HeaderServerTest, HttpPersistentConnectionTest, HttpPipeliningTest,
Matus Fabianb7a9ed72024-05-10 16:20:40 +020025 HttpStaticMovedTest, HttpStaticNotFoundTest, HttpCliMethodNotAllowedTest,
Matus Fabian82ad9662024-06-04 19:00:00 +020026 HttpCliBadRequestTest, HttpStaticBuildInUrlGetIfStatsTest, HttpStaticBuildInUrlPostIfStatsTest,
27 HttpInvalidRequestLineTest, HttpMethodNotImplementedTest, HttpInvalidHeadersTest,
28 HttpContentLengthTest, HttpStaticBuildInUrlGetIfListTest, HttpStaticBuildInUrlGetVersionTest,
29 HttpStaticMacTimeTest, HttpStaticBuildInUrlGetVersionVerboseTest, HttpVersionNotSupportedTest,
30 HttpInvalidContentLengthTest, HttpInvalidTargetSyntaxTest, HttpStaticPathTraversalTest, HttpUriDecodeTest,
Adrian Villin86fa9432024-08-08 08:56:34 +020031 HttpHeadersTest, HttpStaticFileHandlerTest, HttpStaticFileHandlerDefaultMaxAgeTest, HttpClientTest, HttpClientErrRespTest, HttpClientPostFormTest,
Matus Fabian69123a32024-08-23 17:35:50 +020032 HttpClientPostFileTest, HttpClientPostFilePtrTest, AuthorityFormTargetTest, HttpRequestLineTest)
Matus Fabiand46e6742024-07-31 16:08:40 +020033 RegisterNoTopoSoloTests(HttpStaticPromTest, HttpTpsTest, HttpTpsInterruptModeTest, PromConcurrentConnectionsTest,
Matus Fabian55467552024-08-06 15:55:26 +020034 PromMemLeakTest, HttpClientPostMemLeakTest, HttpInvalidClientRequestMemLeakTest)
Adrian Villincee15aa2024-03-14 11:42:55 -040035}
36
Matus Fabian5409d332024-05-28 13:39:13 +020037const wwwRootPath = "/tmp/www_root"
38
Matus Fabian2d1f0e62024-06-06 11:24:36 +020039func httpDownloadBenchmark(s *HstSuite, experiment *gmeasure.Experiment, data interface{}) {
40 url, isValid := data.(string)
Adrian Villin4677d922024-06-14 09:32:39 +020041 s.AssertEqual(true, isValid)
42 client := NewHttpClient()
Matus Fabian2d1f0e62024-06-06 11:24:36 +020043 req, err := http.NewRequest("GET", url, nil)
Adrian Villin4677d922024-06-14 09:32:39 +020044 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian2d1f0e62024-06-06 11:24:36 +020045 t := time.Now()
46 resp, err := client.Do(req)
Adrian Villin4677d922024-06-14 09:32:39 +020047 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian2d1f0e62024-06-06 11:24:36 +020048 defer resp.Body.Close()
Matus Fabiana647a832024-08-26 18:01:14 +020049 s.AssertHttpStatus(resp, 200)
Matus Fabian2d1f0e62024-06-06 11:24:36 +020050 _, err = io.ReadAll(resp.Body)
Matus Fabiand46e6742024-07-31 16:08:40 +020051 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian2d1f0e62024-06-06 11:24:36 +020052 duration := time.Since(t)
53 experiment.RecordValue("Download Speed", (float64(resp.ContentLength)/1024/1024)/duration.Seconds(), gmeasure.Units("MB/s"), gmeasure.Precision(2))
Matus Fabian2d1f0e62024-06-06 11:24:36 +020054}
55
Adrian Villin1fde9992024-06-24 08:14:05 -040056func HttpTpsInterruptModeTest(s *NoTopoSuite) {
57 HttpTpsTest(s)
58}
59
Matus Fabian2d1f0e62024-06-06 11:24:36 +020060func HttpTpsTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +020061 vpp := s.GetContainerByName("vpp").VppInstance
Matus Fabiana647a832024-08-26 18:01:14 +020062 serverAddress := s.VppAddr()
Matus Fabian2d1f0e62024-06-06 11:24:36 +020063 url := "http://" + serverAddress + ":8080/test_file_10M"
64
Adrian Villin4677d922024-06-14 09:32:39 +020065 vpp.Vppctl("http tps uri tcp://0.0.0.0/8080")
Matus Fabian2d1f0e62024-06-06 11:24:36 +020066
Adrian Villin4677d922024-06-14 09:32:39 +020067 s.RunBenchmark("HTTP tps 10M", 10, 0, httpDownloadBenchmark, url)
Filip Tehlarb15a0002022-11-10 12:34:17 +010068}
69
Matus Fabiand086a362024-06-27 13:20:10 +020070func HttpPersistentConnectionTest(s *NoTopoSuite) {
71 // testing url handler app do not support multi-thread
72 s.SkipIfMultiWorker()
73 vpp := s.GetContainerByName("vpp").VppInstance
Matus Fabiana647a832024-08-26 18:01:14 +020074 serverAddress := s.VppAddr()
Matus Fabiand086a362024-06-27 13:20:10 +020075 s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers"))
76 s.Log(vpp.Vppctl("test-url-handler enable"))
77
78 transport := http.DefaultTransport
79 transport.(*http.Transport).Proxy = nil
80 transport.(*http.Transport).DisableKeepAlives = false
81 client := &http.Client{
82 Transport: transport,
83 Timeout: time.Second * 30,
84 CheckRedirect: func(req *http.Request, via []*http.Request) error {
85 return http.ErrUseLastResponse
86 }}
87
Matus Fabian56cefc82024-08-26 18:26:58 +020088 body := []byte("{\"sandwich\": {\"spam\": 2, \"eggs\": 1}}")
89 req, err := http.NewRequest("POST", "http://"+serverAddress+":80/test3", bytes.NewBuffer(body))
Matus Fabiand086a362024-06-27 13:20:10 +020090 s.AssertNil(err, fmt.Sprint(err))
91 resp, err := client.Do(req)
92 s.AssertNil(err, fmt.Sprint(err))
Matus Fabiand086a362024-06-27 13:20:10 +020093 s.Log(DumpHttpResp(resp, true))
Matus Fabiana647a832024-08-26 18:01:14 +020094 s.AssertHttpStatus(resp, 200)
Matus Fabiand086a362024-06-27 13:20:10 +020095 s.AssertEqual(false, resp.Close)
Matus Fabian56cefc82024-08-26 18:26:58 +020096 s.AssertHttpContentLength(resp, int64(0))
Matus Fabiand086a362024-06-27 13:20:10 +020097 o1 := vpp.Vppctl("show session verbose proto http state ready")
98 s.Log(o1)
99 s.AssertContains(o1, "ESTABLISHED")
100
Matus Fabian56cefc82024-08-26 18:26:58 +0200101 req, err = http.NewRequest("GET", "http://"+serverAddress+":80/test1", nil)
102 s.AssertNil(err, fmt.Sprint(err))
Matus Fabiand086a362024-06-27 13:20:10 +0200103 clientTrace := &httptrace.ClientTrace{
104 GotConn: func(info httptrace.GotConnInfo) {
105 s.AssertEqual(true, info.Reused, "connection not reused")
106 },
107 }
Matus Fabian56cefc82024-08-26 18:26:58 +0200108 req = req.WithContext(httptrace.WithClientTrace(req.Context(), clientTrace))
109 resp, err = client.Do(req)
110 s.AssertNil(err, fmt.Sprint(err))
111 s.Log(DumpHttpResp(resp, true))
112 s.AssertHttpStatus(resp, 200)
113 s.AssertEqual(false, resp.Close)
114 s.AssertHttpBody(resp, "hello")
115 o2 := vpp.Vppctl("show session verbose proto http state ready")
116 s.Log(o2)
117 s.AssertContains(o2, "ESTABLISHED")
118 s.AssertEqual(o1, o2)
119
120 req, err = http.NewRequest("GET", "http://"+serverAddress+":80/test2", nil)
Matus Fabiana647a832024-08-26 18:01:14 +0200121 s.AssertNil(err, fmt.Sprint(err))
Matus Fabiand086a362024-06-27 13:20:10 +0200122 req = req.WithContext(httptrace.WithClientTrace(req.Context(), clientTrace))
123 resp, err = client.Do(req)
124 s.AssertNil(err, fmt.Sprint(err))
Matus Fabiand086a362024-06-27 13:20:10 +0200125 s.Log(DumpHttpResp(resp, true))
Matus Fabiana647a832024-08-26 18:01:14 +0200126 s.AssertHttpStatus(resp, 200)
Matus Fabiand086a362024-06-27 13:20:10 +0200127 s.AssertEqual(false, resp.Close)
Matus Fabiana647a832024-08-26 18:01:14 +0200128 s.AssertHttpBody(resp, "some data")
Matus Fabian56cefc82024-08-26 18:26:58 +0200129 o2 = vpp.Vppctl("show session verbose proto http state ready")
Matus Fabiand086a362024-06-27 13:20:10 +0200130 s.Log(o2)
131 s.AssertContains(o2, "ESTABLISHED")
132 s.AssertEqual(o1, o2)
Matus Fabiana647a832024-08-26 18:01:14 +0200133
Matus Fabiand086a362024-06-27 13:20:10 +0200134}
135
136func HttpPipeliningTest(s *NoTopoSuite) {
137 // testing url handler app do not support multi-thread
138 s.SkipIfMultiWorker()
139 vpp := s.GetContainerByName("vpp").VppInstance
Matus Fabiana647a832024-08-26 18:01:14 +0200140 serverAddress := s.VppAddr()
Matus Fabiand086a362024-06-27 13:20:10 +0200141 s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug"))
142 s.Log(vpp.Vppctl("test-url-handler enable"))
143
144 req1 := "GET /test_delayed HTTP/1.1\r\nHost:" + serverAddress + ":80\r\nUser-Agent:test\r\n\r\n"
145 req2 := "GET /test1 HTTP/1.1\r\nHost:" + serverAddress + ":80\r\nUser-Agent:test\r\n\r\n"
146
147 conn, err := net.DialTimeout("tcp", serverAddress+":80", time.Second*30)
148 s.AssertNil(err, fmt.Sprint(err))
149 defer conn.Close()
150 err = conn.SetDeadline(time.Now().Add(time.Second * 15))
151 s.AssertNil(err, fmt.Sprint(err))
152 n, err := conn.Write([]byte(req1))
153 s.AssertNil(err, fmt.Sprint(err))
154 s.AssertEqual(n, len([]rune(req1)))
155 // send second request a bit later so first is already in progress
156 time.Sleep(500 * time.Millisecond)
157 n, err = conn.Write([]byte(req2))
158 s.AssertNil(err, fmt.Sprint(err))
159 s.AssertEqual(n, len([]rune(req2)))
160 reply := make([]byte, 1024)
161 n, err = conn.Read(reply)
162 s.AssertNil(err, fmt.Sprint(err))
163 s.Log(string(reply))
164 s.AssertContains(string(reply), "delayed data", "first request response not received")
165 s.AssertNotContains(string(reply), "hello", "second request response received")
166 // make sure response for second request is not received later
167 _, err = conn.Read(reply)
168 s.AssertMatchError(err, os.ErrDeadlineExceeded, "second request response received")
169}
170
Adrian Villincee15aa2024-03-14 11:42:55 -0400171func HttpCliTest(s *VethsSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200172 serverContainer := s.GetContainerByName("server-vpp")
173 clientContainer := s.GetContainerByName("client-vpp")
Filip Tehlarb15a0002022-11-10 12:34:17 +0100174
Adrian Villin4677d922024-06-14 09:32:39 +0200175 serverVeth := s.GetInterfaceByName(ServerInterfaceName)
Maros Ondrejickaffa3f602023-01-26 10:07:29 +0100176
Adrian Villin4677d922024-06-14 09:32:39 +0200177 serverContainer.VppInstance.Vppctl("http cli server")
Filip Tehlarb15a0002022-11-10 12:34:17 +0100178
Adrian Villin4677d922024-06-14 09:32:39 +0200179 uri := "http://" + serverVeth.Ip4AddressString() + "/80"
Maros Ondrejickaffa3f602023-01-26 10:07:29 +0100180
Adrian Villin4677d922024-06-14 09:32:39 +0200181 o := clientContainer.VppInstance.Vppctl("http cli client" +
Filip Tehlard8944382023-11-27 13:28:36 +0100182 " uri " + uri + " query /show/vlib/graph")
Filip Tehlarb15a0002022-11-10 12:34:17 +0100183
Adrian Villin4677d922024-06-14 09:32:39 +0200184 s.Log(o)
185 s.AssertContains(o, "<html>", "<html> not found in the result!")
Matus Fabianba9ea132024-07-12 11:07:17 +0200186 s.AssertContains(o, "</html>", "</html> not found in the result!")
Filip Tehlarb15a0002022-11-10 12:34:17 +0100187}
Filip Tehlarc204c872022-12-21 08:59:16 +0100188
Matus Fabian3d008932024-05-13 10:29:11 +0200189func HttpCliConnectErrorTest(s *VethsSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200190 clientContainer := s.GetContainerByName("client-vpp")
Adrian Villin4677d922024-06-14 09:32:39 +0200191 serverVeth := s.GetInterfaceByName(ServerInterfaceName)
Matus Fabian3d008932024-05-13 10:29:11 +0200192
Adrian Villin4677d922024-06-14 09:32:39 +0200193 uri := "http://" + serverVeth.Ip4AddressString() + "/80"
Matus Fabian3d008932024-05-13 10:29:11 +0200194
Adrian Villin4677d922024-06-14 09:32:39 +0200195 o := clientContainer.VppInstance.Vppctl("http cli client" +
Matus Fabian3d008932024-05-13 10:29:11 +0200196 " uri " + uri + " query /show/vlib/graph")
197
Adrian Villin4677d922024-06-14 09:32:39 +0200198 s.Log(o)
199 s.AssertContains(o, "failed to connect")
Matus Fabian3d008932024-05-13 10:29:11 +0200200}
201
Matus Fabianba9ea132024-07-12 11:07:17 +0200202func HttpClientTest(s *NoTopoSuite) {
Matus Fabiana647a832024-08-26 18:01:14 +0200203 serverAddress := s.HostAddr()
Matus Fabianba9ea132024-07-12 11:07:17 +0200204 server := ghttp.NewUnstartedServer()
205 l, err := net.Listen("tcp", serverAddress+":80")
206 s.AssertNil(err, fmt.Sprint(err))
207 server.HTTPTestServer.Listener = l
208 server.AppendHandlers(
209 ghttp.CombineHandlers(
Matus Fabiand46e6742024-07-31 16:08:40 +0200210 s.LogHttpReq(true),
Matus Fabianba9ea132024-07-12 11:07:17 +0200211 ghttp.VerifyRequest("GET", "/test"),
212 ghttp.VerifyHeader(http.Header{"User-Agent": []string{"http_cli_client"}}),
Adrian Villin3601b322024-08-19 14:41:35 +0200213 ghttp.VerifyHeader(http.Header{"Accept": []string{"text/html"}}),
Matus Fabianba9ea132024-07-12 11:07:17 +0200214 ghttp.RespondWith(http.StatusOK, "<html><body><p>Hello</p></body></html>"),
215 ))
216 server.Start()
217 defer server.Close()
218 uri := "http://" + serverAddress + "/80"
219 vpp := s.GetContainerByName("vpp").VppInstance
220 o := vpp.Vppctl("http cli client uri " + uri + " query /test")
221
222 s.Log(o)
223 s.AssertContains(o, "<html>", "<html> not found in the result!")
224 s.AssertContains(o, "</html>", "</html> not found in the result!")
225}
226
227func HttpClientErrRespTest(s *NoTopoSuite) {
Matus Fabiana647a832024-08-26 18:01:14 +0200228 serverAddress := s.HostAddr()
Matus Fabianba9ea132024-07-12 11:07:17 +0200229 server := ghttp.NewUnstartedServer()
230 l, err := net.Listen("tcp", serverAddress+":80")
231 s.AssertNil(err, fmt.Sprint(err))
232 server.HTTPTestServer.Listener = l
233 server.AppendHandlers(
234 ghttp.CombineHandlers(
Matus Fabiand46e6742024-07-31 16:08:40 +0200235 s.LogHttpReq(true),
Matus Fabianba9ea132024-07-12 11:07:17 +0200236 ghttp.VerifyRequest("GET", "/test"),
237 ghttp.RespondWith(http.StatusNotFound, "404: Not Found"),
238 ))
239 server.Start()
240 defer server.Close()
241 uri := "http://" + serverAddress + "/80"
242 vpp := s.GetContainerByName("vpp").VppInstance
243 o := vpp.Vppctl("http cli client uri " + uri + " query /test")
244
245 s.Log(o)
246 s.AssertContains(o, "404: Not Found", "error not found in the result!")
247}
248
Matus Fabiand46e6742024-07-31 16:08:40 +0200249func HttpClientPostFormTest(s *NoTopoSuite) {
Matus Fabiana647a832024-08-26 18:01:14 +0200250 serverAddress := s.HostAddr()
Matus Fabiand46e6742024-07-31 16:08:40 +0200251 body := "field1=value1&field2=value2"
252
253 server := ghttp.NewUnstartedServer()
254 l, err := net.Listen("tcp", serverAddress+":80")
255 s.AssertNil(err, fmt.Sprint(err))
256 server.HTTPTestServer.Listener = l
257 server.AppendHandlers(
258 ghttp.CombineHandlers(
259 s.LogHttpReq(true),
260 ghttp.VerifyRequest("POST", "/test"),
Adrian Villin3601b322024-08-19 14:41:35 +0200261 ghttp.VerifyContentType("application/x-www-form-urlencoded"),
Matus Fabiand46e6742024-07-31 16:08:40 +0200262 ghttp.VerifyBody([]byte(body)),
263 ghttp.RespondWith(http.StatusOK, nil),
264 ))
265 server.Start()
266 defer server.Close()
267
268 uri := "http://" + serverAddress + "/80"
269 vpp := s.GetContainerByName("vpp").VppInstance
270 o := vpp.Vppctl("http post uri " + uri + " target /test data " + body)
271
272 s.Log(o)
273 s.AssertNotContains(o, "error")
274}
275
276func httpClientPostFile(s *NoTopoSuite, usePtr bool, fileSize int) {
Matus Fabiana647a832024-08-26 18:01:14 +0200277 serverAddress := s.HostAddr()
Matus Fabiand46e6742024-07-31 16:08:40 +0200278 vpp := s.GetContainerByName("vpp").VppInstance
279 fileName := "/tmp/test_file.txt"
280 s.Log(vpp.Container.Exec("fallocate -l " + strconv.Itoa(fileSize) + " " + fileName))
281 s.Log(vpp.Container.Exec("ls -la " + fileName))
282
283 server := ghttp.NewUnstartedServer()
284 l, err := net.Listen("tcp", serverAddress+":80")
285 s.AssertNil(err, fmt.Sprint(err))
286 server.HTTPTestServer.Listener = l
287 server.AppendHandlers(
288 ghttp.CombineHandlers(
289 s.LogHttpReq(false),
290 ghttp.VerifyRequest("POST", "/test"),
291 ghttp.VerifyHeader(http.Header{"Content-Length": []string{strconv.Itoa(fileSize)}}),
Adrian Villin3601b322024-08-19 14:41:35 +0200292 ghttp.VerifyContentType("application/octet-stream"),
Matus Fabiand46e6742024-07-31 16:08:40 +0200293 ghttp.RespondWith(http.StatusOK, nil),
294 ))
295 server.Start()
296 defer server.Close()
297
298 uri := "http://" + serverAddress + "/80"
299 cmd := "http post uri " + uri + " target /test file " + fileName
300 if usePtr {
301 cmd += " use-ptr"
302 }
303 o := vpp.Vppctl(cmd)
304
305 s.Log(o)
306 s.AssertNotContains(o, "error")
307}
308
309func HttpClientPostFileTest(s *NoTopoSuite) {
310 httpClientPostFile(s, false, 32768)
311}
312
313func HttpClientPostFilePtrTest(s *NoTopoSuite) {
314 httpClientPostFile(s, true, 131072)
315}
316
Matus Fabiand58177c2024-08-08 12:50:32 +0200317func cliTestAuthority(s *NoTopoSuite, authority string) {
318 o := s.GetContainerByName("vpp").VppInstance.Vppctl("test http authority-form " + authority)
319 s.AssertNotContains(o, "error")
320 s.AssertContains(o, authority)
321}
322
323func cliTestAuthorityError(s *NoTopoSuite, authority string) {
324 o := s.GetContainerByName("vpp").VppInstance.Vppctl("test http authority-form " + authority)
325 s.AssertContains(o, "error")
326}
327
328func AuthorityFormTargetTest(s *NoTopoSuite) {
329 cliTestAuthority(s, "10.10.2.45:20")
330 cliTestAuthority(s, "[dead:beef::1234]:443")
331 cliTestAuthorityError(s, "example.com:80")
332 cliTestAuthorityError(s, "10.10.2.45")
333 cliTestAuthorityError(s, "1000.10.2.45:20")
334 cliTestAuthorityError(s, "[xyz0::1234]:443")
335}
336
Adrian Villincee15aa2024-03-14 11:42:55 -0400337func HttpStaticPromTest(s *NoTopoSuite) {
Filip Tehlarcc1475c2023-11-29 12:59:05 +0100338 query := "stats.prom"
Adrian Villin4677d922024-06-14 09:32:39 +0200339 vpp := s.GetContainerByName("vpp").VppInstance
Matus Fabiana647a832024-08-26 18:01:14 +0200340 serverAddress := s.VppAddr()
Adrian Villin4677d922024-06-14 09:32:39 +0200341 s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers"))
342 s.Log(vpp.Vppctl("prom enable"))
Adrian Villincee15aa2024-03-14 11:42:55 -0400343 time.Sleep(time.Second * 5)
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200344 client := NewHttpClient()
345 req, err := http.NewRequest("GET", "http://"+serverAddress+":80/"+query, nil)
346 s.AssertNil(err, fmt.Sprint(err))
347 resp, err := client.Do(req)
348 s.AssertNil(err, fmt.Sprint(err))
349 defer resp.Body.Close()
350 s.Log(DumpHttpResp(resp, false))
Matus Fabiana647a832024-08-26 18:01:14 +0200351 s.AssertHttpStatus(resp, 200)
352 s.AssertHttpHeaderWithValue(resp, "Content-Type", "text/plain")
353 s.AssertGreaterThan(resp.ContentLength, 0)
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200354 _, err = io.ReadAll(resp.Body)
Matus Fabiand46e6742024-07-31 16:08:40 +0200355 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200356}
357
Matus Fabianc712de52024-07-24 12:56:14 +0200358func promReq(s *NoTopoSuite, url string) {
Matus Fabian5c4c1b62024-06-28 16:11:04 +0200359 client := NewHttpClient()
360 req, err := http.NewRequest("GET", url, nil)
361 s.AssertNil(err, fmt.Sprint(err))
362 resp, err := client.Do(req)
363 s.AssertNil(err, fmt.Sprint(err))
364 defer resp.Body.Close()
Matus Fabiana647a832024-08-26 18:01:14 +0200365 s.AssertHttpStatus(resp, 200)
Matus Fabian5c4c1b62024-06-28 16:11:04 +0200366 _, err = io.ReadAll(resp.Body)
Matus Fabiand46e6742024-07-31 16:08:40 +0200367 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian5c4c1b62024-06-28 16:11:04 +0200368}
369
Matus Fabianc712de52024-07-24 12:56:14 +0200370func promReqWg(s *NoTopoSuite, url string, wg *sync.WaitGroup) {
371 defer GinkgoRecover()
372 defer wg.Done()
373 promReq(s, url)
374}
375
Matus Fabiand46e6742024-07-31 16:08:40 +0200376func PromConcurrentConnectionsTest(s *NoTopoSuite) {
Matus Fabian5c4c1b62024-06-28 16:11:04 +0200377 vpp := s.GetContainerByName("vpp").VppInstance
Matus Fabiana647a832024-08-26 18:01:14 +0200378 serverAddress := s.VppAddr()
Matus Fabian5c4c1b62024-06-28 16:11:04 +0200379 url := "http://" + serverAddress + ":80/stats.prom"
380
381 s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers"))
382 s.Log(vpp.Vppctl("prom enable"))
383 time.Sleep(time.Second * 5)
384
385 var wg sync.WaitGroup
386 for i := 0; i < 20; i++ {
387 wg.Add(1)
Matus Fabianc712de52024-07-24 12:56:14 +0200388 go promReqWg(s, url, &wg)
Matus Fabian5c4c1b62024-06-28 16:11:04 +0200389 }
390 wg.Wait()
391 s.Log(vpp.Vppctl("show session verbose proto http"))
392}
393
Matus Fabianc712de52024-07-24 12:56:14 +0200394func PromMemLeakTest(s *NoTopoSuite) {
395 s.SkipUnlessLeakCheck()
396
397 vpp := s.GetContainerByName("vpp").VppInstance
Matus Fabiana647a832024-08-26 18:01:14 +0200398 serverAddress := s.VppAddr()
Matus Fabianc712de52024-07-24 12:56:14 +0200399 url := "http://" + serverAddress + ":80/stats.prom"
400
401 /* no goVPP less noise */
402 vpp.Disconnect()
403
404 s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers"))
405 s.Log(vpp.Vppctl("prom enable"))
406 time.Sleep(time.Second * 3)
407
408 /* warmup request (FIB) */
409 promReq(s, url)
410
411 vpp.EnableMemoryTrace()
412 traces1, err := vpp.GetMemoryTrace()
413 s.AssertNil(err, fmt.Sprint(err))
414
415 /* collect stats couple of times */
416 for i := 0; i < 5; i++ {
417 time.Sleep(time.Second * 1)
418 promReq(s, url)
419 }
420
421 /* let's give it some time to clean up sessions */
422 time.Sleep(time.Second * 5)
423
424 traces2, err := vpp.GetMemoryTrace()
425 s.AssertNil(err, fmt.Sprint(err))
426 vpp.MemLeakCheck(traces1, traces2)
427}
428
Matus Fabianba9ea132024-07-12 11:07:17 +0200429func HttpClientGetMemLeakTest(s *VethsSuite) {
430 s.SkipUnlessLeakCheck()
431
432 serverContainer := s.GetContainerByName("server-vpp").VppInstance
433 clientContainer := s.GetContainerByName("client-vpp").VppInstance
434 serverVeth := s.GetInterfaceByName(ServerInterfaceName)
435
436 /* no goVPP less noise */
437 clientContainer.Disconnect()
438
439 serverContainer.Vppctl("http cli server")
440
441 uri := "http://" + serverVeth.Ip4AddressString() + "/80"
442
443 /* warmup request (FIB) */
444 clientContainer.Vppctl("http cli client uri " + uri + " query /show/version")
445
Matus Fabiand46e6742024-07-31 16:08:40 +0200446 /* let's give it some time to clean up sessions, so local port can be reused and we have less noise */
447 time.Sleep(time.Second * 12)
448
Matus Fabianba9ea132024-07-12 11:07:17 +0200449 clientContainer.EnableMemoryTrace()
450 traces1, err := clientContainer.GetMemoryTrace()
451 s.AssertNil(err, fmt.Sprint(err))
452
453 clientContainer.Vppctl("http cli client uri " + uri + " query /show/vlib/graph")
454
455 /* let's give it some time to clean up sessions */
456 time.Sleep(time.Second * 12)
457
458 traces2, err := clientContainer.GetMemoryTrace()
459 s.AssertNil(err, fmt.Sprint(err))
460 clientContainer.MemLeakCheck(traces1, traces2)
461}
462
Matus Fabiand46e6742024-07-31 16:08:40 +0200463func HttpClientPostMemLeakTest(s *NoTopoSuite) {
464 s.SkipUnlessLeakCheck()
465
Matus Fabiana647a832024-08-26 18:01:14 +0200466 serverAddress := s.HostAddr()
Matus Fabiand46e6742024-07-31 16:08:40 +0200467 body := "field1=value1&field2=value2"
468
469 uri := "http://" + serverAddress + "/80"
470 vpp := s.GetContainerByName("vpp").VppInstance
471
472 /* no goVPP less noise */
473 vpp.Disconnect()
474
475 server := ghttp.NewUnstartedServer()
476 l, err := net.Listen("tcp", serverAddress+":80")
477 s.AssertNil(err, fmt.Sprint(err))
478 server.HTTPTestServer.Listener = l
479 server.AppendHandlers(
480 ghttp.CombineHandlers(
481 ghttp.VerifyRequest("POST", "/test"),
482 ghttp.RespondWith(http.StatusOK, nil),
483 ),
484 ghttp.CombineHandlers(
485 ghttp.VerifyRequest("POST", "/test"),
486 ghttp.RespondWith(http.StatusOK, nil),
487 ),
488 )
489 server.Start()
490 defer server.Close()
491
492 /* warmup request (FIB) */
493 vpp.Vppctl("http post uri " + uri + " target /test data " + body)
494
495 /* let's give it some time to clean up sessions, so local port can be reused and we have less noise */
496 time.Sleep(time.Second * 12)
497
498 vpp.EnableMemoryTrace()
499 traces1, err := vpp.GetMemoryTrace()
500 s.AssertNil(err, fmt.Sprint(err))
501
502 vpp.Vppctl("http post uri " + uri + " target /test data " + body)
503
504 /* let's give it some time to clean up sessions */
505 time.Sleep(time.Second * 12)
506
507 traces2, err := vpp.GetMemoryTrace()
508 s.AssertNil(err, fmt.Sprint(err))
509 vpp.MemLeakCheck(traces1, traces2)
510}
511
Matus Fabian55467552024-08-06 15:55:26 +0200512func HttpInvalidClientRequestMemLeakTest(s *NoTopoSuite) {
513 s.SkipUnlessLeakCheck()
514
515 vpp := s.GetContainerByName("vpp").VppInstance
Matus Fabiana647a832024-08-26 18:01:14 +0200516 serverAddress := s.VppAddr()
Matus Fabian55467552024-08-06 15:55:26 +0200517
518 /* no goVPP less noise */
519 vpp.Disconnect()
520
521 vpp.Vppctl("http cli server")
522
523 /* warmup request (FIB) */
524 _, err := TcpSendReceive(serverAddress+":80", "GET / HTTP/1.1\r\n")
525 s.AssertNil(err, fmt.Sprint(err))
526
527 /* let's give it some time to clean up sessions, so local port can be reused and we have less noise */
528 time.Sleep(time.Second * 12)
529
530 vpp.EnableMemoryTrace()
531 traces1, err := vpp.GetMemoryTrace()
532 s.AssertNil(err, fmt.Sprint(err))
533
534 _, err = TcpSendReceive(serverAddress+":80", "GET / HTTP/1.1\r\n")
535 s.AssertNil(err, fmt.Sprint(err))
536
537 /* let's give it some time to clean up sessions */
538 time.Sleep(time.Second * 12)
539
540 traces2, err := vpp.GetMemoryTrace()
541 s.AssertNil(err, fmt.Sprint(err))
542 vpp.MemLeakCheck(traces1, traces2)
543
544}
545
Adrian Villin86fa9432024-08-08 08:56:34 +0200546func HttpStaticFileHandlerDefaultMaxAgeTest(s *NoTopoSuite) {
547 HttpStaticFileHandlerTestFunction(s, "default")
548}
549
Matus Fabiand46e6742024-07-31 16:08:40 +0200550func HttpStaticFileHandlerTest(s *NoTopoSuite) {
Adrian Villin86fa9432024-08-08 08:56:34 +0200551 HttpStaticFileHandlerTestFunction(s, "123")
552}
553
554func HttpStaticFileHandlerTestFunction(s *NoTopoSuite, max_age string) {
Matus Fabiana647a832024-08-26 18:01:14 +0200555 var maxAgeFormatted string
Adrian Villin86fa9432024-08-08 08:56:34 +0200556 if max_age == "default" {
Matus Fabiana647a832024-08-26 18:01:14 +0200557 maxAgeFormatted = ""
Adrian Villin86fa9432024-08-08 08:56:34 +0200558 max_age = "600"
559 } else {
Matus Fabiana647a832024-08-26 18:01:14 +0200560 maxAgeFormatted = "max-age " + max_age
Adrian Villin86fa9432024-08-08 08:56:34 +0200561 }
562
Matus Fabianba9ea132024-07-12 11:07:17 +0200563 content := "<html><body><p>Hello</p></body></html>"
564 content2 := "<html><body><p>Page</p></body></html>"
Adrian Villin7e6606a2024-08-16 15:23:28 +0200565
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200566 vpp := s.GetContainerByName("vpp").VppInstance
567 vpp.Container.Exec("mkdir -p " + wwwRootPath)
Matus Fabiand46e6742024-07-31 16:08:40 +0200568 err := vpp.Container.CreateFile(wwwRootPath+"/index.html", content)
569 s.AssertNil(err, fmt.Sprint(err))
570 err = vpp.Container.CreateFile(wwwRootPath+"/page.html", content2)
571 s.AssertNil(err, fmt.Sprint(err))
Matus Fabiana647a832024-08-26 18:01:14 +0200572 serverAddress := s.VppAddr()
573 s.Log(vpp.Vppctl("http static server www-root " + wwwRootPath + " uri tcp://" + serverAddress + "/80 debug cache-size 2m " + maxAgeFormatted))
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200574
575 client := NewHttpClient()
576 req, err := http.NewRequest("GET", "http://"+serverAddress+":80/index.html", nil)
577 s.AssertNil(err, fmt.Sprint(err))
578 resp, err := client.Do(req)
579 s.AssertNil(err, fmt.Sprint(err))
Adrian Villin7e6606a2024-08-16 15:23:28 +0200580
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200581 s.Log(DumpHttpResp(resp, true))
Matus Fabiana647a832024-08-26 18:01:14 +0200582 s.AssertHttpStatus(resp, 200)
583 s.AssertHttpHeaderWithValue(resp, "Content-Type", "text/html")
584 s.AssertHttpHeaderWithValue(resp, "Cache-Control", "max-age="+max_age)
585 parsedTime, err := time.Parse(time.RFC1123, resp.Header.Get("Last-Modified"))
Matus Fabiand46e6742024-07-31 16:08:40 +0200586 s.AssertNil(err, fmt.Sprint(err))
Matus Fabiana647a832024-08-26 18:01:14 +0200587 s.AssertTimeEqualWithinThreshold(parsedTime, time.Now(), time.Minute*5)
588 s.AssertEqual(len(resp.Header.Get("Last-Modified")), 29)
589 s.AssertHttpContentLength(resp, int64(len([]rune(content))))
590 s.AssertHttpBody(resp, content)
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200591 o := vpp.Vppctl("show http static server cache verbose")
592 s.Log(o)
593 s.AssertContains(o, "index.html")
594 s.AssertNotContains(o, "page.html")
595
596 resp, err = client.Do(req)
597 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200598 s.Log(DumpHttpResp(resp, true))
Matus Fabiana647a832024-08-26 18:01:14 +0200599 s.AssertHttpStatus(resp, 200)
600 s.AssertHttpHeaderWithValue(resp, "Content-Type", "text/html")
601 s.AssertHttpHeaderWithValue(resp, "Cache-Control", "max-age="+max_age)
602 s.AssertHttpContentLength(resp, int64(len([]rune(content))))
603 s.AssertHttpBody(resp, content)
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200604
605 req, err = http.NewRequest("GET", "http://"+serverAddress+":80/page.html", nil)
606 s.AssertNil(err, fmt.Sprint(err))
607 resp, err = client.Do(req)
608 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200609 s.Log(DumpHttpResp(resp, true))
Matus Fabiana647a832024-08-26 18:01:14 +0200610 s.AssertHttpStatus(resp, 200)
611 s.AssertHttpHeaderWithValue(resp, "Content-Type", "text/html")
612 s.AssertHttpHeaderWithValue(resp, "Cache-Control", "max-age="+max_age)
613 s.AssertHttpContentLength(resp, int64(len([]rune(content2))))
614 s.AssertHttpBody(resp, content2)
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200615 o = vpp.Vppctl("show http static server cache verbose")
616 s.Log(o)
617 s.AssertContains(o, "index.html")
618 s.AssertContains(o, "page.html")
Filip Tehlarcc1475c2023-11-29 12:59:05 +0100619}
620
Matus Fabian5409d332024-05-28 13:39:13 +0200621func HttpStaticPathTraversalTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200622 vpp := s.GetContainerByName("vpp").VppInstance
623 vpp.Container.Exec("mkdir -p " + wwwRootPath)
624 vpp.Container.Exec("mkdir -p " + "/tmp/secret_folder")
Matus Fabiand46e6742024-07-31 16:08:40 +0200625 err := vpp.Container.CreateFile("/tmp/secret_folder/secret_file.txt", "secret")
626 s.AssertNil(err, fmt.Sprint(err))
Matus Fabiana647a832024-08-26 18:01:14 +0200627 serverAddress := s.VppAddr()
Adrian Villin4677d922024-06-14 09:32:39 +0200628 s.Log(vpp.Vppctl("http static server www-root " + wwwRootPath + " uri tcp://" + serverAddress + "/80 debug"))
Matus Fabian5409d332024-05-28 13:39:13 +0200629
Adrian Villin4677d922024-06-14 09:32:39 +0200630 client := NewHttpClient()
Matus Fabian5409d332024-05-28 13:39:13 +0200631 req, err := http.NewRequest("GET", "http://"+serverAddress+":80/../secret_folder/secret_file.txt", nil)
Adrian Villin4677d922024-06-14 09:32:39 +0200632 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian5409d332024-05-28 13:39:13 +0200633 resp, err := client.Do(req)
Adrian Villin4677d922024-06-14 09:32:39 +0200634 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian5409d332024-05-28 13:39:13 +0200635 defer resp.Body.Close()
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200636 s.Log(DumpHttpResp(resp, true))
Matus Fabiana647a832024-08-26 18:01:14 +0200637 s.AssertHttpStatus(resp, 404)
638 s.AssertHttpHeaderNotPresent(resp, "Content-Type")
639 s.AssertHttpHeaderNotPresent(resp, "Cache-Control")
640 s.AssertHttpContentLength(resp, int64(0))
Matus Fabian5409d332024-05-28 13:39:13 +0200641}
642
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200643func HttpStaticMovedTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200644 vpp := s.GetContainerByName("vpp").VppInstance
645 vpp.Container.Exec("mkdir -p " + wwwRootPath + "/tmp.aaa")
Matus Fabiand46e6742024-07-31 16:08:40 +0200646 err := vpp.Container.CreateFile(wwwRootPath+"/tmp.aaa/index.html", "<html><body><p>Hello</p></body></html>")
647 s.AssertNil(err, fmt.Sprint(err))
Matus Fabiana647a832024-08-26 18:01:14 +0200648 serverAddress := s.VppAddr()
Adrian Villin4677d922024-06-14 09:32:39 +0200649 s.Log(vpp.Vppctl("http static server www-root " + wwwRootPath + " uri tcp://" + serverAddress + "/80 debug"))
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200650
Adrian Villin4677d922024-06-14 09:32:39 +0200651 client := NewHttpClient()
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200652 req, err := http.NewRequest("GET", "http://"+serverAddress+":80/tmp.aaa", nil)
Adrian Villin4677d922024-06-14 09:32:39 +0200653 s.AssertNil(err, fmt.Sprint(err))
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200654 resp, err := client.Do(req)
Adrian Villin4677d922024-06-14 09:32:39 +0200655 s.AssertNil(err, fmt.Sprint(err))
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200656 defer resp.Body.Close()
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200657 s.Log(DumpHttpResp(resp, true))
Matus Fabiana647a832024-08-26 18:01:14 +0200658 s.AssertHttpStatus(resp, 301)
659 s.AssertHttpHeaderWithValue(resp, "Location", "http://"+serverAddress+"/tmp.aaa/index.html")
660 s.AssertHttpHeaderNotPresent(resp, "Content-Type")
661 s.AssertHttpHeaderNotPresent(resp, "Cache-Control")
662 s.AssertHttpContentLength(resp, int64(0))
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200663}
664
665func HttpStaticNotFoundTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200666 vpp := s.GetContainerByName("vpp").VppInstance
667 vpp.Container.Exec("mkdir -p " + wwwRootPath)
Matus Fabiana647a832024-08-26 18:01:14 +0200668 serverAddress := s.VppAddr()
Adrian Villin4677d922024-06-14 09:32:39 +0200669 s.Log(vpp.Vppctl("http static server www-root " + wwwRootPath + " uri tcp://" + serverAddress + "/80 debug"))
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200670
Adrian Villin4677d922024-06-14 09:32:39 +0200671 client := NewHttpClient()
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200672 req, err := http.NewRequest("GET", "http://"+serverAddress+":80/notfound.html", nil)
Adrian Villin4677d922024-06-14 09:32:39 +0200673 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian595d8cb2024-05-17 11:28:43 +0200674 resp, err := client.Do(req)
Adrian Villin4677d922024-06-14 09:32:39 +0200675 s.AssertNil(err, fmt.Sprint(err))
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200676 defer resp.Body.Close()
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200677 s.Log(DumpHttpResp(resp, true))
Matus Fabiana647a832024-08-26 18:01:14 +0200678 s.AssertHttpStatus(resp, 404)
679 s.AssertHttpHeaderNotPresent(resp, "Content-Type")
680 s.AssertHttpHeaderNotPresent(resp, "Cache-Control")
681 s.AssertHttpContentLength(resp, int64(0))
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200682}
683
684func HttpCliMethodNotAllowedTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200685 vpp := s.GetContainerByName("vpp").VppInstance
Matus Fabiana647a832024-08-26 18:01:14 +0200686 serverAddress := s.VppAddr()
Adrian Villin4677d922024-06-14 09:32:39 +0200687 vpp.Vppctl("http cli server")
Matus Fabian616201a2024-05-02 11:17:15 +0200688
Adrian Villin4677d922024-06-14 09:32:39 +0200689 client := NewHttpClient()
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200690 req, err := http.NewRequest("POST", "http://"+serverAddress+":80/test", nil)
Adrian Villin4677d922024-06-14 09:32:39 +0200691 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian595d8cb2024-05-17 11:28:43 +0200692 resp, err := client.Do(req)
Adrian Villin4677d922024-06-14 09:32:39 +0200693 s.AssertNil(err, fmt.Sprint(err))
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200694 defer resp.Body.Close()
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200695 s.Log(DumpHttpResp(resp, true))
Matus Fabiana647a832024-08-26 18:01:14 +0200696 s.AssertHttpStatus(resp, 405)
697 s.AssertHttpHeaderWithValue(resp, "Allow", "GET", "server MUST generate an Allow header")
698 s.AssertHttpHeaderNotPresent(resp, "Content-Type")
699 s.AssertHttpContentLength(resp, int64(0))
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200700}
701
702func HttpCliBadRequestTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200703 vpp := s.GetContainerByName("vpp").VppInstance
Matus Fabiana647a832024-08-26 18:01:14 +0200704 serverAddress := s.VppAddr()
Adrian Villin4677d922024-06-14 09:32:39 +0200705 vpp.Vppctl("http cli server")
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200706
Adrian Villin4677d922024-06-14 09:32:39 +0200707 client := NewHttpClient()
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200708 req, err := http.NewRequest("GET", "http://"+serverAddress+":80", nil)
Adrian Villin4677d922024-06-14 09:32:39 +0200709 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian595d8cb2024-05-17 11:28:43 +0200710 resp, err := client.Do(req)
Adrian Villin4677d922024-06-14 09:32:39 +0200711 s.AssertNil(err, fmt.Sprint(err))
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200712 defer resp.Body.Close()
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200713 s.Log(DumpHttpResp(resp, true))
Matus Fabiana647a832024-08-26 18:01:14 +0200714 s.AssertHttpStatus(resp, 400)
715 s.AssertHttpHeaderNotPresent(resp, "Content-Type")
716 s.AssertHttpContentLength(resp, int64(0))
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200717}
718
Matus Fabian82ad9662024-06-04 19:00:00 +0200719func HttpStaticBuildInUrlGetVersionTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200720 vpp := s.GetContainerByName("vpp").VppInstance
Matus Fabiana647a832024-08-26 18:01:14 +0200721 serverAddress := s.VppAddr()
Adrian Villin4677d922024-06-14 09:32:39 +0200722 s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug"))
Matus Fabian82ad9662024-06-04 19:00:00 +0200723
Adrian Villin4677d922024-06-14 09:32:39 +0200724 client := NewHttpClient()
Matus Fabian82ad9662024-06-04 19:00:00 +0200725 req, err := http.NewRequest("GET", "http://"+serverAddress+":80/version.json", nil)
Adrian Villin4677d922024-06-14 09:32:39 +0200726 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +0200727 resp, err := client.Do(req)
Adrian Villin4677d922024-06-14 09:32:39 +0200728 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +0200729 defer resp.Body.Close()
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200730 s.Log(DumpHttpResp(resp, true))
Matus Fabiana647a832024-08-26 18:01:14 +0200731 s.AssertHttpStatus(resp, 200)
Matus Fabian82ad9662024-06-04 19:00:00 +0200732 data, err := io.ReadAll(resp.Body)
Adrian Villin4677d922024-06-14 09:32:39 +0200733 s.AssertNil(err, fmt.Sprint(err))
734 s.AssertContains(string(data), "vpp_details")
735 s.AssertContains(string(data), "version")
736 s.AssertContains(string(data), "build_date")
737 s.AssertNotContains(string(data), "build_by")
738 s.AssertNotContains(string(data), "build_host")
739 s.AssertNotContains(string(data), "build_dir")
Matus Fabiana647a832024-08-26 18:01:14 +0200740 s.AssertHttpHeaderWithValue(resp, "Content-Type", "application/json")
Matus Fabian82ad9662024-06-04 19:00:00 +0200741}
742
743func HttpStaticBuildInUrlGetVersionVerboseTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200744 vpp := s.GetContainerByName("vpp").VppInstance
Matus Fabiana647a832024-08-26 18:01:14 +0200745 serverAddress := s.VppAddr()
Adrian Villin4677d922024-06-14 09:32:39 +0200746 s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug"))
Matus Fabian82ad9662024-06-04 19:00:00 +0200747
Adrian Villin4677d922024-06-14 09:32:39 +0200748 client := NewHttpClient()
Matus Fabian82ad9662024-06-04 19:00:00 +0200749 req, err := http.NewRequest("GET", "http://"+serverAddress+":80/version.json?verbose=true", nil)
Adrian Villin4677d922024-06-14 09:32:39 +0200750 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +0200751 resp, err := client.Do(req)
Adrian Villin4677d922024-06-14 09:32:39 +0200752 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +0200753 defer resp.Body.Close()
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200754 s.Log(DumpHttpResp(resp, true))
Matus Fabiana647a832024-08-26 18:01:14 +0200755 s.AssertHttpStatus(resp, 200)
Matus Fabian82ad9662024-06-04 19:00:00 +0200756 data, err := io.ReadAll(resp.Body)
Adrian Villin4677d922024-06-14 09:32:39 +0200757 s.AssertNil(err, fmt.Sprint(err))
758 s.AssertContains(string(data), "vpp_details")
759 s.AssertContains(string(data), "version")
760 s.AssertContains(string(data), "build_date")
761 s.AssertContains(string(data), "build_by")
762 s.AssertContains(string(data), "build_host")
763 s.AssertContains(string(data), "build_dir")
Matus Fabiana647a832024-08-26 18:01:14 +0200764 s.AssertHttpHeaderWithValue(resp, "Content-Type", "application/json")
Matus Fabian82ad9662024-06-04 19:00:00 +0200765}
766
767func HttpStaticBuildInUrlGetIfListTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200768 vpp := s.GetContainerByName("vpp").VppInstance
Matus Fabiana647a832024-08-26 18:01:14 +0200769 serverAddress := s.VppAddr()
Adrian Villin4677d922024-06-14 09:32:39 +0200770 s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug"))
Matus Fabian82ad9662024-06-04 19:00:00 +0200771
Adrian Villin4677d922024-06-14 09:32:39 +0200772 client := NewHttpClient()
Matus Fabian82ad9662024-06-04 19:00:00 +0200773 req, err := http.NewRequest("GET", "http://"+serverAddress+":80/interface_list.json", nil)
Adrian Villin4677d922024-06-14 09:32:39 +0200774 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +0200775 resp, err := client.Do(req)
Adrian Villin4677d922024-06-14 09:32:39 +0200776 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +0200777 defer resp.Body.Close()
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200778 s.Log(DumpHttpResp(resp, true))
Matus Fabiana647a832024-08-26 18:01:14 +0200779 s.AssertHttpStatus(resp, 200)
Matus Fabian82ad9662024-06-04 19:00:00 +0200780 data, err := io.ReadAll(resp.Body)
Adrian Villin4677d922024-06-14 09:32:39 +0200781 s.AssertNil(err, fmt.Sprint(err))
782 s.AssertContains(string(data), "interface_list")
Matus Fabiana647a832024-08-26 18:01:14 +0200783 s.AssertContains(string(data), s.VppIfName())
784 s.AssertHttpHeaderWithValue(resp, "Content-Type", "application/json")
Matus Fabian82ad9662024-06-04 19:00:00 +0200785}
786
787func HttpStaticBuildInUrlGetIfStatsTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200788 vpp := s.GetContainerByName("vpp").VppInstance
Matus Fabiana647a832024-08-26 18:01:14 +0200789 serverAddress := s.VppAddr()
Adrian Villin4677d922024-06-14 09:32:39 +0200790 s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug"))
Matus Fabian82ad9662024-06-04 19:00:00 +0200791
Adrian Villin4677d922024-06-14 09:32:39 +0200792 client := NewHttpClient()
Matus Fabian82ad9662024-06-04 19:00:00 +0200793 req, err := http.NewRequest("GET", "http://"+serverAddress+":80/interface_stats.json", nil)
Adrian Villin4677d922024-06-14 09:32:39 +0200794 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +0200795 resp, err := client.Do(req)
Adrian Villin4677d922024-06-14 09:32:39 +0200796 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +0200797 defer resp.Body.Close()
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200798 s.Log(DumpHttpResp(resp, true))
Matus Fabiana647a832024-08-26 18:01:14 +0200799 s.AssertHttpStatus(resp, 200)
Matus Fabian82ad9662024-06-04 19:00:00 +0200800 data, err := io.ReadAll(resp.Body)
Adrian Villin4677d922024-06-14 09:32:39 +0200801 s.AssertNil(err, fmt.Sprint(err))
802 s.AssertContains(string(data), "interface_stats")
803 s.AssertContains(string(data), "local0")
Matus Fabiana647a832024-08-26 18:01:14 +0200804 s.AssertContains(string(data), s.VppIfName())
805 s.AssertHttpHeaderWithValue(resp, "Content-Type", "application/json")
Matus Fabian82ad9662024-06-04 19:00:00 +0200806}
807
808func validatePostInterfaceStats(s *NoTopoSuite, data string) {
Adrian Villin4677d922024-06-14 09:32:39 +0200809 s.AssertContains(data, "interface_stats")
Matus Fabiana647a832024-08-26 18:01:14 +0200810 s.AssertContains(data, s.VppIfName())
Adrian Villin4677d922024-06-14 09:32:39 +0200811 s.AssertNotContains(data, "error")
812 s.AssertNotContains(data, "local0")
Matus Fabian82ad9662024-06-04 19:00:00 +0200813}
814
815func HttpStaticBuildInUrlPostIfStatsTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200816 vpp := s.GetContainerByName("vpp").VppInstance
Matus Fabiana647a832024-08-26 18:01:14 +0200817 serverAddress := s.VppAddr()
Adrian Villin4677d922024-06-14 09:32:39 +0200818 s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug"))
Matus Fabiana647a832024-08-26 18:01:14 +0200819 body := []byte(s.VppIfName())
Matus Fabian82ad9662024-06-04 19:00:00 +0200820
Adrian Villin4677d922024-06-14 09:32:39 +0200821 client := NewHttpClient()
Matus Fabian82ad9662024-06-04 19:00:00 +0200822 req, err := http.NewRequest("POST",
823 "http://"+serverAddress+":80/interface_stats.json", bytes.NewBuffer(body))
Adrian Villin4677d922024-06-14 09:32:39 +0200824 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +0200825 resp, err := client.Do(req)
Adrian Villin4677d922024-06-14 09:32:39 +0200826 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +0200827 defer resp.Body.Close()
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200828 s.Log(DumpHttpResp(resp, true))
Matus Fabiana647a832024-08-26 18:01:14 +0200829 s.AssertHttpStatus(resp, 200)
Matus Fabian82ad9662024-06-04 19:00:00 +0200830 data, err := io.ReadAll(resp.Body)
Adrian Villin4677d922024-06-14 09:32:39 +0200831 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +0200832 validatePostInterfaceStats(s, string(data))
Matus Fabiana647a832024-08-26 18:01:14 +0200833 s.AssertHttpHeaderWithValue(resp, "Content-Type", "application/json")
Matus Fabian82ad9662024-06-04 19:00:00 +0200834}
835
836func HttpStaticMacTimeTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200837 vpp := s.GetContainerByName("vpp").VppInstance
Matus Fabiana647a832024-08-26 18:01:14 +0200838 serverAddress := s.VppAddr()
Adrian Villin4677d922024-06-14 09:32:39 +0200839 s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug"))
Matus Fabiana647a832024-08-26 18:01:14 +0200840 s.Log(vpp.Vppctl("mactime enable-disable " + s.VppIfName()))
Matus Fabian82ad9662024-06-04 19:00:00 +0200841
Adrian Villin4677d922024-06-14 09:32:39 +0200842 client := NewHttpClient()
Matus Fabian82ad9662024-06-04 19:00:00 +0200843 req, err := http.NewRequest("GET", "http://"+serverAddress+":80/mactime.json", nil)
Adrian Villin4677d922024-06-14 09:32:39 +0200844 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +0200845 resp, err := client.Do(req)
Adrian Villin4677d922024-06-14 09:32:39 +0200846 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +0200847 defer resp.Body.Close()
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200848 s.Log(DumpHttpResp(resp, true))
Matus Fabiana647a832024-08-26 18:01:14 +0200849 s.AssertHttpStatus(resp, 200)
Matus Fabian82ad9662024-06-04 19:00:00 +0200850 data, err := io.ReadAll(resp.Body)
Adrian Villin4677d922024-06-14 09:32:39 +0200851 s.AssertNil(err, fmt.Sprint(err))
852 s.AssertContains(string(data), "mactime")
Matus Fabiana647a832024-08-26 18:01:14 +0200853 s.AssertContains(string(data), s.HostAddr())
Adrian Villin4677d922024-06-14 09:32:39 +0200854 s.AssertContains(string(data), s.GetInterfaceByName(TapInterfaceName).HwAddress.String())
Matus Fabiana647a832024-08-26 18:01:14 +0200855 s.AssertHttpHeaderWithValue(resp, "Content-Type", "application/json")
856 parsedTime, err := time.Parse(time.RFC1123, resp.Header.Get("Date"))
857 s.AssertNil(err, fmt.Sprint(err))
858 s.AssertTimeEqualWithinThreshold(parsedTime, time.Now(), time.Minute*5)
Adrian Villin7e6606a2024-08-16 15:23:28 +0200859 s.AssertEqual(len(resp.Header.Get("Date")), 29)
Matus Fabian82ad9662024-06-04 19:00:00 +0200860}
861
862func HttpInvalidRequestLineTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200863 vpp := s.GetContainerByName("vpp").VppInstance
Matus Fabiana647a832024-08-26 18:01:14 +0200864 serverAddress := s.VppAddr()
Adrian Villin4677d922024-06-14 09:32:39 +0200865 vpp.Vppctl("http cli server")
Matus Fabian82ad9662024-06-04 19:00:00 +0200866
Matus Fabian69123a32024-08-23 17:35:50 +0200867 resp, err := TcpSendReceive(serverAddress+":80", " GET / HTTP/1.1")
868 s.AssertNil(err, fmt.Sprint(err))
869 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "invalid request line start not allowed")
870
871 resp, err = TcpSendReceive(serverAddress+":80", "\rGET / HTTP/1.1")
872 s.AssertNil(err, fmt.Sprint(err))
873 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "invalid request line start not allowed")
874
875 resp, err = TcpSendReceive(serverAddress+":80", "\nGET / HTTP/1.1")
876 s.AssertNil(err, fmt.Sprint(err))
877 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "invalid request line start not allowed")
878
879 resp, err = TcpSendReceive(serverAddress+":80", "GET / HTTP/1.1")
Adrian Villin4677d922024-06-14 09:32:39 +0200880 s.AssertNil(err, fmt.Sprint(err))
881 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "invalid framing not allowed")
Matus Fabian82ad9662024-06-04 19:00:00 +0200882
Adrian Villin4677d922024-06-14 09:32:39 +0200883 resp, err = TcpSendReceive(serverAddress+":80", "GET / HTTP/1.1\r\n")
884 s.AssertNil(err, fmt.Sprint(err))
885 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "invalid framing not allowed")
Matus Fabian82ad9662024-06-04 19:00:00 +0200886
Adrian Villin4677d922024-06-14 09:32:39 +0200887 resp, err = TcpSendReceive(serverAddress+":80", "GET /\r\n\r\n")
888 s.AssertNil(err, fmt.Sprint(err))
889 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "HTTP-version must be present")
Matus Fabian82ad9662024-06-04 19:00:00 +0200890
Adrian Villin4677d922024-06-14 09:32:39 +0200891 resp, err = TcpSendReceive(serverAddress+":80", "GET HTTP/1.1\r\n\r\n")
892 s.AssertNil(err, fmt.Sprint(err))
893 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "request-target must be present")
Matus Fabian82ad9662024-06-04 19:00:00 +0200894
Adrian Villin4677d922024-06-14 09:32:39 +0200895 resp, err = TcpSendReceive(serverAddress+":80", "GET HTTP/1.1\r\n\r\n")
896 s.AssertNil(err, fmt.Sprint(err))
897 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "request-target must be present")
Matus Fabian82ad9662024-06-04 19:00:00 +0200898
Adrian Villin4677d922024-06-14 09:32:39 +0200899 resp, err = TcpSendReceive(serverAddress+":80", "GET / HTTP/x\r\n\r\n")
900 s.AssertNil(err, fmt.Sprint(err))
901 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "'HTTP/x' invalid http version not allowed")
Matus Fabian82ad9662024-06-04 19:00:00 +0200902
Adrian Villin4677d922024-06-14 09:32:39 +0200903 resp, err = TcpSendReceive(serverAddress+":80", "GET / HTTP1.1\r\n\r\n")
904 s.AssertNil(err, fmt.Sprint(err))
905 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "'HTTP1.1' invalid http version not allowed")
Matus Fabian82ad9662024-06-04 19:00:00 +0200906}
907
Matus Fabian69123a32024-08-23 17:35:50 +0200908func HttpRequestLineTest(s *NoTopoSuite) {
909 vpp := s.GetContainerByName("vpp").VppInstance
Matus Fabiana647a832024-08-26 18:01:14 +0200910 serverAddress := s.VppAddr()
Matus Fabian69123a32024-08-23 17:35:50 +0200911 vpp.Vppctl("http cli server")
912
913 resp, err := TcpSendReceive(serverAddress+":80", "\r\nGET /show/version HTTP/1.1\r\nHost:"+serverAddress+":80\r\nUser-Agent:test\r\n\r\n")
914 s.AssertNil(err, fmt.Sprint(err))
915 s.AssertContains(resp, "HTTP/1.1 200 OK")
916 s.AssertContains(resp, "<html>", "html content not found")
917}
918
Matus Fabian82ad9662024-06-04 19:00:00 +0200919func HttpInvalidTargetSyntaxTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200920 vpp := s.GetContainerByName("vpp").VppInstance
Matus Fabiana647a832024-08-26 18:01:14 +0200921 serverAddress := s.VppAddr()
Adrian Villin4677d922024-06-14 09:32:39 +0200922 s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug"))
Matus Fabian82ad9662024-06-04 19:00:00 +0200923
Adrian Villin4677d922024-06-14 09:32:39 +0200924 resp, err := TcpSendReceive(serverAddress+":80", "GET /interface|stats.json HTTP/1.1\r\n\r\n")
925 s.AssertNil(err, fmt.Sprint(err))
926 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "'|' not allowed in target path")
Matus Fabian82ad9662024-06-04 19:00:00 +0200927
Adrian Villin4677d922024-06-14 09:32:39 +0200928 resp, err = TcpSendReceive(serverAddress+":80", "GET /interface#stats.json HTTP/1.1\r\n\r\n")
929 s.AssertNil(err, fmt.Sprint(err))
930 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "'#' not allowed in target path")
Matus Fabian82ad9662024-06-04 19:00:00 +0200931
Adrian Villin4677d922024-06-14 09:32:39 +0200932 resp, err = TcpSendReceive(serverAddress+":80", "GET /interface%stats.json HTTP/1.1\r\n\r\n")
933 s.AssertNil(err, fmt.Sprint(err))
934 s.AssertContains(resp, "HTTP/1.1 400 Bad Request",
Matus Fabian82ad9662024-06-04 19:00:00 +0200935 "after '%' there must be two hex-digit characters in target path")
936
Adrian Villin4677d922024-06-14 09:32:39 +0200937 resp, err = TcpSendReceive(serverAddress+":80", "GET /interface%1stats.json HTTP/1.1\r\n\r\n")
938 s.AssertNil(err, fmt.Sprint(err))
939 s.AssertContains(resp, "HTTP/1.1 400 Bad Request",
Matus Fabian82ad9662024-06-04 19:00:00 +0200940 "after '%' there must be two hex-digit characters in target path")
941
Adrian Villin4677d922024-06-14 09:32:39 +0200942 resp, err = TcpSendReceive(serverAddress+":80", "GET /interface%Bstats.json HTTP/1.1\r\n\r\n")
943 s.AssertNil(err, fmt.Sprint(err))
944 s.AssertContains(resp, "HTTP/1.1 400 Bad Request",
Matus Fabian82ad9662024-06-04 19:00:00 +0200945 "after '%' there must be two hex-digit characters in target path")
946
Adrian Villin4677d922024-06-14 09:32:39 +0200947 resp, err = TcpSendReceive(serverAddress+":80", "GET /interface%stats.json%B HTTP/1.1\r\n\r\n")
948 s.AssertNil(err, fmt.Sprint(err))
949 s.AssertContains(resp, "HTTP/1.1 400 Bad Request",
Matus Fabian82ad9662024-06-04 19:00:00 +0200950 "after '%' there must be two hex-digit characters in target path")
951
Adrian Villin4677d922024-06-14 09:32:39 +0200952 resp, err = TcpSendReceive(serverAddress+":80", "GET /version.json?verbose>true HTTP/1.1\r\n\r\n")
953 s.AssertNil(err, fmt.Sprint(err))
954 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "'>' not allowed in target query")
Matus Fabian82ad9662024-06-04 19:00:00 +0200955
Adrian Villin4677d922024-06-14 09:32:39 +0200956 resp, err = TcpSendReceive(serverAddress+":80", "GET /version.json?verbose%true HTTP/1.1\r\n\r\n")
957 s.AssertNil(err, fmt.Sprint(err))
958 s.AssertContains(resp, "HTTP/1.1 400 Bad Request",
Matus Fabian82ad9662024-06-04 19:00:00 +0200959 "after '%' there must be two hex-digit characters in target query")
960
Adrian Villin4677d922024-06-14 09:32:39 +0200961 resp, err = TcpSendReceive(serverAddress+":80", "GET /version.json?verbose=%1 HTTP/1.1\r\n\r\n")
962 s.AssertNil(err, fmt.Sprint(err))
963 s.AssertContains(resp, "HTTP/1.1 400 Bad Request",
Matus Fabian82ad9662024-06-04 19:00:00 +0200964 "after '%' there must be two hex-digit characters in target query")
965}
966
967func HttpInvalidContentLengthTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200968 vpp := s.GetContainerByName("vpp").VppInstance
Matus Fabiana647a832024-08-26 18:01:14 +0200969 serverAddress := s.VppAddr()
Adrian Villin4677d922024-06-14 09:32:39 +0200970 vpp.Vppctl("http cli server")
Matus Fabian82ad9662024-06-04 19:00:00 +0200971
Adrian Villin4677d922024-06-14 09:32:39 +0200972 resp, err := TcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nContent-Length:\r\n\r\n")
973 s.AssertNil(err, fmt.Sprint(err))
974 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "Content-Length value must be present")
Matus Fabian82ad9662024-06-04 19:00:00 +0200975
Adrian Villin4677d922024-06-14 09:32:39 +0200976 resp, err = TcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nContent-Length: \r\n\r\n")
977 s.AssertNil(err, fmt.Sprint(err))
978 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "Content-Length value must be present")
Matus Fabian82ad9662024-06-04 19:00:00 +0200979
Adrian Villin4677d922024-06-14 09:32:39 +0200980 resp, err = TcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nContent-Length: a\r\n\r\n")
981 s.AssertNil(err, fmt.Sprint(err))
982 s.AssertContains(resp, "HTTP/1.1 400 Bad Request",
Matus Fabian82ad9662024-06-04 19:00:00 +0200983 "Content-Length value other than digit not allowed")
984}
985
986func HttpContentLengthTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200987 vpp := s.GetContainerByName("vpp").VppInstance
Matus Fabiana647a832024-08-26 18:01:14 +0200988 serverAddress := s.VppAddr()
Adrian Villin4677d922024-06-14 09:32:39 +0200989 s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug"))
Matus Fabiana647a832024-08-26 18:01:14 +0200990 ifName := s.VppIfName()
Matus Fabian82ad9662024-06-04 19:00:00 +0200991
Adrian Villin4677d922024-06-14 09:32:39 +0200992 resp, err := TcpSendReceive(serverAddress+":80",
Matus Fabian82ad9662024-06-04 19:00:00 +0200993 "POST /interface_stats.json HTTP/1.1\r\nContent-Length:4\r\n\r\n"+ifName)
Adrian Villin4677d922024-06-14 09:32:39 +0200994 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +0200995 validatePostInterfaceStats(s, resp)
996
Adrian Villin4677d922024-06-14 09:32:39 +0200997 resp, err = TcpSendReceive(serverAddress+":80",
Matus Fabian82ad9662024-06-04 19:00:00 +0200998 "POST /interface_stats.json HTTP/1.1\r\n Content-Length: 4 \r\n\r\n"+ifName)
Adrian Villin4677d922024-06-14 09:32:39 +0200999 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +02001000 validatePostInterfaceStats(s, resp)
1001
Adrian Villin4677d922024-06-14 09:32:39 +02001002 resp, err = TcpSendReceive(serverAddress+":80",
Matus Fabian82ad9662024-06-04 19:00:00 +02001003 "POST /interface_stats.json HTTP/1.1\r\n\tContent-Length:\t\t4\r\n\r\n"+ifName)
Adrian Villin4677d922024-06-14 09:32:39 +02001004 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +02001005 validatePostInterfaceStats(s, resp)
1006}
1007
1008func HttpMethodNotImplementedTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +02001009 vpp := s.GetContainerByName("vpp").VppInstance
Matus Fabiana647a832024-08-26 18:01:14 +02001010 serverAddress := s.VppAddr()
Adrian Villin4677d922024-06-14 09:32:39 +02001011 vpp.Vppctl("http cli server")
Matus Fabian82ad9662024-06-04 19:00:00 +02001012
Adrian Villin4677d922024-06-14 09:32:39 +02001013 client := NewHttpClient()
Matus Fabian82ad9662024-06-04 19:00:00 +02001014 req, err := http.NewRequest("OPTIONS", "http://"+serverAddress+":80/show/version", nil)
Adrian Villin4677d922024-06-14 09:32:39 +02001015 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +02001016 resp, err := client.Do(req)
Adrian Villin4677d922024-06-14 09:32:39 +02001017 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +02001018 defer resp.Body.Close()
Matus Fabian8ca6ce62024-06-20 17:08:26 +02001019 s.Log(DumpHttpResp(resp, true))
Matus Fabiana647a832024-08-26 18:01:14 +02001020 s.AssertHttpStatus(resp, 501)
1021 s.AssertHttpHeaderNotPresent(resp, "Content-Type")
1022 s.AssertHttpContentLength(resp, int64(0))
Matus Fabian82ad9662024-06-04 19:00:00 +02001023}
1024
1025func HttpVersionNotSupportedTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +02001026 vpp := s.GetContainerByName("vpp").VppInstance
Matus Fabiana647a832024-08-26 18:01:14 +02001027 serverAddress := s.VppAddr()
Adrian Villin4677d922024-06-14 09:32:39 +02001028 vpp.Vppctl("http cli server")
Matus Fabian82ad9662024-06-04 19:00:00 +02001029
Adrian Villin4677d922024-06-14 09:32:39 +02001030 resp, err := TcpSendReceive(serverAddress+":80", "GET / HTTP/2\r\n\r\n")
1031 s.AssertNil(err, fmt.Sprint(err))
1032 s.AssertContains(resp, "HTTP/1.1 505 HTTP Version Not Supported")
Matus Fabian82ad9662024-06-04 19:00:00 +02001033}
1034
1035func HttpUriDecodeTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +02001036 vpp := s.GetContainerByName("vpp").VppInstance
Matus Fabiana647a832024-08-26 18:01:14 +02001037 serverAddress := s.VppAddr()
Adrian Villin4677d922024-06-14 09:32:39 +02001038 vpp.Vppctl("http cli server")
Matus Fabian82ad9662024-06-04 19:00:00 +02001039
Adrian Villin4677d922024-06-14 09:32:39 +02001040 client := NewHttpClient()
Matus Fabian82ad9662024-06-04 19:00:00 +02001041 req, err := http.NewRequest("GET", "http://"+serverAddress+":80/sh%6fw%20versio%6E%20verbose", nil)
Adrian Villin4677d922024-06-14 09:32:39 +02001042 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +02001043 resp, err := client.Do(req)
Adrian Villin4677d922024-06-14 09:32:39 +02001044 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +02001045 defer resp.Body.Close()
Matus Fabian8ca6ce62024-06-20 17:08:26 +02001046 s.Log(DumpHttpResp(resp, true))
Matus Fabiana647a832024-08-26 18:01:14 +02001047 s.AssertHttpStatus(resp, 200)
Matus Fabian82ad9662024-06-04 19:00:00 +02001048 data, err := io.ReadAll(resp.Body)
Adrian Villin4677d922024-06-14 09:32:39 +02001049 s.AssertNil(err, fmt.Sprint(err))
Adrian Villin4677d922024-06-14 09:32:39 +02001050 s.AssertNotContains(string(data), "unknown input")
1051 s.AssertContains(string(data), "Compiler")
Matus Fabiana647a832024-08-26 18:01:14 +02001052 s.AssertHttpHeaderWithValue(resp, "Content-Type", "text/html")
Matus Fabian82ad9662024-06-04 19:00:00 +02001053}
1054
1055func HttpHeadersTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +02001056 vpp := s.GetContainerByName("vpp").VppInstance
Matus Fabiana647a832024-08-26 18:01:14 +02001057 serverAddress := s.VppAddr()
Adrian Villin4677d922024-06-14 09:32:39 +02001058 vpp.Vppctl("http cli server")
Matus Fabian82ad9662024-06-04 19:00:00 +02001059
Adrian Villin4677d922024-06-14 09:32:39 +02001060 resp, err := TcpSendReceive(
Matus Fabian82ad9662024-06-04 19:00:00 +02001061 serverAddress+":80",
1062 "GET /show/version HTTP/1.1\r\nHost:"+serverAddress+":80\r\nUser-Agent:test\r\nAccept:text/xml\r\nAccept:\ttext/plain\t \r\nAccept:text/html\r\n\r\n")
Adrian Villin4677d922024-06-14 09:32:39 +02001063 s.AssertNil(err, fmt.Sprint(err))
1064 s.AssertContains(resp, "HTTP/1.1 200 OK")
Adrian Villin3601b322024-08-19 14:41:35 +02001065 s.AssertContains(resp, "Content-Type: text/plain")
Adrian Villin4677d922024-06-14 09:32:39 +02001066 s.AssertNotContains(resp, "<html>", "html content received instead of plain text")
Matus Fabian82ad9662024-06-04 19:00:00 +02001067}
1068
1069func HttpInvalidHeadersTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +02001070 vpp := s.GetContainerByName("vpp").VppInstance
Matus Fabiana647a832024-08-26 18:01:14 +02001071 serverAddress := s.VppAddr()
Adrian Villin4677d922024-06-14 09:32:39 +02001072 vpp.Vppctl("http cli server")
Matus Fabian82ad9662024-06-04 19:00:00 +02001073
Adrian Villin4677d922024-06-14 09:32:39 +02001074 resp, err := TcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nUser-Agent: test\r\n")
1075 s.AssertNil(err, fmt.Sprint(err))
1076 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "Header section must end with CRLF CRLF")
Matus Fabian82ad9662024-06-04 19:00:00 +02001077
Adrian Villin4677d922024-06-14 09:32:39 +02001078 resp, err = TcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nHost:"+serverAddress+":80\r\nUser@Agent:test\r\n\r\n")
1079 s.AssertNil(err, fmt.Sprint(err))
1080 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "'@' not allowed in field name")
Matus Fabian82ad9662024-06-04 19:00:00 +02001081
Adrian Villin4677d922024-06-14 09:32:39 +02001082 resp, err = TcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nHost:"+serverAddress+":80\r\nUser-Agent\r\n\r\n")
1083 s.AssertNil(err, fmt.Sprint(err))
1084 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "incomplete field line not allowed")
Matus Fabian82ad9662024-06-04 19:00:00 +02001085
Adrian Villin4677d922024-06-14 09:32:39 +02001086 resp, err = TcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nHost:"+serverAddress+":80\r\n: test\r\n\r\n")
1087 s.AssertNil(err, fmt.Sprint(err))
1088 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "empty field name not allowed")
Matus Fabian82ad9662024-06-04 19:00:00 +02001089
Adrian Villin4677d922024-06-14 09:32:39 +02001090 resp, err = TcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nHost:"+serverAddress+":80\rUser-Agent:test\r\n\r\n")
1091 s.AssertNil(err, fmt.Sprint(err))
1092 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "invalid field line end not allowed")
Matus Fabian82ad9662024-06-04 19:00:00 +02001093
Adrian Villin4677d922024-06-14 09:32:39 +02001094 resp, err = TcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nHost:"+serverAddress+":80\nUser-Agent:test\r\n\r\n")
1095 s.AssertNil(err, fmt.Sprint(err))
1096 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "invalid field line end not allowed")
Matus Fabian82ad9662024-06-04 19:00:00 +02001097
Adrian Villin4677d922024-06-14 09:32:39 +02001098 resp, err = TcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nHost:"+serverAddress+":80\r\nUser-Agent:\r\n\r\n")
1099 s.AssertNil(err, fmt.Sprint(err))
1100 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "empty field value not allowed")
Matus Fabian82ad9662024-06-04 19:00:00 +02001101
Adrian Villin4677d922024-06-14 09:32:39 +02001102 resp, err = TcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nHost:"+serverAddress+":80\r\nUser-Agent: \r\n\r\n")
1103 s.AssertNil(err, fmt.Sprint(err))
1104 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "empty field value not allowed")
Matus Fabian82ad9662024-06-04 19:00:00 +02001105}
1106
Matus Fabianb7a9ed72024-05-10 16:20:40 +02001107func HeaderServerTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +02001108 vpp := s.GetContainerByName("vpp").VppInstance
Matus Fabiana647a832024-08-26 18:01:14 +02001109 serverAddress := s.VppAddr()
Adrian Villin4677d922024-06-14 09:32:39 +02001110 vpp.Vppctl("http cli server")
Matus Fabianb7a9ed72024-05-10 16:20:40 +02001111
Adrian Villin4677d922024-06-14 09:32:39 +02001112 client := NewHttpClient()
Matus Fabianb7a9ed72024-05-10 16:20:40 +02001113 req, err := http.NewRequest("GET", "http://"+serverAddress+":80/show/version", nil)
Adrian Villin4677d922024-06-14 09:32:39 +02001114 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian595d8cb2024-05-17 11:28:43 +02001115 resp, err := client.Do(req)
Adrian Villin4677d922024-06-14 09:32:39 +02001116 s.AssertNil(err, fmt.Sprint(err))
Matus Fabianb7a9ed72024-05-10 16:20:40 +02001117 defer resp.Body.Close()
Matus Fabian8ca6ce62024-06-20 17:08:26 +02001118 s.Log(DumpHttpResp(resp, true))
Matus Fabiana647a832024-08-26 18:01:14 +02001119 s.AssertHttpStatus(resp, 200)
1120 s.AssertHttpHeaderWithValue(resp, "Server", "http_cli_server")
1121 s.AssertHttpHeaderWithValue(resp, "Content-Type", "text/html")
Matus Fabian616201a2024-05-02 11:17:15 +02001122}