icecast relay и редиректы

Сервер icecast может использоваться не только для организации вещания новых сетевых медиапотоков, но и для ретрансляции уже существующих. Источник исходного потока при этом может являться распределенной структурой других icecast-подобных серверов, в которых для распределения нагрузки на головном сервере может использоваться простой http-редирект (код 302) на дополнительные узлы.

Хотя relay-функциональность icecast и позволяет разбирать этот код и реагировать на него соответствующим образом, работает это не всегда.

Можно столкнуться со следующей ситуацией: головной source-сервер перегружен и выдает редиректы на дополнительные серверы, при проверке браузером все корректно, но наш icecast-ретранслятор их будто “не замечает” и выдает клиентам ошибку 404. В логах нашего icecast’а при этом можно увидеть следующие записи:

[2015-09-25  10:58:40] INFO slave/start_relay_stream Starting relayed source at mountpoint "/<mountname>"
[2015-09-25  10:58:40] INFO slave/open_relay_connection connecting to <main.source>:80
[2015-09-25  10:58:40] INFO slave/open_relay_connection redirect received HTTP://<fallback.source>

После этого клиенту выдается ошибка 404 и более ничего содержательного в лог не попадает. Так в чем же дело?

В исходном коде icecast можно найти следующие строки:

            ICECAST_LOG_INFO("redirect received %s", uri);
            if (strncmp (uri, "http://", 7) != 0)
                break;

Так выясняется, что если полученная ссылка из 302-го редиректа не начинается на “http://” (в НИЖНЕМ регистре!), то наш icecast с ней не будет делать вообще ничего и сделает вид, что никакого редиректа не было. А как видно из лога, наш источник рассылает редиректы, начинающиеся на HTTP:// в верхнем регистре.

Очевидно, надо научить icecast не обращать внимание на разницу регистров в протоколе. Это можно сделать разными способами, оптимальность и красота которых зависит от качества вашего владения кунг-фу Си. Можно, например, сделать как-то так:

--- icecast-2.4.2/src/slave.c   2015-04-08 11:06:13.000000000 +0300
+++ icecast-2.4.2-mod/src/slave.c       2015-09-25 10:55:29.495738535 +0300
@@ -238,13 +238,19 @@
         if (strcmp (httpp_getvar (parser, HTTPP_VAR_ERROR_CODE), "302") == 0)
         {
             /* better retry the connection again but with different details */
-            const char *uri, *mountpoint;
-            int len;
+            const char *uri, *mountpoint, *proc = "http://";
+            int i, len;

             uri = httpp_getvar (parser, "location");
+
             ICECAST_LOG_INFO("redirect received %s", uri);
-            if (strncmp (uri, "http://", 7) != 0)
-                break;
+            for (i = 0; i < 7 && uri[i]; i++) {
+                if ((tolower(uri[i]) - tolower(proc[i])) != 0) {
+                    i = 10;
+                    break;
+                }
+            }
+            if (i == 10) break;
             uri += 7;
             mountpoint = strchr (uri, '/');
             free (mount);

Пересобираем, подключаемся, смотрим лог:

[2015-09-25  11:08:40] INFO slave/start_relay_stream Starting relayed source at mountpoint "/<mountname>"
[2015-09-25  11:08:40] INFO slave/open_relay_connection connecting to <main.source>:80
[2015-09-25  11:08:40] INFO slave/open_relay_connection redirect received HTTP://<fallback.source>
[2015-09-25  11:08:40] INFO slave/open_relay_connection connecting to <fallback.source>:80
[2015-09-25  11:08:40] WARN format/format_get_type Unsupported or legacy stream type: "audio/mpeg". Falling back to generic minimal handler for best effort.
[2015-09-25  11:08:40] INFO source/source_main listener count on /<mountname> now 1

И все работает.

This entry was posted in Сеть и интернет and tagged , , . Bookmark the permalink.

One Response to icecast relay и редиректы

  1. The slave will also periodically check the master server to see if any new mountpoints have attached and if so will relay those as well. In this case, the slave server is configured with a server IP, port and mount and only the mountpoint specified is relayed.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>