github.com/coreos/goproxy@v0.0.0-20190513173959-f8dc2d7ba04e/ctx.go (about) 1 package goproxy 2 3 import ( 4 "net/http" 5 "regexp" 6 ) 7 8 // ProxyCtx is the Proxy context, contains useful information about every request. It is passed to 9 // every user function. Also used as a logger. 10 type ProxyCtx struct { 11 // Will contain the client request from the proxy 12 Req *http.Request 13 // Will contain the remote server's response (if available. nil if the request wasn't send yet) 14 Resp *http.Response 15 RoundTripper RoundTripper 16 // will contain the recent error that occured while trying to send receive or parse traffic 17 Error error 18 // A handle for the user to keep data in the context, from the call of ReqHandler to the 19 // call of RespHandler 20 UserData interface{} 21 // Will connect a request to a response 22 Session int64 23 proxy *ProxyHttpServer 24 } 25 26 type RoundTripper interface { 27 RoundTrip(req *http.Request, ctx *ProxyCtx) (*http.Response, error) 28 } 29 30 type RoundTripperFunc func(req *http.Request, ctx *ProxyCtx) (*http.Response, error) 31 32 func (f RoundTripperFunc) RoundTrip(req *http.Request, ctx *ProxyCtx) (*http.Response, error) { 33 return f(req, ctx) 34 } 35 36 func (ctx *ProxyCtx) RoundTrip(req *http.Request) (*http.Response, error) { 37 if ctx.RoundTripper != nil { 38 return ctx.RoundTripper.RoundTrip(req, ctx) 39 } 40 return ctx.proxy.Tr.RoundTrip(req) 41 } 42 43 func (ctx *ProxyCtx) printf(msg string, argv ...interface{}) { 44 ctx.proxy.Logger.Printf("[%03d] "+msg+"\n", append([]interface{}{ctx.Session & 0xFF}, argv...)...) 45 } 46 47 // Logf prints a message to the proxy's log. Should be used in a ProxyHttpServer's filter 48 // This message will be printed only if the Verbose field of the ProxyHttpServer is set to true 49 // 50 // proxy.OnRequest().DoFunc(func(r *http.Request,ctx *goproxy.ProxyCtx) (*http.Request, *http.Response){ 51 // nr := atomic.AddInt32(&counter,1) 52 // ctx.Printf("So far %d requests",nr) 53 // return r, nil 54 // }) 55 func (ctx *ProxyCtx) Logf(msg string, argv ...interface{}) { 56 if ctx.proxy.Verbose { 57 ctx.printf("INFO: "+msg, argv...) 58 } 59 } 60 61 // Warnf prints a message to the proxy's log. Should be used in a ProxyHttpServer's filter 62 // This message will always be printed. 63 // 64 // proxy.OnRequest().DoFunc(func(r *http.Request,ctx *goproxy.ProxyCtx) (*http.Request, *http.Response){ 65 // f,err := os.OpenFile(cachedContent) 66 // if err != nil { 67 // ctx.Warnf("error open file %v: %v",cachedContent,err) 68 // return r, nil 69 // } 70 // return r, nil 71 // }) 72 func (ctx *ProxyCtx) Warnf(msg string, argv ...interface{}) { 73 ctx.printf("WARN: "+msg, argv...) 74 } 75 76 var charsetFinder = regexp.MustCompile("charset=([^ ;]*)") 77 78 // Will try to infer the character set of the request from the headers. 79 // Returns the empty string if we don't know which character set it used. 80 // Currently it will look for charset=<charset> in the Content-Type header of the request. 81 func (ctx *ProxyCtx) Charset() string { 82 charsets := charsetFinder.FindStringSubmatch(ctx.Resp.Header.Get("Content-Type")) 83 if charsets == nil { 84 return "" 85 } 86 return charsets[1] 87 }