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

89 天前
 oyps

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

1475 次点击
所在节点    程序员
9 条回复
ysc3839
89 天前
Wireshark 抓包看看?
codehz
89 天前
你给的两个例子有区别吗
oyps
89 天前
@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
89 天前
如果你的代理是 http 的,得用 httpsOverHttp 的 agent 套一下
oyps
89 天前
@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
89 天前
@lisxour 我分析了一下,只要我设置了代理,不管是什么编程语言,都无法通过 TLS 证书校验,必须要忽略证书错误才可以正常响应,我试了一下,不管是 Clash 还是 Reqable 的证书,都不能通过校验。所以尝试着让证书通过校验是行不通了,那就只能忽略证书错误,现在的问题就是,不管是 Node.js 、Deno 、Java 、Python 、PHP ,都能成功忽略掉证书错误,只有 Bun ,不管怎么设置,用隧道,用 NODE_TLS_REJECT_UNAUTHORIZED=0 ,用 Agent.rejectUnauthorized=false ,Bun 遇到证书错误,还是会继续报错,根本无法绕过证书验证。
houzhenhong
89 天前
这里似乎有一个背景,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
88 天前
@houzhenhong 是的,proxy 的定义来自 @types/bun ,应该是 Bun 特有的。

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

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

项目要求必须使用到 Proxy ,所以真的没办法,折腾了好久,心累。
Rrrrrr
88 天前
你那个抓包的工具,会不会当成中间人。你得有证书?

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

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

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

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

© 2021 V2EX