我正在尝试使用代理通过 HTTP 获取 RTSP 流。Real 客户端的行为似乎有点忙:它一次尝试所有可能的端口、方法和协议。唯一应该工作的是通过端口 80 的 HTTP GET。确实发出了这样的请求,并在服务器上接收到。以下是代理将请求发送到服务器时的外观:
GET /SmpDsBhgRl83c52ef2-d0f4-41ac-bada-93e5350f67d1?1="1" HTTP/1.0\r\n
Connection: Keep-Alive\r\n
Host: 10.194.5.162:80\r\n
Pragma: no-cache\r\n
User-Agent: RealPlayer G2\r\n
Expires: Mon, 18 May 1974 00:00:00 GMT\r\n
Accept: application/x-rtsp-tunnelled, */*\r\n
ClientID: WinNT_5.1_6.0.14.806_RealPlayer_R41UKD_en-GB_686\r\n
X-Actual-URL: rtsp://10.194.5.162:554/01.mp3\r\n
\r\n
这是服务器的响应:
HTTP/1.0 200 OK\r\n
Server: RMServer 1.0\r\n
Expires: Mon, 18 May 1974 00:00:00 GMT\r\n
Pragma: no-cache\r\n
x-server-ipaddress: 10.194.5.162\r\n
Content-type: audio/x-pn-realaudio\r\n
\r\n
此时服务器又收到了 4 个字节(它们的值为 48 02 02 00)——仅此而已。服务器在这一点上是否期望客户端提供任何东西,如果是的话 - 什么?这种操作模式是否有效?
关于这个问题的更多信息:显然,RealPlayer 内置的通过 HTTP 使用 RTSP 的预期机制如下:
- 尝试连接到以下端口:80、8080、554、7070。(也可以通过在端口 80 上发出 GET http://hostname:port/mediafilename来直接下载文件)
- 对于上述每个端口,创建 2 个连接。
- 向 URL http://hostname:port/SmpDsBhgRl
<guid>
?1="1"的连接之一发送 GET 请求,<guid>
是的,这里是新创建的 GUID。向此请求添加一个名为 X-Actual-URL 的标头,其中包含原始 RTSP URL。 - 在另一个连接上向 URL http://hostname:port/SmpDsBhgRl发送一个 POST 请求,并将上面的 GUID 作为请求正文的一部分。发送 32767 字节的 Content-Length 标头,以防止代理过早关闭连接。
- 开始通过 POST 请求向服务器发出命令,并获取相应的 RTSP 流作为 GET 响应的一部分。
奇怪的东西(如果上面还不够奇怪的话)是,例如,它可以与 Squid 一起使用,但如果您使用端口 3128 或 8080 中的任何一个,则不能!不知何故,客户端使用它连接的端口来决定请求的顺序或何时取消请求,但无论如何,尽管难以置信,它可以使用代理端口 9090、3129、8081,但是不是 3128 或 8080。
更新 #2:这是 RealPlayer 的源代码以及对上述行为的解释。虽然仍然没有解决方案。
更新#3:好的,根据上述,48 02 02 00 的魔法值很清楚: 48 == 'h' 是 for HTTP_RESPONSE
,下一个 02 是后面数据的长度,下一个 02 被称为POST_NOT_RECEIVED
(意味着 POST 请求在相应的 GET 请求后一秒钟内没有到达服务器)。
更新#4:这种行为(即具有巨大 Content-Length 的 POST 请求)也是 WebEx 使用的 ActiveX 的特征(可能还有许多其他需要与服务器建立开放通道的 Web 应用程序)。