Node.js中的HTTP代理HTTPS表示

时间:2022-03-15 19:01:50

I wrote an express app as an HTTP proxy, to intercept and analyse some of the network traffic. The parts of traffic my app is interested in are all HTTP, however I still want my app to proxy HTTPS so users can use it without extra setting.

我写了一个快速应用程序作为HTTP代理,拦截和分析一些网络流量。我的应用程序感兴趣的流量部分都是HTTP,但我仍然希望我的应用程序代理HTTPS,以便用户无需额外设置即可使用它。

My express app is created with a HTTP server. When testing, I changed the proxy setting in Chrome with SwitchyOmega, to proxy HTTPS connections with HTTP. HTTP works well, But my express app couldn't get these proxy requests for HTTPS.

我的快速应用程序是使用HTTP服务器创建的。在测试时,我使用SwitchyOmega更改了Chrome中的代理设置,以使用HTTP代理HTTPS连接。 HTTP运行良好,但我的快递应用程序无法获得HTTPS的这些代理请求。

So I wrote a simple TCP proxy to check on them, and find that they're like this:

所以我写了一个简单的TCP代理来检查它们,并发现它们是这样的:

CONNECT HOSTNAME:443 HTTP/1.1
Host: HOSTNAME
Proxy-Connection: keep-alive
User-Agent: MY_AGENT

ENCRYPTED HTTPS

I believe these requests are HTTP, but why express isn't receiving them?

我相信这些请求是HTTP,但为什么express不接收它们?

For sure if I change the browser proxy setting to ignore HTTPS, the app works well. But I do want to know if there is any workaround that I can use to proxy all protocols with HTTP and only one port.

当然,如果我将浏览器代理设置更改为忽略HTTPS,则该应用程序运行良好。但我确实想知道是否有任何解决方法,我可以使用HTTP代理所有协议,只有一个端口。

THX.

UPDATE- code from my express app

来自我的快递应用程序的更新代码

app.use('*', function (req, res, next) {
    // print all the request the app receive
    console.log('received:', req.url)
})

app.use(bodyParser.text({type: '*/*'}))
app.use(cookieParser())
app.use(logger('dev'))
app.use(express.static(path.join(__dirname, 'public')))

// serve web pages for my app, only the request targeting my server
// is handled here(right IP and port), proxy request gets handled after this.
app.use('/', internalRoute)

// analyse the part I want
app.use('/END_POINT_I_WANT', myRoute)

// handle proxy requests
app.use('*', function (req, res, next) {
  // proxy the request here
})

The problem is, my first middleware, which is used to display all the requests the app receive, can't catch the HTTPS proxy requests wrapped in HTTP described above. And of course the middleware I used as proxy can't catch them either.

问题是,我的第一个中间件,用于显示应用程序收到的所有请求,无法捕获上述HTTP中包含的HTTPS代理请求。当然,我用作代理的中间件也无法捕获它们。

UPDATE-tried node-http-prxoy, no luck

UPDATE尝试过node-http-prxoy,没有运气

var httpProxy = require('http-proxy')
  , http = require('http')
  , fs = require('fs')

var options = {target: 'http://127.0.0.1:8099'}
  , proxy = httpProxy.createServer(options)

http.createServer(function (req, res) {
  console.log(req.url)
  proxy.web(req, res)
}).listen(5050)

With the above code, and browser setting to proxy all protocols with HTTP, it works the same as my express app. HTTPS proxy requests gets ERR_EMPTY_RESPONSE, and nothing on the console.

使用上面的代码和浏览器设置来代理使用HTTP的所有协议,它的工作方式与我的快递应用程序相同。 HTTPS代理请求获取ERR_EMPTY_RESPONSE,控制台上没有任何内容。

With the below options, it seems that I have to change the proxy protocol to HTTPS, which I'd rather not use, at least for now. And I get ERR_PROXY_CERTIFICATE_INVALID for my self-signed certs...

使用以下选项,似乎我必须将代理协议更改为HTTPS,我宁愿不使用它,至少目前是这样。我获得了自签名证书的ERR_PROXY_CERTIFICATE_INVALID ...

var options  = { secure: true
               , target: 'http://127.0.0.1:8099'
               , ssl: { key: fs.readFileSync('cert/key.pem', 'utf8')
                      , cert: fs.readFileSync('cert/server.crt', 'utf8')
                      }
               }

UPDATE- pin point the problem to the 'connect' event listener

UPDATE-引脚将问题指向'connect'事件侦听器

Through some searching, I found this post helpful.

通过一些搜索,我发现这篇文章很有帮助。

It pointed out that the http server doesn't have a listener for the connect event. I tried the code in the post, works. But as the last comment of that post mentioned, my app serves as a proxy in order to get the data, it then proxy the request to another proxy in order to go over the GreatFireWall.

它指出http服务器没有connect事件的监听器。我尝试了帖子中的代码,有效。但正如该帖子的最后评论所提到的,我的应用程序充当代理以获取数据,然后将请求代理到另一个代理以便通过GreatFireWall。

The process is like : BROWSER -> MY_APP -> ANOTHER_PROXY -> TARGET.

过程如下:浏览器 - > MY_APP - > ANOTHER_PROXY - > TARGET。

Without the ANOTHER_PROXY, which is an HTTP proxy, it works well for both HTTP and HTTPS. However I failed to chain them all up. The ANOTHER_PROXY I use supports HTTPS over HTTP.

如果没有ANOTHER_PROXY,这是一个HTTP代理,它适用于HTTP和HTTPS。但是我没能将它们全部链接起来。我使用的ANOTHER_PROXY支持HTTPS over HTTP。

1 个解决方案

#1


It's hard to see what might be wrong, since you haven't posted any code.

由于您尚未发布任何代码,因此很难看出可能出现的问题。

However, if you just want to create a simple proxy that supports HTTP and HTTPS, i think that you should consider using a module like node-http-proxy.

但是,如果您只想创建一个支持HTTP和HTTPS的简单代理,我认为您应该考虑使用类似node-http-proxy的模块。

Their readme has example code for the most common scenarios, and it sounds like it will support your needs fine.

他们的自述文件包含最常见场景的示例代码,听起来它可以很好地支持您的需求。

#1


It's hard to see what might be wrong, since you haven't posted any code.

由于您尚未发布任何代码,因此很难看出可能出现的问题。

However, if you just want to create a simple proxy that supports HTTP and HTTPS, i think that you should consider using a module like node-http-proxy.

但是,如果您只想创建一个支持HTTP和HTTPS的简单代理,我认为您应该考虑使用类似node-http-proxy的模块。

Their readme has example code for the most common scenarios, and it sounds like it will support your needs fine.

他们的自述文件包含最常见场景的示例代码,听起来它可以很好地支持您的需求。