Documentation
¶
Overview ¶
Taken from $GOROOT/src/pkg/net/http/chunked needed to write https responses to client.
Package goproxy provides a customizable HTTP proxy, supporting hijacking HTTPS connection.
The intent of the proxy, is to be usable with reasonable amount of traffic yet, customizable and programable.
The proxy itself is simply an `net/http` handler.
Typical usage is
proxy := goproxy.NewProxyHttpServer() proxy.OnRequest(..conditions..).Do(..requesthandler..) proxy.OnRequest(..conditions..).DoFunc(..requesthandlerFunction..) proxy.OnResponse(..conditions..).Do(..responesHandler..) proxy.OnResponse(..conditions..).DoFunc(..responesHandlerFunction..) http.ListenAndServe(":8080", proxy)
Adding a header to each request
proxy.OnRequest().DoFunc(func(r *http.Request,ctx *goproxy.ProxyCtx) (*http.Request, *http.Response){ r.Header.Set("X-GoProxy","1") return r, nil })
Note that the function is called before the proxy sends the request to the server ¶
For printing the content type of all incoming responses
proxy.OnResponse().DoFunc(func(r *http.Response, ctx *goproxy.ProxyCtx)*http.Response{ println(ctx.Req.Host,"->",r.Header.Get("Content-Type")) return r })
note that we used the ProxyCtx context variable here. It contains the request and the response (Req and Resp, Resp is nil if unavailable) of this specific client interaction with the proxy.
To print the content type of all responses from a certain url, we'll add a ReqCondition to the OnResponse function:
proxy.OnResponse(goproxy.UrlIs("golang.org/pkg")).DoFunc(func(r *http.Response, ctx *goproxy.ProxyCtx)*http.Response{ println(ctx.Req.Host,"->",r.Header.Get("Content-Type")) return r })
We can write the condition ourselves, conditions can be set on request and on response
var random = ReqConditionFunc(func(r *http.Request) bool { return rand.Intn(1) == 0 }) var hasGoProxyHeader = RespConditionFunc(func(resp *http.Response,req *http.Request)bool { return resp.Header.Get("X-GoProxy") != "" })
Caution! If you give a RespCondition to the OnRequest function, you'll get a run time panic! It doesn't make sense to read the response, if you still haven't got it!
Finally, we have convenience function to throw a quick response
proxy.OnResponse(hasGoProxyHeader).DoFunc(func(r*http.Response,ctx *goproxy.ProxyCtx)*http.Response { r.Body.Close() return goproxy.ForbiddenTextResponse(ctx.Req,"Can't see response with X-GoProxy header!") })
we close the body of the original repsonse, and return a new 403 response with a short message.
Example use cases:
1. https://github.com/elazarl/goproxy/tree/master/examples/goproxy-avgsize
To measure the average size of an Html served in your site. One can ask all the QA team to access the website by a proxy, and the proxy will measure the average size of all text/html responses from your host.
2. [not yet implemented]
All requests to your web servers should be directed through the proxy, when the proxy will detect html pieces sent as a response to AJAX request, it'll send a warning email.
3. https://github.com/elazarl/goproxy/blob/master/examples/goproxy-httpdump/
Generate a real traffic to your website by real users using through proxy. Record the traffic, and try it again for more real load testing.
4. https://github.com/elazarl/goproxy/tree/master/examples/goproxy-no-reddit-at-worktime
Will allow browsing to reddit.com between 8:00am and 17:00pm
5. https://github.com/elazarl/goproxy/tree/master/examples/goproxy-jquery-version
Will warn if multiple versions of jquery are used in the same domain.
6. https://github.com/elazarl/goproxy/blob/master/examples/goproxy-upside-down-ternet/
Modifies image files in an HTTP response via goproxy's image extension found in ext/.
Index ¶
- Constants
- Variables
- func NewResponse(r *http.Request, contentType string, status int, body string) *http.Response
- func TLSConfigFromCA(ca *tls.Certificate) func(host string, ctx *ProxyCtx) (*tls.Config, error)
- func TextResponse(r *http.Request, text string) *http.Response
- type ConnectAction
- type ConnectActionLiteral
- type CounterEncryptorRand
- type FuncHttpsHandler
- type FuncReqHandler
- type FuncRespHandler
- type HttpsHandler
- type ProxyConds
- type ProxyCtx
- type ProxyHttpServer
- func (proxy *ProxyHttpServer) NewConnectDialToProxy(https_proxy string) func(network, addr string) (net.Conn, error)
- func (proxy *ProxyHttpServer) OnRequest(conds ...ReqCondition) *ReqProxyConds
- func (proxy *ProxyHttpServer) OnResponse(conds ...RespCondition) *ProxyConds
- func (proxy *ProxyHttpServer) ServeHTTP(w http.ResponseWriter, r *http.Request)
- type ReqCondition
- type ReqConditionFunc
- func DstHostIs(host string) ReqConditionFunc
- func Not(r ReqCondition) ReqConditionFunc
- func ReqHostIs(hosts ...string) ReqConditionFunc
- func ReqHostMatches(regexps ...*regexp.Regexp) ReqConditionFunc
- func UrlHasPrefix(prefix string) ReqConditionFunc
- func UrlIs(urls ...string) ReqConditionFunc
- func UrlMatches(re *regexp.Regexp) ReqConditionFunc
- type ReqHandler
- type ReqProxyConds
- func (pcond *ReqProxyConds) Do(h ReqHandler)
- func (pcond *ReqProxyConds) DoFunc(f func(req *http.Request, ctx *ProxyCtx) (*http.Request, *http.Response))
- func (pcond *ReqProxyConds) HandleConnect(h HttpsHandler)
- func (pcond *ReqProxyConds) HandleConnectFunc(f func(host string, ctx *ProxyCtx) (*ConnectAction, string))
- func (pcond *ReqProxyConds) HijackConnect(f func(req *http.Request, client net.Conn, ctx *ProxyCtx))
- type RespCondition
- type RespConditionFunc
- type RespHandler
- type RoundTripper
- type RoundTripperFunc
Constants ¶
const ( ConnectAccept = iota ConnectReject ConnectMitm ConnectHijack ConnectHTTPMitm ConnectProxyAuthHijack )
const ( ContentTypeText = "text/plain" ContentTypeHtml = "text/html" )
Variables ¶
var ( OkConnect = &ConnectAction{Action: ConnectAccept, TLSConfig: TLSConfigFromCA(&GoproxyCa)} MitmConnect = &ConnectAction{Action: ConnectMitm, TLSConfig: TLSConfigFromCA(&GoproxyCa)} HTTPMitmConnect = &ConnectAction{Action: ConnectHTTPMitm, TLSConfig: TLSConfigFromCA(&GoproxyCa)} RejectConnect = &ConnectAction{Action: ConnectReject, TLSConfig: TLSConfigFromCA(&GoproxyCa)} )
var CA_CERT = []byte(`-----BEGIN CERTIFICATE-----
MIIF8jCCA9qgAwIBAgIUAp68XvvuMwaTCeQQjGxHEZhJcPgwDQYJKoZIhvcNAQEN
BQAwgZAxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNU2FuIEZy
YW5jaXNjbzEUMBIGA1UEChMLQ29yZU9TLCBJbmMxIjAgBgNVBAsTGWdpdGh1Yi5j
b20vY29yZW9zL2dvcHJveHkxIjAgBgNVBAMTGWdpdGh1Yi5jb20vY29yZW9zL2dv
cHJveHkwHhcNMTcwMjIyMjI0NjAwWhcNMjIwMjIxMjI0NjAwWjCBkDELMAkGA1UE
BhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRQwEgYD
VQQKEwtDb3JlT1MsIEluYzEiMCAGA1UECxMZZ2l0aHViLmNvbS9jb3Jlb3MvZ29w
cm94eTEiMCAGA1UEAxMZZ2l0aHViLmNvbS9jb3Jlb3MvZ29wcm94eTCCAiIwDQYJ
KoZIhvcNAQEBBQADggIPADCCAgoCggIBANghh+Y4gUYyIY1YzAgHBuLjTt13z5ED
tbjksaK8kUMofaYCnQRrepTORB3xpxn9cIXpmmPND/c3pUZz+sSbidZF+Rfkz+G4
oo5I04X7R2iFrw9jECcavr7qGqOt+vhep9iqVaioSWTKZoXY9FOxTpEUfdKyLE8K
7rd6PfdjkbZ2ZqoKdRHARBE6QlTJv+elIRM6kzshx0oSdZfaUvLdmXFqHdfKz8gb
FABaa8Aca6r76wHRnhK3+RQ2p+Wfz45/ZMxqQVIMr2mbiCCL4lSUPkUrid6L5DoA
4A4pLqY+Y0cX2qIF+lmgUwUPvunqM7dA9toHjwBgeB1yF+jVOhFOizB/dXSCsBA2
D47raP3REIxE6N05pEpGZqUPatcdyakP1Dan9aVO2W3o7P/LGPBdB5AiwVxRiVPx
dNrz+UcE3dCPBrc9bxJLjyD7PtgPTrZ+hzR/kBfBW/+jvBRKIB5NCNSuQEUN99it
P1fIencEz1ghaWhCAU5tQutnVBu8d0YlgjfnaD4vCJYEprifAiIpgZH3HaiHfG14
UXFbdU0MmuIrie2PMAGmtnjhWHG0vc8f2THRklq/CtbfNWtPzUfYv+rpaOFw7bj+
km0n3kVuGzWZhXPixe63TATR5lK9p21CZPXS+2mW/8uswBiJ4aT5lUZmCf/i1xyn
Gzgv9so56vjFAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD
AQH/MB0GA1UdDgQWBBSYLcfHmyPv3jmdTyBs/lu5PZLxPTANBgkqhkiG9w0BAQ0F
AAOCAgEAppb+3MhGcL/IjqyRIWCc587eVMMtuHwGlczpMfXnf8TU0MPrvOdTPrqg
a+AEc1W8O6IGrowmgbZVgfr7Pw0BL4VcSdAEbP7QcbPmRAudF+/xdm5vylJmB339
4Yq5v1G2Ya5AN5PAHx3WVOA7s/caz30DGrsAoNhezlrk8WJRRxrQUauNveXyxNya
urBrqjqNVUWAlv2fRHuNXsxMvG32MWQ1BoPa9Ix+dUWYeeWkxS5E9oNo99TRRTHB
WX4SpsIynmhE+pFEzu2HVP2k5GE5+i78F9/N0cgI5QMSzgYxSebyPEflL1ziqWoq
4xio69OM0Cq+GCxvOZmvKaNlOjwJa6NWa8IyumNFclTLNzMlBaDkVE9Tb5VEBphO
ODzSxFMuAfXba4UlRjG9+BLg8ayzu2t9amB+B5/3/1+gkx1TE26jZNwleU6MnpFv
umPqPa9AW2ZPobCTGjV3MwOIKFyO/cPt4fI6BpKF7jYhUYzsht/BZqQZU/rWY6h8
GSEH8LcJk+Paaw03HzZWSbMp2oXNTz/BpQjuAdWAkeS3yhx5gvHIysWHvPRT017b
Tx+Va9+T4DElT0HtmR/w27bXNL9Urj38ETSlbYoilL7ZKltj8djXmqkI1ZF8T1zk
tj1zk0XYkestBgfrk9XYwvvL7DLyRPPZTAiVq/o5xn5zWp/y40M=
-----END CERTIFICATE-----`)
var CA_KEY = []byte(`-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----`)
var GoproxyCa, _ = tls.X509KeyPair(CA_CERT, CA_KEY)
Functions ¶
func NewResponse ¶
Will generate a valid http response to the given request the response will have the given contentType, and http status. Typical usage, refuse to process requests to local addresses:
proxy.OnRequest(IsLocalHost()).DoFunc(func(r *http.Request, ctx *goproxy.ProxyCtx) (*http.Request,*http.Response) { return nil,NewResponse(r,goproxy.ContentTypeHtml,http.StatusUnauthorized, `<!doctype html><html><head><title>Can't use proxy for local addresses</title></head><body/></html>`) })
func TLSConfigFromCA ¶
Types ¶
type ConnectAction ¶
type ConnectActionLiteral ¶
type ConnectActionLiteral int
type CounterEncryptorRand ¶
type CounterEncryptorRand struct {
// contains filtered or unexported fields
}
func NewCounterEncryptorRandFromKey ¶
func NewCounterEncryptorRandFromKey(key interface{}, seed []byte) (r CounterEncryptorRand, err error)
func (*CounterEncryptorRand) Read ¶
func (c *CounterEncryptorRand) Read(b []byte) (n int, err error)
func (*CounterEncryptorRand) Seed ¶
func (c *CounterEncryptorRand) Seed(b []byte)
type FuncHttpsHandler ¶
type FuncHttpsHandler func(host string, ctx *ProxyCtx) (*ConnectAction, string)
A wrapper that would convert a function to a HttpsHandler interface type
var AlwaysMitm FuncHttpsHandler = func(host string, ctx *ProxyCtx) (*ConnectAction, string) { return MitmConnect, host }
AlwaysMitm is a HttpsHandler that always eavesdrop https connections, for example to eavesdrop all https connections to www.google.com, we can use
proxy.OnRequest(goproxy.ReqHostIs("www.google.com")).HandleConnect(goproxy.AlwaysMitm)
var AlwaysReject FuncHttpsHandler = func(host string, ctx *ProxyCtx) (*ConnectAction, string) { return RejectConnect, host }
AlwaysReject is a HttpsHandler that drops any CONNECT request, for example, this code will disallow connections to hosts on any other port than 443
proxy.OnRequest(goproxy.Not(goproxy.ReqHostMatches(regexp.MustCompile(":443$"))). HandleConnect(goproxy.AlwaysReject)
func (FuncHttpsHandler) HandleConnect ¶
func (f FuncHttpsHandler) HandleConnect(host string, ctx *ProxyCtx) (*ConnectAction, string)
FuncHttpsHandler should implement the RespHandler interface
type FuncReqHandler ¶
A wrapper that would convert a function to a ReqHandler interface type
type FuncRespHandler ¶
A wrapper that would convert a function to a RespHandler interface type
type HttpsHandler ¶
type HttpsHandler interface {
HandleConnect(req string, ctx *ProxyCtx) (*ConnectAction, string)
}
When a client send a CONNECT request to a host, the request is filtered through all the HttpsHandlers the proxy has, and if one returns true, the connection is sniffed using Man in the Middle attack. That is, the proxy will create a TLS connection with the client, another TLS connection with the destination the client wished to connect to, and would send back and forth all messages from the server to the client and vice versa. The request and responses sent in this Man In the Middle channel are filtered through the usual flow (request and response filtered through the ReqHandlers and RespHandlers)
type ProxyConds ¶
type ProxyConds struct {
// contains filtered or unexported fields
}
ProxyConds is used to aggregate RespConditions for a ProxyHttpServer. Upon calling ProxyConds.Do, it will register a RespHandler that would handle the HTTP response from remote server if all conditions on the HTTP response are met.
func (*ProxyConds) Do ¶
func (pcond *ProxyConds) Do(h RespHandler)
ProxyConds.Do will register the RespHandler on the proxy, h.Handle(resp,ctx) will be called on every request that matches the conditions aggregated in pcond.
type ProxyCtx ¶
type ProxyCtx struct { // Will contain the client request from the proxy Req *http.Request // Will contain the remote server's response (if available. nil if the request wasn't send yet) Resp *http.Response RoundTripper RoundTripper // will contain the recent error that occured while trying to send receive or parse traffic Error error // A handle for the user to keep data in the context, from the call of ReqHandler to the // call of RespHandler UserData interface{} // Will connect a request to a response Session int64 // contains filtered or unexported fields }
ProxyCtx is the Proxy context, contains useful information about every request. It is passed to every user function. Also used as a logger.
func (*ProxyCtx) Charset ¶
Will try to infer the character set of the request from the headers. Returns the empty string if we don't know which character set it used. Currently it will look for charset=<charset> in the Content-Type header of the request.
func (*ProxyCtx) Logf ¶
Logf prints a message to the proxy's log. Should be used in a ProxyHttpServer's filter This message will be printed only if the Verbose field of the ProxyHttpServer is set to true
proxy.OnRequest().DoFunc(func(r *http.Request,ctx *goproxy.ProxyCtx) (*http.Request, *http.Response){ nr := atomic.AddInt32(&counter,1) ctx.Printf("So far %d requests",nr) return r, nil })
func (*ProxyCtx) Warnf ¶
Warnf prints a message to the proxy's log. Should be used in a ProxyHttpServer's filter This message will always be printed.
proxy.OnRequest().DoFunc(func(r *http.Request,ctx *goproxy.ProxyCtx) (*http.Request, *http.Response){ f,err := os.OpenFile(cachedContent) if err != nil { ctx.Warnf("error open file %v: %v",cachedContent,err) return r, nil } return r, nil })
type ProxyHttpServer ¶
type ProxyHttpServer struct { // setting Verbose to true will log information on each request sent to the proxy Verbose bool Logger *log.Logger NonproxyHandler http.Handler Tr *http.Transport // ConnectDial will be used to create TCP connections for CONNECT requests // if nil Tr.Dial will be used ConnectDial func(network string, addr string) (net.Conn, error) // contains filtered or unexported fields }
The basic proxy type. Implements http.Handler.
func NewProxyHttpServer ¶
func NewProxyHttpServer() *ProxyHttpServer
New proxy server, logs to StdErr by default
func NewReverseProxyHttpServer ¶
func NewReverseProxyHttpServer() *ProxyHttpServer
func (*ProxyHttpServer) NewConnectDialToProxy ¶
func (*ProxyHttpServer) OnRequest ¶
func (proxy *ProxyHttpServer) OnRequest(conds ...ReqCondition) *ReqProxyConds
ProxyHttpServer.OnRequest Will return a temporary ReqProxyConds struct, aggregating the given condtions. You will use the ReqProxyConds struct to register a ReqHandler, that would filter the request, only if all the given ReqCondition matched. Typical usage:
proxy.OnRequest(UrlIs("example.com/foo"),UrlMatches(regexp.MustParse(`.*\.exampl.\com\./.*`)).Do(...)
func (*ProxyHttpServer) OnResponse ¶
func (proxy *ProxyHttpServer) OnResponse(conds ...RespCondition) *ProxyConds
OnResponse is used when adding a response-filter to the HTTP proxy, usual pattern is
proxy.OnResponse(cond1,cond2).Do(handler) // handler.Handle(resp,ctx) will be used // if cond1.HandleResp(resp) && cond2.HandleResp(resp)
func (*ProxyHttpServer) ServeHTTP ¶
func (proxy *ProxyHttpServer) ServeHTTP(w http.ResponseWriter, r *http.Request)
Standard net/http function. Shouldn't be used directly, http.Serve will use it.
type ReqCondition ¶
type ReqCondition interface { RespCondition HandleReq(req *http.Request, ctx *ProxyCtx) bool }
ReqCondition.HandleReq will decide whether or not to use the ReqHandler on an HTTP request before sending it to the remote server
func SrcIpIs ¶
func SrcIpIs(ips ...string) ReqCondition
SrcIpIs returns a ReqCondition testing whether the source IP of the request is one of the given strings
type ReqConditionFunc ¶
ReqConditionFunc.HandleReq(req,ctx) <=> ReqConditionFunc(req,ctx)
var IsLocalHost ReqConditionFunc = func(req *http.Request, ctx *ProxyCtx) bool {
return req.URL.Host == "::1" ||
req.URL.Host == "0:0:0:0:0:0:0:1" ||
localHostIpv4.MatchString(req.URL.Host) ||
req.URL.Host == "localhost"
}
IsLocalHost checks whether the destination host is explicitly local host (buggy, there can be IPv6 addresses it doesn't catch)
func DstHostIs ¶
func DstHostIs(host string) ReqConditionFunc
DstHostIs returns a ReqCondition testing wether the host in the request url is the given string
func Not ¶
func Not(r ReqCondition) ReqConditionFunc
Not returns a ReqCondition negating the given ReqCondition
func ReqHostIs ¶
func ReqHostIs(hosts ...string) ReqConditionFunc
ReqHostIs returns a ReqCondition, testing whether the host to which the request is directed to equal to one of the given strings
func ReqHostMatches ¶
func ReqHostMatches(regexps ...*regexp.Regexp) ReqConditionFunc
ReqHostMatches returns a ReqCondition, testing whether the host to which the request was directed to matches any of the given regular expressions.
func UrlHasPrefix ¶
func UrlHasPrefix(prefix string) ReqConditionFunc
UrlHasPrefix returns a ReqCondition checking wether the destination URL the proxy client has requested has the given prefix, with or without the host. For example UrlHasPrefix("host/x") will match requests of the form 'GET host/x', and will match requests to url 'http://host/x'
func UrlIs ¶
func UrlIs(urls ...string) ReqConditionFunc
UrlIs returns a ReqCondition, testing whether or not the request URL is one of the given strings with or without the host prefix. UrlIs("google.com/","foo") will match requests 'GET /' to 'google.com', requests `'GET google.com/' to any host, and requests of the form 'GET foo'.
func UrlMatches ¶
func UrlMatches(re *regexp.Regexp) ReqConditionFunc
UrlMatches returns a ReqCondition testing whether the destination URL of the request matches the given regexp, with or without prefix
func (ReqConditionFunc) HandleReq ¶
func (c ReqConditionFunc) HandleReq(req *http.Request, ctx *ProxyCtx) bool
func (ReqConditionFunc) HandleResp ¶
func (c ReqConditionFunc) HandleResp(resp *http.Response, ctx *ProxyCtx) bool
ReqConditionFunc cannot test responses. It only satisfies RespCondition interface so that to be usable as RespCondition.
type ReqHandler ¶
type ReqHandler interface {
Handle(req *http.Request, ctx *ProxyCtx) (*http.Request, *http.Response)
}
ReqHandler will "tamper" with the request coming to the proxy server If Handle returns req,nil the proxy will send the returned request to the destination server. If it returns nil,resp the proxy will skip sending any requests, and will simply return the response `resp` to the client.
type ReqProxyConds ¶
type ReqProxyConds struct {
// contains filtered or unexported fields
}
ReqProxyConds aggregate ReqConditions for a ProxyHttpServer. Upon calling Do, it will register a ReqHandler that would handle the request if all conditions on the HTTP request are met.
func (*ReqProxyConds) Do ¶
func (pcond *ReqProxyConds) Do(h ReqHandler)
ReqProxyConds.Do will register the ReqHandler on the proxy, the ReqHandler will handle the HTTP request if all the conditions aggregated in the ReqProxyConds are met. Typical usage:
proxy.OnRequest().Do(handler) // will call handler.Handle(req,ctx) on every request to the proxy proxy.OnRequest(cond1,cond2).Do(handler) // given request to the proxy, will test if cond1.HandleReq(req,ctx) && cond2.HandleReq(req,ctx) are true // if they are, will call handler.Handle(req,ctx)
func (*ReqProxyConds) DoFunc ¶
func (pcond *ReqProxyConds) DoFunc(f func(req *http.Request, ctx *ProxyCtx) (*http.Request, *http.Response))
DoFunc is equivalent to proxy.OnRequest().Do(FuncReqHandler(f))
func (*ReqProxyConds) HandleConnect ¶
func (pcond *ReqProxyConds) HandleConnect(h HttpsHandler)
HandleConnect is used when proxy receives an HTTP CONNECT request, it'll then use the HttpsHandler to determine what should it do with this request. The handler returns a ConnectAction struct, the Action field in the ConnectAction struct returned will determine what to do with this request. ConnectAccept will simply accept the request forwarding all bytes from the client to the remote host, ConnectReject will close the connection with the client, and ConnectMitm, will assume the underlying connection is an HTTPS connection, and will use Man in the Middle attack to eavesdrop the connection. All regular handler will be active on this eavesdropped connection. The ConnectAction struct contains possible tlsConfig that will be used for eavesdropping. If nil, the proxy will use the default tls configuration.
proxy.OnRequest().HandleConnect(goproxy.AlwaysReject) // rejects all CONNECT requests
func (*ReqProxyConds) HandleConnectFunc ¶
func (pcond *ReqProxyConds) HandleConnectFunc(f func(host string, ctx *ProxyCtx) (*ConnectAction, string))
HandleConnectFunc is equivalent to HandleConnect, for example, accepting CONNECT request if they contain a password in header
io.WriteString(h,password) passHash := h.Sum(nil) proxy.OnRequest().HandleConnectFunc(func(host string, ctx *ProxyCtx) (*ConnectAction, string) { c := sha1.New() io.WriteString(c,ctx.Req.Header.Get("X-GoProxy-Auth")) if c.Sum(nil) == passHash { return OkConnect, host } return RejectConnect, host })
func (*ReqProxyConds) HijackConnect ¶
type RespCondition ¶
RespCondition.HandleReq will decide whether or not to use the RespHandler on an HTTP response before sending it to the proxy client. Note that resp might be nil, in case there was an error sending the request.
func ContentTypeIs ¶
func ContentTypeIs(typ string, types ...string) RespCondition
ContentTypeIs returns a RespCondition testing whether the HTTP response has Content-Type header equal to one of the given strings.
type RespConditionFunc ¶
RespConditionFunc.HandleResp(resp,ctx) <=> RespConditionFunc(resp,ctx)
func (RespConditionFunc) HandleResp ¶
func (c RespConditionFunc) HandleResp(resp *http.Response, ctx *ProxyCtx) bool
type RespHandler ¶
after the proxy have sent the request to the destination server, it will "filter" the response through the RespHandlers it has. The proxy server will send to the client the response returned by the RespHandler. In case of error, resp will be nil, and ctx.RoundTrip.Error will contain the error
func HandleBytes ¶
func HandleBytes(f func(b []byte, ctx *ProxyCtx) []byte) RespHandler
HandleBytes will return a RespHandler that read the entire body of the request to a byte array in memory, would run the user supplied f function on the byte arra, and will replace the body of the original response with the resulting byte array.
type RoundTripper ¶
Source Files
¶
Directories
¶
Path | Synopsis |
---|---|
examples
|
|
goproxy-yui-minify
This example would minify standalone Javascript files (identified by their content type) using the command line utility YUI compressor http://yui.github.io/yuicompressor/ Example usage: ./yui -java /usr/local/bin/java -yuicompressor ~/Downloads/yuicompressor-2.4.8.jar $ curl -vx localhost:8080 http://golang.org/lib/godoc/godocs.js (function(){function g(){var u=$("#search");if(u.length===0){return}function t(){if(....
|
This example would minify standalone Javascript files (identified by their content type) using the command line utility YUI compressor http://yui.github.io/yuicompressor/ Example usage: ./yui -java /usr/local/bin/java -yuicompressor ~/Downloads/yuicompressor-2.4.8.jar $ curl -vx localhost:8080 http://golang.org/lib/godoc/godocs.js (function(){function g(){var u=$("#search");if(u.length===0){return}function t(){if(.... |
ext
|
|
html
extension to goproxy that will allow you to easily filter web browser related content.
|
extension to goproxy that will allow you to easily filter web browser related content. |