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  }