实施 Web 代理时,服务器应如何报告低级协议错误?

When implementing a web proxy, how should the server report lower-level protocol errors?

我正在实施 HTTP 代理。有时,当浏览器通过我的代理发出请求时,我会收到诸如 ECONNRESETAddress not found 之类的错误。这些指示低于 HTTP 级别的错误。我不是在谈论我的程序中的错误——而是在我向其他服务器发送 HTTP 请求时它们的行为方式。

有些服务器可能根本不存在,有些服务器关闭套接字,还有一些服务器根本不响应。

向呼叫者报告这些错误的最佳方式是什么?有没有一种标准方法,如果我使用它,浏览器会将我的 HTTP 消息转换为适当的错误消息? (即他们从代理那里得到回复,告诉他们 ECONNRESET,并且他们表现得好像他们自己收到了 ECONNRESET)。

如果不是,应该如何处理?

动机

我真的希望我的代理是完全透明的,浏览器或其他客户端就像没有连接到它一样工作,所以我想复制错误的有机行为,例如 ECONNRESET 而不是发送带有错误代码的 HTTP 消息,这将是完全不同的行为。

我有点认为这是编写 HTTP 代理时的意图。

我不会向他们提供太多信息。通过内部日志报告您的需求,以防您必须解决问题。 Return 400、403 或 418。为什么?也许他们只是在黑客攻击。

有几点需要牢记。

首先,如果客户端配置为使用代理(实际上我会推荐),那么从根本上讲,它的行为将不同于直接通过 Internet 连接。这对用户来说几乎是不可见的,但会影响以下内容:

  • FTP 网址
  • 一些缓存差异
  • 如果需要,对代理进行身份验证
  • 报告连接错误等<=您的问题。

在报告错误的情况下,如果浏览器无法连接到代理或通过代理打开隧道,浏览器将显示连接错误,但对于上游错误,代理将提供一个页面(取决于错误,例如,如果已经发送了响应,则代理只能关闭连接。此页面看起来与您的浏览器页面完全不同。

如果浏览器未配置为使用代理,则您需要转移或拦截与代理的连接。如果您决定要根据代理对用户进行身份验证(以识别他们/实施用户特定的规则等),这可能会导致问题。

其次,HTTPS 确实令人头疼。随着越来越多的网站转向仅使用 HTTPS,这个问题越来越严重。有几个问题:

  • 配置为使用代理的浏览器,对于 HTTPS URLS,将首先使用 CONNECT 方法通过代理打开隧道。如果您的代理想要阻止这种情况,那么它在块响应中提供的任何信息都会被浏览器忽略,而是您会看到通用的浏览器连接错误页面。

  • 如果您想提供通常希望从代理获得的任何其他好处(例如缓存/扫描等),您需要实施 MitM(中间人)和欺骗服务器 SSL证书等。实际上,如果您只想发回阻止页面以拒绝某些事情,则需要这样做。

有一种方法可以使浏览器的行为更像是通过代理直接连接,这就是使用 SOCKS。如果存在上游连接错误,SOCKS 有办法 return 一个错误代码。然而,这不是实际的套接字错误代码。

这些都是我们编写 WinGate Internet Client 的原因,它是我们产品 WinGate 的基于 LSP 的产品。然后客户端应用程序了解实际的上游错误代码等。

不过现在这不是一个受欢迎的方法,因为它需要在客户端计算机上安装软件。