blob: 872f4c234b3ed59b6811d2f016d13ccd852d9f51 [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 Fabiand58177c2024-08-08 12:50:32 +020032 HttpClientPostFileTest, HttpClientPostFilePtrTest, AuthorityFormTargetTest)
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()
Adrian Villin4677d922024-06-14 09:32:39 +020049 s.AssertEqual(200, resp.StatusCode)
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
62 serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString()
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
74 serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString()
75 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
88 req, err := http.NewRequest("GET", "http://"+serverAddress+":80/test1", nil)
89 s.AssertNil(err, fmt.Sprint(err))
90 resp, err := client.Do(req)
91 s.AssertNil(err, fmt.Sprint(err))
92 defer resp.Body.Close()
93 s.Log(DumpHttpResp(resp, true))
94 s.AssertEqual(200, resp.StatusCode)
95 s.AssertEqual(false, resp.Close)
96 body, err := io.ReadAll(resp.Body)
97 s.AssertNil(err, fmt.Sprint(err))
98 s.AssertEqual(string(body), "hello")
99 o1 := vpp.Vppctl("show session verbose proto http state ready")
100 s.Log(o1)
101 s.AssertContains(o1, "ESTABLISHED")
102
103 req, err = http.NewRequest("GET", "http://"+serverAddress+":80/test2", nil)
104 s.AssertNil(err, fmt.Sprint(err))
105 clientTrace := &httptrace.ClientTrace{
106 GotConn: func(info httptrace.GotConnInfo) {
107 s.AssertEqual(true, info.Reused, "connection not reused")
108 },
109 }
110 req = req.WithContext(httptrace.WithClientTrace(req.Context(), clientTrace))
111 resp, err = client.Do(req)
112 s.AssertNil(err, fmt.Sprint(err))
113 defer resp.Body.Close()
114 s.Log(DumpHttpResp(resp, true))
115 s.AssertEqual(200, resp.StatusCode)
116 s.AssertEqual(false, resp.Close)
117 body, err = io.ReadAll(resp.Body)
118 s.AssertNil(err, fmt.Sprint(err))
119 s.AssertEqual(string(body), "some data")
Matus Fabiand086a362024-06-27 13:20:10 +0200120 o2 := vpp.Vppctl("show session verbose proto http state ready")
121 s.Log(o2)
122 s.AssertContains(o2, "ESTABLISHED")
123 s.AssertEqual(o1, o2)
124}
125
126func HttpPipeliningTest(s *NoTopoSuite) {
127 // testing url handler app do not support multi-thread
128 s.SkipIfMultiWorker()
129 vpp := s.GetContainerByName("vpp").VppInstance
130 serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString()
131 s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug"))
132 s.Log(vpp.Vppctl("test-url-handler enable"))
133
134 req1 := "GET /test_delayed HTTP/1.1\r\nHost:" + serverAddress + ":80\r\nUser-Agent:test\r\n\r\n"
135 req2 := "GET /test1 HTTP/1.1\r\nHost:" + serverAddress + ":80\r\nUser-Agent:test\r\n\r\n"
136
137 conn, err := net.DialTimeout("tcp", serverAddress+":80", time.Second*30)
138 s.AssertNil(err, fmt.Sprint(err))
139 defer conn.Close()
140 err = conn.SetDeadline(time.Now().Add(time.Second * 15))
141 s.AssertNil(err, fmt.Sprint(err))
142 n, err := conn.Write([]byte(req1))
143 s.AssertNil(err, fmt.Sprint(err))
144 s.AssertEqual(n, len([]rune(req1)))
145 // send second request a bit later so first is already in progress
146 time.Sleep(500 * time.Millisecond)
147 n, err = conn.Write([]byte(req2))
148 s.AssertNil(err, fmt.Sprint(err))
149 s.AssertEqual(n, len([]rune(req2)))
150 reply := make([]byte, 1024)
151 n, err = conn.Read(reply)
152 s.AssertNil(err, fmt.Sprint(err))
153 s.Log(string(reply))
154 s.AssertContains(string(reply), "delayed data", "first request response not received")
155 s.AssertNotContains(string(reply), "hello", "second request response received")
156 // make sure response for second request is not received later
157 _, err = conn.Read(reply)
158 s.AssertMatchError(err, os.ErrDeadlineExceeded, "second request response received")
159}
160
Adrian Villincee15aa2024-03-14 11:42:55 -0400161func HttpCliTest(s *VethsSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200162 serverContainer := s.GetContainerByName("server-vpp")
163 clientContainer := s.GetContainerByName("client-vpp")
Filip Tehlarb15a0002022-11-10 12:34:17 +0100164
Adrian Villin4677d922024-06-14 09:32:39 +0200165 serverVeth := s.GetInterfaceByName(ServerInterfaceName)
Maros Ondrejickaffa3f602023-01-26 10:07:29 +0100166
Adrian Villin4677d922024-06-14 09:32:39 +0200167 serverContainer.VppInstance.Vppctl("http cli server")
Filip Tehlarb15a0002022-11-10 12:34:17 +0100168
Adrian Villin4677d922024-06-14 09:32:39 +0200169 uri := "http://" + serverVeth.Ip4AddressString() + "/80"
Maros Ondrejickaffa3f602023-01-26 10:07:29 +0100170
Adrian Villin4677d922024-06-14 09:32:39 +0200171 o := clientContainer.VppInstance.Vppctl("http cli client" +
Filip Tehlard8944382023-11-27 13:28:36 +0100172 " uri " + uri + " query /show/vlib/graph")
Filip Tehlarb15a0002022-11-10 12:34:17 +0100173
Adrian Villin4677d922024-06-14 09:32:39 +0200174 s.Log(o)
175 s.AssertContains(o, "<html>", "<html> not found in the result!")
Matus Fabianba9ea132024-07-12 11:07:17 +0200176 s.AssertContains(o, "</html>", "</html> not found in the result!")
Filip Tehlarb15a0002022-11-10 12:34:17 +0100177}
Filip Tehlarc204c872022-12-21 08:59:16 +0100178
Matus Fabian3d008932024-05-13 10:29:11 +0200179func HttpCliConnectErrorTest(s *VethsSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200180 clientContainer := s.GetContainerByName("client-vpp")
Adrian Villin4677d922024-06-14 09:32:39 +0200181 serverVeth := s.GetInterfaceByName(ServerInterfaceName)
Matus Fabian3d008932024-05-13 10:29:11 +0200182
Adrian Villin4677d922024-06-14 09:32:39 +0200183 uri := "http://" + serverVeth.Ip4AddressString() + "/80"
Matus Fabian3d008932024-05-13 10:29:11 +0200184
Adrian Villin4677d922024-06-14 09:32:39 +0200185 o := clientContainer.VppInstance.Vppctl("http cli client" +
Matus Fabian3d008932024-05-13 10:29:11 +0200186 " uri " + uri + " query /show/vlib/graph")
187
Adrian Villin4677d922024-06-14 09:32:39 +0200188 s.Log(o)
189 s.AssertContains(o, "failed to connect")
Matus Fabian3d008932024-05-13 10:29:11 +0200190}
191
Matus Fabianba9ea132024-07-12 11:07:17 +0200192func HttpClientTest(s *NoTopoSuite) {
193 serverAddress := s.GetInterfaceByName(TapInterfaceName).Ip4AddressString()
194 server := ghttp.NewUnstartedServer()
195 l, err := net.Listen("tcp", serverAddress+":80")
196 s.AssertNil(err, fmt.Sprint(err))
197 server.HTTPTestServer.Listener = l
198 server.AppendHandlers(
199 ghttp.CombineHandlers(
Matus Fabiand46e6742024-07-31 16:08:40 +0200200 s.LogHttpReq(true),
Matus Fabianba9ea132024-07-12 11:07:17 +0200201 ghttp.VerifyRequest("GET", "/test"),
202 ghttp.VerifyHeader(http.Header{"User-Agent": []string{"http_cli_client"}}),
Adrian Villin3601b322024-08-19 14:41:35 +0200203 ghttp.VerifyHeader(http.Header{"Accept": []string{"text/html"}}),
Matus Fabianba9ea132024-07-12 11:07:17 +0200204 ghttp.RespondWith(http.StatusOK, "<html><body><p>Hello</p></body></html>"),
205 ))
206 server.Start()
207 defer server.Close()
208 uri := "http://" + serverAddress + "/80"
209 vpp := s.GetContainerByName("vpp").VppInstance
210 o := vpp.Vppctl("http cli client uri " + uri + " query /test")
211
212 s.Log(o)
213 s.AssertContains(o, "<html>", "<html> not found in the result!")
214 s.AssertContains(o, "</html>", "</html> not found in the result!")
215}
216
217func HttpClientErrRespTest(s *NoTopoSuite) {
218 serverAddress := s.GetInterfaceByName(TapInterfaceName).Ip4AddressString()
219 server := ghttp.NewUnstartedServer()
220 l, err := net.Listen("tcp", serverAddress+":80")
221 s.AssertNil(err, fmt.Sprint(err))
222 server.HTTPTestServer.Listener = l
223 server.AppendHandlers(
224 ghttp.CombineHandlers(
Matus Fabiand46e6742024-07-31 16:08:40 +0200225 s.LogHttpReq(true),
Matus Fabianba9ea132024-07-12 11:07:17 +0200226 ghttp.VerifyRequest("GET", "/test"),
227 ghttp.RespondWith(http.StatusNotFound, "404: Not Found"),
228 ))
229 server.Start()
230 defer server.Close()
231 uri := "http://" + serverAddress + "/80"
232 vpp := s.GetContainerByName("vpp").VppInstance
233 o := vpp.Vppctl("http cli client uri " + uri + " query /test")
234
235 s.Log(o)
236 s.AssertContains(o, "404: Not Found", "error not found in the result!")
237}
238
Matus Fabiand46e6742024-07-31 16:08:40 +0200239func HttpClientPostFormTest(s *NoTopoSuite) {
240 serverAddress := s.GetInterfaceByName(TapInterfaceName).Ip4AddressString()
241 body := "field1=value1&field2=value2"
242
243 server := ghttp.NewUnstartedServer()
244 l, err := net.Listen("tcp", serverAddress+":80")
245 s.AssertNil(err, fmt.Sprint(err))
246 server.HTTPTestServer.Listener = l
247 server.AppendHandlers(
248 ghttp.CombineHandlers(
249 s.LogHttpReq(true),
250 ghttp.VerifyRequest("POST", "/test"),
Adrian Villin3601b322024-08-19 14:41:35 +0200251 ghttp.VerifyContentType("application/x-www-form-urlencoded"),
Matus Fabiand46e6742024-07-31 16:08:40 +0200252 ghttp.VerifyBody([]byte(body)),
253 ghttp.RespondWith(http.StatusOK, nil),
254 ))
255 server.Start()
256 defer server.Close()
257
258 uri := "http://" + serverAddress + "/80"
259 vpp := s.GetContainerByName("vpp").VppInstance
260 o := vpp.Vppctl("http post uri " + uri + " target /test data " + body)
261
262 s.Log(o)
263 s.AssertNotContains(o, "error")
264}
265
266func httpClientPostFile(s *NoTopoSuite, usePtr bool, fileSize int) {
267 serverAddress := s.GetInterfaceByName(TapInterfaceName).Ip4AddressString()
268 vpp := s.GetContainerByName("vpp").VppInstance
269 fileName := "/tmp/test_file.txt"
270 s.Log(vpp.Container.Exec("fallocate -l " + strconv.Itoa(fileSize) + " " + fileName))
271 s.Log(vpp.Container.Exec("ls -la " + fileName))
272
273 server := ghttp.NewUnstartedServer()
274 l, err := net.Listen("tcp", serverAddress+":80")
275 s.AssertNil(err, fmt.Sprint(err))
276 server.HTTPTestServer.Listener = l
277 server.AppendHandlers(
278 ghttp.CombineHandlers(
279 s.LogHttpReq(false),
280 ghttp.VerifyRequest("POST", "/test"),
281 ghttp.VerifyHeader(http.Header{"Content-Length": []string{strconv.Itoa(fileSize)}}),
Adrian Villin3601b322024-08-19 14:41:35 +0200282 ghttp.VerifyContentType("application/octet-stream"),
Matus Fabiand46e6742024-07-31 16:08:40 +0200283 ghttp.RespondWith(http.StatusOK, nil),
284 ))
285 server.Start()
286 defer server.Close()
287
288 uri := "http://" + serverAddress + "/80"
289 cmd := "http post uri " + uri + " target /test file " + fileName
290 if usePtr {
291 cmd += " use-ptr"
292 }
293 o := vpp.Vppctl(cmd)
294
295 s.Log(o)
296 s.AssertNotContains(o, "error")
297}
298
299func HttpClientPostFileTest(s *NoTopoSuite) {
300 httpClientPostFile(s, false, 32768)
301}
302
303func HttpClientPostFilePtrTest(s *NoTopoSuite) {
304 httpClientPostFile(s, true, 131072)
305}
306
Matus Fabiand58177c2024-08-08 12:50:32 +0200307func cliTestAuthority(s *NoTopoSuite, authority string) {
308 o := s.GetContainerByName("vpp").VppInstance.Vppctl("test http authority-form " + authority)
309 s.AssertNotContains(o, "error")
310 s.AssertContains(o, authority)
311}
312
313func cliTestAuthorityError(s *NoTopoSuite, authority string) {
314 o := s.GetContainerByName("vpp").VppInstance.Vppctl("test http authority-form " + authority)
315 s.AssertContains(o, "error")
316}
317
318func AuthorityFormTargetTest(s *NoTopoSuite) {
319 cliTestAuthority(s, "10.10.2.45:20")
320 cliTestAuthority(s, "[dead:beef::1234]:443")
321 cliTestAuthorityError(s, "example.com:80")
322 cliTestAuthorityError(s, "10.10.2.45")
323 cliTestAuthorityError(s, "1000.10.2.45:20")
324 cliTestAuthorityError(s, "[xyz0::1234]:443")
325}
326
Adrian Villincee15aa2024-03-14 11:42:55 -0400327func HttpStaticPromTest(s *NoTopoSuite) {
Filip Tehlarcc1475c2023-11-29 12:59:05 +0100328 query := "stats.prom"
Adrian Villin4677d922024-06-14 09:32:39 +0200329 vpp := s.GetContainerByName("vpp").VppInstance
330 serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString()
331 s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers"))
332 s.Log(vpp.Vppctl("prom enable"))
Adrian Villincee15aa2024-03-14 11:42:55 -0400333 time.Sleep(time.Second * 5)
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200334 client := NewHttpClient()
335 req, err := http.NewRequest("GET", "http://"+serverAddress+":80/"+query, nil)
336 s.AssertNil(err, fmt.Sprint(err))
337 resp, err := client.Do(req)
338 s.AssertNil(err, fmt.Sprint(err))
339 defer resp.Body.Close()
340 s.Log(DumpHttpResp(resp, false))
341 s.AssertEqual(200, resp.StatusCode)
342 s.AssertContains(resp.Header.Get("Content-Type"), "text")
343 s.AssertContains(resp.Header.Get("Content-Type"), "plain")
344 s.AssertNotEqual(int64(0), resp.ContentLength)
345 _, err = io.ReadAll(resp.Body)
Matus Fabiand46e6742024-07-31 16:08:40 +0200346 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200347}
348
Matus Fabianc712de52024-07-24 12:56:14 +0200349func promReq(s *NoTopoSuite, url string) {
Matus Fabian5c4c1b62024-06-28 16:11:04 +0200350 client := NewHttpClient()
351 req, err := http.NewRequest("GET", url, nil)
352 s.AssertNil(err, fmt.Sprint(err))
353 resp, err := client.Do(req)
354 s.AssertNil(err, fmt.Sprint(err))
355 defer resp.Body.Close()
356 s.AssertEqual(200, resp.StatusCode)
357 _, err = io.ReadAll(resp.Body)
Matus Fabiand46e6742024-07-31 16:08:40 +0200358 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian5c4c1b62024-06-28 16:11:04 +0200359}
360
Matus Fabianc712de52024-07-24 12:56:14 +0200361func promReqWg(s *NoTopoSuite, url string, wg *sync.WaitGroup) {
362 defer GinkgoRecover()
363 defer wg.Done()
364 promReq(s, url)
365}
366
Matus Fabiand46e6742024-07-31 16:08:40 +0200367func PromConcurrentConnectionsTest(s *NoTopoSuite) {
Matus Fabian5c4c1b62024-06-28 16:11:04 +0200368 vpp := s.GetContainerByName("vpp").VppInstance
369 serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString()
370 url := "http://" + serverAddress + ":80/stats.prom"
371
372 s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers"))
373 s.Log(vpp.Vppctl("prom enable"))
374 time.Sleep(time.Second * 5)
375
376 var wg sync.WaitGroup
377 for i := 0; i < 20; i++ {
378 wg.Add(1)
Matus Fabianc712de52024-07-24 12:56:14 +0200379 go promReqWg(s, url, &wg)
Matus Fabian5c4c1b62024-06-28 16:11:04 +0200380 }
381 wg.Wait()
382 s.Log(vpp.Vppctl("show session verbose proto http"))
383}
384
Matus Fabianc712de52024-07-24 12:56:14 +0200385func PromMemLeakTest(s *NoTopoSuite) {
386 s.SkipUnlessLeakCheck()
387
388 vpp := s.GetContainerByName("vpp").VppInstance
389 serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString()
390 url := "http://" + serverAddress + ":80/stats.prom"
391
392 /* no goVPP less noise */
393 vpp.Disconnect()
394
395 s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers"))
396 s.Log(vpp.Vppctl("prom enable"))
397 time.Sleep(time.Second * 3)
398
399 /* warmup request (FIB) */
400 promReq(s, url)
401
402 vpp.EnableMemoryTrace()
403 traces1, err := vpp.GetMemoryTrace()
404 s.AssertNil(err, fmt.Sprint(err))
405
406 /* collect stats couple of times */
407 for i := 0; i < 5; i++ {
408 time.Sleep(time.Second * 1)
409 promReq(s, url)
410 }
411
412 /* let's give it some time to clean up sessions */
413 time.Sleep(time.Second * 5)
414
415 traces2, err := vpp.GetMemoryTrace()
416 s.AssertNil(err, fmt.Sprint(err))
417 vpp.MemLeakCheck(traces1, traces2)
418}
419
Matus Fabianba9ea132024-07-12 11:07:17 +0200420func HttpClientGetMemLeakTest(s *VethsSuite) {
421 s.SkipUnlessLeakCheck()
422
423 serverContainer := s.GetContainerByName("server-vpp").VppInstance
424 clientContainer := s.GetContainerByName("client-vpp").VppInstance
425 serverVeth := s.GetInterfaceByName(ServerInterfaceName)
426
427 /* no goVPP less noise */
428 clientContainer.Disconnect()
429
430 serverContainer.Vppctl("http cli server")
431
432 uri := "http://" + serverVeth.Ip4AddressString() + "/80"
433
434 /* warmup request (FIB) */
435 clientContainer.Vppctl("http cli client uri " + uri + " query /show/version")
436
Matus Fabiand46e6742024-07-31 16:08:40 +0200437 /* let's give it some time to clean up sessions, so local port can be reused and we have less noise */
438 time.Sleep(time.Second * 12)
439
Matus Fabianba9ea132024-07-12 11:07:17 +0200440 clientContainer.EnableMemoryTrace()
441 traces1, err := clientContainer.GetMemoryTrace()
442 s.AssertNil(err, fmt.Sprint(err))
443
444 clientContainer.Vppctl("http cli client uri " + uri + " query /show/vlib/graph")
445
446 /* let's give it some time to clean up sessions */
447 time.Sleep(time.Second * 12)
448
449 traces2, err := clientContainer.GetMemoryTrace()
450 s.AssertNil(err, fmt.Sprint(err))
451 clientContainer.MemLeakCheck(traces1, traces2)
452}
453
Matus Fabiand46e6742024-07-31 16:08:40 +0200454func HttpClientPostMemLeakTest(s *NoTopoSuite) {
455 s.SkipUnlessLeakCheck()
456
457 serverAddress := s.GetInterfaceByName(TapInterfaceName).Ip4AddressString()
458 body := "field1=value1&field2=value2"
459
460 uri := "http://" + serverAddress + "/80"
461 vpp := s.GetContainerByName("vpp").VppInstance
462
463 /* no goVPP less noise */
464 vpp.Disconnect()
465
466 server := ghttp.NewUnstartedServer()
467 l, err := net.Listen("tcp", serverAddress+":80")
468 s.AssertNil(err, fmt.Sprint(err))
469 server.HTTPTestServer.Listener = l
470 server.AppendHandlers(
471 ghttp.CombineHandlers(
472 ghttp.VerifyRequest("POST", "/test"),
473 ghttp.RespondWith(http.StatusOK, nil),
474 ),
475 ghttp.CombineHandlers(
476 ghttp.VerifyRequest("POST", "/test"),
477 ghttp.RespondWith(http.StatusOK, nil),
478 ),
479 )
480 server.Start()
481 defer server.Close()
482
483 /* warmup request (FIB) */
484 vpp.Vppctl("http post uri " + uri + " target /test data " + body)
485
486 /* let's give it some time to clean up sessions, so local port can be reused and we have less noise */
487 time.Sleep(time.Second * 12)
488
489 vpp.EnableMemoryTrace()
490 traces1, err := vpp.GetMemoryTrace()
491 s.AssertNil(err, fmt.Sprint(err))
492
493 vpp.Vppctl("http post uri " + uri + " target /test data " + body)
494
495 /* let's give it some time to clean up sessions */
496 time.Sleep(time.Second * 12)
497
498 traces2, err := vpp.GetMemoryTrace()
499 s.AssertNil(err, fmt.Sprint(err))
500 vpp.MemLeakCheck(traces1, traces2)
501}
502
Matus Fabian55467552024-08-06 15:55:26 +0200503func HttpInvalidClientRequestMemLeakTest(s *NoTopoSuite) {
504 s.SkipUnlessLeakCheck()
505
506 vpp := s.GetContainerByName("vpp").VppInstance
507 serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString()
508
509 /* no goVPP less noise */
510 vpp.Disconnect()
511
512 vpp.Vppctl("http cli server")
513
514 /* warmup request (FIB) */
515 _, err := TcpSendReceive(serverAddress+":80", "GET / HTTP/1.1\r\n")
516 s.AssertNil(err, fmt.Sprint(err))
517
518 /* let's give it some time to clean up sessions, so local port can be reused and we have less noise */
519 time.Sleep(time.Second * 12)
520
521 vpp.EnableMemoryTrace()
522 traces1, err := vpp.GetMemoryTrace()
523 s.AssertNil(err, fmt.Sprint(err))
524
525 _, err = TcpSendReceive(serverAddress+":80", "GET / HTTP/1.1\r\n")
526 s.AssertNil(err, fmt.Sprint(err))
527
528 /* let's give it some time to clean up sessions */
529 time.Sleep(time.Second * 12)
530
531 traces2, err := vpp.GetMemoryTrace()
532 s.AssertNil(err, fmt.Sprint(err))
533 vpp.MemLeakCheck(traces1, traces2)
534
535}
536
Adrian Villin86fa9432024-08-08 08:56:34 +0200537func HttpStaticFileHandlerDefaultMaxAgeTest(s *NoTopoSuite) {
538 HttpStaticFileHandlerTestFunction(s, "default")
539}
540
Matus Fabiand46e6742024-07-31 16:08:40 +0200541func HttpStaticFileHandlerTest(s *NoTopoSuite) {
Adrian Villin86fa9432024-08-08 08:56:34 +0200542 HttpStaticFileHandlerTestFunction(s, "123")
543}
544
545func HttpStaticFileHandlerTestFunction(s *NoTopoSuite, max_age string) {
546 var max_age_formatted string
547 if max_age == "default" {
548 max_age_formatted = ""
549 max_age = "600"
550 } else {
551 max_age_formatted = "max-age " + max_age
552 }
553
Matus Fabianba9ea132024-07-12 11:07:17 +0200554 content := "<html><body><p>Hello</p></body></html>"
555 content2 := "<html><body><p>Page</p></body></html>"
Adrian Villin7e6606a2024-08-16 15:23:28 +0200556 currentDate := time.Now().In(time.FixedZone("GMT", 0)).Format(http.TimeFormat)[:17]
557
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200558 vpp := s.GetContainerByName("vpp").VppInstance
559 vpp.Container.Exec("mkdir -p " + wwwRootPath)
Matus Fabiand46e6742024-07-31 16:08:40 +0200560 err := vpp.Container.CreateFile(wwwRootPath+"/index.html", content)
561 s.AssertNil(err, fmt.Sprint(err))
562 err = vpp.Container.CreateFile(wwwRootPath+"/page.html", content2)
563 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200564 serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString()
Adrian Villin86fa9432024-08-08 08:56:34 +0200565 s.Log(vpp.Vppctl("http static server www-root " + wwwRootPath + " uri tcp://" + serverAddress + "/80 debug cache-size 2m " + max_age_formatted))
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200566
567 client := NewHttpClient()
568 req, err := http.NewRequest("GET", "http://"+serverAddress+":80/index.html", nil)
569 s.AssertNil(err, fmt.Sprint(err))
570 resp, err := client.Do(req)
571 s.AssertNil(err, fmt.Sprint(err))
572 defer resp.Body.Close()
Adrian Villin7e6606a2024-08-16 15:23:28 +0200573
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200574 s.Log(DumpHttpResp(resp, true))
575 s.AssertEqual(200, resp.StatusCode)
576 s.AssertContains(resp.Header.Get("Content-Type"), "html")
Adrian Villin86fa9432024-08-08 08:56:34 +0200577 s.AssertContains(resp.Header.Get("Cache-Control"), "max-age="+max_age)
Adrian Villin7e6606a2024-08-16 15:23:28 +0200578 // only checking date
579 s.AssertContains(resp.Header.Get("Last-Modified"), currentDate)
580 s.AssertEqual(len(resp.Header.Get("Last-Modified")), 29)
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200581 s.AssertEqual(int64(len([]rune(content))), resp.ContentLength)
Adrian Villin7e6606a2024-08-16 15:23:28 +0200582
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200583 body, err := io.ReadAll(resp.Body)
Matus Fabiand46e6742024-07-31 16:08:40 +0200584 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200585 s.AssertEqual(string(body), content)
586 o := vpp.Vppctl("show http static server cache verbose")
587 s.Log(o)
588 s.AssertContains(o, "index.html")
589 s.AssertNotContains(o, "page.html")
590
591 resp, err = client.Do(req)
592 s.AssertNil(err, fmt.Sprint(err))
593 defer resp.Body.Close()
594 s.Log(DumpHttpResp(resp, true))
595 s.AssertEqual(200, resp.StatusCode)
596 s.AssertContains(resp.Header.Get("Content-Type"), "html")
Adrian Villin86fa9432024-08-08 08:56:34 +0200597 s.AssertContains(resp.Header.Get("Cache-Control"), "max-age="+max_age)
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200598 s.AssertEqual(int64(len([]rune(content))), resp.ContentLength)
Adrian Villin7e6606a2024-08-16 15:23:28 +0200599
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200600 body, err = io.ReadAll(resp.Body)
Matus Fabiand46e6742024-07-31 16:08:40 +0200601 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200602 s.AssertEqual(string(body), content)
603
604 req, err = http.NewRequest("GET", "http://"+serverAddress+":80/page.html", nil)
605 s.AssertNil(err, fmt.Sprint(err))
606 resp, err = client.Do(req)
607 s.AssertNil(err, fmt.Sprint(err))
608 defer resp.Body.Close()
609 s.Log(DumpHttpResp(resp, true))
610 s.AssertEqual(200, resp.StatusCode)
611 s.AssertContains(resp.Header.Get("Content-Type"), "html")
Adrian Villin86fa9432024-08-08 08:56:34 +0200612 s.AssertContains(resp.Header.Get("Cache-Control"), "max-age="+max_age)
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200613 s.AssertEqual(int64(len([]rune(content2))), resp.ContentLength)
Adrian Villin7e6606a2024-08-16 15:23:28 +0200614
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200615 body, err = io.ReadAll(resp.Body)
Matus Fabiand46e6742024-07-31 16:08:40 +0200616 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200617 s.AssertEqual(string(body), content2)
618 o = vpp.Vppctl("show http static server cache verbose")
619 s.Log(o)
620 s.AssertContains(o, "index.html")
621 s.AssertContains(o, "page.html")
Filip Tehlarcc1475c2023-11-29 12:59:05 +0100622}
623
Matus Fabian5409d332024-05-28 13:39:13 +0200624func HttpStaticPathTraversalTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200625 vpp := s.GetContainerByName("vpp").VppInstance
626 vpp.Container.Exec("mkdir -p " + wwwRootPath)
627 vpp.Container.Exec("mkdir -p " + "/tmp/secret_folder")
Matus Fabiand46e6742024-07-31 16:08:40 +0200628 err := vpp.Container.CreateFile("/tmp/secret_folder/secret_file.txt", "secret")
629 s.AssertNil(err, fmt.Sprint(err))
Adrian Villin4677d922024-06-14 09:32:39 +0200630 serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString()
631 s.Log(vpp.Vppctl("http static server www-root " + wwwRootPath + " uri tcp://" + serverAddress + "/80 debug"))
Matus Fabian5409d332024-05-28 13:39:13 +0200632
Adrian Villin4677d922024-06-14 09:32:39 +0200633 client := NewHttpClient()
Matus Fabian5409d332024-05-28 13:39:13 +0200634 req, err := http.NewRequest("GET", "http://"+serverAddress+":80/../secret_folder/secret_file.txt", nil)
Adrian Villin4677d922024-06-14 09:32:39 +0200635 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian5409d332024-05-28 13:39:13 +0200636 resp, err := client.Do(req)
Adrian Villin4677d922024-06-14 09:32:39 +0200637 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian5409d332024-05-28 13:39:13 +0200638 defer resp.Body.Close()
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200639 s.Log(DumpHttpResp(resp, true))
Adrian Villin4677d922024-06-14 09:32:39 +0200640 s.AssertEqual(404, resp.StatusCode)
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200641 s.AssertEmpty(resp.Header.Get("Content-Type"))
642 s.AssertEmpty(resp.Header.Get("Cache-Control"))
643 s.AssertEqual(int64(0), resp.ContentLength)
Matus Fabian5409d332024-05-28 13:39:13 +0200644}
645
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200646func HttpStaticMovedTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200647 vpp := s.GetContainerByName("vpp").VppInstance
648 vpp.Container.Exec("mkdir -p " + wwwRootPath + "/tmp.aaa")
Matus Fabiand46e6742024-07-31 16:08:40 +0200649 err := vpp.Container.CreateFile(wwwRootPath+"/tmp.aaa/index.html", "<html><body><p>Hello</p></body></html>")
650 s.AssertNil(err, fmt.Sprint(err))
Adrian Villin4677d922024-06-14 09:32:39 +0200651 serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString()
652 s.Log(vpp.Vppctl("http static server www-root " + wwwRootPath + " uri tcp://" + serverAddress + "/80 debug"))
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200653
Adrian Villin4677d922024-06-14 09:32:39 +0200654 client := NewHttpClient()
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200655 req, err := http.NewRequest("GET", "http://"+serverAddress+":80/tmp.aaa", nil)
Adrian Villin4677d922024-06-14 09:32:39 +0200656 s.AssertNil(err, fmt.Sprint(err))
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200657 resp, err := client.Do(req)
Adrian Villin4677d922024-06-14 09:32:39 +0200658 s.AssertNil(err, fmt.Sprint(err))
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200659 defer resp.Body.Close()
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200660 s.Log(DumpHttpResp(resp, true))
Adrian Villin4677d922024-06-14 09:32:39 +0200661 s.AssertEqual(301, resp.StatusCode)
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200662 s.AssertEqual("http://"+serverAddress+"/tmp.aaa/index.html", resp.Header.Get("Location"))
663 s.AssertEmpty(resp.Header.Get("Content-Type"))
664 s.AssertEmpty(resp.Header.Get("Cache-Control"))
665 s.AssertEqual(int64(0), resp.ContentLength)
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200666}
667
668func HttpStaticNotFoundTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200669 vpp := s.GetContainerByName("vpp").VppInstance
670 vpp.Container.Exec("mkdir -p " + wwwRootPath)
671 serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString()
672 s.Log(vpp.Vppctl("http static server www-root " + wwwRootPath + " uri tcp://" + serverAddress + "/80 debug"))
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200673
Adrian Villin4677d922024-06-14 09:32:39 +0200674 client := NewHttpClient()
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200675 req, err := http.NewRequest("GET", "http://"+serverAddress+":80/notfound.html", nil)
Adrian Villin4677d922024-06-14 09:32:39 +0200676 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian595d8cb2024-05-17 11:28:43 +0200677 resp, err := client.Do(req)
Adrian Villin4677d922024-06-14 09:32:39 +0200678 s.AssertNil(err, fmt.Sprint(err))
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200679 defer resp.Body.Close()
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200680 s.Log(DumpHttpResp(resp, true))
Adrian Villin4677d922024-06-14 09:32:39 +0200681 s.AssertEqual(404, resp.StatusCode)
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200682 s.AssertEmpty(resp.Header.Get("Content-Type"))
683 s.AssertEmpty(resp.Header.Get("Cache-Control"))
684 s.AssertEqual(int64(0), resp.ContentLength)
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200685}
686
687func HttpCliMethodNotAllowedTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200688 vpp := s.GetContainerByName("vpp").VppInstance
689 serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString()
690 vpp.Vppctl("http cli server")
Matus Fabian616201a2024-05-02 11:17:15 +0200691
Adrian Villin4677d922024-06-14 09:32:39 +0200692 client := NewHttpClient()
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200693 req, err := http.NewRequest("POST", "http://"+serverAddress+":80/test", nil)
Adrian Villin4677d922024-06-14 09:32:39 +0200694 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian595d8cb2024-05-17 11:28:43 +0200695 resp, err := client.Do(req)
Adrian Villin4677d922024-06-14 09:32:39 +0200696 s.AssertNil(err, fmt.Sprint(err))
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200697 defer resp.Body.Close()
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200698 s.Log(DumpHttpResp(resp, true))
Adrian Villin4677d922024-06-14 09:32:39 +0200699 s.AssertEqual(405, resp.StatusCode)
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200700 s.AssertNotEqual("", resp.Header.Get("Allow"), "server MUST generate an Allow header")
701 s.AssertEmpty(resp.Header.Get("Content-Type"))
702 s.AssertEqual(int64(0), resp.ContentLength)
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200703}
704
705func HttpCliBadRequestTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200706 vpp := s.GetContainerByName("vpp").VppInstance
707 serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString()
708 vpp.Vppctl("http cli server")
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200709
Adrian Villin4677d922024-06-14 09:32:39 +0200710 client := NewHttpClient()
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200711 req, err := http.NewRequest("GET", "http://"+serverAddress+":80", nil)
Adrian Villin4677d922024-06-14 09:32:39 +0200712 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian595d8cb2024-05-17 11:28:43 +0200713 resp, err := client.Do(req)
Adrian Villin4677d922024-06-14 09:32:39 +0200714 s.AssertNil(err, fmt.Sprint(err))
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200715 defer resp.Body.Close()
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200716 s.Log(DumpHttpResp(resp, true))
Adrian Villin4677d922024-06-14 09:32:39 +0200717 s.AssertEqual(400, resp.StatusCode)
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200718 s.AssertEmpty(resp.Header.Get("Content-Type"))
719 s.AssertEqual(int64(0), resp.ContentLength)
Matus Fabianb7a9ed72024-05-10 16:20:40 +0200720}
721
Matus Fabian82ad9662024-06-04 19:00:00 +0200722func HttpStaticBuildInUrlGetVersionTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200723 vpp := s.GetContainerByName("vpp").VppInstance
724 serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString()
725 s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug"))
Matus Fabian82ad9662024-06-04 19:00:00 +0200726
Adrian Villin4677d922024-06-14 09:32:39 +0200727 client := NewHttpClient()
Matus Fabian82ad9662024-06-04 19:00:00 +0200728 req, err := http.NewRequest("GET", "http://"+serverAddress+":80/version.json", nil)
Adrian Villin4677d922024-06-14 09:32:39 +0200729 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +0200730 resp, err := client.Do(req)
Adrian Villin4677d922024-06-14 09:32:39 +0200731 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +0200732 defer resp.Body.Close()
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200733 s.Log(DumpHttpResp(resp, true))
Adrian Villin4677d922024-06-14 09:32:39 +0200734 s.AssertEqual(200, resp.StatusCode)
Matus Fabian82ad9662024-06-04 19:00:00 +0200735 data, err := io.ReadAll(resp.Body)
Adrian Villin4677d922024-06-14 09:32:39 +0200736 s.AssertNil(err, fmt.Sprint(err))
737 s.AssertContains(string(data), "vpp_details")
738 s.AssertContains(string(data), "version")
739 s.AssertContains(string(data), "build_date")
740 s.AssertNotContains(string(data), "build_by")
741 s.AssertNotContains(string(data), "build_host")
742 s.AssertNotContains(string(data), "build_dir")
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200743 s.AssertContains(resp.Header.Get("Content-Type"), "json")
Matus Fabian82ad9662024-06-04 19:00:00 +0200744}
745
746func HttpStaticBuildInUrlGetVersionVerboseTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200747 vpp := s.GetContainerByName("vpp").VppInstance
748 serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString()
749 s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug"))
Matus Fabian82ad9662024-06-04 19:00:00 +0200750
Adrian Villin4677d922024-06-14 09:32:39 +0200751 client := NewHttpClient()
Matus Fabian82ad9662024-06-04 19:00:00 +0200752 req, err := http.NewRequest("GET", "http://"+serverAddress+":80/version.json?verbose=true", nil)
Adrian Villin4677d922024-06-14 09:32:39 +0200753 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +0200754 resp, err := client.Do(req)
Adrian Villin4677d922024-06-14 09:32:39 +0200755 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +0200756 defer resp.Body.Close()
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200757 s.Log(DumpHttpResp(resp, true))
Adrian Villin4677d922024-06-14 09:32:39 +0200758 s.AssertEqual(200, resp.StatusCode)
Matus Fabian82ad9662024-06-04 19:00:00 +0200759 data, err := io.ReadAll(resp.Body)
Adrian Villin4677d922024-06-14 09:32:39 +0200760 s.AssertNil(err, fmt.Sprint(err))
761 s.AssertContains(string(data), "vpp_details")
762 s.AssertContains(string(data), "version")
763 s.AssertContains(string(data), "build_date")
764 s.AssertContains(string(data), "build_by")
765 s.AssertContains(string(data), "build_host")
766 s.AssertContains(string(data), "build_dir")
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200767 s.AssertContains(resp.Header.Get("Content-Type"), "json")
Matus Fabian82ad9662024-06-04 19:00:00 +0200768}
769
770func HttpStaticBuildInUrlGetIfListTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200771 vpp := s.GetContainerByName("vpp").VppInstance
772 serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString()
773 s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug"))
Matus Fabian82ad9662024-06-04 19:00:00 +0200774
Adrian Villin4677d922024-06-14 09:32:39 +0200775 client := NewHttpClient()
Matus Fabian82ad9662024-06-04 19:00:00 +0200776 req, err := http.NewRequest("GET", "http://"+serverAddress+":80/interface_list.json", nil)
Adrian Villin4677d922024-06-14 09:32:39 +0200777 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +0200778 resp, err := client.Do(req)
Adrian Villin4677d922024-06-14 09:32:39 +0200779 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +0200780 defer resp.Body.Close()
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200781 s.Log(DumpHttpResp(resp, true))
Adrian Villin4677d922024-06-14 09:32:39 +0200782 s.AssertEqual(200, resp.StatusCode)
Matus Fabian82ad9662024-06-04 19:00:00 +0200783 data, err := io.ReadAll(resp.Body)
Adrian Villin4677d922024-06-14 09:32:39 +0200784 s.AssertNil(err, fmt.Sprint(err))
785 s.AssertContains(string(data), "interface_list")
786 s.AssertContains(string(data), s.GetInterfaceByName(TapInterfaceName).Peer.Name())
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200787 s.AssertContains(resp.Header.Get("Content-Type"), "json")
Matus Fabian82ad9662024-06-04 19:00:00 +0200788}
789
790func HttpStaticBuildInUrlGetIfStatsTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200791 vpp := s.GetContainerByName("vpp").VppInstance
792 serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString()
793 s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug"))
Matus Fabian82ad9662024-06-04 19:00:00 +0200794
Adrian Villin4677d922024-06-14 09:32:39 +0200795 client := NewHttpClient()
Matus Fabian82ad9662024-06-04 19:00:00 +0200796 req, err := http.NewRequest("GET", "http://"+serverAddress+":80/interface_stats.json", nil)
Adrian Villin4677d922024-06-14 09:32:39 +0200797 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +0200798 resp, err := client.Do(req)
Adrian Villin4677d922024-06-14 09:32:39 +0200799 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +0200800 defer resp.Body.Close()
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200801 s.Log(DumpHttpResp(resp, true))
Adrian Villin4677d922024-06-14 09:32:39 +0200802 s.AssertEqual(200, resp.StatusCode)
Matus Fabian82ad9662024-06-04 19:00:00 +0200803 data, err := io.ReadAll(resp.Body)
Adrian Villin4677d922024-06-14 09:32:39 +0200804 s.AssertNil(err, fmt.Sprint(err))
805 s.AssertContains(string(data), "interface_stats")
806 s.AssertContains(string(data), "local0")
807 s.AssertContains(string(data), s.GetInterfaceByName(TapInterfaceName).Peer.Name())
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200808 s.AssertContains(resp.Header.Get("Content-Type"), "json")
Matus Fabian82ad9662024-06-04 19:00:00 +0200809}
810
811func validatePostInterfaceStats(s *NoTopoSuite, data string) {
Adrian Villin4677d922024-06-14 09:32:39 +0200812 s.AssertContains(data, "interface_stats")
813 s.AssertContains(data, s.GetInterfaceByName(TapInterfaceName).Peer.Name())
814 s.AssertNotContains(data, "error")
815 s.AssertNotContains(data, "local0")
Matus Fabian82ad9662024-06-04 19:00:00 +0200816}
817
818func HttpStaticBuildInUrlPostIfStatsTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200819 vpp := s.GetContainerByName("vpp").VppInstance
820 serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString()
821 s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug"))
822 body := []byte(s.GetInterfaceByName(TapInterfaceName).Peer.Name())
Matus Fabian82ad9662024-06-04 19:00:00 +0200823
Adrian Villin4677d922024-06-14 09:32:39 +0200824 client := NewHttpClient()
Matus Fabian82ad9662024-06-04 19:00:00 +0200825 req, err := http.NewRequest("POST",
826 "http://"+serverAddress+":80/interface_stats.json", bytes.NewBuffer(body))
Adrian Villin4677d922024-06-14 09:32:39 +0200827 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +0200828 resp, err := client.Do(req)
Adrian Villin4677d922024-06-14 09:32:39 +0200829 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +0200830 defer resp.Body.Close()
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200831 s.Log(DumpHttpResp(resp, true))
Adrian Villin4677d922024-06-14 09:32:39 +0200832 s.AssertEqual(200, resp.StatusCode)
Matus Fabian82ad9662024-06-04 19:00:00 +0200833 data, err := io.ReadAll(resp.Body)
Adrian Villin4677d922024-06-14 09:32:39 +0200834 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +0200835 validatePostInterfaceStats(s, string(data))
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200836 s.AssertContains(resp.Header.Get("Content-Type"), "json")
Matus Fabian82ad9662024-06-04 19:00:00 +0200837}
838
839func HttpStaticMacTimeTest(s *NoTopoSuite) {
Adrian Villin7e6606a2024-08-16 15:23:28 +0200840 currentDate := time.Now().In(time.FixedZone("GMT", 0)).Format(http.TimeFormat)[:17]
Adrian Villin4677d922024-06-14 09:32:39 +0200841 vpp := s.GetContainerByName("vpp").VppInstance
842 serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString()
843 s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug"))
844 s.Log(vpp.Vppctl("mactime enable-disable " + s.GetInterfaceByName(TapInterfaceName).Peer.Name()))
Matus Fabian82ad9662024-06-04 19:00:00 +0200845
Adrian Villin4677d922024-06-14 09:32:39 +0200846 client := NewHttpClient()
Matus Fabian82ad9662024-06-04 19:00:00 +0200847 req, err := http.NewRequest("GET", "http://"+serverAddress+":80/mactime.json", nil)
Adrian Villin4677d922024-06-14 09:32:39 +0200848 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +0200849 resp, err := client.Do(req)
Adrian Villin4677d922024-06-14 09:32:39 +0200850 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +0200851 defer resp.Body.Close()
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200852 s.Log(DumpHttpResp(resp, true))
Adrian Villin4677d922024-06-14 09:32:39 +0200853 s.AssertEqual(200, resp.StatusCode)
Matus Fabian82ad9662024-06-04 19:00:00 +0200854 data, err := io.ReadAll(resp.Body)
Adrian Villin4677d922024-06-14 09:32:39 +0200855 s.AssertNil(err, fmt.Sprint(err))
856 s.AssertContains(string(data), "mactime")
857 s.AssertContains(string(data), s.GetInterfaceByName(TapInterfaceName).Ip4AddressString())
858 s.AssertContains(string(data), s.GetInterfaceByName(TapInterfaceName).HwAddress.String())
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200859 s.AssertContains(resp.Header.Get("Content-Type"), "json")
Adrian Villin7e6606a2024-08-16 15:23:28 +0200860 s.AssertEqual(len(resp.Header.Get("Date")), 29)
861 // only checking date
Adrian Villin1fb7ae32024-08-19 10:51:59 +0200862 s.AssertContains(resp.Header.Get("Date"), currentDate)
Matus Fabian82ad9662024-06-04 19:00:00 +0200863}
864
865func HttpInvalidRequestLineTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200866 vpp := s.GetContainerByName("vpp").VppInstance
867 serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString()
868 vpp.Vppctl("http cli server")
Matus Fabian82ad9662024-06-04 19:00:00 +0200869
Adrian Villin4677d922024-06-14 09:32:39 +0200870 resp, err := TcpSendReceive(serverAddress+":80", "GET / HTTP/1.1")
871 s.AssertNil(err, fmt.Sprint(err))
872 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "invalid framing not allowed")
Matus Fabian82ad9662024-06-04 19:00:00 +0200873
Adrian Villin4677d922024-06-14 09:32:39 +0200874 resp, err = TcpSendReceive(serverAddress+":80", "GET / HTTP/1.1\r\n")
875 s.AssertNil(err, fmt.Sprint(err))
876 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "invalid framing not allowed")
Matus Fabian82ad9662024-06-04 19:00:00 +0200877
Adrian Villin4677d922024-06-14 09:32:39 +0200878 resp, err = TcpSendReceive(serverAddress+":80", "GET /\r\n\r\n")
879 s.AssertNil(err, fmt.Sprint(err))
880 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "HTTP-version must be present")
Matus Fabian82ad9662024-06-04 19:00:00 +0200881
Adrian Villin4677d922024-06-14 09:32:39 +0200882 resp, err = TcpSendReceive(serverAddress+":80", "GET HTTP/1.1\r\n\r\n")
883 s.AssertNil(err, fmt.Sprint(err))
884 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "request-target must be present")
Matus Fabian82ad9662024-06-04 19:00:00 +0200885
Adrian Villin4677d922024-06-14 09:32:39 +0200886 resp, err = TcpSendReceive(serverAddress+":80", "GET HTTP/1.1\r\n\r\n")
887 s.AssertNil(err, fmt.Sprint(err))
888 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "request-target must be present")
Matus Fabian82ad9662024-06-04 19:00:00 +0200889
Adrian Villin4677d922024-06-14 09:32:39 +0200890 resp, err = TcpSendReceive(serverAddress+":80", "GET / HTTP/x\r\n\r\n")
891 s.AssertNil(err, fmt.Sprint(err))
892 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "'HTTP/x' invalid http version not allowed")
Matus Fabian82ad9662024-06-04 19:00:00 +0200893
Adrian Villin4677d922024-06-14 09:32:39 +0200894 resp, err = TcpSendReceive(serverAddress+":80", "GET / HTTP1.1\r\n\r\n")
895 s.AssertNil(err, fmt.Sprint(err))
896 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "'HTTP1.1' invalid http version not allowed")
Matus Fabian82ad9662024-06-04 19:00:00 +0200897}
898
899func HttpInvalidTargetSyntaxTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200900 vpp := s.GetContainerByName("vpp").VppInstance
901 serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString()
902 s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug"))
Matus Fabian82ad9662024-06-04 19:00:00 +0200903
Adrian Villin4677d922024-06-14 09:32:39 +0200904 resp, err := TcpSendReceive(serverAddress+":80", "GET /interface|stats.json HTTP/1.1\r\n\r\n")
905 s.AssertNil(err, fmt.Sprint(err))
906 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "'|' not allowed in target path")
Matus Fabian82ad9662024-06-04 19:00:00 +0200907
Adrian Villin4677d922024-06-14 09:32:39 +0200908 resp, err = TcpSendReceive(serverAddress+":80", "GET /interface#stats.json HTTP/1.1\r\n\r\n")
909 s.AssertNil(err, fmt.Sprint(err))
910 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "'#' not allowed in target path")
Matus Fabian82ad9662024-06-04 19:00:00 +0200911
Adrian Villin4677d922024-06-14 09:32:39 +0200912 resp, err = TcpSendReceive(serverAddress+":80", "GET /interface%stats.json HTTP/1.1\r\n\r\n")
913 s.AssertNil(err, fmt.Sprint(err))
914 s.AssertContains(resp, "HTTP/1.1 400 Bad Request",
Matus Fabian82ad9662024-06-04 19:00:00 +0200915 "after '%' there must be two hex-digit characters in target path")
916
Adrian Villin4677d922024-06-14 09:32:39 +0200917 resp, err = TcpSendReceive(serverAddress+":80", "GET /interface%1stats.json HTTP/1.1\r\n\r\n")
918 s.AssertNil(err, fmt.Sprint(err))
919 s.AssertContains(resp, "HTTP/1.1 400 Bad Request",
Matus Fabian82ad9662024-06-04 19:00:00 +0200920 "after '%' there must be two hex-digit characters in target path")
921
Adrian Villin4677d922024-06-14 09:32:39 +0200922 resp, err = TcpSendReceive(serverAddress+":80", "GET /interface%Bstats.json HTTP/1.1\r\n\r\n")
923 s.AssertNil(err, fmt.Sprint(err))
924 s.AssertContains(resp, "HTTP/1.1 400 Bad Request",
Matus Fabian82ad9662024-06-04 19:00:00 +0200925 "after '%' there must be two hex-digit characters in target path")
926
Adrian Villin4677d922024-06-14 09:32:39 +0200927 resp, err = TcpSendReceive(serverAddress+":80", "GET /interface%stats.json%B HTTP/1.1\r\n\r\n")
928 s.AssertNil(err, fmt.Sprint(err))
929 s.AssertContains(resp, "HTTP/1.1 400 Bad Request",
Matus Fabian82ad9662024-06-04 19:00:00 +0200930 "after '%' there must be two hex-digit characters in target path")
931
Adrian Villin4677d922024-06-14 09:32:39 +0200932 resp, err = TcpSendReceive(serverAddress+":80", "GET /version.json?verbose>true HTTP/1.1\r\n\r\n")
933 s.AssertNil(err, fmt.Sprint(err))
934 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "'>' not allowed in target query")
Matus Fabian82ad9662024-06-04 19:00:00 +0200935
Adrian Villin4677d922024-06-14 09:32:39 +0200936 resp, err = TcpSendReceive(serverAddress+":80", "GET /version.json?verbose%true HTTP/1.1\r\n\r\n")
937 s.AssertNil(err, fmt.Sprint(err))
938 s.AssertContains(resp, "HTTP/1.1 400 Bad Request",
Matus Fabian82ad9662024-06-04 19:00:00 +0200939 "after '%' there must be two hex-digit characters in target query")
940
Adrian Villin4677d922024-06-14 09:32:39 +0200941 resp, err = TcpSendReceive(serverAddress+":80", "GET /version.json?verbose=%1 HTTP/1.1\r\n\r\n")
942 s.AssertNil(err, fmt.Sprint(err))
943 s.AssertContains(resp, "HTTP/1.1 400 Bad Request",
Matus Fabian82ad9662024-06-04 19:00:00 +0200944 "after '%' there must be two hex-digit characters in target query")
945}
946
947func HttpInvalidContentLengthTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200948 vpp := s.GetContainerByName("vpp").VppInstance
949 serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString()
950 vpp.Vppctl("http cli server")
Matus Fabian82ad9662024-06-04 19:00:00 +0200951
Adrian Villin4677d922024-06-14 09:32:39 +0200952 resp, err := TcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nContent-Length:\r\n\r\n")
953 s.AssertNil(err, fmt.Sprint(err))
954 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "Content-Length value must be present")
Matus Fabian82ad9662024-06-04 19:00:00 +0200955
Adrian Villin4677d922024-06-14 09:32:39 +0200956 resp, err = TcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nContent-Length: \r\n\r\n")
957 s.AssertNil(err, fmt.Sprint(err))
958 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "Content-Length value must be present")
Matus Fabian82ad9662024-06-04 19:00:00 +0200959
Adrian Villin4677d922024-06-14 09:32:39 +0200960 resp, err = TcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nContent-Length: a\r\n\r\n")
961 s.AssertNil(err, fmt.Sprint(err))
962 s.AssertContains(resp, "HTTP/1.1 400 Bad Request",
Matus Fabian82ad9662024-06-04 19:00:00 +0200963 "Content-Length value other than digit not allowed")
964}
965
966func HttpContentLengthTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200967 vpp := s.GetContainerByName("vpp").VppInstance
968 serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString()
969 s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug"))
970 ifName := s.GetInterfaceByName(TapInterfaceName).Peer.Name()
Matus Fabian82ad9662024-06-04 19:00:00 +0200971
Adrian Villin4677d922024-06-14 09:32:39 +0200972 resp, err := TcpSendReceive(serverAddress+":80",
Matus Fabian82ad9662024-06-04 19:00:00 +0200973 "POST /interface_stats.json HTTP/1.1\r\nContent-Length:4\r\n\r\n"+ifName)
Adrian Villin4677d922024-06-14 09:32:39 +0200974 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +0200975 validatePostInterfaceStats(s, resp)
976
Adrian Villin4677d922024-06-14 09:32:39 +0200977 resp, err = TcpSendReceive(serverAddress+":80",
Matus Fabian82ad9662024-06-04 19:00:00 +0200978 "POST /interface_stats.json HTTP/1.1\r\n Content-Length: 4 \r\n\r\n"+ifName)
Adrian Villin4677d922024-06-14 09:32:39 +0200979 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +0200980 validatePostInterfaceStats(s, resp)
981
Adrian Villin4677d922024-06-14 09:32:39 +0200982 resp, err = TcpSendReceive(serverAddress+":80",
Matus Fabian82ad9662024-06-04 19:00:00 +0200983 "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 +0200984 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +0200985 validatePostInterfaceStats(s, resp)
986}
987
988func HttpMethodNotImplementedTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +0200989 vpp := s.GetContainerByName("vpp").VppInstance
990 serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString()
991 vpp.Vppctl("http cli server")
Matus Fabian82ad9662024-06-04 19:00:00 +0200992
Adrian Villin4677d922024-06-14 09:32:39 +0200993 client := NewHttpClient()
Matus Fabian82ad9662024-06-04 19:00:00 +0200994 req, err := http.NewRequest("OPTIONS", "http://"+serverAddress+":80/show/version", nil)
Adrian Villin4677d922024-06-14 09:32:39 +0200995 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +0200996 resp, err := client.Do(req)
Adrian Villin4677d922024-06-14 09:32:39 +0200997 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +0200998 defer resp.Body.Close()
Matus Fabian8ca6ce62024-06-20 17:08:26 +0200999 s.Log(DumpHttpResp(resp, true))
Adrian Villin4677d922024-06-14 09:32:39 +02001000 s.AssertEqual(501, resp.StatusCode)
Matus Fabian8ca6ce62024-06-20 17:08:26 +02001001 s.AssertEmpty(resp.Header.Get("Content-Type"))
1002 s.AssertEqual(int64(0), resp.ContentLength)
Matus Fabian82ad9662024-06-04 19:00:00 +02001003}
1004
1005func HttpVersionNotSupportedTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +02001006 vpp := s.GetContainerByName("vpp").VppInstance
1007 serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString()
1008 vpp.Vppctl("http cli server")
Matus Fabian82ad9662024-06-04 19:00:00 +02001009
Adrian Villin4677d922024-06-14 09:32:39 +02001010 resp, err := TcpSendReceive(serverAddress+":80", "GET / HTTP/2\r\n\r\n")
1011 s.AssertNil(err, fmt.Sprint(err))
1012 s.AssertContains(resp, "HTTP/1.1 505 HTTP Version Not Supported")
Matus Fabian82ad9662024-06-04 19:00:00 +02001013}
1014
1015func HttpUriDecodeTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +02001016 vpp := s.GetContainerByName("vpp").VppInstance
1017 serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString()
1018 vpp.Vppctl("http cli server")
Matus Fabian82ad9662024-06-04 19:00:00 +02001019
Adrian Villin4677d922024-06-14 09:32:39 +02001020 client := NewHttpClient()
Matus Fabian82ad9662024-06-04 19:00:00 +02001021 req, err := http.NewRequest("GET", "http://"+serverAddress+":80/sh%6fw%20versio%6E%20verbose", nil)
Adrian Villin4677d922024-06-14 09:32:39 +02001022 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +02001023 resp, err := client.Do(req)
Adrian Villin4677d922024-06-14 09:32:39 +02001024 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian82ad9662024-06-04 19:00:00 +02001025 defer resp.Body.Close()
Matus Fabian8ca6ce62024-06-20 17:08:26 +02001026 s.Log(DumpHttpResp(resp, true))
Adrian Villin4677d922024-06-14 09:32:39 +02001027 s.AssertEqual(200, resp.StatusCode)
Matus Fabian82ad9662024-06-04 19:00:00 +02001028 data, err := io.ReadAll(resp.Body)
Adrian Villin4677d922024-06-14 09:32:39 +02001029 s.AssertNil(err, fmt.Sprint(err))
Adrian Villin4677d922024-06-14 09:32:39 +02001030 s.AssertNotContains(string(data), "unknown input")
1031 s.AssertContains(string(data), "Compiler")
Matus Fabian8ca6ce62024-06-20 17:08:26 +02001032 s.AssertContains(resp.Header.Get("Content-Type"), "html")
Matus Fabian82ad9662024-06-04 19:00:00 +02001033}
1034
1035func HttpHeadersTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +02001036 vpp := s.GetContainerByName("vpp").VppInstance
1037 serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString()
1038 vpp.Vppctl("http cli server")
Matus Fabian82ad9662024-06-04 19:00:00 +02001039
Adrian Villin4677d922024-06-14 09:32:39 +02001040 resp, err := TcpSendReceive(
Matus Fabian82ad9662024-06-04 19:00:00 +02001041 serverAddress+":80",
1042 "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 +02001043 s.AssertNil(err, fmt.Sprint(err))
1044 s.AssertContains(resp, "HTTP/1.1 200 OK")
Adrian Villin3601b322024-08-19 14:41:35 +02001045 s.AssertContains(resp, "Content-Type: text/plain")
Adrian Villin4677d922024-06-14 09:32:39 +02001046 s.AssertNotContains(resp, "<html>", "html content received instead of plain text")
Matus Fabian82ad9662024-06-04 19:00:00 +02001047}
1048
1049func HttpInvalidHeadersTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +02001050 vpp := s.GetContainerByName("vpp").VppInstance
1051 serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString()
1052 vpp.Vppctl("http cli server")
Matus Fabian82ad9662024-06-04 19:00:00 +02001053
Adrian Villin4677d922024-06-14 09:32:39 +02001054 resp, err := TcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nUser-Agent: test\r\n")
1055 s.AssertNil(err, fmt.Sprint(err))
1056 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "Header section must end with CRLF CRLF")
Matus Fabian82ad9662024-06-04 19:00:00 +02001057
Adrian Villin4677d922024-06-14 09:32:39 +02001058 resp, err = TcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nHost:"+serverAddress+":80\r\nUser@Agent:test\r\n\r\n")
1059 s.AssertNil(err, fmt.Sprint(err))
1060 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "'@' not allowed in field name")
Matus Fabian82ad9662024-06-04 19:00:00 +02001061
Adrian Villin4677d922024-06-14 09:32:39 +02001062 resp, err = TcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nHost:"+serverAddress+":80\r\nUser-Agent\r\n\r\n")
1063 s.AssertNil(err, fmt.Sprint(err))
1064 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "incomplete field line not allowed")
Matus Fabian82ad9662024-06-04 19:00:00 +02001065
Adrian Villin4677d922024-06-14 09:32:39 +02001066 resp, err = TcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nHost:"+serverAddress+":80\r\n: test\r\n\r\n")
1067 s.AssertNil(err, fmt.Sprint(err))
1068 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "empty field name not allowed")
Matus Fabian82ad9662024-06-04 19:00:00 +02001069
Adrian Villin4677d922024-06-14 09:32:39 +02001070 resp, err = TcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nHost:"+serverAddress+":80\rUser-Agent:test\r\n\r\n")
1071 s.AssertNil(err, fmt.Sprint(err))
1072 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "invalid field line end not allowed")
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\nHost:"+serverAddress+":80\nUser-Agent:test\r\n\r\n")
1075 s.AssertNil(err, fmt.Sprint(err))
1076 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "invalid field line end not allowed")
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:\r\n\r\n")
1079 s.AssertNil(err, fmt.Sprint(err))
1080 s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "empty field value not allowed")
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", "empty field value not allowed")
Matus Fabian82ad9662024-06-04 19:00:00 +02001085}
1086
Matus Fabianb7a9ed72024-05-10 16:20:40 +02001087func HeaderServerTest(s *NoTopoSuite) {
Adrian Villin4677d922024-06-14 09:32:39 +02001088 vpp := s.GetContainerByName("vpp").VppInstance
1089 serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString()
1090 vpp.Vppctl("http cli server")
Matus Fabianb7a9ed72024-05-10 16:20:40 +02001091
Adrian Villin4677d922024-06-14 09:32:39 +02001092 client := NewHttpClient()
Matus Fabianb7a9ed72024-05-10 16:20:40 +02001093 req, err := http.NewRequest("GET", "http://"+serverAddress+":80/show/version", nil)
Adrian Villin4677d922024-06-14 09:32:39 +02001094 s.AssertNil(err, fmt.Sprint(err))
Matus Fabian595d8cb2024-05-17 11:28:43 +02001095 resp, err := client.Do(req)
Adrian Villin4677d922024-06-14 09:32:39 +02001096 s.AssertNil(err, fmt.Sprint(err))
Matus Fabianb7a9ed72024-05-10 16:20:40 +02001097 defer resp.Body.Close()
Matus Fabian8ca6ce62024-06-20 17:08:26 +02001098 s.Log(DumpHttpResp(resp, true))
1099 s.AssertEqual(200, resp.StatusCode)
Adrian Villin4677d922024-06-14 09:32:39 +02001100 s.AssertEqual("http_cli_server", resp.Header.Get("Server"))
Matus Fabian8ca6ce62024-06-20 17:08:26 +02001101 s.AssertContains(resp.Header.Get("Content-Type"), "html")
Matus Fabian616201a2024-05-02 11:17:15 +02001102}