ext/soup/gstsouphttpsrc.*: Try to resume on server disconnect. Fixes bug #522134.

Original commit message from CVS:
Patch by: Wouter Cloetens <wouter at mind dot be>
* ext/soup/gstsouphttpsrc.c: (gst_soup_http_src_init),
(gst_soup_http_src_finished_cb), (gst_soup_http_src_response_cb),
(gst_soup_http_src_build_message), (gst_soup_http_src_create):
* ext/soup/gstsouphttpsrc.h:
Try to resume on server disconnect. Fixes bug #522134.
This commit is contained in:
Wouter Cloetens 2008-03-13 09:45:09 +00:00 committed by Sebastian Dröge
parent fd1c1295dc
commit 812b60aa19
2 changed files with 69 additions and 39 deletions

View file

@ -155,6 +155,7 @@ static gboolean gst_soup_http_src_set_proxy (GstSoupHTTPSrc * src,
static char *gst_soup_http_src_unicodify (const char *str); static char *gst_soup_http_src_unicodify (const char *str);
static gboolean gst_soup_http_src_build_message (GstSoupHTTPSrc * src);
static void gst_soup_http_src_cancel_message (GstSoupHTTPSrc * src); static void gst_soup_http_src_cancel_message (GstSoupHTTPSrc * src);
static void gst_soup_http_src_queue_message (GstSoupHTTPSrc * src); static void gst_soup_http_src_queue_message (GstSoupHTTPSrc * src);
static gboolean gst_soup_http_src_add_range_header (GstSoupHTTPSrc * src, static gboolean gst_soup_http_src_add_range_header (GstSoupHTTPSrc * src,
@ -307,6 +308,7 @@ gst_soup_http_src_init (GstSoupHTTPSrc * src, GstSoupHTTPSrcClass * g_class)
src->session = NULL; src->session = NULL;
src->msg = NULL; src->msg = NULL;
src->interrupted = FALSE; src->interrupted = FALSE;
src->retry = FALSE;
src->have_size = FALSE; src->have_size = FALSE;
src->seekable = TRUE; src->seekable = TRUE;
src->read_position = 0; src->read_position = 0;
@ -663,13 +665,19 @@ gst_soup_http_src_finished_cb (SoupMessage * msg, GstSoupHTTPSrc * src)
return; return;
} }
GST_DEBUG_OBJECT (src, "finished"); GST_DEBUG_OBJECT (src, "finished");
if (G_UNLIKELY (src->session_io_status != src->ret = GST_FLOW_UNEXPECTED;
if (src->session_io_status == GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_RUNNING &&
src->read_position > 0) {
/* The server disconnected while streaming. Reconnect and seeking to the
* last location. */
src->retry = TRUE;
src->ret = GST_FLOW_CUSTOM_ERROR;
} else if (G_UNLIKELY (src->session_io_status !=
GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_RUNNING)) { GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_RUNNING)) {
GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND,
("%s", msg->reason_phrase), ("%s", msg->reason_phrase),
("libsoup status code %d", msg->status_code)); ("libsoup status code %d", msg->status_code));
} }
src->ret = GST_FLOW_UNEXPECTED;
if (src->loop) if (src->loop)
g_main_loop_quit (src->loop); g_main_loop_quit (src->loop);
} }
@ -791,6 +799,12 @@ gst_soup_http_src_response_cb (SoupSession * session, SoupMessage * msg,
} }
GST_DEBUG_OBJECT (src, "got response %d: %s", msg->status_code, GST_DEBUG_OBJECT (src, "got response %d: %s", msg->status_code,
msg->reason_phrase); msg->reason_phrase);
if (src->session_io_status == GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_RUNNING &&
src->read_position > 0) {
/* The server disconnected while streaming. Reconnect and seeking to the
* last location. */
src->retry = TRUE;
} else
gst_soup_http_src_parse_status (msg, src); gst_soup_http_src_parse_status (msg, src);
g_main_loop_quit (src->loop); g_main_loop_quit (src->loop);
} }
@ -842,29 +856,14 @@ gst_soup_http_src_parse_status (SoupMessage * msg, GstSoupHTTPSrc * src)
} }
} }
static GstFlowReturn static gboolean
gst_soup_http_src_create (GstPushSrc * psrc, GstBuffer ** outbuf) gst_soup_http_src_build_message (GstSoupHTTPSrc * src)
{ {
GstSoupHTTPSrc *src;
src = GST_SOUP_HTTP_SRC (psrc);
if (src->msg && (src->request_position != src->read_position)) {
if (src->session_io_status == GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_IDLE) {
gst_soup_http_src_add_range_header (src, src->request_position);
} else {
GST_DEBUG_OBJECT (src, "Seek from position %" G_GUINT64_FORMAT
" to %" G_GUINT64_FORMAT ": requeueing connection request",
src->read_position, src->request_position);
gst_soup_http_src_cancel_message (src);
}
}
if (!src->msg) {
src->msg = soup_message_new (SOUP_METHOD_GET, src->location); src->msg = soup_message_new (SOUP_METHOD_GET, src->location);
if (!src->msg) { if (!src->msg) {
GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
(NULL), ("Error parsing URL \"%s\"", src->location)); (NULL), ("Error parsing URL \"%s\"", src->location));
return GST_FLOW_ERROR; return FALSE;
} }
src->session_io_status = GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_IDLE; src->session_io_status = GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_IDLE;
soup_message_headers_append (src->msg->request_headers, "Connection", soup_message_headers_append (src->msg->request_headers, "Connection",
@ -895,7 +894,30 @@ gst_soup_http_src_create (GstPushSrc * psrc, GstBuffer ** outbuf)
soup_message_set_chunk_allocator (src->msg, soup_message_set_chunk_allocator (src->msg,
gst_soup_http_src_chunk_allocator, src, NULL); gst_soup_http_src_chunk_allocator, src, NULL);
gst_soup_http_src_add_range_header (src, src->request_position); gst_soup_http_src_add_range_header (src, src->request_position);
return TRUE;
}
static GstFlowReturn
gst_soup_http_src_create (GstPushSrc * psrc, GstBuffer ** outbuf)
{
GstSoupHTTPSrc *src;
src = GST_SOUP_HTTP_SRC (psrc);
if (src->msg && (src->request_position != src->read_position)) {
if (src->session_io_status == GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_IDLE) {
gst_soup_http_src_add_range_header (src, src->request_position);
} else {
GST_DEBUG_OBJECT (src, "Seek from position %" G_GUINT64_FORMAT
" to %" G_GUINT64_FORMAT ": requeueing connection request",
src->read_position, src->request_position);
gst_soup_http_src_cancel_message (src);
} }
}
if (!src->msg)
if (!gst_soup_http_src_build_message (src))
return GST_FLOW_ERROR;
src->ret = GST_FLOW_CUSTOM_ERROR; src->ret = GST_FLOW_CUSTOM_ERROR;
src->outbuf = outbuf; src->outbuf = outbuf;
@ -904,6 +926,13 @@ gst_soup_http_src_create (GstPushSrc * psrc, GstBuffer ** outbuf)
gst_soup_http_src_cancel_message (src); gst_soup_http_src_cancel_message (src);
break; break;
} }
if (src->retry) {
GST_DEBUG_OBJECT (src, "Reconnecting");
if (!gst_soup_http_src_build_message (src))
return GST_FLOW_ERROR;
src->retry = FALSE;
continue;
}
if (!src->msg) { if (!src->msg) {
GST_DEBUG_OBJECT (src, "EOS reached"); GST_DEBUG_OBJECT (src, "EOS reached");
break; break;

View file

@ -61,6 +61,7 @@ struct _GstSoupHTTPSrc {
GstFlowReturn ret; /* Return code from callback. */ GstFlowReturn ret; /* Return code from callback. */
GstBuffer **outbuf; /* Return buffer allocated by callback. */ GstBuffer **outbuf; /* Return buffer allocated by callback. */
gboolean interrupted; /* Signal unlock(). */ gboolean interrupted; /* Signal unlock(). */
gboolean retry; /* Should attempt to reconnect. */
gboolean have_size; /* Received and parsed Content-Length gboolean have_size; /* Received and parsed Content-Length
header. */ header. */