souphttpsrc: Handle non-UTF8 headers and error reasons more gracefully
Especially don't put them into GstStructures in one way or another, just ignore them or error out cleanly depending on the importance of their content.
This commit is contained in:
parent
d0f608f60b
commit
37f991f06e
@ -988,6 +988,9 @@ insert_http_header (const gchar * name, const gchar * value, gpointer user_data)
|
|||||||
GstStructure *headers = user_data;
|
GstStructure *headers = user_data;
|
||||||
const GValue *gv;
|
const GValue *gv;
|
||||||
|
|
||||||
|
if (!g_utf8_validate (name, -1, NULL) || !g_utf8_validate (value, -1, NULL))
|
||||||
|
return;
|
||||||
|
|
||||||
gv = gst_structure_get_value (headers, name);
|
gv = gst_structure_get_value (headers, name);
|
||||||
if (gv && GST_VALUE_HOLDS_ARRAY (gv)) {
|
if (gv && GST_VALUE_HOLDS_ARRAY (gv)) {
|
||||||
GValue v = G_VALUE_INIT;
|
GValue v = G_VALUE_INIT;
|
||||||
@ -1035,14 +1038,31 @@ gst_soup_http_src_got_headers (GstSoupHTTPSrc * src, SoupMessage * msg)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (src->automatic_redirect && SOUP_STATUS_IS_REDIRECTION (msg->status_code)) {
|
if (src->automatic_redirect && SOUP_STATUS_IS_REDIRECTION (msg->status_code)) {
|
||||||
src->redirection_uri = g_strdup (soup_message_headers_get_one
|
const gchar *location;
|
||||||
(msg->response_headers, "Location"));
|
|
||||||
|
location = soup_message_headers_get_one (msg->response_headers, "Location");
|
||||||
|
|
||||||
|
if (location) {
|
||||||
|
if (!g_utf8_validate (location, -1, NULL)) {
|
||||||
|
GST_ELEMENT_ERROR_WITH_DETAILS (src, RESOURCE, SEEK,
|
||||||
|
(_("Corrupted HTTP response.")),
|
||||||
|
("Location header is not valid UTF-8"),
|
||||||
|
("http-status-code", G_TYPE_UINT, msg->status_code,
|
||||||
|
"http-redirection-uri", G_TYPE_STRING,
|
||||||
|
GST_STR_NULL (src->redirection_uri), NULL));
|
||||||
|
src->ret = GST_FLOW_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
src->redirection_uri = g_strdup (location);
|
||||||
|
|
||||||
src->redirection_permanent =
|
src->redirection_permanent =
|
||||||
(msg->status_code == SOUP_STATUS_MOVED_PERMANENTLY);
|
(msg->status_code == SOUP_STATUS_MOVED_PERMANENTLY);
|
||||||
GST_DEBUG_OBJECT (src, "%u redirect to \"%s\" (permanent %d)",
|
GST_DEBUG_OBJECT (src, "%u redirect to \"%s\" (permanent %d)",
|
||||||
msg->status_code, src->redirection_uri, src->redirection_permanent);
|
msg->status_code, src->redirection_uri, src->redirection_permanent);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (msg->status_code == SOUP_STATUS_UNAUTHORIZED) {
|
if (msg->status_code == SOUP_STATUS_UNAUTHORIZED) {
|
||||||
/* force an error */
|
/* force an error */
|
||||||
@ -1110,9 +1130,13 @@ gst_soup_http_src_got_headers (GstSoupHTTPSrc * src, SoupMessage * msg)
|
|||||||
if ((value =
|
if ((value =
|
||||||
soup_message_headers_get_one (msg->response_headers,
|
soup_message_headers_get_one (msg->response_headers,
|
||||||
"icy-metaint")) != NULL) {
|
"icy-metaint")) != NULL) {
|
||||||
gint icy_metaint = atoi (value);
|
gint icy_metaint;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (src, "icy-metaint: %s (parsed: %d)", value, icy_metaint);
|
if (g_utf8_validate (value, -1, NULL)) {
|
||||||
|
icy_metaint = atoi (value);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (src, "icy-metaint: %s (parsed: %d)", value,
|
||||||
|
icy_metaint);
|
||||||
if (icy_metaint > 0) {
|
if (icy_metaint > 0) {
|
||||||
if (src->src_caps)
|
if (src->src_caps)
|
||||||
gst_caps_unref (src->src_caps);
|
gst_caps_unref (src->src_caps);
|
||||||
@ -1123,33 +1147,53 @@ gst_soup_http_src_got_headers (GstSoupHTTPSrc * src, SoupMessage * msg)
|
|||||||
gst_base_src_set_caps (GST_BASE_SRC (src), src->src_caps);
|
gst_base_src_set_caps (GST_BASE_SRC (src), src->src_caps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if ((value =
|
if ((value =
|
||||||
soup_message_headers_get_content_type (msg->response_headers,
|
soup_message_headers_get_content_type (msg->response_headers,
|
||||||
¶ms)) != NULL) {
|
¶ms)) != NULL) {
|
||||||
GST_DEBUG_OBJECT (src, "Content-Type: %s", value);
|
if (!g_utf8_validate (value, -1, NULL)) {
|
||||||
if (g_ascii_strcasecmp (value, "audio/L16") == 0) {
|
GST_WARNING_OBJECT (src, "Content-Type is invalid UTF-8");
|
||||||
|
} else if (g_ascii_strcasecmp (value, "audio/L16") == 0) {
|
||||||
gint channels = 2;
|
gint channels = 2;
|
||||||
gint rate = 44100;
|
gint rate = 44100;
|
||||||
char *param;
|
char *param;
|
||||||
|
|
||||||
if (src->src_caps)
|
GST_DEBUG_OBJECT (src, "Content-Type: %s", value);
|
||||||
|
|
||||||
|
if (src->src_caps) {
|
||||||
gst_caps_unref (src->src_caps);
|
gst_caps_unref (src->src_caps);
|
||||||
|
src->src_caps = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
param = g_hash_table_lookup (params, "channels");
|
param = g_hash_table_lookup (params, "channels");
|
||||||
if (param != NULL)
|
if (param != NULL) {
|
||||||
channels = atol (param);
|
guint64 val = g_ascii_strtoull (param, NULL, 10);
|
||||||
|
if (val < 64)
|
||||||
|
channels = val;
|
||||||
|
else
|
||||||
|
channels = 0;
|
||||||
|
}
|
||||||
|
|
||||||
param = g_hash_table_lookup (params, "rate");
|
param = g_hash_table_lookup (params, "rate");
|
||||||
if (param != NULL)
|
if (param != NULL) {
|
||||||
rate = atol (param);
|
guint64 val = g_ascii_strtoull (param, NULL, 10);
|
||||||
|
if (val < G_MAXINT)
|
||||||
|
rate = val;
|
||||||
|
else
|
||||||
|
rate = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rate > 0 && channels > 0) {
|
||||||
src->src_caps = gst_caps_new_simple ("audio/x-unaligned-raw",
|
src->src_caps = gst_caps_new_simple ("audio/x-unaligned-raw",
|
||||||
"format", G_TYPE_STRING, "S16BE",
|
"format", G_TYPE_STRING, "S16BE",
|
||||||
"layout", G_TYPE_STRING, "interleaved",
|
"layout", G_TYPE_STRING, "interleaved",
|
||||||
"channels", G_TYPE_INT, channels, "rate", G_TYPE_INT, rate, NULL);
|
"channels", G_TYPE_INT, channels, "rate", G_TYPE_INT, rate, NULL);
|
||||||
|
|
||||||
gst_base_src_set_caps (GST_BASE_SRC (src), src->src_caps);
|
gst_base_src_set_caps (GST_BASE_SRC (src), src->src_caps);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
GST_DEBUG_OBJECT (src, "Content-Type: %s", value);
|
||||||
|
|
||||||
/* Set the Content-Type field on the caps */
|
/* Set the Content-Type field on the caps */
|
||||||
if (src->src_caps) {
|
if (src->src_caps) {
|
||||||
src->src_caps = gst_caps_make_writable (src->src_caps);
|
src->src_caps = gst_caps_make_writable (src->src_caps);
|
||||||
@ -1166,6 +1210,7 @@ gst_soup_http_src_got_headers (GstSoupHTTPSrc * src, SoupMessage * msg)
|
|||||||
if ((value =
|
if ((value =
|
||||||
soup_message_headers_get_one (msg->response_headers,
|
soup_message_headers_get_one (msg->response_headers,
|
||||||
"icy-name")) != NULL) {
|
"icy-name")) != NULL) {
|
||||||
|
if (g_utf8_validate (value, -1, NULL)) {
|
||||||
g_free (src->iradio_name);
|
g_free (src->iradio_name);
|
||||||
src->iradio_name = gst_soup_http_src_unicodify (value);
|
src->iradio_name = gst_soup_http_src_unicodify (value);
|
||||||
if (src->iradio_name) {
|
if (src->iradio_name) {
|
||||||
@ -1173,9 +1218,11 @@ gst_soup_http_src_got_headers (GstSoupHTTPSrc * src, SoupMessage * msg)
|
|||||||
src->iradio_name, NULL);
|
src->iradio_name, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if ((value =
|
if ((value =
|
||||||
soup_message_headers_get_one (msg->response_headers,
|
soup_message_headers_get_one (msg->response_headers,
|
||||||
"icy-genre")) != NULL) {
|
"icy-genre")) != NULL) {
|
||||||
|
if (g_utf8_validate (value, -1, NULL)) {
|
||||||
g_free (src->iradio_genre);
|
g_free (src->iradio_genre);
|
||||||
src->iradio_genre = gst_soup_http_src_unicodify (value);
|
src->iradio_genre = gst_soup_http_src_unicodify (value);
|
||||||
if (src->iradio_genre) {
|
if (src->iradio_genre) {
|
||||||
@ -1183,8 +1230,10 @@ gst_soup_http_src_got_headers (GstSoupHTTPSrc * src, SoupMessage * msg)
|
|||||||
src->iradio_genre, NULL);
|
src->iradio_genre, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if ((value = soup_message_headers_get_one (msg->response_headers, "icy-url"))
|
if ((value = soup_message_headers_get_one (msg->response_headers, "icy-url"))
|
||||||
!= NULL) {
|
!= NULL) {
|
||||||
|
if (g_utf8_validate (value, -1, NULL)) {
|
||||||
g_free (src->iradio_url);
|
g_free (src->iradio_url);
|
||||||
src->iradio_url = gst_soup_http_src_unicodify (value);
|
src->iradio_url = gst_soup_http_src_unicodify (value);
|
||||||
if (src->iradio_url) {
|
if (src->iradio_url) {
|
||||||
@ -1192,6 +1241,7 @@ gst_soup_http_src_got_headers (GstSoupHTTPSrc * src, SoupMessage * msg)
|
|||||||
src->iradio_url, NULL);
|
src->iradio_url, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!gst_tag_list_is_empty (tag_list)) {
|
if (!gst_tag_list_is_empty (tag_list)) {
|
||||||
GST_DEBUG_OBJECT (src,
|
GST_DEBUG_OBJECT (src,
|
||||||
"calling gst_element_found_tags with %" GST_PTR_FORMAT, tag_list);
|
"calling gst_element_found_tags with %" GST_PTR_FORMAT, tag_list);
|
||||||
@ -1298,6 +1348,14 @@ gst_soup_http_src_parse_status (SoupMessage * msg, GstSoupHTTPSrc * src)
|
|||||||
} else if (SOUP_STATUS_IS_CLIENT_ERROR (msg->status_code) ||
|
} else if (SOUP_STATUS_IS_CLIENT_ERROR (msg->status_code) ||
|
||||||
SOUP_STATUS_IS_REDIRECTION (msg->status_code) ||
|
SOUP_STATUS_IS_REDIRECTION (msg->status_code) ||
|
||||||
SOUP_STATUS_IS_SERVER_ERROR (msg->status_code)) {
|
SOUP_STATUS_IS_SERVER_ERROR (msg->status_code)) {
|
||||||
|
const gchar *reason_phrase;
|
||||||
|
|
||||||
|
reason_phrase = msg->reason_phrase;
|
||||||
|
if (reason_phrase && !g_utf8_validate (reason_phrase, -1, NULL)) {
|
||||||
|
GST_ERROR_OBJECT (src, "Invalid UTF-8 in reason");
|
||||||
|
reason_phrase = "(invalid)";
|
||||||
|
}
|
||||||
|
|
||||||
/* Report HTTP error. */
|
/* Report HTTP error. */
|
||||||
|
|
||||||
/* when content_size is unknown and we have just finished receiving
|
/* when content_size is unknown and we have just finished receiving
|
||||||
@ -1316,8 +1374,8 @@ gst_soup_http_src_parse_status (SoupMessage * msg, GstSoupHTTPSrc * src)
|
|||||||
*/
|
*/
|
||||||
if (msg->status_code == SOUP_STATUS_NOT_FOUND) {
|
if (msg->status_code == SOUP_STATUS_NOT_FOUND) {
|
||||||
GST_ELEMENT_ERROR_WITH_DETAILS (src, RESOURCE, NOT_FOUND,
|
GST_ELEMENT_ERROR_WITH_DETAILS (src, RESOURCE, NOT_FOUND,
|
||||||
("%s", msg->reason_phrase),
|
("%s", reason_phrase),
|
||||||
("%s (%d), URL: %s, Redirect to: %s", msg->reason_phrase,
|
("%s (%d), URL: %s, Redirect to: %s", reason_phrase,
|
||||||
msg->status_code, src->location,
|
msg->status_code, src->location,
|
||||||
GST_STR_NULL (src->redirection_uri)),
|
GST_STR_NULL (src->redirection_uri)),
|
||||||
("http-status-code", G_TYPE_UINT, msg->status_code,
|
("http-status-code", G_TYPE_UINT, msg->status_code,
|
||||||
@ -1328,15 +1386,15 @@ gst_soup_http_src_parse_status (SoupMessage * msg, GstSoupHTTPSrc * src)
|
|||||||
|| msg->status_code == SOUP_STATUS_FORBIDDEN
|
|| msg->status_code == SOUP_STATUS_FORBIDDEN
|
||||||
|| msg->status_code == SOUP_STATUS_PROXY_AUTHENTICATION_REQUIRED) {
|
|| msg->status_code == SOUP_STATUS_PROXY_AUTHENTICATION_REQUIRED) {
|
||||||
GST_ELEMENT_ERROR_WITH_DETAILS (src, RESOURCE, NOT_AUTHORIZED, ("%s",
|
GST_ELEMENT_ERROR_WITH_DETAILS (src, RESOURCE, NOT_AUTHORIZED, ("%s",
|
||||||
msg->reason_phrase), ("%s (%d), URL: %s, Redirect to: %s",
|
reason_phrase), ("%s (%d), URL: %s, Redirect to: %s",
|
||||||
msg->reason_phrase, msg->status_code, src->location,
|
reason_phrase, msg->status_code, src->location,
|
||||||
GST_STR_NULL (src->redirection_uri)), ("http-status-code",
|
GST_STR_NULL (src->redirection_uri)), ("http-status-code",
|
||||||
G_TYPE_UINT, msg->status_code, "http-redirect-uri", G_TYPE_STRING,
|
G_TYPE_UINT, msg->status_code, "http-redirect-uri", G_TYPE_STRING,
|
||||||
GST_STR_NULL (src->redirection_uri), NULL));
|
GST_STR_NULL (src->redirection_uri), NULL));
|
||||||
} else {
|
} else {
|
||||||
GST_ELEMENT_ERROR_WITH_DETAILS (src, RESOURCE, OPEN_READ,
|
GST_ELEMENT_ERROR_WITH_DETAILS (src, RESOURCE, OPEN_READ,
|
||||||
("%s", msg->reason_phrase),
|
("%s", reason_phrase),
|
||||||
("%s (%d), URL: %s, Redirect to: %s", msg->reason_phrase,
|
("%s (%d), URL: %s, Redirect to: %s", reason_phrase,
|
||||||
msg->status_code, src->location,
|
msg->status_code, src->location,
|
||||||
GST_STR_NULL (src->redirection_uri)),
|
GST_STR_NULL (src->redirection_uri)),
|
||||||
("http-status-code", G_TYPE_UINT, msg->status_code,
|
("http-status-code", G_TYPE_UINT, msg->status_code,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user