github.com/coreos/goproxy@v0.0.0-20190513173959-f8dc2d7ba04e/examples/goproxy-jquery-version/main.go (about) 1 package main 2 3 import ( 4 "github.com/elazarl/goproxy" 5 "github.com/elazarl/goproxy/ext/html" 6 "log" 7 "net/http" 8 "regexp" 9 ) 10 11 var ( 12 // who said we can't parse HTML with regexp? 13 scriptMatcher = regexp.MustCompile(`(?i:<script\s+)`) 14 srcAttrMatcher = regexp.MustCompile(`^(?i:[^>]*\ssrc=["']([^"']*)["'])`) 15 ) 16 17 // findScripts returns all sources of HTML script tags found in input text. 18 func findScriptSrc(html string) []string { 19 srcs := make([]string, 0) 20 matches := scriptMatcher.FindAllStringIndex(html, -1) 21 for _, match := range matches { 22 // -1 to capture the whitespace at the end of the script tag 23 srcMatch := srcAttrMatcher.FindStringSubmatch(html[match[1]-1:]) 24 if srcMatch != nil { 25 srcs = append(srcs, srcMatch[1]) 26 } 27 } 28 return srcs 29 } 30 31 // NewJQueryVersionProxy creates a proxy checking responses HTML content, looks 32 // for scripts referencing jQuery library and emits warnings if different 33 // versions of the library are being used for a given host. 34 func NewJqueryVersionProxy() *goproxy.ProxyHttpServer { 35 proxy := goproxy.NewProxyHttpServer() 36 m := make(map[string]string) 37 jqueryMatcher := regexp.MustCompile(`(?i:jquery\.)`) 38 proxy.OnResponse(goproxy_html.IsHtml).Do(goproxy_html.HandleString( 39 func(s string, ctx *goproxy.ProxyCtx) string { 40 for _, src := range findScriptSrc(s) { 41 if !jqueryMatcher.MatchString(src) { 42 continue 43 } 44 prev, ok := m[ctx.Req.Host] 45 if ok { 46 if prev != src { 47 ctx.Warnf("In %v, Contradicting jqueries %v %v", 48 ctx.Req.URL, prev, src) 49 break 50 } 51 } else { 52 ctx.Warnf("%s uses jquery %s", ctx.Req.Host, src) 53 m[ctx.Req.Host] = src 54 } 55 } 56 return s 57 })) 58 return proxy 59 } 60 61 func main() { 62 proxy := NewJqueryVersionProxy() 63 log.Fatal(http.ListenAndServe(":8080", proxy)) 64 }