forked from abourget/goproxy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
roundtripper.go
95 lines (75 loc) · 2.27 KB
/
roundtripper.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package goproxy
import (
"crypto/tls"
"fmt"
"net/http"
"strings"
"time"
)
type RoundTripper interface {
RoundTrip(req *http.Request, ctx *ProxyCtx) (*http.Response, error)
}
type RoundTripperFunc func(req *http.Request, ctx *ProxyCtx) (*http.Response, error)
func (f RoundTripperFunc) RoundTrip(req *http.Request, ctx *ProxyCtx) (*http.Response, error) {
return f(req, ctx)
}
func (ctx *ProxyCtx) RoundTrip(req *http.Request) (*http.Response, error) {
var tr *http.Transport
var addendum = []string{""}
// Redirect with Fake Destination ?
if ctx.RoundTripper == nil {
if ctx.fakeDestinationDNS != "" {
req.URL.Host = ctx.fakeDestinationDNS
transport := &http.Transport{
TLSClientConfig: &tls.Config{
ServerName: strings.Split(ctx.host, ":")[0],
InsecureSkipVerify: true,
},
Proxy: ctx.proxy.Transport.Proxy,
}
addendum = append(addendum, fmt.Sprintf(", sni=%q, fakedns=%q", transport.TLSClientConfig.ServerName, ctx.fakeDestinationDNS))
tr = transport
} else {
tr = ctx.proxy.Transport
}
ctx.RoundTripper = ctx.wrapTransport(tr)
}
if ctx.isLogEnabled {
addendum = append(addendum, "log=yes")
}
ctx.Logf("RoundTrip for req.URL=%q, req.Host=%q%s", req.URL, req.Host, strings.Join(addendum, ", "))
resp, err := ctx._roundTripWithLog(req)
ctx.Logf(" RoundTrip returned: err=%v", err)
return resp, err
}
func (ctx *ProxyCtx) _roundTripWithLog(req *http.Request) (*http.Response, error) {
var resp *http.Response
var err error
if ctx.isLogEnabled == true {
reqAndResp := new(harReqAndResp)
reqAndResp.start = time.Now()
reqAndResp.captureContent = ctx.isLogWithContent
req := ctx.Req
if req.ContentLength > 0 {
req, reqAndResp.req = copyReq(req)
} else {
reqAndResp.req = req
}
resp, err = ctx.RoundTripper.RoundTrip(req, ctx)
if resp != nil && resp.ContentLength != 0 {
resp, reqAndResp.resp = copyResp(resp)
} else {
reqAndResp.resp = resp
}
reqAndResp.end = time.Now()
ctx.proxy.harLogEntryCh <- *reqAndResp
} else {
resp, err = ctx.RoundTripper.RoundTrip(req, ctx)
}
return resp, err
}
func (ctx *ProxyCtx) wrapTransport(tr *http.Transport) RoundTripper {
return RoundTripperFunc(func(req *http.Request, ctx *ProxyCtx) (*http.Response, error) {
return tr.RoundTrip(req)
})
}