MCPcopy Create free account
hub / github.com/SpectoLabs/hoverfly / NewProxy

Function NewProxy

core/proxy.go:30–122  ·  view source on GitHub ↗

Creates goproxy.ProxyHttpServer and configures it to be used as a proxy for Hoverfly goproxy is given handlers that use the Hoverfly request processing

(hoverfly *Hoverfly)

Source from the content-addressed store, hash-verified

28// Creates goproxy.ProxyHttpServer and configures it to be used as a proxy for Hoverfly
29// goproxy is given handlers that use the Hoverfly request processing
30func NewProxy(hoverfly *Hoverfly) *goproxy.ProxyHttpServer {
31 ProxyAuthorizationHeader = hoverfly.Cfg.ProxyAuthorizationHeader
32
33 // creating proxy
34 proxy := goproxy.NewProxyHttpServer()
35
36 // Fix #774: HTTP/1.1 clients may send requests with a relative URL (path only) and a Host header.
37 // goproxy's default NonproxyHandler returns 500 for these. Reconstruct the absolute URL from the
38 // Host header so the request is processed normally, matching the behaviour of NewWebserverProxy.
39 //
40 // Guard: if the Host header targets the proxy's own port the client is connecting directly to
41 // Hoverfly (not using it as a proxy). In that case keep the original 500 "is a proxy server"
42 // response — forwarding to ourselves would cause infinite recursion or a panic.
43 proxy.NonproxyHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
44 if r.Host == "" {
45 http.Error(w, "Cannot handle requests without Host header, e.g., HTTP 1.0", http.StatusBadRequest)
46 return
47 }
48 if _, port, err := net.SplitHostPort(r.Host); err == nil && port == hoverfly.Cfg.ProxyPort {
49 http.Error(w, "This is a proxy server. Does not respond to non-proxy requests.", http.StatusInternalServerError)
50 return
51 }
52 r.URL.Scheme = "http"
53 r.URL.Host = r.Host
54 proxy.ServeHTTP(w, r)
55 })
56
57 if hoverfly.Cfg.AuthEnabled {
58 log.Info("Enabling proxy authentication")
59 proxyBasicAndBearer(proxy, "hoverfly", func(user, password string) bool {
60
61 proxyUser := &backends.User{
62 Username: user,
63 Password: password,
64 }
65
66 responseStatus, _ := authentication.Login(proxyUser, hoverfly.Authentication, nil, 0)
67
68 return responseStatus == http.StatusOK
69 }, func(headerToken string) bool {
70 return authentication.IsJwtTokenValid(headerToken, hoverfly.Authentication, hoverfly.Cfg.SecretKey, hoverfly.Cfg.JWTExpirationDelta)
71 })
72 }
73
74 proxy.OnRequest(matchesFilter(hoverfly.Cfg.Destination)).
75 HandleConnect(goproxy.FuncHttpsHandler(func(host string, ctx *goproxy.ProxyCtx) (*goproxy.ConnectAction, string) {
76 if hoverfly.Cfg.PlainHttpTunneling && !strings.HasSuffix(host, ":443") {
77 return goproxy.HTTPMitmConnect, host
78 }
79 return goproxy.MitmConnect, host
80 }))
81
82 // processing connections
83 proxy.OnRequest(matchesFilter(hoverfly.Cfg.Destination)).DoFunc(
84 func(r *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
85 startTime := time.Now()
86 resp, journalIDChannel := hoverfly.processRequest(r)
87 id, _ := hoverfly.Journal.NewEntry(r, resp, hoverfly.Cfg.Mode, startTime)

Calls 10

LoginFunction · 0.92
IsJwtTokenValidFunction · 0.92
proxyBasicAndBearerFunction · 0.85
matchesFilterFunction · 0.85
processRequestMethod · 0.80
NewEntryMethod · 0.80
CountMethod · 0.80
GetModeMethod · 0.65
ErrorMethod · 0.45