Documentation ¶
Overview ¶
Package forward creates a pre-configured httputil.ReverseProxy.
Index ¶
Examples ¶
Constants ¶
const ( XForwardedProto = "X-Forwarded-Proto" XForwardedFor = "X-Forwarded-For" XForwardedHost = "X-Forwarded-Host" XForwardedPort = "X-Forwarded-Port" XForwardedServer = "X-Forwarded-Server" XRealIP = "X-Real-Ip" )
X-* Header names.
const ( Connection = "Connection" KeepAlive = "Keep-Alive" ProxyAuthenticate = "Proxy-Authenticate" ProxyAuthorization = "Proxy-Authorization" Te = "Te" // canonicalized version of "TE" Trailers = "Trailers" TransferEncoding = "Transfer-Encoding" Upgrade = "Upgrade" ContentLength = "Content-Length" )
Headers names.
const ( SecWebsocketKey = "Sec-Websocket-Key" SecWebsocketVersion = "Sec-Websocket-Version" SecWebsocketExtensions = "Sec-Websocket-Extensions" SecWebsocketAccept = "Sec-Websocket-Accept" )
WebSocket Header names.
const ( StateConnected = iota StateDisconnected )
Connection states.
Variables ¶
var HopHeaders = []string{ Connection, KeepAlive, ProxyAuthenticate, ProxyAuthorization, Te, Trailers, TransferEncoding, Upgrade, }
HopHeaders Hop-by-hop headers. These are removed when sent to the backend. http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html Copied from reverseproxy.go, too bad.
var WebsocketDialHeaders = []string{ Upgrade, Connection, SecWebsocketKey, SecWebsocketVersion, SecWebsocketExtensions, SecWebsocketAccept, }
WebsocketDialHeaders Websocket dial headers.
var WebsocketUpgradeHeaders = []string{ Upgrade, Connection, SecWebsocketAccept, SecWebsocketExtensions, }
WebsocketUpgradeHeaders Websocket upgrade headers.
var XHeaders = []string{ XForwardedProto, XForwardedFor, XForwardedHost, XForwardedPort, XForwardedServer, XRealIP, }
XHeaders X-* headers.
Functions ¶
func New ¶
func New(passHostHeader bool) *httputil.ReverseProxy
New creates a new ReverseProxy.
Example (CustomErrHandler) ¶
f := New(true) f.ErrorHandler = func(w http.ResponseWriter, _ *http.Request, _ error) { w.WriteHeader(http.StatusTeapot) _, _ = w.Write([]byte(http.StatusText(http.StatusTeapot))) } proxy := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { req.URL, _ = url.ParseRequestURI("http://localhost:63450") f.ServeHTTP(w, req) })) defer proxy.Close() resp, err := http.Get(proxy.URL) if err != nil { fmt.Println(err) return } body, err := io.ReadAll(resp.Body) if err != nil { fmt.Println(err) return } fmt.Println(resp.StatusCode) fmt.Println(string(body))
Output: 418 I'm a teapot
Example (CustomTransport) ¶
srv := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { _, _ = w.Write([]byte("hello")) })) defer srv.Close() f := New(true) f.Transport = &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } proxy := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { req.URL, _ = url.ParseRequestURI(srv.URL) f.ServeHTTP(w, req) })) defer proxy.Close() resp, err := http.Get(proxy.URL) if err != nil { fmt.Println(err) return } body, err := io.ReadAll(resp.Body) if err != nil { fmt.Println(err) return } fmt.Println(resp.StatusCode) fmt.Println(string(body))
Output: 200 hello
Example (ResponseModifier) ¶
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { _, _ = w.Write([]byte("hello")) })) defer srv.Close() f := New(true) f.ModifyResponse = func(resp *http.Response) error { resp.Header.Add("X-Test", "CUSTOM") return nil } proxy := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { req.URL, _ = url.ParseRequestURI(srv.URL) f.ServeHTTP(w, req) })) defer proxy.Close() resp, err := http.Get(proxy.URL) if err != nil { fmt.Println(err) return } fmt.Println(resp.StatusCode) fmt.Println(resp.Header.Get("X-Test"))
Output: 200 CUSTOM
Types ¶
type HeaderRewriter ¶
HeaderRewriter is responsible for removing hop-by-hop headers and setting forwarding headers.
func NewHeaderRewriter ¶
func NewHeaderRewriter() *HeaderRewriter
NewHeaderRewriter creates a new HeaderRewriter middleware.
func (*HeaderRewriter) Rewrite ¶
func (rw *HeaderRewriter) Rewrite(req *http.Request)
Rewrite request headers.
type StateListener ¶
type StateListener struct {
// contains filtered or unexported fields
}
StateListener listens on state change for urls.
func NewStateListener ¶
func NewStateListener(next http.Handler, stateListener URLForwardingStateListener) *StateListener
NewStateListener creates a new StateListener middleware.
Example ¶
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { _, _ = w.Write([]byte("hello")) })) defer srv.Close() f := New(true) f.ModifyResponse = func(resp *http.Response) error { resp.Header.Add("X-Test", "CUSTOM") return nil } stateLn := NewStateListener(f, func(u *url.URL, i int) { fmt.Println(u.Hostname(), i) }) proxy := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { req.URL, _ = url.ParseRequestURI(srv.URL) stateLn.ServeHTTP(w, req) })) defer proxy.Close() resp, err := http.Get(proxy.URL) if err != nil { fmt.Println(err) return } fmt.Println(resp.StatusCode)
Output: 127.0.0.1 0 127.0.0.1 1 200
func (*StateListener) ServeHTTP ¶
func (s *StateListener) ServeHTTP(rw http.ResponseWriter, req *http.Request)
type URLForwardingStateListener ¶
URLForwardingStateListener URL forwarding state listener.