http: return more than data from server app
Server app could return headers in front of body/data buffer. Offers apis for building and serialization of headers section. HTTP layer now only add Date, Server and Content-Lengths headers, rest is up to app. Well known header names are predefined. Type: improvement Change-Id: If778bdfc9acf6b0d11a48f0a745a3a56c96c2436 Signed-off-by: Matus Fabian <matfabia@cisco.com>
This commit is contained in:

committed by
Florin Coras

parent
1f870c9bdc
commit
8ca6ce6fe1
@ -9,7 +9,6 @@ import (
|
||||
"time"
|
||||
|
||||
. "fd.io/hs-test/infra"
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -21,7 +20,7 @@ func init() {
|
||||
HttpContentLengthTest, HttpStaticBuildInUrlGetIfListTest, HttpStaticBuildInUrlGetVersionTest,
|
||||
HttpStaticMacTimeTest, HttpStaticBuildInUrlGetVersionVerboseTest, HttpVersionNotSupportedTest,
|
||||
HttpInvalidContentLengthTest, HttpInvalidTargetSyntaxTest, HttpStaticPathTraversalTest, HttpUriDecodeTest,
|
||||
HttpHeadersTest)
|
||||
HttpHeadersTest, HttpStaticFileHandler)
|
||||
RegisterNoTopoSoloTests(HttpStaticPromTest, HttpTpsTest, HttpTpsInterruptModeTest)
|
||||
}
|
||||
|
||||
@ -89,19 +88,81 @@ func HttpCliConnectErrorTest(s *VethsSuite) {
|
||||
}
|
||||
|
||||
func HttpStaticPromTest(s *NoTopoSuite) {
|
||||
finished := make(chan error, 1)
|
||||
query := "stats.prom"
|
||||
vpp := s.GetContainerByName("vpp").VppInstance
|
||||
serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString()
|
||||
s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers"))
|
||||
s.Log(vpp.Vppctl("prom enable"))
|
||||
time.Sleep(time.Second * 5)
|
||||
go func() {
|
||||
defer GinkgoRecover()
|
||||
s.StartWget(finished, serverAddress, "80", query, "")
|
||||
}()
|
||||
err := <-finished
|
||||
s.AssertNil(err)
|
||||
client := NewHttpClient()
|
||||
req, err := http.NewRequest("GET", "http://"+serverAddress+":80/"+query, nil)
|
||||
s.AssertNil(err, fmt.Sprint(err))
|
||||
resp, err := client.Do(req)
|
||||
s.AssertNil(err, fmt.Sprint(err))
|
||||
defer resp.Body.Close()
|
||||
s.Log(DumpHttpResp(resp, false))
|
||||
s.AssertEqual(200, resp.StatusCode)
|
||||
s.AssertContains(resp.Header.Get("Content-Type"), "text")
|
||||
s.AssertContains(resp.Header.Get("Content-Type"), "plain")
|
||||
s.AssertNotEqual(int64(0), resp.ContentLength)
|
||||
_, err = io.ReadAll(resp.Body)
|
||||
}
|
||||
|
||||
func HttpStaticFileHandler(s *NoTopoSuite) {
|
||||
content := "<http><body><p>Hello</p></body></http>"
|
||||
content2 := "<http><body><p>Page</p></body></http>"
|
||||
vpp := s.GetContainerByName("vpp").VppInstance
|
||||
vpp.Container.Exec("mkdir -p " + wwwRootPath)
|
||||
vpp.Container.CreateFile(wwwRootPath+"/index.html", content)
|
||||
vpp.Container.CreateFile(wwwRootPath+"/page.html", content2)
|
||||
serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString()
|
||||
s.Log(vpp.Vppctl("http static server www-root " + wwwRootPath + " uri tcp://" + serverAddress + "/80 debug cache-size 2m"))
|
||||
|
||||
client := NewHttpClient()
|
||||
req, err := http.NewRequest("GET", "http://"+serverAddress+":80/index.html", nil)
|
||||
s.AssertNil(err, fmt.Sprint(err))
|
||||
resp, err := client.Do(req)
|
||||
s.AssertNil(err, fmt.Sprint(err))
|
||||
defer resp.Body.Close()
|
||||
s.Log(DumpHttpResp(resp, true))
|
||||
s.AssertEqual(200, resp.StatusCode)
|
||||
s.AssertContains(resp.Header.Get("Content-Type"), "html")
|
||||
s.AssertContains(resp.Header.Get("Cache-Control"), "max-age=")
|
||||
s.AssertEqual(int64(len([]rune(content))), resp.ContentLength)
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
s.AssertEqual(string(body), content)
|
||||
o := vpp.Vppctl("show http static server cache verbose")
|
||||
s.Log(o)
|
||||
s.AssertContains(o, "index.html")
|
||||
s.AssertNotContains(o, "page.html")
|
||||
|
||||
resp, err = client.Do(req)
|
||||
s.AssertNil(err, fmt.Sprint(err))
|
||||
defer resp.Body.Close()
|
||||
s.Log(DumpHttpResp(resp, true))
|
||||
s.AssertEqual(200, resp.StatusCode)
|
||||
s.AssertContains(resp.Header.Get("Content-Type"), "html")
|
||||
s.AssertContains(resp.Header.Get("Cache-Control"), "max-age=")
|
||||
s.AssertEqual(int64(len([]rune(content))), resp.ContentLength)
|
||||
body, err = io.ReadAll(resp.Body)
|
||||
s.AssertEqual(string(body), content)
|
||||
|
||||
req, err = http.NewRequest("GET", "http://"+serverAddress+":80/page.html", nil)
|
||||
s.AssertNil(err, fmt.Sprint(err))
|
||||
resp, err = client.Do(req)
|
||||
s.AssertNil(err, fmt.Sprint(err))
|
||||
defer resp.Body.Close()
|
||||
s.Log(DumpHttpResp(resp, true))
|
||||
s.AssertEqual(200, resp.StatusCode)
|
||||
s.AssertContains(resp.Header.Get("Content-Type"), "html")
|
||||
s.AssertContains(resp.Header.Get("Cache-Control"), "max-age=")
|
||||
s.AssertEqual(int64(len([]rune(content2))), resp.ContentLength)
|
||||
body, err = io.ReadAll(resp.Body)
|
||||
s.AssertEqual(string(body), content2)
|
||||
o = vpp.Vppctl("show http static server cache verbose")
|
||||
s.Log(o)
|
||||
s.AssertContains(o, "index.html")
|
||||
s.AssertContains(o, "page.html")
|
||||
}
|
||||
|
||||
func HttpStaticPathTraversalTest(s *NoTopoSuite) {
|
||||
@ -118,7 +179,11 @@ func HttpStaticPathTraversalTest(s *NoTopoSuite) {
|
||||
resp, err := client.Do(req)
|
||||
s.AssertNil(err, fmt.Sprint(err))
|
||||
defer resp.Body.Close()
|
||||
s.Log(DumpHttpResp(resp, true))
|
||||
s.AssertEqual(404, resp.StatusCode)
|
||||
s.AssertEmpty(resp.Header.Get("Content-Type"))
|
||||
s.AssertEmpty(resp.Header.Get("Cache-Control"))
|
||||
s.AssertEqual(int64(0), resp.ContentLength)
|
||||
}
|
||||
|
||||
func HttpStaticMovedTest(s *NoTopoSuite) {
|
||||
@ -134,8 +199,12 @@ func HttpStaticMovedTest(s *NoTopoSuite) {
|
||||
resp, err := client.Do(req)
|
||||
s.AssertNil(err, fmt.Sprint(err))
|
||||
defer resp.Body.Close()
|
||||
s.Log(DumpHttpResp(resp, true))
|
||||
s.AssertEqual(301, resp.StatusCode)
|
||||
s.AssertNotEqual("", resp.Header.Get("Location"))
|
||||
s.AssertEqual("http://"+serverAddress+"/tmp.aaa/index.html", resp.Header.Get("Location"))
|
||||
s.AssertEmpty(resp.Header.Get("Content-Type"))
|
||||
s.AssertEmpty(resp.Header.Get("Cache-Control"))
|
||||
s.AssertEqual(int64(0), resp.ContentLength)
|
||||
}
|
||||
|
||||
func HttpStaticNotFoundTest(s *NoTopoSuite) {
|
||||
@ -150,7 +219,11 @@ func HttpStaticNotFoundTest(s *NoTopoSuite) {
|
||||
resp, err := client.Do(req)
|
||||
s.AssertNil(err, fmt.Sprint(err))
|
||||
defer resp.Body.Close()
|
||||
s.Log(DumpHttpResp(resp, true))
|
||||
s.AssertEqual(404, resp.StatusCode)
|
||||
s.AssertEmpty(resp.Header.Get("Content-Type"))
|
||||
s.AssertEmpty(resp.Header.Get("Cache-Control"))
|
||||
s.AssertEqual(int64(0), resp.ContentLength)
|
||||
}
|
||||
|
||||
func HttpCliMethodNotAllowedTest(s *NoTopoSuite) {
|
||||
@ -164,9 +237,11 @@ func HttpCliMethodNotAllowedTest(s *NoTopoSuite) {
|
||||
resp, err := client.Do(req)
|
||||
s.AssertNil(err, fmt.Sprint(err))
|
||||
defer resp.Body.Close()
|
||||
s.Log(DumpHttpResp(resp, true))
|
||||
s.AssertEqual(405, resp.StatusCode)
|
||||
// TODO: need to be fixed in http code
|
||||
//s.AssertNotEqual("", resp.Header.Get("Allow"))
|
||||
s.AssertNotEqual("", resp.Header.Get("Allow"), "server MUST generate an Allow header")
|
||||
s.AssertEmpty(resp.Header.Get("Content-Type"))
|
||||
s.AssertEqual(int64(0), resp.ContentLength)
|
||||
}
|
||||
|
||||
func HttpCliBadRequestTest(s *NoTopoSuite) {
|
||||
@ -180,7 +255,10 @@ func HttpCliBadRequestTest(s *NoTopoSuite) {
|
||||
resp, err := client.Do(req)
|
||||
s.AssertNil(err, fmt.Sprint(err))
|
||||
defer resp.Body.Close()
|
||||
s.Log(DumpHttpResp(resp, true))
|
||||
s.AssertEqual(400, resp.StatusCode)
|
||||
s.AssertEmpty(resp.Header.Get("Content-Type"))
|
||||
s.AssertEqual(int64(0), resp.ContentLength)
|
||||
}
|
||||
|
||||
func HttpStaticBuildInUrlGetVersionTest(s *NoTopoSuite) {
|
||||
@ -194,6 +272,7 @@ func HttpStaticBuildInUrlGetVersionTest(s *NoTopoSuite) {
|
||||
resp, err := client.Do(req)
|
||||
s.AssertNil(err, fmt.Sprint(err))
|
||||
defer resp.Body.Close()
|
||||
s.Log(DumpHttpResp(resp, true))
|
||||
s.AssertEqual(200, resp.StatusCode)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
s.AssertNil(err, fmt.Sprint(err))
|
||||
@ -203,6 +282,7 @@ func HttpStaticBuildInUrlGetVersionTest(s *NoTopoSuite) {
|
||||
s.AssertNotContains(string(data), "build_by")
|
||||
s.AssertNotContains(string(data), "build_host")
|
||||
s.AssertNotContains(string(data), "build_dir")
|
||||
s.AssertContains(resp.Header.Get("Content-Type"), "json")
|
||||
}
|
||||
|
||||
func HttpStaticBuildInUrlGetVersionVerboseTest(s *NoTopoSuite) {
|
||||
@ -216,6 +296,7 @@ func HttpStaticBuildInUrlGetVersionVerboseTest(s *NoTopoSuite) {
|
||||
resp, err := client.Do(req)
|
||||
s.AssertNil(err, fmt.Sprint(err))
|
||||
defer resp.Body.Close()
|
||||
s.Log(DumpHttpResp(resp, true))
|
||||
s.AssertEqual(200, resp.StatusCode)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
s.AssertNil(err, fmt.Sprint(err))
|
||||
@ -225,6 +306,7 @@ func HttpStaticBuildInUrlGetVersionVerboseTest(s *NoTopoSuite) {
|
||||
s.AssertContains(string(data), "build_by")
|
||||
s.AssertContains(string(data), "build_host")
|
||||
s.AssertContains(string(data), "build_dir")
|
||||
s.AssertContains(resp.Header.Get("Content-Type"), "json")
|
||||
}
|
||||
|
||||
func HttpStaticBuildInUrlGetIfListTest(s *NoTopoSuite) {
|
||||
@ -238,11 +320,13 @@ func HttpStaticBuildInUrlGetIfListTest(s *NoTopoSuite) {
|
||||
resp, err := client.Do(req)
|
||||
s.AssertNil(err, fmt.Sprint(err))
|
||||
defer resp.Body.Close()
|
||||
s.Log(DumpHttpResp(resp, true))
|
||||
s.AssertEqual(200, resp.StatusCode)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
s.AssertNil(err, fmt.Sprint(err))
|
||||
s.AssertContains(string(data), "interface_list")
|
||||
s.AssertContains(string(data), s.GetInterfaceByName(TapInterfaceName).Peer.Name())
|
||||
s.AssertContains(resp.Header.Get("Content-Type"), "json")
|
||||
}
|
||||
|
||||
func HttpStaticBuildInUrlGetIfStatsTest(s *NoTopoSuite) {
|
||||
@ -256,12 +340,14 @@ func HttpStaticBuildInUrlGetIfStatsTest(s *NoTopoSuite) {
|
||||
resp, err := client.Do(req)
|
||||
s.AssertNil(err, fmt.Sprint(err))
|
||||
defer resp.Body.Close()
|
||||
s.Log(DumpHttpResp(resp, true))
|
||||
s.AssertEqual(200, resp.StatusCode)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
s.AssertNil(err, fmt.Sprint(err))
|
||||
s.AssertContains(string(data), "interface_stats")
|
||||
s.AssertContains(string(data), "local0")
|
||||
s.AssertContains(string(data), s.GetInterfaceByName(TapInterfaceName).Peer.Name())
|
||||
s.AssertContains(resp.Header.Get("Content-Type"), "json")
|
||||
}
|
||||
|
||||
func validatePostInterfaceStats(s *NoTopoSuite, data string) {
|
||||
@ -284,10 +370,12 @@ func HttpStaticBuildInUrlPostIfStatsTest(s *NoTopoSuite) {
|
||||
resp, err := client.Do(req)
|
||||
s.AssertNil(err, fmt.Sprint(err))
|
||||
defer resp.Body.Close()
|
||||
s.Log(DumpHttpResp(resp, true))
|
||||
s.AssertEqual(200, resp.StatusCode)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
s.AssertNil(err, fmt.Sprint(err))
|
||||
validatePostInterfaceStats(s, string(data))
|
||||
s.AssertContains(resp.Header.Get("Content-Type"), "json")
|
||||
}
|
||||
|
||||
func HttpStaticMacTimeTest(s *NoTopoSuite) {
|
||||
@ -302,12 +390,14 @@ func HttpStaticMacTimeTest(s *NoTopoSuite) {
|
||||
resp, err := client.Do(req)
|
||||
s.AssertNil(err, fmt.Sprint(err))
|
||||
defer resp.Body.Close()
|
||||
s.Log(DumpHttpResp(resp, true))
|
||||
s.AssertEqual(200, resp.StatusCode)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
s.AssertNil(err, fmt.Sprint(err))
|
||||
s.AssertContains(string(data), "mactime")
|
||||
s.AssertContains(string(data), s.GetInterfaceByName(TapInterfaceName).Ip4AddressString())
|
||||
s.AssertContains(string(data), s.GetInterfaceByName(TapInterfaceName).HwAddress.String())
|
||||
s.AssertContains(resp.Header.Get("Content-Type"), "json")
|
||||
}
|
||||
|
||||
func HttpInvalidRequestLineTest(s *NoTopoSuite) {
|
||||
@ -444,7 +534,10 @@ func HttpMethodNotImplementedTest(s *NoTopoSuite) {
|
||||
resp, err := client.Do(req)
|
||||
s.AssertNil(err, fmt.Sprint(err))
|
||||
defer resp.Body.Close()
|
||||
s.Log(DumpHttpResp(resp, true))
|
||||
s.AssertEqual(501, resp.StatusCode)
|
||||
s.AssertEmpty(resp.Header.Get("Content-Type"))
|
||||
s.AssertEqual(int64(0), resp.ContentLength)
|
||||
}
|
||||
|
||||
func HttpVersionNotSupportedTest(s *NoTopoSuite) {
|
||||
@ -468,12 +561,13 @@ func HttpUriDecodeTest(s *NoTopoSuite) {
|
||||
resp, err := client.Do(req)
|
||||
s.AssertNil(err, fmt.Sprint(err))
|
||||
defer resp.Body.Close()
|
||||
s.Log(DumpHttpResp(resp, true))
|
||||
s.AssertEqual(200, resp.StatusCode)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
s.AssertNil(err, fmt.Sprint(err))
|
||||
s.Log(string(data))
|
||||
s.AssertNotContains(string(data), "unknown input")
|
||||
s.AssertContains(string(data), "Compiler")
|
||||
s.AssertContains(resp.Header.Get("Content-Type"), "html")
|
||||
}
|
||||
|
||||
func HttpHeadersTest(s *NoTopoSuite) {
|
||||
@ -539,5 +633,8 @@ func HeaderServerTest(s *NoTopoSuite) {
|
||||
resp, err := client.Do(req)
|
||||
s.AssertNil(err, fmt.Sprint(err))
|
||||
defer resp.Body.Close()
|
||||
s.Log(DumpHttpResp(resp, true))
|
||||
s.AssertEqual(200, resp.StatusCode)
|
||||
s.AssertEqual("http_cli_server", resp.Header.Get("Server"))
|
||||
s.AssertContains(resp.Header.Get("Content-Type"), "html")
|
||||
}
|
||||
|
Reference in New Issue
Block a user