http - Indy 代理服务器 HTTPS 到 HTTP

标签 http ssl https proxy indy

我正在尝试在 Indy 中编写一个代理服务器来接收来自外部客户端的 HTTPS 调用,并将它们以 HTTP 形式转发到同一台机器上的另一个服务器应用程序。原因是其他应用程序不支持 SSL,因此我想将其流量包装在 SSL 层中以实现外部安全。

我目前的方法是使用带有 SSL IOHandler 的 TIdHTTPserver,在它的 OnCommandGet 处理程序中,我动态创建了一个 TIdHTTP 客户端,它从内部应用程序获取 TFileStream ContentStream,并将该流作为 Response.ContentStream 返回到外部来电者。

这种方法的问题是在开始发送外部流之前必须等待内部内容流被完全接收而导致的延迟。例如,它不适用于流媒体。

我的问题是:是否有更好的方法将 HTTPS 代理到适用于流的 HTTP?即无需使用中间文件流。

最佳答案

如果发出请求的客户端支持 HTTP 1.1 分块(请参阅 RFC 2616 Section 3.6.1 ),这将允许您从目标服务器读取数据并立即将其实时发送到客户端。

如果您使用的是较新版本的 Indy,TIdHTTP有一个 OnChunkReceived事件,以及一个 hoNoReadChunked在其 HTTPOptions 中标记属性:

New TIdHTTP flags and OnChunkReceived event

在你的TIdHTTPServer.OnCommand...事件处理程序,您可以填充 AResponseInfo如所须。确保:

  • 离开 AResponseInfo.ContentTextAResponseInfo.ContentStream未分配

  • 设置AResponseInfo.ContentLength到 0

  • 设置AResponseInfo.TransferEncoding'chunked'

然后调用AResponseInfo.WriteHeader()直接方法,例如 TIdHTTP.OnHeadersRecceived事件,将响应 header 发送到客户端。

然后您可以使用OnChunkedReceived 读取目标服务器的响应正文或 hoNoReadChunked ,并使用 AContext.Connection.IOHandler 将每个接收到的 block 写入客户端直接。

但是,有一些注意事项:

  • 如果您使用 TIdHTTP.OnChunkReceived事件,您仍然需要提供输出 TStreamTIdHTTP否则事件不会被触发(在未来的版本中可能会删除此限制)。但是,您可以使用 TIdEventStream没有分配 OnWrite它的事件处理程序。或者写一个自定义 TStream覆盖虚拟的类 Write()什么都不做的方法。或者,只使用任何 TStream你想要,并拥有 OnChunkReceived事件处理程序清除收到的 Chunk所以没有什么可以写入 TStream .

  • 如果您使用 hoNoReadChunked标志,这允许您手动从 TIdHTTP.IOHandler 读取 HTTP block 直接在 TIdHTTP 之后导出。只要确保启用 HTTP keep-alives 否则 TIdHTTP将在您有机会读取服务器的响应正文之前关闭与服务器的连接。

如果您使用的是旧版本的 Indy,或者如果目标服务器不支持分块,则不会丢失所有内容。您应该能够编写自定义 TStream覆盖虚拟的类 Write()方法将提供的数据 block 作为 HTTP block 写入客户端。然后你可以使用那个类作为输出 TStream对于 TIdHTTP .

如果客户端不支持 HTTP 分块,或者如果这些方法对您不起作用,那么您可能不得不求助于使用 TIdTCPServer直接代替 TIdHTTPServer并从头开始自己实现整个 HTTP 协议(protocol),然后您可以根据需要处理自己的流媒体。查看 TIdHTTPProxyServer 的源代码对于一些想法(TIdHTTPProxyServer 本身并不适合您的特定情况,但它会告诉您如何在一般情况下近乎实时地在连接之间传递 HTTP 请求/响应)。

关于http - Indy 代理服务器 HTTPS 到 HTTP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41504247/

相关文章:

javascript - 如何使用 Turkit 进行 MTURK?

http - 应如何在 RESTful API 中检索 transient 资源

java - 如何使用 Spring 和 MongoDB 高效返回 304(未修改)HTTP 响应

ssl - 通过 IIS 反向代理上的 https 设置 YouTrack

ssl - TLS/SSLv3 不安全吗?

apache - 301 将单个页面的 HTTPS 重定向到 HTTP

php - PHP 中跨 HTTP 和 HTTPS 的 Cookie

php - HTTP、PHP : Return base64 image png as download

http - 无法在 Golang 中解码 JSON 数组

android - Android 上使用 Wifi 的 HttpClient 导致延迟(根据初始请求)