@@ -17,6 +17,7 @@ package gorules
17
17
18
18
import (
19
19
"github.com/quasilyte/go-ruleguard/dsl"
20
+ "github.com/quasilyte/go-ruleguard/dsl/types"
20
21
)
21
22
22
23
// Use xerrors everywhere! It provides additional stacktrace info!
@@ -238,3 +239,30 @@ func ProperRBACReturn(m dsl.Matcher) {
238
239
}
239
240
` ).Report ("Must write to 'ResponseWriter' before returning'" )
240
241
}
242
+
243
+ // FullResponseWriter ensures that any overridden response writer has full
244
+ // functionality. Mainly is hijackable and flushable.
245
+ func FullResponseWriter (m dsl.Matcher ) {
246
+ m .Match (`
247
+ type $w struct {
248
+ $*_
249
+ http.ResponseWriter
250
+ $*_
251
+ }
252
+ ` ).
253
+ At (m ["w" ]).
254
+ Where (m ["w" ].Filter (notImplementsFullResponseWriter )).
255
+ Report ("ResponseWriter \" $w\" must implement http.Flusher and http.Hijacker" )
256
+ }
257
+
258
+ // notImplementsFullResponseWriter returns false if the type does not implement
259
+ // http.Flusher, http.Hijacker, and http.ResponseWriter.
260
+ func notImplementsFullResponseWriter (ctx * dsl.VarFilterContext ) bool {
261
+ flusher := ctx .GetInterface (`net/http.Flusher` )
262
+ hijacker := ctx .GetInterface (`net/http.Hijacker` )
263
+ writer := ctx .GetInterface (`net/http.ResponseWriter` )
264
+ p := types .NewPointer (ctx .Type )
265
+ return ! (types .Implements (p , writer ) || types .Implements (ctx .Type , writer )) ||
266
+ ! (types .Implements (p , flusher ) || types .Implements (ctx .Type , flusher )) ||
267
+ ! (types .Implements (p , hijacker ) || types .Implements (ctx .Type , hijacker ))
268
+ }
0 commit comments