简体   繁体   English

在 Node.js express 中使用 HTTP 代理 HTTPS

[英]Proxy HTTPS with HTTP in Node.js express

I wrote an express app as an HTTP proxy, to intercept and analyse some of the network traffic.我写了一个快速应用程序作为 HTTP 代理,来拦截和分析一些网络流量。 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,但是我仍然希望我的应用代理 HTTPS,以便用户无需额外设置即可使用它。

My express app is created with a HTTP server.我的快速应用程序是使用 HTTP 服务器创建的。 When testing, I changed the proxy setting in Chrome with SwitchyOmega, to proxy HTTPS connections with HTTP.测试时,我使用 SwitchyOmega 将 Chrome 中的代理设置更改为使用 HTTP 代理 HTTPS 连接。 HTTP works well, But my express app couldn't get these proxy requests for 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.当然,如果我将浏览器代理设置更改为忽略 HTTPS,该应用程序运行良好。 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.但我确实想知道是否有任何解决方法可以用来代理所有使用 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.问题是,我的第一个中间件,用于显示应用程序接收到的所有请求,无法捕获上述 HTTP 包装的 HTTPS 代理请求。 And of course the middleware I used as proxy can't catch them either.当然,我用作代理的中间件也无法捕获它们。

UPDATE-tried node-http-prxoy , no luck更新尝试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.使用上面的代码,以及使用 HTTP 代理所有协议的浏览器设置,它的工作方式与我的 express 应用程序相同。 HTTPS proxy requests gets ERR_EMPTY_RESPONSE , and nothing on the console. 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.使用以下选项,似乎我必须将代理协议更改为 HTTPS,我宁愿不使用它,至少现在是这样。 And I get ERR_PROXY_CERTIFICATE_INVALID for my self-signed certs...我的自签名证书得到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更新-将问题指向“连接”事件侦听器

Through some searching, I found this post helpful.通过一些搜索,我发现这篇文章很有帮助。

It pointed out that the http server doesn't have a listener for the connect event.它指出 http 服务器没有connect事件的侦听器。 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.但正如该帖子的最后一条评论所提到的,我的应用程序充当代理以获取数据,然后将请求代理到另一个代理以通过 GreatFireWall。

The process is like : BROWSER -> MY_APP -> ANOTHER_PROXY -> TARGET .这个过程就像: BROWSER -> MY_APP -> ANOTHER_PROXY -> TARGET

Without the ANOTHER_PROXY , which is an HTTP proxy, it works well for both HTTP and HTTPS.如果没有ANOTHER_PROXY ,它是一个 HTTP 代理,它适用于 HTTP 和 HTTPS。 However I failed to chain them all up.但是我没能把它们全部锁起来。 The ANOTHER_PROXY I use supports HTTPS over HTTP.我使用的ANOTHER_PROXY支持 HTTPS over HTTP。

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.他们的自述文件包含最常见场景的示例代码,听起来它可以很好地支持您的需求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM