diff options
-rw-r--r-- | ChangeLog | 19 | ||||
-rw-r--r-- | configure.ac | 13 | ||||
-rw-r--r-- | docs/plugins/Makefile.am | 1 | ||||
-rw-r--r-- | docs/plugins/gst-plugins-bad-plugins-docs.sgml | 2 | ||||
-rw-r--r-- | docs/plugins/gst-plugins-bad-plugins-sections.txt | 15 | ||||
-rw-r--r-- | docs/plugins/gst-plugins-bad-plugins.args | 90 | ||||
-rw-r--r-- | docs/plugins/inspect/plugin-soup.xml | 28 | ||||
-rw-r--r-- | ext/Makefile.am | 8 | ||||
-rw-r--r-- | ext/soup/Makefile.am | 9 | ||||
-rw-r--r-- | ext/soup/gstsouphttpsrc.c | 1184 | ||||
-rw-r--r-- | ext/soup/gstsouphttpsrc.h | 92 | ||||
-rw-r--r-- | tests/check/Makefile.am | 9 | ||||
-rw-r--r-- | tests/check/elements/souphttpsrc.c | 453 | ||||
-rw-r--r-- | tests/check/test-cert.pem | 22 | ||||
-rw-r--r-- | tests/check/test-key.pem | 15 |
15 files changed, 19 insertions, 1941 deletions
@@ -1,3 +1,22 @@ +2008-04-13 Jan Schmidt <jan.schmidt@sun.com> + + * configure.ac: + * docs/plugins/Makefile.am: + * docs/plugins/gst-plugins-bad-plugins-docs.sgml: + * docs/plugins/gst-plugins-bad-plugins-sections.txt: + * docs/plugins/gst-plugins-bad-plugins.args: + * docs/plugins/inspect/plugin-soup.xml: + * ext/Makefile.am: + * ext/soup/Makefile.am: + * ext/soup/gstsouphttpsrc.c: + * ext/soup/gstsouphttpsrc.h: + * tests/check/Makefile.am: + * tests/check/elements/souphttpsrc.c: + * tests/check/test-cert.pem: + * tests/check/test-key.pem: + + Remove soup plugin that's moved to -good (#523124) + 2008-04-12 Tim-Philipp Müller <tim at centricular dot net> * gst/flv/gstflvparse.c: (gst_flv_parse_metadata_item), diff --git a/configure.ac b/configure.ac index db59d781..e68cb238 100644 --- a/configure.ac +++ b/configure.ac @@ -861,17 +861,6 @@ AG_GST_CHECK_FEATURE(OFA, [ofa plugins], ofa, [ AC_SUBST(OFA_LIBS) ]) -dnl *** soup *** -translit(dnm, m, l) AM_CONDITIONAL(USE_SOUP, true) -AG_GST_CHECK_FEATURE(SOUP, [soup http client plugin (2.4)], souphttpsrc, [ - PKG_CHECK_MODULES(SOUP, libsoup-2.4 >= 2.3.2, HAVE_SOUP="yes", [ - HAVE_SOUP="no" - AC_MSG_RESULT(no) - ]) - AC_SUBST(SOUP_CFLAGS) - AC_SUBST(SOUP_LIBS) -]) - dnl *** timidity *** translit(dnm, m, l) AM_CONDITIONAL(USE_TIMIDITY, true) AG_GST_CHECK_FEATURE(TIMIDITY, [timidity midi soft synth plugin], timidity, [ @@ -1082,7 +1071,6 @@ AM_CONDITIONAL(USE_NAS, false) AM_CONDITIONAL(USE_NEON, false) AM_CONDITIONAL(USE_OFA, false) AM_CONDITIONAL(USE_OSS4, false) -AM_CONDITIONAL(USE_SOUP, false) AM_CONDITIONAL(USE_SDL, false) AM_CONDITIONAL(USE_SNDFILE, false) AM_CONDITIONAL(USE_SOUNDTOUCH, false) @@ -1234,7 +1222,6 @@ ext/musicbrainz/Makefile ext/mythtv/Makefile ext/neon/Makefile ext/ofa/Makefile -ext/soup/Makefile ext/sdl/Makefile ext/sndfile/Makefile ext/soundtouch/Makefile diff --git a/docs/plugins/Makefile.am b/docs/plugins/Makefile.am index ae400828..9e4a7cde 100644 --- a/docs/plugins/Makefile.am +++ b/docs/plugins/Makefile.am @@ -99,7 +99,6 @@ EXTRA_HFILES = \ $(top_srcdir)/ext/amrwb/gstamrwbparse.h \ $(top_srcdir)/ext/dc1394/gstdc1394.h \ $(top_srcdir)/ext/directfb/dfbvideosink.h \ - $(top_srcdir)/ext/soup/gstsouphttpsrc.h \ $(top_srcdir)/ext/ivorbis/vorbisdec.h \ $(top_srcdir)/ext/jack/gstjackaudiosink.h \ $(top_srcdir)/ext/musicbrainz/gsttrm.h \ diff --git a/docs/plugins/gst-plugins-bad-plugins-docs.sgml b/docs/plugins/gst-plugins-bad-plugins-docs.sgml index 9eb8c964..38d7d07f 100644 --- a/docs/plugins/gst-plugins-bad-plugins-docs.sgml +++ b/docs/plugins/gst-plugins-bad-plugins-docs.sgml @@ -42,7 +42,6 @@ <xi:include href="xml/element-sdlaudiosink.xml" /> <xi:include href="xml/element-sdlvideosink.xml" /> <xi:include href="xml/element-sdpdemux.xml" /> - <xi:include href="xml/element-souphttpsrc.xml" /> <xi:include href="xml/element-speed.xml" /> <xi:include href="xml/element-speexresample.xml" /> <!--xi:include href="xml/element-theoradecexp.xml" /--> @@ -106,7 +105,6 @@ <xi:include href="xml/plugin-selector.xml" /> <xi:include href="xml/plugin-sndfile.xml" /> <xi:include href="xml/plugin-soundtouch.xml" /> - <xi:include href="xml/plugin-soup.xml" /> <xi:include href="xml/plugin-spcdec.xml" /> <xi:include href="xml/plugin-speed.xml" /> <xi:include href="xml/plugin-speexresample.xml" /> diff --git a/docs/plugins/gst-plugins-bad-plugins-sections.txt b/docs/plugins/gst-plugins-bad-plugins-sections.txt index 8ca69553..90ff6da5 100644 --- a/docs/plugins/gst-plugins-bad-plugins-sections.txt +++ b/docs/plugins/gst-plugins-bad-plugins-sections.txt @@ -154,21 +154,6 @@ FESTIVAL_DEFAULT_SERVER_PORT FESTIVAL_DEFAULT_TEXT_MODE </SECTION> -<SECTION> -<FILE>element-souphttpsrc</FILE> -<TITLE>souphttpsrc</TITLE> -GstSoupHTTPSrc -<SUBSECTION Standard> -GstSoupHTTPSrcClass -GST_SOUP_HTTP_SRC -GST_SOUP_HTTP_SRC_CLASS -GST_IS_SOUP_HTTP_SRC -GST_IS_SOUP_HTTP_SRC_CLASS -GST_TYPE_SOUP_HTTP_SRC -gst_soup_http_src_get_type -</SECTION> - -<SECTION> <FILE>element-input-selector</FILE> <TITLE>input-selector</TITLE> GstInputSelector diff --git a/docs/plugins/gst-plugins-bad-plugins.args b/docs/plugins/gst-plugins-bad-plugins.args index 2e234adb..c90394c8 100644 --- a/docs/plugins/gst-plugins-bad-plugins.args +++ b/docs/plugins/gst-plugins-bad-plugins.args @@ -18409,96 +18409,6 @@ </ARG> <ARG> -<NAME>GstSoupHTTPSrc::location</NAME> -<TYPE>gchar*</TYPE> -<RANGE></RANGE> -<FLAGS>rw</FLAGS> -<NICK>Location</NICK> -<BLURB>Location to read from.</BLURB> -<DEFAULT>""</DEFAULT> -</ARG> - -<ARG> -<NAME>GstSoupHTTPSrc::iradio-genre</NAME> -<TYPE>gchar*</TYPE> -<RANGE></RANGE> -<FLAGS>r</FLAGS> -<NICK>iradio-genre</NICK> -<BLURB>Genre of the stream.</BLURB> -<DEFAULT>NULL</DEFAULT> -</ARG> - -<ARG> -<NAME>GstSoupHTTPSrc::iradio-mode</NAME> -<TYPE>gboolean</TYPE> -<RANGE></RANGE> -<FLAGS>rw</FLAGS> -<NICK>iradio-mode</NICK> -<BLURB>Enable internet radio mode (extraction of shoutcast/icecast metadata).</BLURB> -<DEFAULT>FALSE</DEFAULT> -</ARG> - -<ARG> -<NAME>GstSoupHTTPSrc::iradio-name</NAME> -<TYPE>gchar*</TYPE> -<RANGE></RANGE> -<FLAGS>r</FLAGS> -<NICK>iradio-name</NICK> -<BLURB>Name of the stream.</BLURB> -<DEFAULT>NULL</DEFAULT> -</ARG> - -<ARG> -<NAME>GstSoupHTTPSrc::iradio-title</NAME> -<TYPE>gchar*</TYPE> -<RANGE></RANGE> -<FLAGS>r</FLAGS> -<NICK>iradio-title</NICK> -<BLURB>Name of currently playing song.</BLURB> -<DEFAULT>NULL</DEFAULT> -</ARG> - -<ARG> -<NAME>GstSoupHTTPSrc::iradio-url</NAME> -<TYPE>gchar*</TYPE> -<RANGE></RANGE> -<FLAGS>r</FLAGS> -<NICK>iradio-url</NICK> -<BLURB>Homepage URL for radio stream.</BLURB> -<DEFAULT>NULL</DEFAULT> -</ARG> - -<ARG> -<NAME>GstSoupHTTPSrc::user-agent</NAME> -<TYPE>gchar*</TYPE> -<RANGE></RANGE> -<FLAGS>rw</FLAGS> -<NICK>User-Agent</NICK> -<BLURB>Value of the User-Agent HTTP request header field.</BLURB> -<DEFAULT>"GStreamer souphttpsrc"</DEFAULT> -</ARG> - -<ARG> -<NAME>GstSoupHTTPSrc::automatic-redirect</NAME> -<TYPE>gboolean</TYPE> -<RANGE></RANGE> -<FLAGS>rw</FLAGS> -<NICK>automatic-redirect</NICK> -<BLURB>Automatically follow HTTP redirects (HTTP Status Code 3xx).</BLURB> -<DEFAULT>TRUE</DEFAULT> -</ARG> - -<ARG> -<NAME>GstSoupHTTPSrc::proxy</NAME> -<TYPE>gchar*</TYPE> -<RANGE></RANGE> -<FLAGS>rw</FLAGS> -<NICK>Proxy</NICK> -<BLURB>HTTP proxy server URI.</BLURB> -<DEFAULT>""</DEFAULT> -</ARG> - -<ARG> <NAME>GstSpeexResample::quality</NAME> <TYPE>gint</TYPE> <RANGE>[0,10]</RANGE> diff --git a/docs/plugins/inspect/plugin-soup.xml b/docs/plugins/inspect/plugin-soup.xml deleted file mode 100644 index 25155819..00000000 --- a/docs/plugins/inspect/plugin-soup.xml +++ /dev/null @@ -1,28 +0,0 @@ -<plugin> - <name>soup</name> - <description>libsoup HTTP client src</description> - <filename>../../ext/soup/.libs/libgstsouphttpsrc.so</filename> - <basename>libgstsouphttpsrc.so</basename> - <version>0.10.5.1</version> - <license>LGPL</license> - <source>gst-plugins-bad</source> - <package>GStreamer Bad Plug-ins CVS/prerelease</package> - <origin>Unknown package origin</origin> - <elements> - <element> - <name>souphttpsrc</name> - <longname>HTTP client source</longname> - <class>Source/Network</class> - <description>Receive data as a client over the network via HTTP using SOUP</description> - <author>Wouter Cloetens <wouter@mind.be></author> - <pads> - <caps> - <name>src</name> - <direction>source</direction> - <presence>always</presence> - <details>ANY</details> - </caps> - </pads> - </element> - </elements> -</plugin>
\ No newline at end of file diff --git a/ext/Makefile.am b/ext/Makefile.am index 43b81777..8ed3191b 100644 --- a/ext/Makefile.am +++ b/ext/Makefile.am @@ -196,12 +196,6 @@ else OFA_DIR= endif -if USE_SOUP -SOUP_DIR=soup -else -SOUP_DIR= -endif - if USE_TIMIDITY TIMIDITY_DIR=timidity endif @@ -328,7 +322,6 @@ SUBDIRS=\ $(NAS_DIR) \ $(NEON_DIR) \ $(OFA_DIR) \ - $(SOUP_DIR) \ $(POLYP_DIR) \ $(SDL_DIR) \ $(SHOUT_DIR) \ @@ -370,7 +363,6 @@ DIST_SUBDIRS = \ nas \ neon \ ofa \ - soup \ sdl \ sndfile \ soundtouch \ diff --git a/ext/soup/Makefile.am b/ext/soup/Makefile.am deleted file mode 100644 index 168ca916..00000000 --- a/ext/soup/Makefile.am +++ /dev/null @@ -1,9 +0,0 @@ -plugin_LTLIBRARIES = libgstsouphttpsrc.la - -libgstsouphttpsrc_la_SOURCES = gstsouphttpsrc.c - -libgstsouphttpsrc_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(SOUP_CFLAGS) -libgstsouphttpsrc_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) -lgsttag-@GST_MAJORMINOR@ $(GST_BASE_LIBS) $(SOUP_LIBS) -libgstsouphttpsrc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) - -noinst_HEADERS = gstsouphttpsrc.h diff --git a/ext/soup/gstsouphttpsrc.c b/ext/soup/gstsouphttpsrc.c deleted file mode 100644 index baf29438..00000000 --- a/ext/soup/gstsouphttpsrc.c +++ /dev/null @@ -1,1184 +0,0 @@ -/* GStreamer - * Copyright (C) 2007-2008 Wouter Cloetens <wouter@mind.be> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more - */ - -/** - * SECTION:element-souphttpsrc - * @short_description: Read from an HTTP/HTTPS/WebDAV/Icecast/Shoutcast - * location. - * - * <refsect2> - * <para> - * This plugin reads data from a remote location specified by a URI. - * Supported protocols are 'http', 'https'. - * </para> - * <para> - * An HTTP proxy must be specified by its URL. - * If the "http_proxy" environment variable is set, its value is used. - * The element-souphttpsrc::proxy property can be used to override the - * default. - * </para> - * <para> - * In case the element-souphttpsrc::iradio-mode property is set and the - * location is an HTTP resource, souphttpsrc will send special Icecast HTTP - * headers to the server to request additional Icecast meta-information. If - * the server is not an Icecast server, it will behave as if the - * element-souphttpsrc::iradio-mode property were not set. If it is, - * souphttpsrc will output data with a media type of application/x-icy, - * in which case you will need to use the #ICYDemux element as follow-up - * element to extract the Icecast metadata and to determine the underlying - * media type. - * </para> - * <para> - * Example pipeline: - * <programlisting> - * gst-launch -v souphttpsrc location=https://some.server.org/index.html - * ! filesink location=/home/joe/server.html - * </programlisting> - * The above pipeline reads a web page from a server using the HTTPS protocol - * and writes it to a local file. - * </para> - * <para> - * Another example pipeline: - * <programlisting> - * gst-launch -v souphttpsrc user-agent="FooPlayer 0.99 beta" - * automatic-redirect=false proxy=http://proxy.intranet.local:8080 - * location=http://music.foobar.com/demo.mp3 ! mad ! audioconvert - * ! audioresample ! alsasink - * </programlisting> - * The above pipeline will read and decode and play an mp3 file from a - * web server using the HTTP protocol. If the server sends redirects, - * the request fails instead of following the redirect. The specified - * HTTP proxy server is used. The User-Agent HTTP request header - * is set to a custom string instead of "GStreamer souphttpsrc." - * </para> - * <para> - * Yet another example pipeline: - * <programlisting> - * gst-launch -v souphttpsrc location=http://10.11.12.13/mjpeg - * do-timestamp=true ! multipartdemux - * ! image/jpeg,width=640,height=480 ! matroskamux - * ! filesink location=mjpeg.mkv - * </programlisting> - * The above pipeline reads a motion JPEG stream from an IP camera - * using the HTTP protocol, encoded as mime/multipart image/jpeg - * parts, and writes a Matroska motion JPEG file. The width and - * height properties are set in the caps to provide the Matroska - * multiplexer with the information to set this in the header. - * Timestamps are set on the buffers as they arrive from the camera. - * These are used by the mime/multipart demultiplexer to emit timestamps - * on the JPEG-encoded video frame buffers. This allows the Matroska - * multiplexer to timestamp the frames in the resulting file. - * </para> - * </refsect2> - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <string.h> -#include <gst/gstelement.h> -#include <gst/gst-i18n-plugin.h> -#include <libsoup/soup.h> -#include "gstsouphttpsrc.h" - -#include <gst/tag/tag.h> - -GST_DEBUG_CATEGORY_STATIC (souphttpsrc_debug); -#define GST_CAT_DEFAULT souphttpsrc_debug - -static const GstElementDetails gst_soup_http_src_details = -GST_ELEMENT_DETAILS ("HTTP client source", - "Source/Network", - "Receive data as a client over the network via HTTP using SOUP", - "Wouter Cloetens <wouter@mind.be>"); - -static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY); - -enum -{ - PROP_0, - PROP_LOCATION, - PROP_USER_AGENT, - PROP_AUTOMATIC_REDIRECT, - PROP_PROXY, - PROP_COOKIES, - PROP_IRADIO_MODE, - PROP_IRADIO_NAME, - PROP_IRADIO_GENRE, - PROP_IRADIO_URL, - PROP_IRADIO_TITLE -}; - -#define DEFAULT_USER_AGENT "GStreamer souphttpsrc " - -static void gst_soup_http_src_uri_handler_init (gpointer g_iface, - gpointer iface_data); -static void gst_soup_http_src_init (GstSoupHTTPSrc * src, - GstSoupHTTPSrcClass * g_class); -static void gst_soup_http_src_dispose (GObject * gobject); -static void gst_soup_http_src_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); -static void gst_soup_http_src_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); - -static GstFlowReturn gst_soup_http_src_create (GstPushSrc * psrc, - GstBuffer ** outbuf); -static gboolean gst_soup_http_src_start (GstBaseSrc * bsrc); -static gboolean gst_soup_http_src_stop (GstBaseSrc * bsrc); -static gboolean gst_soup_http_src_get_size (GstBaseSrc * bsrc, guint64 * size); -static gboolean gst_soup_http_src_is_seekable (GstBaseSrc * bsrc); -static gboolean gst_soup_http_src_do_seek (GstBaseSrc * bsrc, - GstSegment * segment); -static gboolean gst_soup_http_src_unlock (GstBaseSrc * bsrc); -static gboolean gst_soup_http_src_unlock_stop (GstBaseSrc * bsrc); - -static gboolean gst_soup_http_src_set_location (GstSoupHTTPSrc * src, - const gchar * uri); -static gboolean gst_soup_http_src_set_proxy (GstSoupHTTPSrc * src, - const gchar * uri); - -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_queue_message (GstSoupHTTPSrc * src); -static gboolean gst_soup_http_src_add_range_header (GstSoupHTTPSrc * src, - guint64 offset); -static void gst_soup_http_src_session_unpause_message (GstSoupHTTPSrc * src); -static void gst_soup_http_src_session_pause_message (GstSoupHTTPSrc * src); -static void gst_soup_http_src_session_close (GstSoupHTTPSrc * src); -static void gst_soup_http_src_parse_status (SoupMessage * msg, - GstSoupHTTPSrc * src); -static void gst_soup_http_src_chunk_free (gpointer gstbuf); -static SoupBuffer *gst_soup_http_src_chunk_allocator (SoupMessage * msg, - gsize max_len, gpointer user_data); -static void gst_soup_http_src_got_chunk_cb (SoupMessage * msg, - SoupBuffer * chunk, GstSoupHTTPSrc * src); -static void gst_soup_http_src_response_cb (SoupSession * session, - SoupMessage * msg, GstSoupHTTPSrc * src); -static void gst_soup_http_src_got_headers_cb (SoupMessage * msg, - GstSoupHTTPSrc * src); -static void gst_soup_http_src_got_body_cb (SoupMessage * msg, - GstSoupHTTPSrc * src); -static void gst_soup_http_src_finished_cb (SoupMessage * msg, - GstSoupHTTPSrc * src); - - -static void -_do_init (GType type) -{ - static const GInterfaceInfo urihandler_info = { - gst_soup_http_src_uri_handler_init, - NULL, - NULL - }; - - g_type_add_interface_static (type, GST_TYPE_URI_HANDLER, &urihandler_info); - - GST_DEBUG_CATEGORY_INIT (souphttpsrc_debug, "souphttpsrc", 0, - "SOUP HTTP src"); -} - -GST_BOILERPLATE_FULL (GstSoupHTTPSrc, gst_soup_http_src, GstPushSrc, - GST_TYPE_PUSH_SRC, _do_init); - -static void -gst_soup_http_src_base_init (gpointer g_class) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&srctemplate)); - - gst_element_class_set_details (element_class, &gst_soup_http_src_details); -} - -static void -gst_soup_http_src_class_init (GstSoupHTTPSrcClass * klass) -{ - GObjectClass *gobject_class; - GstBaseSrcClass *gstbasesrc_class; - GstPushSrcClass *gstpushsrc_class; - - gobject_class = (GObjectClass *) klass; - gstbasesrc_class = (GstBaseSrcClass *) klass; - gstpushsrc_class = (GstPushSrcClass *) klass; - - gobject_class->set_property = gst_soup_http_src_set_property; - gobject_class->get_property = gst_soup_http_src_get_property; - gobject_class->dispose = gst_soup_http_src_dispose; - - g_object_class_install_property (gobject_class, - PROP_LOCATION, - g_param_spec_string ("location", "Location", - "Location to read from", "", G_PARAM_READWRITE)); - g_object_class_install_property (gobject_class, - PROP_USER_AGENT, - g_param_spec_string ("user-agent", "User-Agent", - "Value of the User-Agent HTTP request header field", - DEFAULT_USER_AGENT, G_PARAM_READWRITE)); - g_object_class_install_property (gobject_class, - PROP_AUTOMATIC_REDIRECT, - g_param_spec_boolean ("automatic-redirect", "automatic-redirect", - "Automatically follow HTTP redirects (HTTP Status Code 3xx)", - TRUE, G_PARAM_READWRITE)); - g_object_class_install_property (gobject_class, - PROP_PROXY, - g_param_spec_string ("proxy", "Proxy", - "HTTP proxy server URI", "", G_PARAM_READWRITE)); - g_object_class_install_property (gobject_class, - PROP_COOKIES, g_param_spec_boxed ("cookies", "Cookies", - "HTTP request cookies", G_TYPE_STRV, G_PARAM_READWRITE)); - - /* icecast stuff */ - g_object_class_install_property (gobject_class, - PROP_IRADIO_MODE, - g_param_spec_boolean ("iradio-mode", - "iradio-mode", - "Enable internet radio mode (extraction of shoutcast/icecast metadata)", - FALSE, G_PARAM_READWRITE)); - g_object_class_install_property (gobject_class, - PROP_IRADIO_NAME, - g_param_spec_string ("iradio-name", - "iradio-name", "Name of the stream", NULL, G_PARAM_READABLE)); - g_object_class_install_property (gobject_class, - PROP_IRADIO_GENRE, - g_param_spec_string ("iradio-genre", - "iradio-genre", "Genre of the stream", NULL, G_PARAM_READABLE)); - g_object_class_install_property (gobject_class, - PROP_IRADIO_URL, - g_param_spec_string ("iradio-url", - "iradio-url", - "Homepage URL for radio stream", NULL, G_PARAM_READABLE)); - g_object_class_install_property (gobject_class, - PROP_IRADIO_TITLE, - g_param_spec_string ("iradio-title", - "iradio-title", - "Name of currently playing song", NULL, G_PARAM_READABLE)); - - gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_soup_http_src_start); - gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_soup_http_src_stop); - gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_soup_http_src_unlock); - gstbasesrc_class->unlock_stop = - GST_DEBUG_FUNCPTR (gst_soup_http_src_unlock_stop); - gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_soup_http_src_get_size); - gstbasesrc_class->is_seekable = - GST_DEBUG_FUNCPTR (gst_soup_http_src_is_seekable); - gstbasesrc_class->do_seek = GST_DEBUG_FUNCPTR (gst_soup_http_src_do_seek); - - gstpushsrc_class->create = GST_DEBUG_FUNCPTR (gst_soup_http_src_create); - - GST_DEBUG_CATEGORY_INIT (souphttpsrc_debug, "souphttpsrc", 0, - "SOUP HTTP Client Source"); -} - -static void -gst_soup_http_src_init (GstSoupHTTPSrc * src, GstSoupHTTPSrcClass * g_class) -{ - const gchar *proxy; - - src->location = NULL; - src->automatic_redirect = TRUE; - src->user_agent = g_strdup (DEFAULT_USER_AGENT); - src->cookies = NULL; - src->icy_caps = NULL; - src->iradio_mode = FALSE; - src->iradio_name = NULL; - src->iradio_genre = NULL; - src->iradio_url = NULL; - src->iradio_title = NULL; - src->loop = NULL; - src->context = NULL; - src->session = NULL; - src->msg = NULL; - src->interrupted = FALSE; - src->retry = FALSE; - src->have_size = FALSE; - src->seekable = TRUE; - src->read_position = 0; - src->request_position = 0; - proxy = g_getenv ("http_proxy"); - if (proxy && !gst_soup_http_src_set_proxy (src, proxy)) { - GST_WARNING_OBJECT (src, - "The proxy in the http_proxy env var (\"%s\") cannot be parsed.", - proxy); - } -} - -static void -gst_soup_http_src_dispose (GObject * gobject) -{ - GstSoupHTTPSrc *src = GST_SOUP_HTTP_SRC (gobject); - - GST_DEBUG_OBJECT (src, "dispose"); - g_free (src->location); - src->location = NULL; - g_free (src->user_agent); - src->user_agent = NULL; - if (src->proxy != NULL) { - soup_uri_free (src->proxy); - src->proxy = NULL; - } - g_strfreev (src->cookies); - g_free (src->iradio_name); - src->iradio_name = NULL; - g_free (src->iradio_genre); - src->iradio_genre = NULL; - g_free (src->iradio_url); - src->iradio_url = NULL; - g_free (src->iradio_title); - src->iradio_title = NULL; - if (src->icy_caps) { - gst_caps_unref (src->icy_caps); - src->icy_caps = NULL; - } - - G_OBJECT_CLASS (parent_class)->dispose (gobject); -} - -static void -gst_soup_http_src_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstSoupHTTPSrc *src = GST_SOUP_HTTP_SRC (object); - - switch (prop_id) { - case PROP_LOCATION: - { - const gchar *location; - - location = g_value_get_string (value); - - if (location == NULL) { - GST_WARNING ("location property cannot be NULL"); - goto done; - } - if (!gst_soup_http_src_set_location (src, location)) { - GST_WARNING ("badly formatted location"); - goto done; - } - break; - } - case PROP_USER_AGENT: - if (src->user_agent) - g_free (src->user_agent); - src->user_agent = g_value_dup_string (value); - break; - case PROP_IRADIO_MODE: - src->iradio_mode = g_value_get_boolean (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - case PROP_AUTOMATIC_REDIRECT: - src->automatic_redirect = g_value_get_boolean (value); - break; - case PROP_PROXY: - { - const gchar *proxy; - - proxy = g_value_get_string (value); - - if (proxy == NULL) { - GST_WARNING ("proxy property cannot be NULL"); - goto done; - } - if (!gst_soup_http_src_set_proxy (src, proxy)) { - GST_WARNING ("badly formatted proxy URI"); - goto done; - } - break; - } - case PROP_COOKIES: - g_strfreev (src->cookies); - src->cookies = g_strdupv (g_value_get_boxed (value)); - break; - } -done: - return; -} - -static void -gst_soup_http_src_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstSoupHTTPSrc *src = GST_SOUP_HTTP_SRC (object); - - switch (prop_id) { - case PROP_LOCATION: - g_value_set_string (value, src->location); - break; - case PROP_USER_AGENT: - g_value_set_string (value, src->user_agent); - break; - case PROP_AUTOMATIC_REDIRECT: - g_value_set_boolean (value, src->automatic_redirect); - break; - case PROP_PROXY: - if (src->proxy == NULL) - g_value_set_string (value, ""); - else { - char *proxy = soup_uri_to_string (src->proxy, FALSE); - - g_value_set_string (value, proxy); - free (proxy); - } - break; - case PROP_COOKIES: - g_value_set_boxed (value, g_strdupv (src->cookies)); - break; - case PROP_IRADIO_MODE: - g_value_set_boolean (value, src->iradio_mode); - break; - case PROP_IRADIO_NAME: - g_value_set_string (value, src->iradio_name); - break; - case PROP_IRADIO_GENRE: - g_value_set_string (value, src->iradio_genre); - break; - case PROP_IRADIO_URL: - g_value_set_string (value, src->iradio_url); - break; - case PROP_IRADIO_TITLE: - g_value_set_string (value, src->iradio_title); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static gchar * -gst_soup_http_src_unicodify (const gchar * str) -{ - const gchar *env_vars[] = { "GST_ICY_TAG_ENCODING", - "GST_TAG_ENCODING", NULL - }; - - return gst_tag_freeform_string_to_utf8 (str, -1, env_vars); -} - -static void -gst_soup_http_src_cancel_message (GstSoupHTTPSrc * src) -{ - if (src->msg != NULL) - soup_session_cancel_message (src->session, src->msg, SOUP_STATUS_CANCELLED); - src->session_io_status = GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_IDLE; - src->msg = NULL; -} - -static void -gst_soup_http_src_queue_message (GstSoupHTTPSrc * src) -{ - soup_session_queue_message (src->session, src->msg, - (SoupSessionCallback) gst_soup_http_src_response_cb, src); - src->session_io_status = GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_QUEUED; -} - -static gboolean -gst_soup_http_src_add_range_header (GstSoupHTTPSrc * src, guint64 offset) -{ - gchar buf[64]; - gint rc; - - soup_message_headers_remove (src->msg->request_headers, "Range"); - if (offset) { - rc = g_snprintf (buf, sizeof (buf), "bytes=%" G_GUINT64_FORMAT "-", offset); - if (rc > sizeof (buf) || rc < 0) - return FALSE; - soup_message_headers_append (src->msg->request_headers, "Range", buf); - } - src->read_position = offset; - return TRUE; -} - -static void -gst_soup_http_src_session_unpause_message (GstSoupHTTPSrc * src) -{ - soup_session_unpause_message (src->session, src->msg); -} - -static void -gst_soup_http_src_session_pause_message (GstSoupHTTPSrc * src) -{ - soup_session_pause_message (src->session, src->msg); -} - -static void -gst_soup_http_src_session_close (GstSoupHTTPSrc * src) -{ - if (src->session) { - soup_session_abort (src->session); /* This unrefs the message. */ - g_object_unref (src->session); - src->session = NULL; - src->msg = NULL; - } -} - -static void -gst_soup_http_src_got_headers_cb (SoupMessage * msg, GstSoupHTTPSrc * src) -{ - const char *value; - GstTagList *tag_list; - GstBaseSrc *basesrc; - guint64 newsize; - - GST_DEBUG_OBJECT (src, "got headers"); - - if (src->automatic_redirect && SOUP_STATUS_IS_REDIRECTION (msg->status_code)) { - GST_DEBUG_OBJECT (src, "%u redirect to \"%s\"", msg->status_code, - soup_message_headers_get (msg->response_headers, "Location")); - return; - } - - src->session_io_status = GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_RUNNING; - - /* Parse Content-Length. */ - if (soup_message_headers_get_encoding (msg->response_headers) == - SOUP_ENCODING_CONTENT_LENGTH) { - newsize = src->request_position + - soup_message_headers_get_content_length (msg->response_headers); - if (!src->have_size || (src->content_size != newsize)) { - src->content_size = newsize; - src->have_size = TRUE; - GST_DEBUG_OBJECT (src, "size = %" G_GUINT64_FORMAT, src->content_size); - - basesrc = GST_BASE_SRC_CAST (src); - gst_segment_set_duration (&basesrc->segment, GST_FORMAT_BYTES, - src->content_size); - gst_element_post_message (GST_ELEMENT (src), - gst_message_new_duration (GST_OBJECT (src), GST_FORMAT_BYTES, - src->content_size)); - } - } - - /* Icecast stuff */ - tag_list = gst_tag_list_new (); - - if ((value = - soup_message_headers_get (msg->response_headers, - "icy-metaint")) != NULL) { - gint icy_metaint = atoi (value); - - GST_DEBUG_OBJECT (src, "icy-metaint: %s (parsed: %d)", value, icy_metaint); - if (icy_metaint > 0) { - if (src->icy_caps) - gst_caps_unref (src->icy_caps); - - src->icy_caps = gst_caps_new_simple ("application/x-icy", - "metadata-interval", G_TYPE_INT, icy_metaint, NULL); - } - } - - if ((value = - soup_message_headers_get (msg->response_headers, - "icy-name")) != NULL) { - g_free (src->iradio_name); - src->iradio_name = gst_soup_http_src_unicodify (value); - if (src->iradio_name) { - g_object_notify (G_OBJECT (src), "iradio-name"); - gst_tag_list_add (tag_list, GST_TAG_MERGE_REPLACE, GST_TAG_ORGANIZATION, - src->iradio_name, NULL); - } - } - if ((value = - soup_message_headers_get (msg->response_headers, - "icy-genre")) != NULL) { - g_free (src->iradio_genre); - src->iradio_genre = gst_soup_http_src_unicodify (value); - if (src->iradio_genre) { - g_object_notify (G_OBJECT (src), "iradio-genre"); - gst_tag_list_add (tag_list, GST_TAG_MERGE_REPLACE, GST_TAG_GENRE, - src->iradio_genre, NULL); - } - } - if ((value = soup_message_headers_get (msg->response_headers, "icy-url")) - != NULL) { - g_free (src->iradio_url); - src->iradio_url = gst_soup_http_src_unicodify (value); - if (src->iradio_url) { - g_object_notify (G_OBJECT (src), "iradio-url"); - gst_tag_list_add (tag_list, GST_TAG_MERGE_REPLACE, GST_TAG_LOCATION, - src->iradio_url, NULL); - } - } - if (!gst_tag_list_is_empty (tag_list)) { - GST_DEBUG_OBJECT (src, - "calling gst_element_found_tags with %" GST_PTR_FORMAT, tag_list); - gst_element_found_tags (GST_ELEMENT_CAST (src), tag_list); - } else { - gst_tag_list_free (tag_list); - } - - /* Handle HTTP errors. */ - gst_soup_http_src_parse_status (msg, src); - - /* Check if Range header was respected. */ - if (src->ret == GST_FLOW_CUSTOM_ERROR && - src->read_position && msg->status_code != SOUP_STATUS_PARTIAL_CONTENT) { - src->seekable = FALSE; - GST_ELEMENT_ERROR (src, RESOURCE, READ, - ("\"%s\": failed to seek; server does not accept Range HTTP header", - src->location), (NULL)); - src->ret = GST_FLOW_ERROR; - } -} - -/* Have body. Signal EOS. */ -static void -gst_soup_http_src_got_body_cb (SoupMessage * msg, GstSoupHTTPSrc * src) -{ - if (G_UNLIKELY (msg != src->msg)) { - GST_DEBUG_OBJECT (src, "got body, but not for current message"); - return; - } - if (G_UNLIKELY (src->session_io_status != - GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_RUNNING)) { - /* Probably a redirect. */ - return; - } - GST_DEBUG_OBJECT (src, "got body"); - src->ret = GST_FLOW_UNEXPECTED; - if (src->loop) - g_main_loop_quit (src->loop); - gst_soup_http_src_session_pause_message (src); -} - -/* Finished. Signal EOS. */ -static void -gst_soup_http_src_finished_cb (SoupMessage * msg, GstSoupHTTPSrc * src) -{ - if (G_UNLIKELY (msg != src->msg)) { - GST_DEBUG_OBJECT (src, "finished, but not for current message"); - return; - } - GST_DEBUG_OBJECT (src, "finished"); - 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_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, - ("%s", msg->reason_phrase), - ("libsoup status code %d", msg->status_code)); - } - if (src->loop) - g_main_loop_quit (src->loop); -} - -/* Buffer lifecycle management. - * - * gst_soup_http_src_create() runs the GMainLoop for this element, to let - * Soup take control. - * A GstBuffer is allocated in gst_soup_http_src_chunk_allocator() and - * associated with a SoupBuffer. - * Soup reads HTTP data in the GstBuffer's data buffer. - * The gst_soup_http_src_got_chunk_cb() is then called with the SoupBuffer. - * That sets gst_soup_http_src_create()'s return argument to the GstBuffer, - * increments its refcount (to 2), pauses the flow of data from the HTTP - * source to prevent gst_soup_http_src_got_chunk_cb() from being called - * again and breaks out of the GMainLoop. - * Because the SOUP_MESSAGE_OVERWRITE_CHUNKS flag is set, Soup frees the - * SoupBuffer and calls gst_soup_http_src_chunk_free(), which decrements the - * refcount (to 1). - * gst_soup_http_src_create() returns the GstBuffer. It will be freed by a - * downstream element. - * If Soup fails to read HTTP data, it does not call - * gst_soup_http_src_got_chunk_cb(), but still frees the SoupBuffer and - * calls gst_soup_http_src_chunk_free(), which decrements the GstBuffer's - * refcount to 0, freeing it. - */ - -static void -gst_soup_http_src_chunk_free (gpointer gstbuf) -{ - gst_buffer_unref (GST_BUFFER_CAST (gstbuf)); -} - -static SoupBuffer * -gst_soup_http_src_chunk_allocator (SoupMessage * msg, gsize max_len, - gpointer user_data) -{ - GstSoupHTTPSrc *src = (GstSoupHTTPSrc *) user_data; - GstBaseSrc *basesrc = GST_BASE_SRC_CAST (src); - GstBuffer *gstbuf; - SoupBuffer *soupbuf; - gsize length; - GstFlowReturn rc; - - if (max_len) - length = MIN (basesrc->blocksize, max_len); - else - length = basesrc->blocksize; - GST_DEBUG_OBJECT (src, "alloc %" G_GSIZE_FORMAT " bytes <= %" G_GSIZE_FORMAT, - length, max_len); - - - rc = gst_pad_alloc_buffer (GST_BASE_SRC_PAD (basesrc), - GST_BUFFER_OFFSET_NONE, length, - src->icy_caps ? src->icy_caps : - GST_PAD_CAPS (GST_BASE_SRC_PAD (basesrc)), &gstbuf); - if (G_UNLIKELY (rc != GST_FLOW_OK)) { - /* Failed to allocate buffer. Stall SoupSession and return error code - * to create(). */ - src->ret = rc; - g_main_loop_quit (src->loop); - return NULL; - } - - soupbuf = soup_buffer_new_with_owner (GST_BUFFER_DATA (gstbuf), length, - gstbuf, gst_soup_http_src_chunk_free); - - return soupbuf; -} - -static void -gst_soup_http_src_got_chunk_cb (SoupMessage * msg, SoupBuffer * chunk, - GstSoupHTTPSrc * src) -{ - GstBaseSrc *basesrc; - guint64 new_position; - - if (G_UNLIKELY (msg != src->msg)) { - GST_DEBUG_OBJECT (src, "got chunk, but not for current message"); - return; - } - if (G_UNLIKELY (src->session_io_status != - GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_RUNNING)) { - /* Probably a redirect. */ - return; - } - basesrc = GST_BASE_SRC_CAST (src); - GST_DEBUG_OBJECT (src, "got chunk of %" G_GSIZE_FORMAT " bytes", - chunk->length); - - /* Extract the GstBuffer from the SoupBuffer and set its fields. */ - *src->outbuf = GST_BUFFER_CAST (soup_buffer_get_owner (chunk)); - gst_buffer_ref (*src->outbuf); - GST_BUFFER_SIZE (*src->outbuf) = chunk->length; - GST_BUFFER_OFFSET (*src->outbuf) = basesrc->segment.last_stop; - - gst_buffer_set_caps (*src->outbuf, - (src->icy_caps) ? src-> - icy_caps : GST_PAD_CAPS (GST_BASE_SRC_PAD (basesrc))); - - new_position = src->read_position + chunk->length; - if (G_LIKELY (src->request_position == src->read_position)) - src->request_position = new_position; - src->read_position = new_position; - - src->ret = GST_FLOW_OK; - g_main_loop_quit (src->loop); - gst_soup_http_src_session_pause_message (src); -} - -static void -gst_soup_http_src_response_cb (SoupSession * session, SoupMessage * msg, - GstSoupHTTPSrc * src) -{ - if (G_UNLIKELY (msg != src->msg)) { - GST_DEBUG_OBJECT (src, "got response %d: %s, but not for current message", - msg->status_code, msg->reason_phrase); - return; - } - if (G_UNLIKELY (src->session_io_status != - GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_RUNNING) - && SOUP_STATUS_IS_REDIRECTION (msg->status_code)) { - /* Ignore redirections. */ - return; - } - GST_DEBUG_OBJECT (src, "got response %d: %s", msg->status_code, - 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); - g_main_loop_quit (src->loop); -} - -static void -gst_soup_http_src_parse_status (SoupMessage * msg, GstSoupHTTPSrc * src) -{ - if (SOUP_STATUS_IS_TRANSPORT_ERROR (msg->status_code)) { - switch (msg->status_code) { - case SOUP_STATUS_CANT_RESOLVE: - GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, - ("\"%s\": %s", src->location, msg->reason_phrase), - ("libsoup status code %d", msg->status_code)); - src->ret = GST_FLOW_ERROR; - break; - case SOUP_STATUS_CANT_RESOLVE_PROXY: - GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, - ("%s", msg->reason_phrase), - ("libsoup status code %d", msg->status_code)); - src->ret = GST_FLOW_ERROR; - break; - case SOUP_STATUS_CANT_CONNECT: - case SOUP_STATUS_CANT_CONNECT_PROXY: - case SOUP_STATUS_SSL_FAILED: - GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, - ("\"%s\": %s", src->location, msg->reason_phrase), - ("libsoup status code %d", msg->status_code)); - src->ret = GST_FLOW_ERROR; - break; - case SOUP_STATUS_IO_ERROR: - case SOUP_STATUS_MALFORMED: - GST_ELEMENT_ERROR (src, RESOURCE, READ, - ("\"%s\": %s", src->location, msg->reason_phrase), - ("libsoup status code %d", msg->status_code)); - src->ret = GST_FLOW_ERROR; - break; - case SOUP_STATUS_CANCELLED: - /* No error message when interrupted by program. */ - break; - } - } else if (SOUP_STATUS_IS_CLIENT_ERROR (msg->status_code) || - SOUP_STATUS_IS_REDIRECTION (msg->status_code) || - SOUP_STATUS_IS_SERVER_ERROR (msg->status_code)) { - /* Report HTTP error. */ - GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, - ("\"%s\": %s", src->location, msg->reason_phrase), - ("%d %s", msg->status_code, msg->reason_phrase)); - src->ret = GST_FLOW_ERROR; - } -} - -static gboolean -gst_soup_http_src_build_message (GstSoupHTTPSrc * src) -{ - src->msg = soup_message_new (SOUP_METHOD_GET, src->location); - if (!src->msg) { - GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, - (NULL), ("Error parsing URL \"%s\"", src->location)); - return FALSE; - } - src->session_io_status = GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_IDLE; - soup_message_headers_append (src->msg->request_headers, "Connection", - "close"); - if (src->iradio_mode) { - soup_message_headers_append (src->msg->request_headers, "icy-metadata", - "1"); - } - if (src->cookies) { - gchar **cookie; - - for (cookie = src->cookies; *cookie != NULL; cookie++) { - soup_message_headers_append (src->msg->request_headers, "Cookie", - *cookie); - } - } - - g_signal_connect (src->msg, "got_headers", - G_CALLBACK (gst_soup_http_src_got_headers_cb), src); - g_signal_connect (src->msg, "got_body", - G_CALLBACK (gst_soup_http_src_got_body_cb), src); - g_signal_connect (src->msg, "finished", - G_CALLBACK (gst_soup_http_src_finished_cb), src); - g_signal_connect (src->msg, "got_chunk", - G_CALLBACK (gst_soup_http_src_got_chunk_cb), src); - soup_message_set_flags (src->msg, SOUP_MESSAGE_OVERWRITE_CHUNKS | - (src->automatic_redirect ? 0 : SOUP_MESSAGE_NO_REDIRECT)); - soup_message_set_chunk_allocator (src->msg, - gst_soup_http_src_chunk_allocator, src, NULL); - 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->outbuf = outbuf; - do { - if (src->interrupted) { - gst_soup_http_src_cancel_message (src); - 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) { - GST_DEBUG_OBJECT (src, "EOS reached"); - break; - } - - switch (src->session_io_status) { - case GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_IDLE: - GST_DEBUG_OBJECT (src, "Queueing connection request"); - gst_soup_http_src_queue_message (src); - break; - case GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_QUEUED: - break; - case GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_RUNNING: - gst_soup_http_src_session_unpause_message (src); - break; - } - - if (src->ret == GST_FLOW_CUSTOM_ERROR) - g_main_loop_run (src->loop); - } while (src->ret == GST_FLOW_CUSTOM_ERROR); - - if (src->ret == GST_FLOW_CUSTOM_ERROR) - src->ret = GST_FLOW_UNEXPECTED; - return src->ret; -} - -static gboolean -gst_soup_http_src_start (GstBaseSrc * bsrc) -{ - GstSoupHTTPSrc *src = GST_SOUP_HTTP_SRC (bsrc); - - GST_DEBUG_OBJECT (src, "start(\"%s\")", src->location); - - if (!src->location) { - GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, - (NULL), ("Missing location property")); - return FALSE; - } - - src->context = g_main_context_new (); - - src->loop = g_main_loop_new (src->context, TRUE); - if (!src->loop) { - GST_ELEMENT_ERROR (src, LIBRARY, INIT, - (NULL), ("Failed to start GMainLoop")); - g_main_context_unref (src->context); - return FALSE; - } - - if (src->proxy == NULL) - src->session = - soup_session_async_new_with_options (SOUP_SESSION_ASYNC_CONTEXT, - src->context, SOUP_SESSION_USER_AGENT, src->user_agent, NULL); - else - src->session = - soup_session_async_new_with_options (SOUP_SESSION_ASYNC_CONTEXT, - src->context, SOUP_SESSION_PROXY_URI, src->proxy, - SOUP_SESSION_USER_AGENT, src->user_agent, NULL); - if (!src->session) { - GST_ELEMENT_ERROR (src, LIBRARY, INIT, - (NULL), ("Failed to create async session")); - return FALSE; - } - - return TRUE; -} - -static gboolean -gst_soup_http_src_stop (GstBaseSrc * bsrc) -{ - GstSoupHTTPSrc *src; - - src = GST_SOUP_HTTP_SRC (bsrc); - GST_DEBUG_OBJECT (src, "stop()"); - gst_soup_http_src_session_close (src); - if (src->loop) { - g_main_loop_unref (src->loop); - g_main_context_unref (src->context); - src->loop = NULL; - src->context = NULL; - } - - return TRUE; -} - -/* Interrupt a blocking request. */ -static gboolean -gst_soup_http_src_unlock (GstBaseSrc * bsrc) -{ - GstSoupHTTPSrc *src; - - src = GST_SOUP_HTTP_SRC (bsrc); - GST_DEBUG_OBJECT (src, "unlock()"); - - src->interrupted = TRUE; - if (src->loop) - g_main_loop_quit (src->loop); - return TRUE; -} - -/* Interrupt interrupt. */ -static gboolean -gst_soup_http_src_unlock_stop (GstBaseSrc * bsrc) -{ - GstSoupHTTPSrc *src; - - src = GST_SOUP_HTTP_SRC (bsrc); - GST_DEBUG_OBJECT (src, "unlock_stop()"); - - src->interrupted = FALSE; - return TRUE; -} - -static gboolean -gst_soup_http_src_get_size (GstBaseSrc * bsrc, guint64 * size) -{ - GstSoupHTTPSrc *src; - - src = GST_SOUP_HTTP_SRC (bsrc); - - if (src->have_size) { - GST_DEBUG_OBJECT (src, "get_size() = %" G_GUINT64_FORMAT, - src->content_size); - *size = src->content_size; - return TRUE; - } - GST_DEBUG_OBJECT (src, "get_size() = FALSE"); - return FALSE; -} - -static gboolean -gst_soup_http_src_is_seekable (GstBaseSrc * bsrc) -{ - GstSoupHTTPSrc *src = GST_SOUP_HTTP_SRC (bsrc); - - return src->seekable; -} - -static gboolean -gst_soup_http_src_do_seek (GstBaseSrc * bsrc, GstSegment * segment) -{ - GstSoupHTTPSrc *src = GST_SOUP_HTTP_SRC (bsrc); - - GST_DEBUG_OBJECT (src, "do_seek(%" G_GUINT64_FORMAT ")", segment->start); - - if (src->read_position == segment->start) - return TRUE; - - if (!src->seekable) - return FALSE; - - /* Wait for create() to handle the jump in offset. */ - src->request_position = segment->start; - return TRUE; -} - -static gboolean -gst_soup_http_src_set_location (GstSoupHTTPSrc * src, const gchar * uri) -{ - if (src->location) { - g_free (src->location); - src->location = NULL; - } - src->location = g_strdup (uri); - - return TRUE; -} - -static gboolean -gst_soup_http_src_set_proxy (GstSoupHTTPSrc * src, const gchar * uri) -{ - if (src->proxy) { - soup_uri_free (src->proxy); - src->proxy = NULL; - } - if (g_str_has_prefix (uri, "http://")) { - src->proxy = soup_uri_new (uri); - } else { - gchar *new_uri = g_strconcat ("http://", uri, NULL); - - src->proxy = soup_uri_new (new_uri); - g_free (new_uri); - } - - return TRUE; -} - -static guint -gst_soup_http_src_uri_get_type (void) -{ - return GST_URI_SRC; -} - -static gchar ** -gst_soup_http_src_uri_get_protocols (void) -{ - static gchar *protocols[] = { "http", "https", NULL }; - return protocols; -} - -static const gchar * -gst_soup_http_src_uri_get_uri (GstURIHandler * handler) -{ - GstSoupHTTPSrc *src = GST_SOUP_HTTP_SRC (handler); - - return src->location; -} - -static gboolean -gst_soup_http_src_uri_set_uri (GstURIHandler * handler, const gchar * uri) -{ - GstSoupHTTPSrc *src = GST_SOUP_HTTP_SRC (handler); - - return gst_soup_http_src_set_location (src, uri); -} - -static void -gst_soup_http_src_uri_handler_init (gpointer g_iface, gpointer iface_data) -{ - GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface; - - iface->get_type = gst_soup_http_src_uri_get_type; - iface->get_protocols = gst_soup_http_src_uri_get_protocols; - iface->get_uri = gst_soup_http_src_uri_get_uri; - iface->set_uri = gst_soup_http_src_uri_set_uri; -} - -static gboolean -plugin_init (GstPlugin * plugin) -{ - return gst_element_register (plugin, "souphttpsrc", GST_RANK_MARGINAL, - GST_TYPE_SOUP_HTTP_SRC); -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "soup", - "libsoup HTTP client src", - plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN) diff --git a/ext/soup/gstsouphttpsrc.h b/ext/soup/gstsouphttpsrc.h deleted file mode 100644 index f959a4f1..00000000 --- a/ext/soup/gstsouphttpsrc.h +++ /dev/null @@ -1,92 +0,0 @@ -/* GStreamer - * Copyright (C) 2007-2008 Wouter Cloetens <wouter@mind.be> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more - */ - -#ifndef __GST_SOUP_HTTP_SRC_H__ -#define __GST_SOUP_HTTP_SRC_H__ - -#include <gst/gst.h> -#include <gst/base/gstpushsrc.h> -#include <glib.h> - -G_BEGIN_DECLS - -#include <libsoup/soup.h> - -#define GST_TYPE_SOUP_HTTP_SRC \ - (gst_soup_http_src_get_type()) -#define GST_SOUP_HTTP_SRC(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SOUP_HTTP_SRC,GstSoupHTTPSrc)) -#define GST_SOUP_HTTP_SRC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), \ - GST_TYPE_SOUP_HTTP_SRC,GstSoupHTTPSrcClass)) -#define GST_IS_SOUP_HTTP_SRC(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SOUP_HTTP_SRC)) -#define GST_IS_SOUP_HTTP_SRC_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SOUP_HTTP_SRC)) - -typedef struct _GstSoupHTTPSrc GstSoupHTTPSrc; -typedef struct _GstSoupHTTPSrcClass GstSoupHTTPSrcClass; - -typedef enum { - GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_IDLE, - GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_QUEUED, - GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_RUNNING, -} GstSoupHTTPSrcSessionIOStatus; - -struct _GstSoupHTTPSrc { - GstPushSrc element; - - gchar *location; /* Full URI. */ - gchar *user_agent; /* User-Agent HTTP header. */ - gboolean automatic_redirect; /* Follow redirects. */ - SoupURI *proxy; /* HTTP proxy URI. */ - gchar **cookies; /* HTTP request cookies. */ - GMainContext *context; /* I/O context. */ - GMainLoop *loop; /* Event loop. */ - SoupSession *session; /* Async context. */ - GstSoupHTTPSrcSessionIOStatus session_io_status; - /* Async I/O status. */ - SoupMessage *msg; /* Request message. */ - GstFlowReturn ret; /* Return code from callback. */ - GstBuffer **outbuf; /* Return buffer allocated by callback. */ - gboolean interrupted; /* Signal unlock(). */ - gboolean retry; /* Should attempt to reconnect. */ - - gboolean have_size; /* Received and parsed Content-Length - header. */ - guint64 content_size; /* Value of Content-Length header. */ - guint64 read_position; /* Current position. */ - gboolean seekable; /* FALSE if the server does not support - Range. */ - guint64 request_position; /* Seek to this position. */ - - /* Shoutcast/icecast metadata extraction handling. */ - gboolean iradio_mode; - GstCaps *icy_caps; - gchar *iradio_name; - gchar *iradio_genre; - gchar *iradio_url; - gchar *iradio_title; -}; - -struct _GstSoupHTTPSrcClass { - GstPushSrcClass parent_class; -}; - -GType gst_soup_http_src_get_type (void); - -G_END_DECLS - -#endif /* __GST_SOUP_HTTP_SRC_H__ */ - diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am index c2d880c7..aae45b7c 100644 --- a/tests/check/Makefile.am +++ b/tests/check/Makefile.am @@ -53,12 +53,6 @@ else check_ofa = endif -if USE_SOUP -check_soup = elements/souphttpsrc -else -check_soup = -endif - if USE_TIMIDITY check_timidity=elements/timidity else @@ -80,7 +74,6 @@ check_PROGRAMS = \ $(check_mplex) \ $(check_neon) \ $(check_ofa) \ - $(check_soup) \ $(check_timidity) \ elements/interleave \ elements/rganalysis \ @@ -99,5 +92,3 @@ LDADD = $(GST_OBJ_LIBS) $(GST_CHECK_LIBS) $(CHECK_LIBS) elements_timidity_CFLAGS = $(GST_BASE_CFLAGS) $(AM_CFLAGS) elements_timidity_LDADD = $(GST_BASE_LIBS) $(LDADD) -elements_souphttpsrc_CFLAGS = $(SOUP_CFLAGS) $(AM_CFLAGS) -elements_souphttpsrc_LDADD = $(SOUP_LIBS) $(LDADD) diff --git a/tests/check/elements/souphttpsrc.c b/tests/check/elements/souphttpsrc.c deleted file mode 100644 index be7aa728..00000000 --- a/tests/check/elements/souphttpsrc.c +++ /dev/null @@ -1,453 +0,0 @@ -/* GStreamer unit tests for the souphttpsrc element - * Copyright (C) 2006-2007 Tim-Philipp Müller <tim centricular net> - * Copyright (C) 2008 Wouter Cloetens <wouter@mind.be> - * Copyright (C) 2001-2003, Ximian, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include <glib.h> -#include <glib/gprintf.h> -#include <libsoup/soup-address.h> -#include <libsoup/soup-message.h> -#include <libsoup/soup-server.h> -#include <gst/check/gstcheck.h> - -static int http_port = 0, https_port = 0; -gboolean redirect = TRUE; -static const char **cookies = NULL; - -static int run_server (int *http_port, int *https_port); - - -static void -handoff_cb (GstElement * fakesink, GstBuffer * buf, GstPad * pad, - GstBuffer ** p_outbuf) -{ - GST_LOG ("handoff, buf = %p", buf); - if (*p_outbuf == NULL) - *p_outbuf = gst_buffer_ref (buf); -} - -int -run_test (const char *format, ...) -{ - GstStateChangeReturn ret; - GstElement *pipe, *src, *sink; - GstBuffer *buf = NULL; - GstMessage *msg; - gchar *url; - va_list args; - int rc = -1; - - pipe = gst_pipeline_new (NULL); - - src = gst_element_factory_make ("souphttpsrc", NULL); - fail_unless (src != NULL); - - sink = gst_element_factory_make ("fakesink", NULL); - fail_unless (sink != NULL); - - gst_bin_add (GST_BIN (pipe), src); - gst_bin_add (GST_BIN (pipe), sink); - fail_unless (gst_element_link (src, sink)); - - if (http_port == 0) { - GST_DEBUG ("failed to start soup http server"); - } - fail_unless (http_port != 0); - va_start (args, format); - g_vasprintf (&url, format, args); - va_end (args); - fail_unless (url != NULL); - g_object_set (src, "location", url, NULL); - g_free (url); - - g_object_set (src, "automatic-redirect", redirect, NULL); - if (cookies != NULL) - g_object_set (src, "cookies", cookies, NULL); - g_object_set (sink, "signal-handoffs", TRUE, NULL); - g_signal_connect (sink, "preroll-handoff", G_CALLBACK (handoff_cb), &buf); - - ret = gst_element_set_state (pipe, GST_STATE_PAUSED); - if (ret != GST_STATE_CHANGE_ASYNC) { - GST_DEBUG ("failed to start up soup http src, ret = %d", ret); - goto done; - } - - gst_element_set_state (pipe, GST_STATE_PLAYING); - msg = gst_bus_poll (GST_ELEMENT_BUS (pipe), - GST_MESSAGE_EOS | GST_MESSAGE_ERROR, -1); - if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) { - gchar *debug = NULL; - GError *err = NULL; - - gst_message_parse_error (msg, &err, &debug); - GST_INFO ("error: %s", err->message); - if (g_str_has_suffix (err->message, "Not Found")) - rc = 404; - else if (g_str_has_suffix (err->message, "Forbidden")) - rc = 403; - else if (g_str_has_suffix (err->message, "Found")) - rc = 302; - GST_INFO ("debug: %s", debug); - g_error_free (err); - g_free (debug); - gst_message_unref (msg); - goto done; - } - gst_message_unref (msg); - - /* don't wait for more than 10 seconds */ - ret = gst_element_get_state (pipe, NULL, NULL, 10 * GST_SECOND); - GST_LOG ("ret = %u", ret); - - if (buf == NULL) { - /* we want to test the buffer offset, nothing else; if there's a failure - * it might be for lots of reasons (no network connection, whatever), we're - * not interested in those */ - GST_DEBUG ("didn't manage to get data within 10 seconds, skipping test"); - goto done; - } - - GST_DEBUG ("buffer offset = %" G_GUINT64_FORMAT, GST_BUFFER_OFFSET (buf)); - - /* first buffer should have a 0 offset */ - fail_unless (GST_BUFFER_OFFSET (buf) == 0); - gst_buffer_unref (buf); - rc = 0; - -done: - - gst_element_set_state (pipe, GST_STATE_NULL); - gst_object_unref (pipe); - return rc; -} - -GST_START_TEST (test_first_buffer_has_offset) -{ - fail_unless (run_test ("http://127.0.0.1:%d/", http_port) == 0); -} - -GST_END_TEST; - -GST_START_TEST (test_not_found) -{ - fail_unless (run_test ("http://127.0.0.1:%d/404", http_port) == 404); -} - -GST_END_TEST; - -GST_START_TEST (test_forbidden) -{ - fail_unless (run_test ("http://127.0.0.1:%d/403", http_port) == 403); -} - -GST_END_TEST; - -GST_START_TEST (test_redirect_no) -{ - redirect = FALSE; - fail_unless (run_test ("http://127.0.0.1:%d/302", http_port) == 302); -} - -GST_END_TEST; - -GST_START_TEST (test_redirect_yes) -{ - redirect = TRUE; - fail_unless (run_test ("http://127.0.0.1:%d/302", http_port) == 0); -} - -GST_END_TEST; - -GST_START_TEST (test_https) -{ - if (!https_port) - GST_INFO ("Failed to start an HTTPS server; let's just skip this test."); - else - fail_unless (run_test ("https://127.0.0.1:%d/", https_port) == 0); -} - -GST_END_TEST; - -GST_START_TEST (test_cookies) -{ - static const char *biscotti[] = { "delacre=yummie", "koekje=lu", NULL }; - int rc; - - cookies = biscotti; - rc = run_test ("http://127.0.0.1:%d/", http_port); - cookies = NULL; - fail_unless (rc == 0); -} - -GST_END_TEST; - -static gboolean icy_caps = FALSE; - -static void -got_buffer (GstElement * fakesink, GstBuffer * buf, GstPad * pad, - gpointer user_data) -{ - GstStructure *s; - - /* Caps can be anything if we don't except icy caps */ - if (!icy_caps) - return; - - /* Otherwise they _must_ be "application/x-icy" */ - fail_unless (GST_BUFFER_CAPS (buf) != NULL); - s = gst_caps_get_structure (GST_BUFFER_CAPS (buf), 0); - fail_unless_equals_string (gst_structure_get_name (s), "application/x-icy"); -} - -GST_START_TEST (test_icy_stream) -{ - GstElement *pipe, *src, *sink; - GstMessage *msg; - - pipe = gst_pipeline_new (NULL); - - src = gst_element_factory_make ("souphttpsrc", NULL); - fail_unless (src != NULL); - g_object_set (src, "iradio-mode", TRUE, NULL); - - sink = gst_element_factory_make ("fakesink", NULL); - fail_unless (sink != NULL); - g_object_set (sink, "signal-handoffs", TRUE, NULL); - g_signal_connect (sink, "handoff", G_CALLBACK (got_buffer), NULL); - - gst_bin_add (GST_BIN (pipe), src); - gst_bin_add (GST_BIN (pipe), sink); - fail_unless (gst_element_link (src, sink)); - - /* First try Virgin Radio Ogg stream, to see if there's connectivity and all - * (which is an attempt to work around the completely horrid error reporting - * and that we can't distinguish different types of failures here). */ - - g_object_set (src, "location", "http://ogg2.smgradio.com/vr32.ogg", NULL); - g_object_set (src, "num-buffers", 1, NULL); - icy_caps = FALSE; - gst_element_set_state (pipe, GST_STATE_PLAYING); - - msg = gst_bus_poll (GST_ELEMENT_BUS (pipe), - GST_MESSAGE_EOS | GST_MESSAGE_ERROR, -1); - if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) { - GST_INFO ("looks like there's no net connectivity or sgmradio.com is " - "down. In any case, let's just skip this test"); - gst_message_unref (msg); - goto done; - } - gst_message_unref (msg); - msg = NULL; - gst_element_set_state (pipe, GST_STATE_NULL); - - /* Now, if the ogg stream works, the mp3 shoutcast stream should work as - * well (time will tell if that's true) */ - - /* Virgin Radio 32kbps mp3 shoutcast stream */ - g_object_set (src, "location", "http://mp3-vr-32.smgradio.com:80/", NULL); - - - /* EOS after the first buffer */ - g_object_set (src, "num-buffers", 1, NULL); - icy_caps = TRUE; - gst_element_set_state (pipe, GST_STATE_PLAYING); - msg = gst_bus_poll (GST_ELEMENT_BUS (pipe), - GST_MESSAGE_EOS | GST_MESSAGE_ERROR, -1); - - if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_EOS) { - GST_DEBUG ("success, we're done here"); - gst_message_unref (msg); - goto done; - } - - { - GError *err = NULL; - - gst_message_parse_error (msg, &err, NULL); - gst_message_unref (msg); - g_error ("Error with ICY mp3 shoutcast stream: %s", err->message); - g_error_free (err); - } - -done: - icy_caps = FALSE; - - gst_element_set_state (pipe, GST_STATE_NULL); - gst_object_unref (pipe); -} - -GST_END_TEST; - -static Suite * -souphttpsrc_suite (void) -{ - g_type_init (); - g_thread_init (NULL); - - Suite *s = suite_create ("souphttpsrc"); - TCase *tc_chain = tcase_create ("general"); - TCase *tc_internet = tcase_create ("internet"); - - suite_add_tcase (s, tc_chain); - run_server (&http_port, &https_port); - tcase_add_test (tc_chain, test_first_buffer_has_offset); - tcase_add_test (tc_chain, test_https); - tcase_add_test (tc_chain, test_redirect_yes); - tcase_add_test (tc_chain, test_redirect_no); - tcase_add_test (tc_chain, test_not_found); - tcase_add_test (tc_chain, test_forbidden); - tcase_add_test (tc_chain, test_cookies); - - suite_add_tcase (s, tc_internet); - tcase_set_timeout (tc_internet, 250); - tcase_add_test (tc_internet, test_icy_stream); - - return s; -} - -GST_CHECK_MAIN (souphttpsrc); - -static void -do_get (SoupMessage * msg, const char *path) -{ - char *uri; - int buflen = 4096; - SoupKnownStatusCode status = SOUP_STATUS_OK; - - uri = soup_uri_to_string (soup_message_get_uri (msg), FALSE); - GST_DEBUG ("request: \"%s\"", uri); - - if (!strcmp (path, "/301")) - status = SOUP_STATUS_MOVED_PERMANENTLY; - else if (!strcmp (path, "/302")) - status = SOUP_STATUS_MOVED_TEMPORARILY; - else if (!strcmp (path, "/307")) - status = SOUP_STATUS_TEMPORARY_REDIRECT; - else if (!strcmp (path, "/403")) - status = SOUP_STATUS_FORBIDDEN; - else if (!strcmp (path, "/404")) - status = SOUP_STATUS_NOT_FOUND; - - if (SOUP_STATUS_IS_REDIRECTION (status)) { - char *redir_uri; - - redir_uri = g_strdup_printf ("%s-redirected", uri); - soup_message_headers_append (msg->response_headers, "Location", redir_uri); - g_free (redir_uri); - } - if (status != SOUP_STATUS_OK) - goto leave; - - if (msg->method == SOUP_METHOD_GET) { - char *buf; - - buf = g_malloc (buflen); - memset (buf, 0, buflen); - soup_message_body_append (msg->response_body, SOUP_MEMORY_TAKE, - buf, buflen); - } else { /* msg->method == SOUP_METHOD_HEAD */ - - char *length; - - /* We could just use the same code for both GET and - * HEAD. But we'll optimize and avoid the extra - * malloc. - */ - length = g_strdup_printf ("%lu", (gulong) buflen); - soup_message_headers_append (msg->response_headers, - "Content-Length", length); - g_free (length); - } - -leave: - soup_message_set_status (msg, status); - g_free (uri); -} - -static void -print_header (const char *name, const char *value, gpointer data) -{ - GST_DEBUG ("header: %s: %s", name, value); -} - -static void -server_callback (SoupServer * server, SoupMessage * msg, - const char *path, GHashTable * query, - SoupClientContext * context, gpointer data) -{ - GST_DEBUG ("%s %s HTTP/1.%d", msg->method, path, - soup_message_get_http_version (msg)); - soup_message_headers_foreach (msg->request_headers, print_header, NULL); - if (msg->request_body->length) - GST_DEBUG ("%s", msg->request_body->data); - - if (msg->method == SOUP_METHOD_GET || msg->method == SOUP_METHOD_HEAD) - do_get (msg, path); - else - soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED); - - GST_DEBUG (" -> %d %s", msg->status_code, msg->reason_phrase); -} - -int -run_server (int *http_port, int *https_port) -{ - SoupServer *server, *ssl_server; - int port = SOUP_ADDRESS_ANY_PORT; - int ssl_port = SOUP_ADDRESS_ANY_PORT; - const char *ssl_cert_file = "test-cert.pem", *ssl_key_file = "test-key.pem"; - static int server_running = 0; - - if (server_running) - return 0; - server_running = 1; - - *http_port = *https_port = 0; - - server = soup_server_new (SOUP_SERVER_PORT, port, NULL); - if (!server) { - GST_DEBUG ("Unable to bind to server port %d", port); - return 1; - } - *http_port = soup_server_get_port (server); - GST_INFO ("HTTP server listening on port %d", *http_port); - soup_server_add_handler (server, NULL, server_callback, NULL, NULL); - soup_server_run_async (server); - - if (ssl_cert_file && ssl_key_file) { - ssl_server = soup_server_new (SOUP_SERVER_PORT, ssl_port, - SOUP_SERVER_SSL_CERT_FILE, ssl_cert_file, - SOUP_SERVER_SSL_KEY_FILE, ssl_key_file, NULL); - - if (!ssl_server) { - GST_DEBUG ("Unable to bind to SSL server port %d", ssl_port); - return 1; - } - *https_port = soup_server_get_port (ssl_server); - GST_INFO ("HTTPS server listening on port %d", *https_port); - soup_server_add_handler (ssl_server, NULL, server_callback, NULL, NULL); - soup_server_run_async (ssl_server); - } - - return 0; -} diff --git a/tests/check/test-cert.pem b/tests/check/test-cert.pem deleted file mode 100644 index a6b66083..00000000 --- a/tests/check/test-cert.pem +++ /dev/null @@ -1,22 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDjzCCAvigAwIBAgIBADANBgkqhkiG9w0BAQQFADCBkjELMAkGA1UEBhMCVVMx -FjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxDzANBgNVBAcTBkJvc3RvbjEPMA0GA1UE -ChMGWGltaWFuMRUwEwYDVQQLEwxTb3VwIEtpdGNoZW4xEjAQBgNVBAMTCWxvY2Fs -aG9zdDEeMBwGCSqGSIb3DQEJARYPc291cEB4aW1pYW4uY29tMB4XDTAzMDkyMzE4 -Mzc0MVoXDTEzMDkyMzE4Mzc0MVowgZIxCzAJBgNVBAYTAlVTMRYwFAYDVQQIEw1N -YXNzYWNodXNldHRzMQ8wDQYDVQQHEwZCb3N0b24xDzANBgNVBAoTBlhpbWlhbjEV -MBMGA1UECxMMU291cCBLaXRjaGVuMRIwEAYDVQQDEwlsb2NhbGhvc3QxHjAcBgkq -hkiG9w0BCQEWD3NvdXBAeGltaWFuLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw -gYkCgYEAwzT/WxfdXqb2hbyjQav3FtN7tLxj3UbZKCKDYlizBsNLxb9exfebhV4h -CoAcaSNvLUnk3tAXnk+BDsIC1V4SbwqHYR17PnO3YZ8fkNwh5RGZwNx+zafdfFyu -+3Sh+mE03bljpDlTsgPL8CiFCd68MPRnuHoKt5iTpSyLC6Df0qcCAwEAAaOB8jCB -7zAdBgNVHQ4EFgQU9A9omrgBK5Kkl6FRxrgJU2voj4Uwgb8GA1UdIwSBtzCBtIAU -9A9omrgBK5Kkl6FRxrgJU2voj4WhgZikgZUwgZIxCzAJBgNVBAYTAlVTMRYwFAYD -VQQIEw1NYXNzYWNodXNldHRzMQ8wDQYDVQQHEwZCb3N0b24xDzANBgNVBAoTBlhp -bWlhbjEVMBMGA1UECxMMU291cCBLaXRjaGVuMRIwEAYDVQQDEwlsb2NhbGhvc3Qx -HjAcBgkqhkiG9w0BCQEWD3NvdXBAeGltaWFuLmNvbYIBADAMBgNVHRMEBTADAQH/ -MA0GCSqGSIb3DQEBBAUAA4GBAGCV56N7bEDNdE76T8i68gS00NIVVosVQjS39Ojd -ED+rvq0YYvuc2UXlzAonuCJfwFc73g4wSIjS0xijF5rnugZ+aay0LNv2y+Rf34CQ -RNswrwurFjlxgTOO+Wx2IM64mAnBfj43M8uKEZFqAiGKrZZ0xIqyUMlku0FgXDH2 -Jvpg ------END CERTIFICATE----- diff --git a/tests/check/test-key.pem b/tests/check/test-key.pem deleted file mode 100644 index 9bea9bf2..00000000 --- a/tests/check/test-key.pem +++ /dev/null @@ -1,15 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIICWwIBAAKBgQDDNP9bF91epvaFvKNBq/cW03u0vGPdRtkoIoNiWLMGw0vFv17F -95uFXiEKgBxpI28tSeTe0BeeT4EOwgLVXhJvCodhHXs+c7dhnx+Q3CHlEZnA3H7N -p918XK77dKH6YTTduWOkOVOyA8vwKIUJ3rww9Ge4egq3mJOlLIsLoN/SpwIDAQAB -AoGAOGAi6zzuKrrPcXo0L/ApEQeMr3rE4I/ogUXOaeWx9l8KkBafmU7UNGUl57Fu -AxM/tXWkypCQcaEGZau0Q8jCS5wKgynNi72F4OzBqgjgW4vvtrjfC1LagnCd2ZMX -V5XVECjO/sEDg0hJeOsXlKbECAgvHMU3dSCGO7DmuG9tIxkCQQDsth1VvVjOdfp6 -klOfYzbAM1p9HIcNPJMeuBFqq//UHX4aPqh/6G6W06TOTN+bjZBmitG9yjV958t2 -rPxl64f7AkEA0x0WOLm5S0LNsv7zwjXuTcj+NCHL36b3dK90oxX8Gq69PANL/EJY -ItpHNLgzzo4DRmQy8q0WZlC9HYk1YljERQJAEN7+AkFnlfeErb3GJgMNQO+oEGi7 -G29o0PSvkRnHNxgPB9HVcqBfWXKmOWnzOgQB+b0FK/DAlUOzFbdImf8KhwJAFLty -hzeV/tIcqUtoXNY3BOSMMkpvXxNikc75QVrTWzt10gLw32EUjreo7oB4dfx0TeFh -L3vYC0w6hkAHQhU9kQJAPSEQ+Bqzlk6BrQNrNFEVzi1Rwpz7LOzhOjuYW6bsiAdX -axA4r6Xh25x08ZU7cqX7gwVLHL6pgrEKuUs0Nc5Klg== ------END RSA PRIVATE KEY----- |