@@ -28,6 +28,27 @@ import (
2828 "google.golang.org/grpc/metadata"
2929)
3030
31+ // findSetHeader searches for a header by key name in a slice of HeaderValueOption,
32+ // returning (value, true) if found, or ("", false) if not found. This is
33+ // order-independent since http.Header iteration is non-deterministic.
34+ func findSetHeader (headers []* v3.HeaderValueOption , key string ) (string , bool ) {
35+ for _ , h := range headers {
36+ if h .GetHeader ().Key == key {
37+ return string (h .GetHeader ().RawValue ), true
38+ }
39+ }
40+ return "" , false
41+ }
42+
43+ // requireSetHeader asserts that a header with the given key exists in headers
44+ // and that its value equals the expected value.
45+ func requireSetHeader (t * testing.T , headers []* v3.HeaderValueOption , key , expectedValue string ) {
46+ t .Helper ()
47+ val , ok := findSetHeader (headers , key )
48+ require .True (t , ok , "expected header %q to be present in SetHeaders" , key )
49+ require .Equal (t , expectedValue , val , "unexpected value for header %q" , key )
50+ }
51+
3152func TestAppSec (t * testing.T ) {
3253 t .Setenv ("DD_APPSEC_RULES" , "../../../internal/appsec/testdata/user_rules.json" )
3354 t .Setenv ("DD_APPSEC_WAF_TIMEOUT" , "10ms" )
@@ -98,8 +119,7 @@ func TestAppSec(t *testing.T) {
98119 require .IsType (t , & envoyextproc.ProcessingResponse_ImmediateResponse {}, res .GetResponse ())
99120 require .Equal (t , uint32 (0 ), res .GetImmediateResponse ().GetGrpcStatus ().Status )
100121 require .Equal (t , envoytypes .StatusCode (403 ), res .GetImmediateResponse ().GetStatus ().Code )
101- require .Equal (t , "Content-Type" , res .GetImmediateResponse ().GetHeaders ().SetHeaders [0 ].GetHeader ().Key )
102- require .Equal (t , "application/json" , string (res .GetImmediateResponse ().GetHeaders ().SetHeaders [0 ].GetHeader ().RawValue ))
122+ requireSetHeader (t , res .GetImmediateResponse ().GetHeaders ().SetHeaders , "Content-Type" , "application/json" )
103123 require .NoError (t , err )
104124
105125 err = stream .CloseSend ()
@@ -130,8 +150,7 @@ func TestAppSec(t *testing.T) {
130150 require .IsType (t , & envoyextproc.ProcessingResponse_ImmediateResponse {}, res .GetResponse ())
131151 require .Equal (t , uint32 (0 ), res .GetImmediateResponse ().GetGrpcStatus ().Status )
132152 require .Equal (t , envoytypes .StatusCode (418 ), res .GetImmediateResponse ().GetStatus ().Code )
133- require .Equal (t , "Content-Type" , res .GetImmediateResponse ().GetHeaders ().SetHeaders [0 ].GetHeader ().Key )
134- require .Equal (t , "application/json" , string (res .GetImmediateResponse ().GetHeaders ().SetHeaders [0 ].GetHeader ().RawValue ))
153+ requireSetHeader (t , res .GetImmediateResponse ().GetHeaders ().SetHeaders , "Content-Type" , "application/json" )
135154 require .NoError (t , err )
136155
137156 err = stream .CloseSend ()
@@ -162,8 +181,7 @@ func TestAppSec(t *testing.T) {
162181 require .IsType (t , & envoyextproc.ProcessingResponse_ImmediateResponse {}, res .GetResponse ())
163182 require .Equal (t , uint32 (0 ), res .GetImmediateResponse ().GetGrpcStatus ().Status )
164183 require .Equal (t , envoytypes .StatusCode (418 ), res .GetImmediateResponse ().GetStatus ().Code )
165- require .Equal (t , "Content-Type" , res .GetImmediateResponse ().GetHeaders ().SetHeaders [0 ].GetHeader ().Key )
166- require .Equal (t , "application/json" , string (res .GetImmediateResponse ().GetHeaders ().SetHeaders [0 ].GetHeader ().RawValue ))
184+ requireSetHeader (t , res .GetImmediateResponse ().GetHeaders ().SetHeaders , "Content-Type" , "application/json" )
167185 require .NoError (t , err )
168186
169187 err = stream .CloseSend ()
@@ -223,8 +241,7 @@ func TestAppSec(t *testing.T) {
223241 require .IsType (t , & envoyextproc.ProcessingResponse_ImmediateResponse {}, res .GetResponse ())
224242 require .Equal (t , uint32 (0 ), res .GetImmediateResponse ().GetGrpcStatus ().Status )
225243 require .Equal (t , envoytypes .StatusCode (403 ), res .GetImmediateResponse ().GetStatus ().Code )
226- require .Equal (t , "Content-Type" , res .GetImmediateResponse ().GetHeaders ().SetHeaders [0 ].GetHeader ().Key )
227- require .Equal (t , "application/json" , string (res .GetImmediateResponse ().GetHeaders ().SetHeaders [0 ].GetHeader ().RawValue ))
244+ requireSetHeader (t , res .GetImmediateResponse ().GetHeaders ().SetHeaders , "Content-Type" , "application/json" )
228245 require .NoError (t , err )
229246
230247 err = stream .CloseSend ()
@@ -392,8 +409,7 @@ func TestAppSecBodyParsingEnabled(t *testing.T) {
392409 require .IsType (t , & envoyextproc.ProcessingResponse_ImmediateResponse {}, res .GetResponse ())
393410 require .Equal (t , uint32 (0 ), res .GetImmediateResponse ().GetGrpcStatus ().Status )
394411 require .Equal (t , envoytypes .StatusCode (403 ), res .GetImmediateResponse ().GetStatus ().Code )
395- require .Equal (t , "Content-Type" , res .GetImmediateResponse ().GetHeaders ().SetHeaders [0 ].GetHeader ().Key )
396- require .Equal (t , "application/json" , string (res .GetImmediateResponse ().GetHeaders ().SetHeaders [0 ].GetHeader ().RawValue ))
412+ requireSetHeader (t , res .GetImmediateResponse ().GetHeaders ().SetHeaders , "Content-Type" , "application/json" )
397413 require .NoError (t , err )
398414
399415 err = stream .CloseSend ()
@@ -425,9 +441,8 @@ func TestAppSecBodyParsingEnabled(t *testing.T) {
425441 require .IsType (t , & envoyextproc.ProcessingResponse_ImmediateResponse {}, res .GetResponse ())
426442 require .Equal (t , uint32 (0 ), res .GetImmediateResponse ().GetGrpcStatus ().Status )
427443 require .Equal (t , envoytypes .StatusCode (418 ), res .GetImmediateResponse ().GetStatus ().Code ) // 418 because of the rule file
428- require .Len (t , res .GetImmediateResponse ().GetHeaders ().SetHeaders , 1 )
429- require .Equal (t , "Content-Type" , res .GetImmediateResponse ().GetHeaders ().SetHeaders [0 ].GetHeader ().Key )
430- require .Equal (t , "application/json" , string (res .GetImmediateResponse ().GetHeaders ().SetHeaders [0 ].GetHeader ().RawValue ))
444+ require .Len (t , res .GetImmediateResponse ().GetHeaders ().SetHeaders , 2 )
445+ requireSetHeader (t , res .GetImmediateResponse ().GetHeaders ().SetHeaders , "Content-Type" , "application/json" )
431446 require .NoError (t , err )
432447
433448 err = stream .CloseSend ()
@@ -478,9 +493,8 @@ func TestAppSecBodyParsingEnabled(t *testing.T) {
478493 require .IsType (t , & envoyextproc.ProcessingResponse_ImmediateResponse {}, res .GetResponse ())
479494 require .Equal (t , uint32 (0 ), res .GetImmediateResponse ().GetGrpcStatus ().Status )
480495 require .Equal (t , envoytypes .StatusCode (418 ), res .GetImmediateResponse ().GetStatus ().Code ) // 418 because of the rule file
481- require .Len (t , res .GetImmediateResponse ().GetHeaders ().SetHeaders , 1 )
482- require .Equal (t , "Content-Type" , res .GetImmediateResponse ().GetHeaders ().SetHeaders [0 ].GetHeader ().Key )
483- require .Equal (t , "application/json" , string (res .GetImmediateResponse ().GetHeaders ().SetHeaders [0 ].GetHeader ().RawValue ))
496+ require .Len (t , res .GetImmediateResponse ().GetHeaders ().SetHeaders , 2 )
497+ requireSetHeader (t , res .GetImmediateResponse ().GetHeaders ().SetHeaders , "Content-Type" , "application/json" )
484498 require .NoError (t , err )
485499
486500 err = stream .CloseSend ()
@@ -545,8 +559,7 @@ func TestAppSecBodyParsingEnabled(t *testing.T) {
545559 require .IsType (t , & envoyextproc.ProcessingResponse_ImmediateResponse {}, res .GetResponse ())
546560 require .Equal (t , uint32 (0 ), res .GetImmediateResponse ().GetGrpcStatus ().Status )
547561 require .Equal (t , envoytypes .StatusCode (403 ), res .GetImmediateResponse ().GetStatus ().Code )
548- require .Equal (t , "Content-Type" , res .GetImmediateResponse ().GetHeaders ().SetHeaders [0 ].GetHeader ().Key )
549- require .Equal (t , "application/json" , string (res .GetImmediateResponse ().GetHeaders ().SetHeaders [0 ].GetHeader ().RawValue ))
562+ requireSetHeader (t , res .GetImmediateResponse ().GetHeaders ().SetHeaders , "Content-Type" , "application/json" )
550563 require .NoError (t , err )
551564
552565 err = stream .CloseSend ()
@@ -615,8 +628,7 @@ func TestAppSecBodyParsingEnabled(t *testing.T) {
615628 require.IsType(t, &envoyextproc.ProcessingResponse_ImmediateResponse{}, res.GetResponse())
616629 require.Equal(t, uint32(0), res.GetImmediateResponse().GetGrpcStatus().Status)
617630 require.Equal(t, envoytypes.StatusCode(403), res.GetImmediateResponse().GetStatus().Code)
618- require.Equal(t, "Content-Type", res.GetImmediateResponse().GetHeaders().SetHeaders[0].GetHeader().Key)
619- require.Equal(t, "application/json", string(res.GetImmediateResponse().GetHeaders().SetHeaders[0].GetHeader().RawValue))
631+ requireSetHeader(t, res.GetImmediateResponse().GetHeaders().SetHeaders, "Content-Type", "application/json")
620632 require.NoError(t, err)
621633
622634 err = stream.CloseSend()
0 commit comments