V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
oyps
V2EX  ›  程序员

Bun 遇到的一个 Bug,请求大佬分析分析,非常感谢

  •  
  •   oyps ·
    oyps · 31 天前 · 1319 次点击

    Bun 的 1.1.12 和最新的 1.1.24 都试过了,均出现问题。

    我调用原生的 fetch 方法,并设置 proxy 参数,我的环境变量没有设置 http_proxyhttps_proxy

    Bun 官方对 proxy 的说明: https://bun.sh/guides/http/proxy

    我的代码如下( xxx.js ):

    // https 请求,在有 proxy 参数情况下,会先发一个 CONNECT 并且就此报错
    fetch('https://www.google.com', {
        proxy: 'http://127.0.0.1:7890',
    })
    
    // 如果换成 http ,就不会发 CONNECT ,正常拿响应
    fetch('https://www.google.com', {
        proxy: 'http://127.0.0.1:7890',
    })
    

    只要是 https ,就会出现下面的问题,而 http 没有:

    > bun index.ts
    [fetch] > HTTP/1.1 GET https://www.google.com/
    [fetch] > Connection: keep-alive
    [fetch] > User-Agent: Bun/1.1.24
    [fetch] > Accept: */*
    [fetch] > Host: www.google.com
    [fetch] > Accept-Encoding: gzip, deflate, br
    
    [fetch] < 200 Connection established
    
    Syscall: Syscall fetching "https://www.google.com/". For more information, pass `verbose: true` in the second argument to fetch()
     path: "https://www.google.com/"
    

    上面是原生 fetch 的操作,我下面换成 axios:

    import axios from 'axios'
    import https from 'https'
    
    const instance = axios.create({
        httpsAgent: new https.Agent({
            rejectUnauthorized: false
        }),
        proxy: {
            host: '127.0.0.1',
            port: 7890
        }
    })
    
    instance.get('https://www.google.com').catch(err => {
        console.log(err.message)
    })
    

    这里报错:unable to get issuer certificate

    大概就是个证书有关,可是我如果不使用 proxy ,就不会有这个问题,所以这个不知道是 Bun 问题,还是 Clash 问题。

    这个是我在 Bun 提的 ISSUES: https://github.com/oven-sh/bun/issues/13344

    这个 40 秒的视频复现了问题: https://files.imdodo.com/dodo/083cecbf0bcc0b8f362c35b11d7e910e.mp4

    9 条回复    2024-08-17 16:33:03 +08:00
    ysc3839
        1
    ysc3839  
       31 天前 via Android
    Wireshark 抓包看看?
    codehz
        2
    codehz  
       31 天前
    你给的两个例子有区别吗
    oyps
        3
    oyps  
    OP
       31 天前
    @codehz 一个是用原生的 fetch 请求的,走代理请求 https 返回 200 Connection established 而不是 200 OK
    然后我用 axios 去请求试试,也是设置代理,然后发现返回 unable to get issuer certificate ,这就搞不明白了


    @ysc3839 抓了,用原生 fetch 走 proxy 去请求 https 时,会先发起一个 CONNECT ,如下:
    CONNECT / HTTP/1.1
    Host: www.iuroc.com:443
    Proxy-Connection: Keep-Alive
    lisxour
        4
    lisxour  
       30 天前
    如果你的代理是 http 的,得用 httpsOverHttp 的 agent 套一下
    oyps
        5
    oyps  
    OP
       30 天前
    @lisxour 下面的这段代码,"type": "module",用 node 去执行能正常响应,用 bun 执行,完全卡住

    ```js
    import axios from 'axios'
    import { HttpsProxyAgent } from 'https-proxy-agent'

    process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
    axios.defaults.httpsAgent = new HttpsProxyAgent('http://192.168.119.242:9000')
    await axios.get('https://www.youtube.com')
    .then(res => console.log(res.data))
    .catch(console.log)
    ```

    30 秒视频展示: https://files.imdodo.com/dodo/3b7afca812bbdc61cdc13ca1a7058108.mp4
    oyps
        6
    oyps  
    OP
       30 天前
    @lisxour 我分析了一下,只要我设置了代理,不管是什么编程语言,都无法通过 TLS 证书校验,必须要忽略证书错误才可以正常响应,我试了一下,不管是 Clash 还是 Reqable 的证书,都不能通过校验。所以尝试着让证书通过校验是行不通了,那就只能忽略证书错误,现在的问题就是,不管是 Node.js 、Deno 、Java 、Python 、PHP ,都能成功忽略掉证书错误,只有 Bun ,不管怎么设置,用隧道,用 NODE_TLS_REJECT_UNAUTHORIZED=0 ,用 Agent.rejectUnauthorized=false ,Bun 遇到证书错误,还是会继续报错,根本无法绕过证书验证。
    houzhenhong
        7
    houzhenhong  
       30 天前
    这里似乎有一个背景,fetch 里面的 proxy 配置好像是 bun 特有的,nodejs 并不会遵循。如果需要在 nodejs 中使用,需要使用额外的配置,更多信息可以看 https://github.com/nodejs/undici/issues/1650 https://github.com/nodejs/node/issues/8381

    我这里测试的现象是,macOS bun 不会校验证书是否在系统根证书中。(无论是否设置 NODE_TLS_REJECT_UNAUTHORIZED=0 ) nodejs 需要配置该环境变量

    但是在 Windows 中只要使用 bun proxy 的时候访问 https 都会有问题。( tcpdump 发现 Connection Established 之后,bun 会发送 RST )

    这里有许多 issue 指出了这个问题

    https://github.com/oven-sh/bun/issues/13238
    https://github.com/oven-sh/bun/issues/13245
    https://github.com/oven-sh/bun/issues/11111
    ...

    这里也有 pr 在尝试解决这个问题。

    https://github.com/oven-sh/bun/pull/12750

    你可以去 CI 中下载最新的构建看是否解决了这个问题(我自己尝试是没有的)
    oyps
        8
    oyps  
    OP
       30 天前
    @houzhenhong 是的,proxy 的定义来自 @types/bun ,应该是 Bun 特有的。

    昨天我就翻遍了 bun issue ,实在是没找到有用的解决办法,所以来 V2EX 问问大佬们。

    目前看来,还是等官方更新吧,目前先用 TSX 代替使用。

    项目要求必须使用到 Proxy ,所以真的没办法,折腾了好久,心累。
    Rrrrrr
        9
    Rrrrrr  
       30 天前
    你那个抓包的工具,会不会当成中间人。你得有证书?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   990 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 19:03 · PVG 03:03 · LAX 12:03 · JFK 15:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.