Я пытаюсь получить поток RTSP через HTTP, используя прокси. Поведение Реального клиента кажется немного беспокойным: он пробует все возможные порты, методы и протоколы одновременно. Единственное, что должно работать - это HTTP GET через порт 80. Такой запрос действительно выдается и принимается на сервере. Вот как выглядит запрос, когда он отправляется прокси на сервер:
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) - и все, больше ничего. Ожидает ли сервер что-либо от клиента в этот момент, и если да, то что? Этот режим работы работает вообще?
Еще немного информации по этой проблеме: очевидно, предполагаемый механизм работы с RTSP через HTTP, встроенный в RealPlayer, выглядит следующим образом:
- Попробуйте подключиться к следующим портам: 80, 8080, 554, 7070.
(Попробуйте также загрузить файл напрямую, просто так, выполнив команду GET http://hostname:port/mediafilename на порт 80)
- Для каждого из указанных портов создайте 2 соединения.
- Отправьте запрос GET на одно из соединений по URL-адресу http://hostname:port/SmpDsBhgRl
?1="1",, где <guid>
- это, да, только что созданный GUID. Добавьте к этому запросу заголовок с именем X-Actual-URL, содержащий исходный URL-адрес RTSP.
- Отправьте запрос POST по другому соединению на URL http://hostname:port/SmpDsBhgRl с указанным выше GUID как часть тела запроса. Отправьте заголовок Content-Length длиной 32767 байт, чтобы прокси-сервер преждевременно не закрыл соединение.
- Начните выдавать команды серверу через запрос POST и получите соответствующий поток RTSP как часть ответа GET.
Странная вещь (если вышеупомянутое не достаточно странно) заключается в том, что, например, она работает со Squid, но не при использовании любого из портов 3128 или 8080! Так или иначе, клиент использует порт, к которому он подключается, чтобы определить порядок запросов или когда запрос должен быть отменен, но в любом случае, как бы трудно это ни было, он работает с прокси-портом 9090, 3129, 8081, но не с 3128 или 8080.
Обновление № 2: Здесь - источник RealPlayer с объяснением вышеупомянутого поведения. Тем не менее, пока нет решения.
Обновление № 3: ОК, в свете вышесказанного, магическое значение 48 02 02 00 ясно: 48 == 'h' для HTTP_RESPONSE
, следующие 02 - длина следующих данных, следующий 02 называется POST_NOT_RECEIVED
(это означает, что запрос POST не достиг сервера в течение секунды после соответствующего запроса GET).
Обновление № 4: это поведение (то есть POST-запросы с огромным Content-Length) также характерно для ActiveX, используемого WebEx (и, возможно, многими другими веб-приложениями, которым требуется открытый канал для сервера).