101 lines
2.8 KiB
Go
101 lines
2.8 KiB
Go
package proxy
|
|
|
|
import (
|
|
"context"
|
|
"crypto/tls"
|
|
"net/http"
|
|
"net/url"
|
|
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
"gitlab.com/inetmock/inetmock/pkg/logging"
|
|
"go.uber.org/zap"
|
|
"gopkg.in/elazarl/goproxy.v1"
|
|
)
|
|
|
|
type proxyHttpHandler struct {
|
|
handlerName string
|
|
options httpProxyOptions
|
|
logger logging.Logger
|
|
}
|
|
|
|
type proxyHttpsHandler struct {
|
|
handlerName string
|
|
tlsConfig *tls.Config
|
|
logger logging.Logger
|
|
}
|
|
|
|
func (p *proxyHttpsHandler) HandleConnect(req string, _ *goproxy.ProxyCtx) (*goproxy.ConnectAction, string) {
|
|
totalHttpsRequestCounter.WithLabelValues(p.handlerName).Inc()
|
|
p.logger.Info(
|
|
"Intercepting HTTPS proxy request",
|
|
zap.String("request", req),
|
|
)
|
|
|
|
return &goproxy.ConnectAction{
|
|
Action: goproxy.ConnectMitm,
|
|
TLSConfig: func(host string, ctx *goproxy.ProxyCtx) (*tls.Config, error) {
|
|
return p.tlsConfig, nil
|
|
},
|
|
}, ""
|
|
}
|
|
|
|
func (p *proxyHttpHandler) Handle(req *http.Request, ctx *goproxy.ProxyCtx) (retReq *http.Request, resp *http.Response) {
|
|
timer := prometheus.NewTimer(requestDurationHistogram.WithLabelValues(p.handlerName))
|
|
defer timer.ObserveDuration()
|
|
totalRequestCounter.WithLabelValues(p.handlerName).Inc()
|
|
|
|
retReq = req
|
|
p.logger.Info(
|
|
"Handling request",
|
|
zap.String("source", req.RemoteAddr),
|
|
zap.String("host", req.Host),
|
|
zap.String("method", req.Method),
|
|
zap.String("protocol", req.Proto),
|
|
zap.String("path", req.RequestURI),
|
|
zap.Reflect("headers", req.Header),
|
|
)
|
|
|
|
var err error
|
|
if resp, err = ctx.RoundTrip(p.redirectHTTPRequest(req)); err != nil {
|
|
p.logger.Error(
|
|
"error while doing roundtrip",
|
|
zap.Error(err),
|
|
)
|
|
return req, nil
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (p proxyHttpHandler) redirectHTTPRequest(originalRequest *http.Request) (redirectReq *http.Request) {
|
|
redirectReq = &http.Request{
|
|
Method: originalRequest.Method,
|
|
URL: &url.URL{
|
|
Host: p.options.Target.host(),
|
|
Path: originalRequest.URL.Path,
|
|
ForceQuery: originalRequest.URL.ForceQuery,
|
|
Fragment: originalRequest.URL.Fragment,
|
|
Opaque: originalRequest.URL.Opaque,
|
|
RawPath: originalRequest.URL.RawPath,
|
|
RawQuery: originalRequest.URL.RawQuery,
|
|
User: originalRequest.URL.User,
|
|
},
|
|
Proto: originalRequest.Proto,
|
|
ProtoMajor: originalRequest.ProtoMajor,
|
|
ProtoMinor: originalRequest.ProtoMinor,
|
|
Header: originalRequest.Header,
|
|
Body: originalRequest.Body,
|
|
GetBody: originalRequest.GetBody,
|
|
ContentLength: originalRequest.ContentLength,
|
|
TransferEncoding: originalRequest.TransferEncoding,
|
|
Close: false,
|
|
Host: originalRequest.Host,
|
|
Form: originalRequest.Form,
|
|
PostForm: originalRequest.PostForm,
|
|
MultipartForm: originalRequest.MultipartForm,
|
|
Trailer: originalRequest.Trailer,
|
|
}
|
|
redirectReq = redirectReq.WithContext(context.Background())
|
|
|
|
return
|
|
}
|