mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 09:10:36 +00:00
Allow HTTP redirect (HTTP status code 302).
Original commit message from CVS: Allow HTTP redirect (HTTP status code 302).
This commit is contained in:
parent
fac7780d02
commit
af9d0408cd
3 changed files with 178 additions and 27 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
2006-08-04 Edgard Lima <edgard.lima@indt.org.br>
|
||||||
|
|
||||||
|
Patch by: rosfran dot borges at indt dot org dot br
|
||||||
|
|
||||||
|
* ext/neon/gstneonhttpsrc.c:
|
||||||
|
* ext/neon/gstneonhttpsrc.h:
|
||||||
|
Allow HTTP redirect (HTTP status code 302).
|
||||||
|
|
||||||
2006-08-04 Zaheer Abbas Merali <zaheerabbas at merali dot org>
|
2006-08-04 Zaheer Abbas Merali <zaheerabbas at merali dot org>
|
||||||
|
|
||||||
* gst/gdp/gstgdpdepay.c: (gst_gdp_depay_chain):
|
* gst/gdp/gstgdpdepay.c: (gst_gdp_depay_chain):
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* vim: set sw=2: -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2; c-indent-level: 2 -*- */
|
||||||
/* GStreamer
|
/* GStreamer
|
||||||
* Copyright (C) <2005> Edgard Lima <edgard.lima@indt.org.br>
|
* Copyright (C) <2005> Edgard Lima <edgard.lima@indt.org.br>
|
||||||
*
|
*
|
||||||
|
@ -20,6 +21,8 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <ne_redirect.h>
|
||||||
|
|
||||||
#ifndef NE_FREE
|
#ifndef NE_FREE
|
||||||
#define NEON_026_OR_LATER 1
|
#define NEON_026_OR_LATER 1
|
||||||
#endif
|
#endif
|
||||||
|
@ -33,6 +36,8 @@ GST_DEBUG_CATEGORY_STATIC (neonhttpsrc_debug);
|
||||||
|
|
||||||
#define MAX_READ_SIZE (4 * 1024)
|
#define MAX_READ_SIZE (4 * 1024)
|
||||||
|
|
||||||
|
/* max number of HTTP redirects, when iterating over a sequence of HTTP 302 status code */
|
||||||
|
#define MAX_HTTP_REDIRECTS_NUMBER 5
|
||||||
|
|
||||||
static const GstElementDetails gst_neonhttp_src_details =
|
static const GstElementDetails gst_neonhttp_src_details =
|
||||||
GST_ELEMENT_DETAILS ("HTTP client source",
|
GST_ELEMENT_DETAILS ("HTTP client source",
|
||||||
|
@ -55,7 +60,11 @@ enum
|
||||||
PROP_IRADIO_MODE,
|
PROP_IRADIO_MODE,
|
||||||
PROP_IRADIO_NAME,
|
PROP_IRADIO_NAME,
|
||||||
PROP_IRADIO_GENRE,
|
PROP_IRADIO_GENRE,
|
||||||
PROP_IRADIO_URL
|
PROP_IRADIO_URL,
|
||||||
|
PROP_NEON_HTTP_REDIRECT
|
||||||
|
#ifndef GST_DISABLE_GST_DEBUG
|
||||||
|
, PROP_NEON_HTTP_DBG
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static void oom_callback ();
|
static void oom_callback ();
|
||||||
|
@ -178,6 +187,19 @@ gst_neonhttp_src_class_init (GstNeonhttpSrcClass * klass)
|
||||||
"iradio-url",
|
"iradio-url",
|
||||||
"Homepage URL for radio stream", NULL, G_PARAM_READABLE));
|
"Homepage URL for radio stream", NULL, G_PARAM_READABLE));
|
||||||
|
|
||||||
|
g_object_class_install_property
|
||||||
|
(gobject_class, PROP_NEON_HTTP_REDIRECT,
|
||||||
|
g_param_spec_boolean ("automatic-redirect", "automatic-redirect",
|
||||||
|
"Enable Neon HTTP Redirects (HTTP Status Code 302)",
|
||||||
|
FALSE, G_PARAM_READWRITE));
|
||||||
|
|
||||||
|
#ifndef GST_DISABLE_GST_DEBUG
|
||||||
|
g_object_class_install_property
|
||||||
|
(gobject_class, PROP_NEON_HTTP_DBG,
|
||||||
|
g_param_spec_boolean ("neon-http-debug", "neon-http-debug",
|
||||||
|
"Enable Neon HTTP debug messages", FALSE, G_PARAM_READWRITE));
|
||||||
|
#endif
|
||||||
|
|
||||||
gstbasesrc_class->start = gst_neonhttp_src_start;
|
gstbasesrc_class->start = gst_neonhttp_src_start;
|
||||||
gstbasesrc_class->stop = gst_neonhttp_src_stop;
|
gstbasesrc_class->stop = gst_neonhttp_src_stop;
|
||||||
gstbasesrc_class->get_size = gst_neonhttp_src_get_size;
|
gstbasesrc_class->get_size = gst_neonhttp_src_get_size;
|
||||||
|
@ -375,18 +397,34 @@ gst_neonhttp_src_unicodify (const char *str)
|
||||||
return unicodify (str, -1, "locale", "ISO-8859-1", NULL);
|
return unicodify (str, -1, "locale", "ISO-8859-1", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create a socket for connecting to remote server */
|
#define HTTP_SOCKET_ERROR -2
|
||||||
static gboolean
|
#define HTTP_REQUEST_WRONG_PROXY -1
|
||||||
gst_neonhttp_src_start (GstBaseSrc * bsrc)
|
|
||||||
|
/**
|
||||||
|
* Try to send the HTTP request to the Icecast server, and if possible deals with
|
||||||
|
* all the probable redirections (HTTP status code == 302)
|
||||||
|
*/
|
||||||
|
static gint
|
||||||
|
send_request_and_redirect (GstNeonhttpSrc * src, gboolean do_redir)
|
||||||
{
|
{
|
||||||
GstNeonhttpSrc *src = GST_NEONHTTP_SRC (bsrc);
|
|
||||||
const char *content_length;
|
|
||||||
gint res;
|
gint res;
|
||||||
|
gint http_status = 0;
|
||||||
|
|
||||||
|
const gchar *redir = g_strdup ("");
|
||||||
|
|
||||||
|
guint request_count = 0;
|
||||||
|
|
||||||
|
#ifndef GST_DISABLE_GST_DEBUG
|
||||||
|
if (src->neon_http_msgs_dbg)
|
||||||
|
ne_debug_init (stderr, NE_DBG_HTTP);
|
||||||
|
#endif
|
||||||
|
|
||||||
ne_oom_callback (oom_callback);
|
ne_oom_callback (oom_callback);
|
||||||
|
|
||||||
if ((res = ne_sock_init ()) != 0)
|
if ((res = ne_sock_init ()) != 0)
|
||||||
goto init_failed;
|
return HTTP_SOCKET_ERROR;
|
||||||
|
|
||||||
|
do {
|
||||||
|
|
||||||
src->session =
|
src->session =
|
||||||
ne_session_create (src->uri.scheme, src->uri.host, src->uri.port);
|
ne_session_create (src->uri.scheme, src->uri.host, src->uri.port);
|
||||||
|
@ -395,7 +433,7 @@ gst_neonhttp_src_start (GstBaseSrc * bsrc)
|
||||||
ne_session_proxy (src->session, src->proxy.host, src->proxy.port);
|
ne_session_proxy (src->session, src->proxy.host, src->proxy.port);
|
||||||
} else if (src->proxy.host || src->proxy.port) {
|
} else if (src->proxy.host || src->proxy.port) {
|
||||||
/* both proxy host and port must be specified or none */
|
/* both proxy host and port must be specified or none */
|
||||||
goto wrong_proxy;
|
return HTTP_REQUEST_WRONG_PROXY;
|
||||||
}
|
}
|
||||||
|
|
||||||
src->request = ne_request_create (src->session, "GET", src->uri.path);
|
src->request = ne_request_create (src->session, "GET", src->uri.path);
|
||||||
|
@ -408,8 +446,85 @@ gst_neonhttp_src_start (GstBaseSrc * bsrc)
|
||||||
ne_add_request_header (src->request, "icy-metadata", "1");
|
ne_add_request_header (src->request, "icy-metadata", "1");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((res = ne_begin_request (src->request)) != NE_OK)
|
res = ne_begin_request (src->request);
|
||||||
|
|
||||||
|
if (res == NE_OK) {
|
||||||
|
/* When the HTTP status code is 302, it is not the SHOUTcast streaming content yet;
|
||||||
|
* Reload the HTTP request with a new URI value */
|
||||||
|
http_status = ne_get_status (src->request)->code;
|
||||||
|
if (http_status == 302) {
|
||||||
|
/* the new URI value to go when redirecting can be found on the 'Location' HTTP header */
|
||||||
|
redir = ne_get_response_header (src->request, "Location");
|
||||||
|
if (redir != NULL) {
|
||||||
|
ne_uri_free (&src->uri);
|
||||||
|
set_uri (src, redir, &src->uri, &src->ishttps, &src->uristr, FALSE);
|
||||||
|
#ifndef GST_DISABLE_GST_DEBUG
|
||||||
|
if (src->neon_http_msgs_dbg)
|
||||||
|
GST_LOG_OBJECT (src,
|
||||||
|
"--> Got HTTP Status Code %d; Using 'Location' header [%s]\n",
|
||||||
|
http_status, src->uri.host);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
/* if - http_status == 302 */
|
||||||
|
}
|
||||||
|
/* if - NE_OK */
|
||||||
|
++request_count;
|
||||||
|
if (http_status == 302) {
|
||||||
|
GST_WARNING_OBJECT (src, "%s %s.\n",
|
||||||
|
(request_count < MAX_HTTP_REDIRECTS_NUMBER)
|
||||||
|
&& do_redir ? "Redirecting to" :
|
||||||
|
"WILL NOT redirect, try it again with a different URI; an alternative is",
|
||||||
|
src->uri.host);
|
||||||
|
}
|
||||||
|
#ifndef GST_DISABLE_GST_DEBUG
|
||||||
|
if (src->neon_http_msgs_dbg)
|
||||||
|
GST_LOG_OBJECT (src, "--> request_count = %d\n", request_count);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* do the redirect, go back to send another HTTP request now using the 'Location' */
|
||||||
|
} while (do_redir && (request_count < MAX_HTTP_REDIRECTS_NUMBER)
|
||||||
|
&& http_status == 302);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create a socket for connecting to remote server */
|
||||||
|
static gboolean
|
||||||
|
gst_neonhttp_src_start (GstBaseSrc * bsrc)
|
||||||
|
{
|
||||||
|
GstNeonhttpSrc *src = GST_NEONHTTP_SRC (bsrc);
|
||||||
|
const char *content_length;
|
||||||
|
|
||||||
|
gint res = send_request_and_redirect (src, src->neon_http_redirect);
|
||||||
|
|
||||||
|
if (res != NE_OK) {
|
||||||
|
if (res == HTTP_SOCKET_ERROR) {
|
||||||
|
#ifndef GST_DISABLE_GST_DEBUG
|
||||||
|
if (src->neon_http_msgs_dbg) {
|
||||||
|
GST_ERROR_OBJECT (src, "HTTP Request failed when opening socket!\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
goto init_failed;
|
||||||
|
} else if (res == HTTP_REQUEST_WRONG_PROXY) {
|
||||||
|
#ifndef GST_DISABLE_GST_DEBUG
|
||||||
|
if (src->neon_http_msgs_dbg) {
|
||||||
|
GST_ERROR_OBJECT (src,
|
||||||
|
"Proxy Server URI is invalid to the HTTP Request!\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
goto wrong_proxy;
|
||||||
|
} else {
|
||||||
|
#ifndef GST_DISABLE_GST_DEBUG
|
||||||
|
if (src->neon_http_msgs_dbg) {
|
||||||
|
GST_ERROR_OBJECT (src, "HTTP Request failed, error unrecognized!\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
goto begin_req_failed;
|
goto begin_req_failed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
content_length = ne_get_response_header (src->request, "Content-Length");
|
content_length = ne_get_response_header (src->request, "Content-Length");
|
||||||
|
|
||||||
|
@ -461,6 +576,7 @@ gst_neonhttp_src_start (GstBaseSrc * bsrc)
|
||||||
src->iradio_url = gst_neonhttp_src_unicodify (str_value);
|
src->iradio_url = gst_neonhttp_src_unicodify (str_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
|
@ -706,6 +822,18 @@ gst_neonhttp_src_set_property (GObject * object, guint prop_id,
|
||||||
this->iradio_mode = g_value_get_boolean (value);
|
this->iradio_mode = g_value_get_boolean (value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case PROP_NEON_HTTP_REDIRECT:
|
||||||
|
{
|
||||||
|
this->neon_http_redirect = g_value_get_boolean (value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#ifndef GST_DISABLE_GST_DEBUG
|
||||||
|
case PROP_NEON_HTTP_DBG:
|
||||||
|
{
|
||||||
|
this->neon_http_msgs_dbg = g_value_get_boolean (value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -769,6 +897,14 @@ gst_neonhttp_src_get_property (GObject * object, guint prop_id,
|
||||||
case PROP_IRADIO_URL:
|
case PROP_IRADIO_URL:
|
||||||
g_value_set_string (value, neonhttpsrc->iradio_url);
|
g_value_set_string (value, neonhttpsrc->iradio_url);
|
||||||
break;
|
break;
|
||||||
|
case PROP_NEON_HTTP_REDIRECT:
|
||||||
|
g_value_set_boolean (value, neonhttpsrc->neon_http_redirect);
|
||||||
|
break;
|
||||||
|
#ifndef GST_DISABLE_GST_DEBUG
|
||||||
|
case PROP_NEON_HTTP_DBG:
|
||||||
|
g_value_set_boolean (value, neonhttpsrc->neon_http_msgs_dbg);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* vim: set sw=2: -*- Mode: C; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2; c-indent-level: 2 -*- */
|
||||||
/* GStreamer
|
/* GStreamer
|
||||||
* Copyright (C) <2005> Edgard Lima <edgard.lima@indt.org.br>
|
* Copyright (C) <2005> Edgard Lima <edgard.lima@indt.org.br>
|
||||||
*
|
*
|
||||||
|
@ -63,6 +64,12 @@ struct _GstNeonhttpSrc {
|
||||||
gchar *iradio_url;
|
gchar *iradio_url;
|
||||||
GstCaps *icy_caps;
|
GstCaps *icy_caps;
|
||||||
gint icy_metaint;
|
gint icy_metaint;
|
||||||
|
|
||||||
|
/* enable Neon HTTP redirects (HTTP 302 status code) */
|
||||||
|
gboolean neon_http_redirect;
|
||||||
|
|
||||||
|
/* enable Neon HTTP debug messages */
|
||||||
|
gboolean neon_http_msgs_dbg;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstNeonhttpSrcClass {
|
struct _GstNeonhttpSrcClass {
|
||||||
|
|
Loading…
Reference in a new issue