github.com/coreos/goproxy@v0.0.0-20190513173959-f8dc2d7ba04e/examples/goproxy-stats/main.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/elazarl/goproxy"
     6  	"github.com/elazarl/goproxy/ext/html"
     7  	"io"
     8  	"log"
     9  	. "net/http"
    10  	"time"
    11  )
    12  
    13  type Count struct {
    14  	Id    string
    15  	Count int64
    16  }
    17  type CountReadCloser struct {
    18  	Id string
    19  	R  io.ReadCloser
    20  	ch chan<- Count
    21  	nr int64
    22  }
    23  
    24  func (c *CountReadCloser) Read(b []byte) (n int, err error) {
    25  	n, err = c.R.Read(b)
    26  	c.nr += int64(n)
    27  	return
    28  }
    29  func (c CountReadCloser) Close() error {
    30  	c.ch <- Count{c.Id, c.nr}
    31  	return c.R.Close()
    32  }
    33  
    34  func main() {
    35  	proxy := goproxy.NewProxyHttpServer()
    36  	timer := make(chan bool)
    37  	ch := make(chan Count, 10)
    38  	go func() {
    39  		for {
    40  			time.Sleep(20 * time.Second)
    41  			timer <- true
    42  		}
    43  	}()
    44  	go func() {
    45  		m := make(map[string]int64)
    46  		for {
    47  			select {
    48  			case c := <-ch:
    49  				m[c.Id] = m[c.Id] + c.Count
    50  			case <-timer:
    51  				fmt.Printf("statistics\n")
    52  				for k, v := range m {
    53  					fmt.Printf("%s -> %d\n", k, v)
    54  				}
    55  			}
    56  		}
    57  	}()
    58  
    59  	// IsWebRelatedText filters on html/javascript/css resources
    60  	proxy.OnResponse(goproxy_html.IsWebRelatedText).DoFunc(func(resp *Response, ctx *goproxy.ProxyCtx) *Response {
    61  		resp.Body = &CountReadCloser{ctx.Req.URL.String(), resp.Body, ch, 0}
    62  		return resp
    63  	})
    64  	fmt.Printf("listening on :8080\n")
    65  	log.Fatal(ListenAndServe(":8080", proxy))
    66  }