如果是第三方库的话一般就直接 down 下来魔改了,但是 go 的标准库怎么操作呢?
主要是想重写 net/http/transport.go
里面的代码,是下面这个方法,需要 case 一个新的协议,官方
的 transport 只实现了 proxy 的 socks5 、http 、https
func (t *Transport) dialConn(ctx context.Context, cm connectMethod) (pconn *persistConn, err error) {
// 省略
// Proxy setup.
switch {
case cm.proxyURL == nil:
// Do nothing. Not using a proxy.
case cm.proxyURL.Scheme == "socks5":
conn := pconn.conn
d := socksNewDialer("tcp", conn.RemoteAddr().String())
if u := cm.proxyURL.User; u != nil {
auth := &socksUsernamePassword{
Username: u.Username(),
}
auth.Password, _ = u.Password()
d.AuthMethods = []socksAuthMethod{
socksAuthMethodNotRequired,
socksAuthMethodUsernamePassword,
}
d.Authenticate = auth.Authenticate
}
if _, err := d.DialWithConn(ctx, conn, "tcp", cm.targetAddr); err != nil {
conn.Close()
return nil, err
}
case cm.targetScheme == "http":
pconn.isProxy = true
if pa := cm.proxyAuth(); pa != "" {
pconn.mutateHeaderFunc = func(h Header) {
h.Set("Proxy-Authorization", pa)
}
}
case cm.targetScheme == "https":
conn := pconn.conn
var hdr Header
if t.GetProxyConnectHeader != nil {
var err error
hdr, err = t.GetProxyConnectHeader(ctx, cm.proxyURL, cm.targetAddr)
if err != nil {
conn.Close()
return nil, err
}
} else {
hdr = t.ProxyConnectHeader
}
if hdr == nil {
hdr = make(Header)
}
if pa := cm.proxyAuth(); pa != "" {
hdr = hdr.Clone()
hdr.Set("Proxy-Authorization", pa)
}
connectReq := &Request{
Method: "CONNECT",
URL: &url.URL{Opaque: cm.targetAddr},
Host: cm.targetAddr,
Header: hdr,
}
}
Python 话一般继承后重写就 ok 了
golang 的话 函数参数首字母也是小写的,外部也不能调用。。。
1
rimutuyuan 2022-12-28 16:03:29 +08:00
net/http 在 GOROOT/src/net/http 路径下,可以拷贝出来修改后以第三方包的形式导入
|
2
aladdinding OP @rimutuyuan 可以是可以,0.0 还要改一大堆导包了
|
3
777777 2022-12-28 16:22:20 +08:00
go 发明者建议:如果代码量不大,那就复制重写
|
4
iamperiod331www 2022-12-28 18:44:26 +08:00
可以改完之后打 patch ,保存 patch 文件到自己的项目
编译之前,对基础库打 patch |
5
iamperiod331www 2022-12-28 18:44:54 +08:00
感觉,go 的 http 包写的不怎么样,很多地方不方便
|
6
wangsongyan 2022-12-28 18:51:17 +08:00 via iPhone
我见过的方式是实现自己的 transport
|
7
patrickyoung 2022-12-28 18:52:38 +08:00 via iPhone
实现自己的 transport ,然后指定 client 使用自己的 transport
|
8
corvofeng 2022-12-28 19:06:05 +08:00
没太理解你问题, 可能有两种情况
1. 要一种新的 uri 方案, 比如不用 http, 改 url 的头部 xx://www.baidu.com 2. 一种新的代理方式, 比如传输层不用 socks5 协议, 改用 ssh 协议 前面那种没试过, 后面这个你可以指定 Transport 和 dialer |
9
j0hnj 2022-12-28 19:21:36 +08:00 via iPhone
//go:linkname
|