2008-11-03 2 views
6

Я пытаюсь получить поток RTSP через HTTP с помощью прокси. Поведение реального клиента кажется немного беспокойным: он одновременно пытается использовать все возможные порты, методы и протоколы. Единственное, что должно работать, это HTTP GET через порт 80. Такой запрос действительно выдается и получен на сервере. Вот как запрос выглядит, когда он отправляется на прокси-сервер:rtsp через http через прокси

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 выглядит следующим образом:

  1. Попытка подключения к следующим портам: 80, 8080, 554, 7070 (Попробуйте также загрузить файл напрямую, просто для этого, выдав GET http://hostname:port/mediafilename на порт 80)
  2. Для каждого из указанных портов создайте 2 соединения.
  3. Отправить запрос GET на одно из соединений с адресом http://hostname:port/SmpDsBhgRl<guid>? 1 = "1", где <guid> есть, да, только что созданный GUID. Добавьте заголовок к этому запросу с именем X-Actual-URL, содержащим исходный URL-адрес RTSP.
  4. Отправьте запрос POST на другое соединение, по адресу http://hostname:port/SmpDsBhgRl с указанным GUID как частью тела запроса. Отправьте заголовок Content-Length из 32767 байт, чтобы предотвратить прокси-сервер преждевременно закрывать соединение.
  5. Начать выдачу команд серверу через запрос POST и получить соответствующий поток RTSP как часть ответа GET.

Странные вещи (если это не так странно) заключается в том, что, например, он работает с Squid, но не если вы используете любой из портов 3128 или 8080! Так или иначе, клиент использует порт, к которому он подключается, чтобы принять решение о порядке запросов или когда запрос должен быть отменен, но в любом случае, как это трудно поверить, он работает с прокси-портом 9090, 3129, 8081, но не с 3128 или 8080.

Обновление №2: Here является источником RealPlayer с объяснением описанного выше поведения. Тем не менее, нет решения.

Обновление № 3: ОК, в свете вышеизложенного, волшебное значение 48 02 02 00 ясно: 48 == 'h' для HTTP_RESPONSE, следующее 02 - это длина следующих данных, следующий 02 называется POST_NOT_RECEIVED (это означает, что запрос POST не дошел до сервера в течение секунды от соответствующего запроса GET).

Обновление № 4: Это поведение (то есть POST-запросы с огромным контентом) также характерно для ActiveX, используемого WebEx (и, возможно, для многих других веб-приложений, которым необходим открытый канал для сервера).

+0

Действительно ли ответ HTTP-сервера HTTP 200 OK ?! Мой сервер работал так же, как ваш, но RealPlayer прекратил отвечать после открытия GET и POST-соединений. Затем я добавил в тело ответ 48 02 00 00 и атрибут Content-Length: 4, и он сработал ... Возможно, вам нужно изменить ответ HTTP OK и отправить его после получения POST-соединения, а не до этого. – Cipi 2010-03-10 13:16:46

ответ

0
  1. Посмотрите, может ли выдача одного и того же запроса, но в обход прокси (например, повтор запроса, который вы отправили выше, с использованием Netcat), приводит к передаче более четырех байтов в тело ответа.
  2. Посмотрите, какие TCP-пакеты получает прокси-сервер, например, путем прослушивания трафика TCP на компьютере, на котором запущен прокси-сервер, скажем, с помощью Wireshark.
3

Во-первых, вы можете прочитать:

http://developer.apple.com/quicktime/icefloe/dispatch028.html

Во-вторых, HTTP запросы (как GET и POST) должны быть отформатированы так, что они получают проксированном должным образом. Я видел прокси-серверы, которые настаивают на кешировании слишком большого количества запроса POST, не позволяя ему добраться до сервера. Эти прокси-серверы ошибочны, но вы ничего не можете с этим поделать, и мне не удалось обойти эту проблему. В основном я видел это с антивирусным программным обеспечением, которое пытается прозрачно проксировать запросы POST, поступающие из браузера, чтобы отсканировать их для получения личной информации, такой как номера социального страхования. Возможно, вы столкнулись с той же проблемой.

Вы случайно используете антивирус McAfee?

Кроме того, похоже, что Real изобрел свой собственный способ сделать то же самое, но базовый дизайн очень похож - GET для нисходящей линии связи, POST для восходящего потока, с некоторым волшебным печеньем (в этом случае GUID), чтобы связать их вместе на сервере. В любом случае, POST должен попасть на сервер, и в вашем случае кажется, что нет.

Кстати, поскольку проблема связана с тем, что запрос POST не проходит через прокси-сервер, как насчет отправки этого запроса в дополнение к GET?

Смежные вопросы