V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
aladdinding
V2EX  ›  问与答

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

  •  
  •   aladdinding · 2022-12-28 15:58:15 +08:00 · 1569 次点击
    这是一个创建于 698 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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


    前面那种没试过, 后面这个你可以指定 Transport 和 dialer
    j0hnj
        9
    j0hnj  
       2022-12-28 19:21:36 +08:00 via iPhone
    //go:linkname
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1200 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 23:16 · PVG 07:16 · LAX 15:16 · JFK 18:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.