golang 怎么重写标准库内的代码呢

2022-12-28 15:58:15 +08:00
 aladdinding

如果是第三方库的话一般就直接 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 的话 函数参数首字母也是小写的,外部也不能调用。。。

1354 次点击
所在节点    问与答
9 条回复
rimutuyuan
2022-12-28 16:03:29 +08:00
net/http 在 GOROOT/src/net/http 路径下,可以拷贝出来修改后以第三方包的形式导入
aladdinding
2022-12-28 16:21:46 +08:00
@rimutuyuan 可以是可以,0.0 还要改一大堆导包了
777777
2022-12-28 16:22:20 +08:00
go 发明者建议:如果代码量不大,那就复制重写
iamperiod331www
2022-12-28 18:44:26 +08:00
可以改完之后打 patch ,保存 patch 文件到自己的项目
编译之前,对基础库打 patch
iamperiod331www
2022-12-28 18:44:54 +08:00
感觉,go 的 http 包写的不怎么样,很多地方不方便
wangsongyan
2022-12-28 18:51:17 +08:00
我见过的方式是实现自己的 transport
patrickyoung
2022-12-28 18:52:38 +08:00
实现自己的 transport ,然后指定 client 使用自己的 transport
corvofeng
2022-12-28 19:06:05 +08:00
没太理解你问题, 可能有两种情况

1. 要一种新的 uri 方案, 比如不用 http, 改 url 的头部 xx://www.baidu.com

2. 一种新的代理方式, 比如传输层不用 socks5 协议, 改用 ssh 协议


前面那种没试过, 后面这个你可以指定 Transport 和 dialer
j0hnj
2022-12-28 19:21:36 +08:00
//go:linkname

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/905175

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX