mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 16:50:47 +00:00
souphttpsrc: do not emit EOS when connection drops
If the pipeline is stalled for too long, souphttpsrc will block and stop fetching data from the network. This can cause the connection to drop and souphttpsrc would handle it as an EOS. This patch makes it persist and try to fetch more data until the end of the content length or until receiving an error that it is beyong limits in case the content is unknown. https://bugzilla.gnome.org/show_bug.cgi?id=683536
This commit is contained in:
parent
c65a8881f9
commit
856c07ea00
2 changed files with 30 additions and 5 deletions
|
@ -281,6 +281,7 @@ gst_soup_http_src_reset (GstSoupHTTPSrc * src)
|
||||||
src->request_position = 0;
|
src->request_position = 0;
|
||||||
src->stop_position = -1;
|
src->stop_position = -1;
|
||||||
src->content_size = 0;
|
src->content_size = 0;
|
||||||
|
src->have_body = FALSE;
|
||||||
|
|
||||||
gst_caps_replace (&src->src_caps, NULL);
|
gst_caps_replace (&src->src_caps, NULL);
|
||||||
g_free (src->iradio_name);
|
g_free (src->iradio_name);
|
||||||
|
@ -892,7 +893,7 @@ gst_soup_http_src_got_headers_cb (SoupMessage * msg, GstSoupHTTPSrc * src)
|
||||||
* don't output any data (such as an error html page), and return
|
* don't output any data (such as an error html page), and return
|
||||||
* GST_FLOW_ERROR from the create function instead of having
|
* GST_FLOW_ERROR from the create function instead of having
|
||||||
* got_chunk_cb overwrite src->ret with FLOW_OK again. */
|
* got_chunk_cb overwrite src->ret with FLOW_OK again. */
|
||||||
if (src->ret == GST_FLOW_ERROR) {
|
if (src->ret == GST_FLOW_ERROR || src->ret == GST_FLOW_EOS) {
|
||||||
gst_soup_http_src_session_pause_message (src);
|
gst_soup_http_src_session_pause_message (src);
|
||||||
|
|
||||||
if (src->loop)
|
if (src->loop)
|
||||||
|
@ -916,9 +917,14 @@ gst_soup_http_src_got_body_cb (SoupMessage * msg, GstSoupHTTPSrc * src)
|
||||||
}
|
}
|
||||||
GST_DEBUG_OBJECT (src, "got body");
|
GST_DEBUG_OBJECT (src, "got body");
|
||||||
src->ret = GST_FLOW_EOS;
|
src->ret = GST_FLOW_EOS;
|
||||||
if (src->loop)
|
src->have_body = TRUE;
|
||||||
g_main_loop_quit (src->loop);
|
|
||||||
gst_soup_http_src_session_pause_message (src);
|
/* no need to interrupt the message here, we do it on the
|
||||||
|
* finished_cb anyway if needed. And getting the body might mean
|
||||||
|
* that the connection was hang up before finished. This happens when
|
||||||
|
* the pipeline is stalled for too long (long pauses during playback).
|
||||||
|
* Best to let it continue from here and pause because it reached the
|
||||||
|
* final bytes based on content_size or received an out of range error */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Finished. Signal EOS. */
|
/* Finished. Signal EOS. */
|
||||||
|
@ -936,7 +942,8 @@ gst_soup_http_src_finished_cb (SoupMessage * msg, GstSoupHTTPSrc * src)
|
||||||
* that occurred in the QUEUEING state; i.e. before the connection setup
|
* that occurred in the QUEUEING state; i.e. before the connection setup
|
||||||
* was complete. Do nothing */
|
* was complete. Do nothing */
|
||||||
} else if (src->session_io_status ==
|
} else if (src->session_io_status ==
|
||||||
GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_RUNNING && src->read_position > 0) {
|
GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_RUNNING && src->read_position > 0 &&
|
||||||
|
(!src->have_size || src->read_position < src->content_size)) {
|
||||||
/* The server disconnected while streaming. Reconnect and seeking to the
|
/* The server disconnected while streaming. Reconnect and seeking to the
|
||||||
* last location. */
|
* last location. */
|
||||||
src->retry = TRUE;
|
src->retry = TRUE;
|
||||||
|
@ -1047,6 +1054,7 @@ gst_soup_http_src_got_chunk_cb (SoupMessage * msg, SoupBuffer * chunk,
|
||||||
GST_DEBUG_OBJECT (src, "got chunk, but not for current message");
|
GST_DEBUG_OBJECT (src, "got chunk, but not for current message");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
src->have_body = FALSE;
|
||||||
if (G_UNLIKELY (src->session_io_status !=
|
if (G_UNLIKELY (src->session_io_status !=
|
||||||
GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_RUNNING)) {
|
GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_RUNNING)) {
|
||||||
/* Probably a redirect. */
|
/* Probably a redirect. */
|
||||||
|
@ -1164,6 +1172,18 @@ gst_soup_http_src_parse_status (SoupMessage * msg, GstSoupHTTPSrc * src)
|
||||||
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)) {
|
||||||
/* Report HTTP error. */
|
/* Report HTTP error. */
|
||||||
|
|
||||||
|
/* when content_size is unknown and we have just finished receiving
|
||||||
|
* a body message, requests that go beyond the content limits will result
|
||||||
|
* in an error. Here we convert those to EOS */
|
||||||
|
if (msg->status_code == SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE &&
|
||||||
|
src->have_body && src->have_size) {
|
||||||
|
GST_DEBUG_OBJECT (src, "Requested range out of limits and received full "
|
||||||
|
"body, returning EOS");
|
||||||
|
src->ret = GST_FLOW_EOS;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* FIXME: reason_phrase is not translated and not suitable for user
|
/* FIXME: reason_phrase is not translated and not suitable for user
|
||||||
* error dialog according to libsoup documentation.
|
* error dialog according to libsoup documentation.
|
||||||
* FIXME: error code (OPEN_READ vs. READ) should depend on http status? */
|
* FIXME: error code (OPEN_READ vs. READ) should depend on http status? */
|
||||||
|
|
|
@ -78,6 +78,11 @@ struct _GstSoupHTTPSrc {
|
||||||
Range. */
|
Range. */
|
||||||
guint64 request_position; /* Seek to this position. */
|
guint64 request_position; /* Seek to this position. */
|
||||||
guint64 stop_position; /* Stop at this position. */
|
guint64 stop_position; /* Stop at this position. */
|
||||||
|
gboolean have_body; /* Indicates if it has just been signaled the
|
||||||
|
* end of the message body. This is used to
|
||||||
|
* decide if an out of range request should be
|
||||||
|
* handled as an error or EOS when the content
|
||||||
|
* size is unknown */
|
||||||
|
|
||||||
/* Shoutcast/icecast metadata extraction handling. */
|
/* Shoutcast/icecast metadata extraction handling. */
|
||||||
gboolean iradio_mode;
|
gboolean iradio_mode;
|
||||||
|
|
Loading…
Reference in a new issue