Skip to content

Instantly share code, notes, and snippets.

@picatz
Created April 29, 2020 19:53
Show Gist options
  • Save picatz/f69e6314a864c45c5dd01fd54b0cf8d3 to your computer and use it in GitHub Desktop.
Save picatz/f69e6314a864c45c5dd01fd54b0cf8d3 to your computer and use it in GitHub Desktop.
POC for an analyzer that finds http requests that unnecessarily set a content-type header
package request
import (
"fmt"
"go/ast"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/inspect"
"golang.org/x/tools/go/ast/inspector"
)
var Analyzer = &analysis.Analyzer{
Name: "http-req-content-type",
Doc: "Finds setting of unnecessary content-type request headers",
Run: run,
Requires: []*analysis.Analyzer{inspect.Analyzer},
}
func run(pass *analysis.Pass) (interface{}, error) {
inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
nodeFilter := []ast.Node{
(*ast.CallExpr)(nil),
}
inspect.Preorder(nodeFilter, func(n ast.Node) {
// cast the node as a call expression
ce := n.(*ast.CallExpr)
// check if the call expression is a selector expression
se, ok := ce.Fun.(*ast.SelectorExpr)
if ok {
// if is, verify we're selecting a header
if pass.TypesInfo.TypeOf(se.X).String() == "net/http.Header" {
// and that the selector name is "Set"
if se.Sel.Name == "Set" {
// then check if the first argument is a basic-literal string
firstArgBasicLit, ok := ce.Args[0].(*ast.BasicLit)
if ok {
// and that it's setting "Content-Length"
if fmt.Sprintf("%v", firstArgBasicLit.Value) == "\"Content-Length\"" {
// so that we can warn about it
pass.Reportf(ce.Pos(), "no need to set content-length for requests")
}
}
}
}
}
})
return nil, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment