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  }