mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2024-12-04 14:46:30 -05:00
- fixed alot of yp logic. timeouts now work properly so the tolerance of
the unavailability of yp servers is much much better now. - new icecast config option <yp-url-timeout> to specify the timeout - url encoding is now fixed so that the yp data is formatted much nicer (and is correct :)) - added url encoding for some fields that were not url-encoded - modified util_dict_urlencode() to not url-encode the key (still does the value) - new curl option (CURLOPT_NOSIGNAL) which prevents curl from using signals when timeouts are hit. This new option needs curl 7.10 at least. svn path=/trunk/icecast/; revision=4603
This commit is contained in:
parent
801ab0bc3e
commit
2c2576ed4e
94
src/source.c
94
src/source.c
@ -298,13 +298,9 @@ void *source_main(void *arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i=0;i<source->num_yp_directories;i++) {
|
for (i=0;i<source->num_yp_directories;i++) {
|
||||||
if (source->ypdata[i]->server_type) {
|
_add_yp_info(source, "server_type",
|
||||||
free(source->ypdata[i]->server_type);
|
source->format->format_description,
|
||||||
}
|
YP_SERVER_TYPE);
|
||||||
source->ypdata[i]->server_type = malloc(
|
|
||||||
strlen(source->format->format_description) + 1);
|
|
||||||
strcpy(source->ypdata[i]->server_type,
|
|
||||||
source->format->format_description);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0;i<source->num_yp_directories;i++) {
|
for (i=0;i<source->num_yp_directories;i++) {
|
||||||
@ -352,35 +348,26 @@ void *source_main(void *arg)
|
|||||||
if (current_time > (source->ypdata[i]->yp_last_touch +
|
if (current_time > (source->ypdata[i]->yp_last_touch +
|
||||||
source->ypdata[i]->yp_touch_interval)) {
|
source->ypdata[i]->yp_touch_interval)) {
|
||||||
current_song[0] = 0;
|
current_song[0] = 0;
|
||||||
if (stats_get_value(source->mount, "artist")) {
|
if ((s = stats_get_value(source->mount, "artist"))) {
|
||||||
strncat(current_song,
|
strncat(current_song, s,
|
||||||
stats_get_value(source->mount, "artist"),
|
|
||||||
sizeof(current_song) - 1);
|
sizeof(current_song) - 1);
|
||||||
if (strlen(current_song) + 4 < sizeof(current_song)) {
|
if (strlen(current_song) + 4 <
|
||||||
|
sizeof(current_song))
|
||||||
|
{
|
||||||
strncat(current_song, " - ", 3);
|
strncat(current_song, " - ", 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (stats_get_value(source->mount, "title")) {
|
if (s = stats_get_value(source->mount, "title")) {
|
||||||
if (strlen(current_song) +
|
if (strlen(current_song) + strlen(s)
|
||||||
strlen(stats_get_value(source->mount, "title"))
|
|
||||||
< sizeof(current_song) -1)
|
< sizeof(current_song) -1)
|
||||||
{
|
{
|
||||||
strncat(current_song,
|
strncat(current_song,
|
||||||
stats_get_value(source->mount, "title"),
|
s,
|
||||||
sizeof(current_song) - 1 -
|
sizeof(current_song) - 1 -
|
||||||
strlen(current_song));
|
strlen(current_song));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_add_yp_info(source, "current_song", current_song, YP_CURRENT_SONG);
|
||||||
if (source->ypdata[i]->current_song) {
|
|
||||||
free(source->ypdata[i]->current_song);
|
|
||||||
source->ypdata[i]->current_song = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
source->ypdata[i]->current_song =
|
|
||||||
malloc(strlen(current_song) + 1);
|
|
||||||
strcpy(source->ypdata[i]->current_song, current_song);
|
|
||||||
|
|
||||||
thread_create("YP Touch Thread", yp_touch_thread,
|
thread_create("YP Touch Thread", yp_touch_thread,
|
||||||
(void *)source, THREAD_DETACHED);
|
(void *)source, THREAD_DETACHED);
|
||||||
}
|
}
|
||||||
@ -743,6 +730,7 @@ static int _parse_audio_info(source_t *source, char *s)
|
|||||||
static void _add_yp_info(source_t *source, char *stat_name,
|
static void _add_yp_info(source_t *source, char *stat_name,
|
||||||
void *info, int type)
|
void *info, int type)
|
||||||
{
|
{
|
||||||
|
char *escaped;
|
||||||
int i;
|
int i;
|
||||||
if (!info) {
|
if (!info) {
|
||||||
return;
|
return;
|
||||||
@ -750,49 +738,69 @@ static void _add_yp_info(source_t *source, char *stat_name,
|
|||||||
for (i=0;i<source->num_yp_directories;i++) {
|
for (i=0;i<source->num_yp_directories;i++) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case YP_SERVER_NAME:
|
case YP_SERVER_NAME:
|
||||||
|
escaped = util_url_escape(info);
|
||||||
|
if (escaped) {
|
||||||
if (source->ypdata[i]->server_name) {
|
if (source->ypdata[i]->server_name) {
|
||||||
free(source->ypdata[i]->server_name);
|
free(source->ypdata[i]->server_name);
|
||||||
}
|
}
|
||||||
source->ypdata[i]->server_name =
|
source->ypdata[i]->server_name =
|
||||||
malloc(strlen((char *)info) +1);
|
malloc(strlen((char *)escaped) +1);
|
||||||
strcpy(source->ypdata[i]->server_name, (char *)info);
|
strcpy(source->ypdata[i]->server_name, (char *)escaped);
|
||||||
stats_event(source->mount, stat_name, (char *)info);
|
stats_event(source->mount, stat_name, (char *)info);
|
||||||
|
free(escaped);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case YP_SERVER_DESC:
|
case YP_SERVER_DESC:
|
||||||
|
escaped = util_url_escape(info);
|
||||||
|
if (escaped) {
|
||||||
if (source->ypdata[i]->server_desc) {
|
if (source->ypdata[i]->server_desc) {
|
||||||
free(source->ypdata[i]->server_desc);
|
free(source->ypdata[i]->server_desc);
|
||||||
}
|
}
|
||||||
source->ypdata[i]->server_desc =
|
source->ypdata[i]->server_desc =
|
||||||
malloc(strlen((char *)info) +1);
|
malloc(strlen((char *)escaped) +1);
|
||||||
strcpy(source->ypdata[i]->server_desc, (char *)info);
|
strcpy(source->ypdata[i]->server_desc, (char *)escaped);
|
||||||
stats_event(source->mount, stat_name, (char *)info);
|
stats_event(source->mount, stat_name, (char *)info);
|
||||||
|
free(escaped);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case YP_SERVER_GENRE:
|
case YP_SERVER_GENRE:
|
||||||
|
escaped = util_url_escape(info);
|
||||||
|
if (escaped) {
|
||||||
if (source->ypdata[i]->server_genre) {
|
if (source->ypdata[i]->server_genre) {
|
||||||
free(source->ypdata[i]->server_genre);
|
free(source->ypdata[i]->server_genre);
|
||||||
}
|
}
|
||||||
source->ypdata[i]->server_genre =
|
source->ypdata[i]->server_genre =
|
||||||
malloc(strlen((char *)info) +1);
|
malloc(strlen((char *)escaped) +1);
|
||||||
strcpy(source->ypdata[i]->server_genre, (char *)info);
|
strcpy(source->ypdata[i]->server_genre, (char *)escaped);
|
||||||
stats_event(source->mount, stat_name, (char *)info);
|
stats_event(source->mount, stat_name, (char *)info);
|
||||||
|
free(escaped);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case YP_SERVER_URL:
|
case YP_SERVER_URL:
|
||||||
|
escaped = util_url_escape(info);
|
||||||
|
if (escaped) {
|
||||||
if (source->ypdata[i]->server_url) {
|
if (source->ypdata[i]->server_url) {
|
||||||
free(source->ypdata[i]->server_url);
|
free(source->ypdata[i]->server_url);
|
||||||
}
|
}
|
||||||
source->ypdata[i]->server_url =
|
source->ypdata[i]->server_url =
|
||||||
malloc(strlen((char *)info) +1);
|
malloc(strlen((char *)escaped) +1);
|
||||||
strcpy(source->ypdata[i]->server_url, (char *)info);
|
strcpy(source->ypdata[i]->server_url, (char *)escaped);
|
||||||
stats_event(source->mount, stat_name, (char *)info);
|
stats_event(source->mount, stat_name, (char *)info);
|
||||||
|
free(escaped);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case YP_BITRATE:
|
case YP_BITRATE:
|
||||||
|
escaped = util_url_escape(info);
|
||||||
|
if (escaped) {
|
||||||
if (source->ypdata[i]->bitrate) {
|
if (source->ypdata[i]->bitrate) {
|
||||||
free(source->ypdata[i]->bitrate);
|
free(source->ypdata[i]->bitrate);
|
||||||
}
|
}
|
||||||
source->ypdata[i]->bitrate =
|
source->ypdata[i]->bitrate =
|
||||||
malloc(strlen((char *)info) +1);
|
malloc(strlen((char *)escaped) +1);
|
||||||
strcpy(source->ypdata[i]->bitrate, (char *)info);
|
strcpy(source->ypdata[i]->bitrate, (char *)escaped);
|
||||||
stats_event(source->mount, stat_name, (char *)info);
|
stats_event(source->mount, stat_name, (char *)info);
|
||||||
|
free(escaped);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case YP_AUDIO_INFO:
|
case YP_AUDIO_INFO:
|
||||||
if (source->ypdata[i]->audio_info) {
|
if (source->ypdata[i]->audio_info) {
|
||||||
@ -803,21 +811,29 @@ static void _add_yp_info(source_t *source, char *stat_name,
|
|||||||
strcpy(source->ypdata[i]->audio_info, (char *)info);
|
strcpy(source->ypdata[i]->audio_info, (char *)info);
|
||||||
break;
|
break;
|
||||||
case YP_SERVER_TYPE:
|
case YP_SERVER_TYPE:
|
||||||
|
escaped = util_url_escape(info);
|
||||||
|
if (escaped) {
|
||||||
if (source->ypdata[i]->server_type) {
|
if (source->ypdata[i]->server_type) {
|
||||||
free(source->ypdata[i]->server_type);
|
free(source->ypdata[i]->server_type);
|
||||||
}
|
}
|
||||||
source->ypdata[i]->server_type =
|
source->ypdata[i]->server_type =
|
||||||
malloc(strlen((char *)info) +1);
|
malloc(strlen((char *)escaped) +1);
|
||||||
strcpy(source->ypdata[i]->server_type, (char *)info);
|
strcpy(source->ypdata[i]->server_type, (char *)escaped);
|
||||||
|
free(escaped);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case YP_CURRENT_SONG:
|
case YP_CURRENT_SONG:
|
||||||
|
escaped = util_url_escape(info);
|
||||||
|
if (escaped) {
|
||||||
if (source->ypdata[i]->current_song) {
|
if (source->ypdata[i]->current_song) {
|
||||||
free(source->ypdata[i]->current_song);
|
free(source->ypdata[i]->current_song);
|
||||||
}
|
}
|
||||||
source->ypdata[i]->current_song =
|
source->ypdata[i]->current_song =
|
||||||
malloc(strlen((char *)info) +1);
|
malloc(strlen((char *)escaped) +1);
|
||||||
strcpy(source->ypdata[i]->current_song, (char *)info);
|
strcpy(source->ypdata[i]->current_song, (char *)escaped);
|
||||||
stats_event(source->mount, stat_name, (char *)info);
|
stats_event(source->mount, stat_name, (char *)info);
|
||||||
|
free(escaped);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case YP_URL_TIMEOUT:
|
case YP_URL_TIMEOUT:
|
||||||
source->ypdata[i]->yp_url_timeout = (int)info;
|
source->ypdata[i]->yp_url_timeout = (int)info;
|
||||||
|
21
src/util.c
21
src/util.c
@ -519,8 +519,8 @@ int util_dict_set(util_dict *dict, const char *key, const char *val)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* given a dictionary, URL-encode each key and val and
|
/* given a dictionary, URL-encode each val and
|
||||||
stringify them in order as key=val&key=val... if val
|
stringify it in order as key=val&key=val... if val
|
||||||
is set, or just key&key if val is NULL.
|
is set, or just key&key if val is NULL.
|
||||||
TODO: Memory management needs overhaul. */
|
TODO: Memory management needs overhaul. */
|
||||||
char *util_dict_urlencode(util_dict *dict, char delim)
|
char *util_dict_urlencode(util_dict *dict, char delim)
|
||||||
@ -533,28 +533,19 @@ char *util_dict_urlencode(util_dict *dict, char delim)
|
|||||||
/* encode key */
|
/* encode key */
|
||||||
if (!dict->key)
|
if (!dict->key)
|
||||||
continue;
|
continue;
|
||||||
if (!(enc = util_url_escape(dict->key))) {
|
|
||||||
if (res)
|
|
||||||
free(res);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (start) {
|
if (start) {
|
||||||
if (!(res = malloc(strlen(enc) + 1))) {
|
if (!(res = malloc(strlen(dict->key) + 1))) {
|
||||||
free(enc);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
sprintf(res, "%s", enc);
|
sprintf(res, "%s", dict->key);
|
||||||
free(enc);
|
|
||||||
start = 0;
|
start = 0;
|
||||||
} else {
|
} else {
|
||||||
if (!(tmp = realloc(res, strlen(res) + strlen(enc) + 2))) {
|
if (!(tmp = realloc(res, strlen(res) + strlen(dict->key) + 2))) {
|
||||||
free(enc);
|
|
||||||
free(res);
|
free(res);
|
||||||
return NULL;
|
return NULL;
|
||||||
} else
|
} else
|
||||||
res = tmp;
|
res = tmp;
|
||||||
sprintf(res + strlen(res), "%c%s", delim, enc);
|
sprintf(res + strlen(res), "%c%s", delim, dict->key);
|
||||||
free(enc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* encode value */
|
/* encode value */
|
||||||
|
13
src/yp.c
13
src/yp.c
@ -19,16 +19,21 @@
|
|||||||
static int yp_submit_url(int curl_con, char *yp_url, char *url, char *type, int i)
|
static int yp_submit_url(int curl_con, char *yp_url, char *url, char *type, int i)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int *timeout;
|
int timeout;
|
||||||
ice_config_t *config = config_get_config();
|
ice_config_t *config = config_get_config();
|
||||||
|
|
||||||
timeout = config->yp_url_timeout + i;
|
timeout = config->yp_url_timeout[i];
|
||||||
config_release_config();
|
config_release_config();
|
||||||
|
/* If not specified, use a reasonable timeout
|
||||||
|
of 30 seconds */
|
||||||
|
if (timeout == 0) {
|
||||||
|
timeout = 30;
|
||||||
|
}
|
||||||
curl_easy_setopt(curl_get_handle(curl_con), CURLOPT_URL, yp_url);
|
curl_easy_setopt(curl_get_handle(curl_con), CURLOPT_URL, yp_url);
|
||||||
curl_easy_setopt(curl_get_handle(curl_con), CURLOPT_POSTFIELDS, url);
|
curl_easy_setopt(curl_get_handle(curl_con), CURLOPT_POSTFIELDS, url);
|
||||||
curl_easy_setopt(curl_get_handle(curl_con), CURLOPT_TIMEOUT, timeout);
|
curl_easy_setopt(curl_get_handle(curl_con), CURLOPT_TIMEOUT, timeout);
|
||||||
|
/* This is to force libcurl to not use signals for timeouts */
|
||||||
|
curl_easy_setopt(curl_get_handle(curl_con), CURLOPT_NOSIGNAL, 1);
|
||||||
/* get it! */
|
/* get it! */
|
||||||
memset(curl_get_result(curl_con), 0, sizeof(struct curl_memory_struct));
|
memset(curl_get_result(curl_con), 0, sizeof(struct curl_memory_struct));
|
||||||
memset(curl_get_header_result(curl_con), 0,
|
memset(curl_get_header_result(curl_con), 0,
|
||||||
|
Loading…
Reference in New Issue
Block a user