summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac3
-rw-r--r--gst-libs/gst/Makefile.am1
-rw-r--r--gst-libs/gst/http/Makefile.am26
-rw-r--r--gst-libs/gst/http/gsthttpcookie.c504
-rw-r--r--gst-libs/gst/http/gsthttpcookie.h111
-rw-r--r--gst-libs/gst/http/gsthttpcookiejar.c381
-rw-r--r--gst-libs/gst/http/gsthttpcookiejar.h84
-rw-r--r--pkgconfig/Makefile.am5
-rw-r--r--pkgconfig/gstreamer-http-uninstalled.pc.in16
-rw-r--r--pkgconfig/gstreamer-http.pc.in16
-rw-r--r--pkgconfig/gstreamer-plugins-base-uninstalled.pc.in4
-rw-r--r--pkgconfig/gstreamer-plugins-base.pc.in2
12 files changed, 1149 insertions, 4 deletions
diff --git a/configure.ac b/configure.ac
index 44db09836..051b22f1f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -867,6 +867,7 @@ gst-libs/gst/allocators/Makefile
gst-libs/gst/audio/Makefile
gst-libs/gst/app/Makefile
gst-libs/gst/fft/Makefile
+gst-libs/gst/http/Makefile
gst-libs/gst/riff/Makefile
gst-libs/gst/rtp/Makefile
gst-libs/gst/rtsp/Makefile
@@ -885,6 +886,8 @@ pkgconfig/gstreamer-app.pc
pkgconfig/gstreamer-app-uninstalled.pc
pkgconfig/gstreamer-fft.pc
pkgconfig/gstreamer-fft-uninstalled.pc
+pkgconfig/gstreamer-http.pc
+pkgconfig/gstreamer-http-uninstalled.pc
pkgconfig/gstreamer-pbutils.pc
pkgconfig/gstreamer-pbutils-uninstalled.pc
pkgconfig/gstreamer-riff.pc
diff --git a/gst-libs/gst/Makefile.am b/gst-libs/gst/Makefile.am
index ae796ff90..a00381eea 100644
--- a/gst-libs/gst/Makefile.am
+++ b/gst-libs/gst/Makefile.am
@@ -1,6 +1,7 @@
SUBDIRS = \
tag \
fft \
+ http \
rtp \
sdp \
rtsp \
diff --git a/gst-libs/gst/http/Makefile.am b/gst-libs/gst/http/Makefile.am
new file mode 100644
index 000000000..6fa8587e1
--- /dev/null
+++ b/gst-libs/gst/http/Makefile.am
@@ -0,0 +1,26 @@
+lib_LTLIBRARIES = libgsthttp-@GST_API_VERSION@.la
+
+libgsthttp_@GST_API_VERSION@_la_SOURCES = \
+ gsthttpcookie.c gsthttpcookiejar.c
+
+libgsthttp_@GST_API_VERSION@includedir = \
+ $(includedir)/gstreamer-@GST_API_VERSION@/gst/http
+
+libgsthttp_@GST_API_VERSION@include_HEADERS = \
+ gsthttpcookie.h gsthttpcookiejar.h
+
+noinst_HEADERS =
+
+libgsthttp_@GST_API_VERSION@_la_CFLAGS = \
+ $(GST_PLUGINS_BAD_CFLAGS) \
+ -DGST_USE_UNSTABLE_API \
+ $(GST_CFLAGS)
+
+libgsthttp_@GST_API_VERSION@_la_LIBADD = \
+ $(GST_BASE_LIBS) \
+ $(GST_LIBS)
+
+libgsthttp_@GST_API_VERSION@_la_LDFLAGS = \
+ $(GST_LIB_LDFLAGS) \
+ $(GST_ALL_LDFLAGS) \
+ $(GST_LT_LDFLAGS)
diff --git a/gst-libs/gst/http/gsthttpcookie.c b/gst-libs/gst/http/gsthttpcookie.c
new file mode 100644
index 000000000..0ab3d8728
--- /dev/null
+++ b/gst-libs/gst/http/gsthttpcookie.c
@@ -0,0 +1,504 @@
+/* GStreamer HTTP library
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * Copyright (C) 2016 Samsung Electronics. All rights reserved.
+ * Author: Thiago Santos <thiagoss@osg.samsung.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+/*
+ * This code was copied from libsoup at commit
+ * 45cf9db7d46ff6ecabd6bbd4e7ae99cfefbc1626
+ * on 20/01/2016.
+ *
+ * libsoup is LGPL v2.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "gsthttpcookie.h"
+
+/**
+ * SECTION:gst-http-cookie
+ * @short_description: HTTP Cookies
+ * @see_also: #GstHttpCookieJar
+ *
+ * #GstHttpCookie implements HTTP cookies, as described by <ulink
+ * url="http://tools.ietf.org/html/rfc6265.txt">RFC 6265</ulink>.
+ **/
+
+/**
+ * GstHttpCookie:
+ * @name: the cookie name
+ * @value: the cookie value
+ * @domain: the "domain" attribute, or else the hostname that the
+ * cookie came from.
+ * @path: the "path" attribute, or %NULL
+ * @expires: the cookie expiration time, or %NULL for a session cookie
+ * @secure: %TRUE if the cookie should only be tranferred over SSL
+ * @http_only: %TRUE if the cookie should not be exposed to scripts
+ *
+ * An HTTP cookie.
+ *
+ * @name and @value will be set for all cookies. If the cookie is
+ * generated from a string that appears to have no name, then @name
+ * will be the empty string.
+ *
+ * @domain and @path give the host or domain, and path within that
+ * host/domain, to restrict this cookie to. If @domain starts with
+ * ".", that indicates a domain (which matches the string after the
+ * ".", or any hostname that has @domain as a suffix). Otherwise, it
+ * is a hostname and must match exactly.
+ *
+ * @expires will be non-%NULL if the cookie uses either the original
+ * "expires" attribute, or the newer "max-age" attribute. If @expires
+ * is %NULL, it indicates that neither "expires" nor "max-age" was
+ * specified, and the cookie expires at the end of the session.
+ *
+ * If @http_only is set, the cookie should not be exposed to untrusted
+ * code (eg, javascript), so as to minimize the danger posed by
+ * cross-site scripting attacks.
+ *
+ * Since: 1.10
+ **/
+
+G_DEFINE_BOXED_TYPE (GstHttpCookie, gst_http_cookie, gst_http_cookie_copy,
+ gst_http_cookie_free);
+
+/**
+ * gst_http_cookie_copy:
+ * @cookie: a #GstHttpCookie
+ *
+ * Copies @cookie.
+ *
+ * Return value: a copy of @cookie
+ *
+ * Since: 1.10
+ **/
+GstHttpCookie *
+gst_http_cookie_copy (GstHttpCookie * cookie)
+{
+ GstHttpCookie *copy = g_slice_new0 (GstHttpCookie);
+
+ copy->name = g_strdup (cookie->name);
+ copy->value = g_strdup (cookie->value);
+ copy->domain = g_strdup (cookie->domain);
+ copy->path = g_strdup (cookie->path);
+ if (cookie->expires)
+ copy->expires = g_date_time_ref (cookie->expires);
+ copy->secure = cookie->secure;
+ copy->http_only = cookie->http_only;
+
+ return copy;
+}
+
+static GstHttpCookie *
+cookie_new_internal (const char *name, const char *value,
+ const char *domain, const char *path, int max_age)
+{
+ GstHttpCookie *cookie;
+
+ cookie = g_slice_new0 (GstHttpCookie);
+ cookie->name = g_strdup (name);
+ cookie->value = g_strdup (value);
+ cookie->domain = g_strdup (domain);
+ cookie->path = g_strdup (path);
+ gst_http_cookie_set_max_age (cookie, max_age);
+
+ return cookie;
+}
+
+/**
+ * gst_http_cookie_new:
+ * @name: cookie name
+ * @value: cookie value
+ * @domain: cookie domain or hostname
+ * @path: cookie path, or %NULL
+ * @max_age: max age of the cookie, or -1 for a session cookie
+ *
+ * Creates a new #GstHttpCookie with the given attributes. (Use
+ * gst_http_cookie_set_secure() and gst_http_cookie_set_http_only() if you
+ * need to set those attributes on the returned cookie.)
+ *
+ * If @domain starts with ".", that indicates a domain (which matches
+ * the string after the ".", or any hostname that has @domain as a
+ * suffix). Otherwise, it is a hostname and must match exactly.
+ *
+ * @max_age is used to set the "expires" attribute on the cookie; pass
+ * -1 to not include the attribute (indicating that the cookie expires
+ * with the current session), 0 for an already-expired cookie, or a
+ * lifetime in seconds.
+ *
+ * Return value: a new #GstHttpCookie.
+ *
+ * Since: 1.10
+ **/
+GstHttpCookie *
+gst_http_cookie_new (const char *name, const char *value,
+ const char *domain, const char *path, int max_age)
+{
+ g_return_val_if_fail (name != NULL, NULL);
+ g_return_val_if_fail (value != NULL, NULL);
+
+ /* We ought to return if domain is NULL too, but this used to
+ * do be incorrectly documented as legal, and it wouldn't
+ * break anything as long as you called
+ * gst_http_cookie_set_domain() immediately after. So we warn but
+ * don't return, to discourage that behavior but not actually
+ * break anyone doing it.
+ */
+ g_warn_if_fail (domain != NULL);
+
+ return cookie_new_internal (name, value, domain, path, max_age);
+}
+
+/**
+ * gst_http_cookie_get_name:
+ * @cookie: a #GstHttpCookie
+ *
+ * Gets @cookie's name
+ *
+ * Return value: @cookie's name
+ *
+ * Since: 1.10
+ **/
+const char *
+gst_http_cookie_get_name (GstHttpCookie * cookie)
+{
+ return cookie->name;
+}
+
+/**
+ * gst_http_cookie_set_name:
+ * @cookie: a #GstHttpCookie
+ * @name: the new name
+ *
+ * Sets @cookie's name to @name
+ *
+ * Since: 1.10
+ **/
+void
+gst_http_cookie_set_name (GstHttpCookie * cookie, const char *name)
+{
+ g_free (cookie->name);
+ cookie->name = g_strdup (name);
+}
+
+/**
+ * gst_http_cookie_get_value:
+ * @cookie: a #GstHttpCookie
+ *
+ * Gets @cookie's value
+ *
+ * Return value: @cookie's value
+ *
+ * Since: 1.10
+ **/
+const char *
+gst_http_cookie_get_value (GstHttpCookie * cookie)
+{
+ return cookie->value;
+}
+
+/**
+ * gst_http_cookie_set_value:
+ * @cookie: a #GstHttpCookie
+ * @value: the new value
+ *
+ * Sets @cookie's value to @value
+ *
+ * Since: 1.10
+ **/
+void
+gst_http_cookie_set_value (GstHttpCookie * cookie, const char *value)
+{
+ g_free (cookie->value);
+ cookie->value = g_strdup (value);
+}
+
+/**
+ * gst_http_cookie_get_domain:
+ * @cookie: a #GstHttpCookie
+ *
+ * Gets @cookie's domain
+ *
+ * Return value: @cookie's domain
+ *
+ * Since: 1.10
+ **/
+const char *
+gst_http_cookie_get_domain (GstHttpCookie * cookie)
+{
+ return cookie->domain;
+}
+
+/**
+ * gst_http_cookie_set_domain:
+ * @cookie: a #GstHttpCookie
+ * @domain: the new domain
+ *
+ * Sets @cookie's domain to @domain
+ *
+ * Since: 1.10
+ **/
+void
+gst_http_cookie_set_domain (GstHttpCookie * cookie, const char *domain)
+{
+ g_free (cookie->domain);
+ cookie->domain = g_strdup (domain);
+}
+
+/**
+ * gst_http_cookie_get_path:
+ * @cookie: a #GstHttpCookie
+ *
+ * Gets @cookie's path
+ *
+ * Return value: @cookie's path
+ *
+ * Since: 1.10
+ **/
+const char *
+gst_http_cookie_get_path (GstHttpCookie * cookie)
+{
+ return cookie->path;
+}
+
+/**
+ * gst_http_cookie_set_path:
+ * @cookie: a #GstHttpCookie
+ * @path: the new path
+ *
+ * Sets @cookie's path to @path
+ *
+ * Since: 1.10
+ **/
+void
+gst_http_cookie_set_path (GstHttpCookie * cookie, const char *path)
+{
+ g_free (cookie->path);
+ cookie->path = g_strdup (path);
+}
+
+/**
+ * gst_http_cookie_set_max_age:
+ * @cookie: a #GstHttpCookie
+ * @max_age: the new max age
+ *
+ * Sets @cookie's max age to @max_age. If @max_age is -1, the cookie
+ * is a session cookie, and will expire at the end of the client's
+ * session. Otherwise, it is the number of seconds until the cookie
+ * expires. (A value of 0 indicates that the cookie should be
+ * considered already-expired.)
+ *
+ * (This sets the same property as gst_http_cookie_set_expires().)
+ *
+ * Since: 1.10
+ **/
+void
+gst_http_cookie_set_max_age (GstHttpCookie * cookie, int max_age)
+{
+ if (cookie->expires)
+ g_date_time_unref (cookie->expires);
+
+ if (max_age == -1)
+ cookie->expires = NULL;
+ else if (max_age == 0) {
+ /* Use a date way in the past, to protect against
+ * clock skew.
+ */
+ cookie->expires = g_date_time_new (NULL, 1970, 1, 1, 0, 0, 0);
+ } else {
+ GDateTime *now = g_date_time_new_now_local ();
+ cookie->expires = g_date_time_add_seconds (now, max_age);
+ g_date_time_unref (now);
+ }
+}
+
+/**
+ * gst_http_cookie_get_expires:
+ * @cookie: a #GstHttpCookie
+ *
+ * Gets @cookie's expiration time
+ *
+ * Return value: (transfer none): @cookie's expiration time, which is
+ * owned by @cookie and should not be modified or freed.
+ *
+ * Since: 1.10
+ **/
+GDateTime *
+gst_http_cookie_get_expires (GstHttpCookie * cookie)
+{
+ return cookie->expires;
+}
+
+/**
+ * gst_http_cookie_set_expires:
+ * @cookie: a #GstHttpCookie
+ * @expires: the new expiration time, or %NULL
+ *
+ * Sets @cookie's expiration time to @expires. If @expires is %NULL,
+ * @cookie will be a session cookie and will expire at the end of the
+ * client's session.
+ *
+ * (This sets the same property as gst_http_cookie_set_max_age().)
+ *
+ * Since: 1.10
+ **/
+void
+gst_http_cookie_set_expires (GstHttpCookie * cookie, GDateTime * expires)
+{
+ if (cookie->expires)
+ g_date_time_unref (cookie->expires);
+
+ if (expires)
+ cookie->expires = g_date_time_ref (expires);
+ else
+ cookie->expires = NULL;
+}
+
+/**
+ * gst_http_cookie_get_secure:
+ * @cookie: a #GstHttpCookie
+ *
+ * Gets @cookie's secure attribute
+ *
+ * Return value: @cookie's secure attribute
+ *
+ * Since: 1.10
+ **/
+gboolean
+gst_http_cookie_get_secure (GstHttpCookie * cookie)
+{
+ return cookie->secure;
+}
+
+/**
+ * gst_http_cookie_set_secure:
+ * @cookie: a #GstHttpCookie
+ * @secure: the new value for the secure attribute
+ *
+ * Sets @cookie's secure attribute to @secure. If %TRUE, @cookie will
+ * only be transmitted from the client to the server over secure
+ * (https) connections.
+ *
+ * Since: 1.10
+ **/
+void
+gst_http_cookie_set_secure (GstHttpCookie * cookie, gboolean secure)
+{
+ cookie->secure = secure;
+}
+
+/**
+ * gst_http_cookie_get_http_only:
+ * @cookie: a #GstHttpCookie
+ *
+ * Gets @cookie's HttpOnly attribute
+ *
+ * Return value: @cookie's HttpOnly attribute
+ *
+ * Since: 1.10
+ **/
+gboolean
+gst_http_cookie_get_http_only (GstHttpCookie * cookie)
+{
+ return cookie->http_only;
+}
+
+/**
+ * gst_http_cookie_set_http_only:
+ * @cookie: a #GstHttpCookie
+ * @http_only: the new value for the HttpOnly attribute
+ *
+ * Sets @cookie's HttpOnly attribute to @http_only. If %TRUE, @cookie
+ * will be marked as "http only", meaning it should not be exposed to
+ * web page scripts or other untrusted code.
+ *
+ * Since: 1.10
+ **/
+void
+gst_http_cookie_set_http_only (GstHttpCookie * cookie, gboolean http_only)
+{
+ cookie->http_only = http_only;
+}
+
+/**
+ * gst_http_cookie_free:
+ * @cookie: a #GstHttpCookie
+ *
+ * Frees @cookie
+ *
+ * Since: 1.10
+ **/
+void
+gst_http_cookie_free (GstHttpCookie * cookie)
+{
+ g_return_if_fail (cookie != NULL);
+
+ g_free (cookie->name);
+ g_free (cookie->value);
+ g_free (cookie->domain);
+ g_free (cookie->path);
+ if (cookie->expires)
+ g_date_time_unref (cookie->expires);
+
+ g_slice_free (GstHttpCookie, cookie);
+}
+
+/**
+ * gst_http_cookies_free: (skip)
+ * @cookies: (element-type GstHttpCookie): a #GSList of #GstHttpCookie
+ *
+ * Frees @cookies.
+ *
+ * Since: 1.10
+ **/
+void
+gst_http_cookies_free (GSList * cookies)
+{
+ g_slist_free_full (cookies, (GDestroyNotify) gst_http_cookie_free);
+}
+
+/**
+ * gst_http_cookie_equal:
+ * @cookie1: a #GstHttpCookie
+ * @cookie2: a #GstHttpCookie
+ *
+ * Tests if @cookie1 and @cookie2 are equal.
+ *
+ * Note that currently, this does not check that the cookie domains
+ * match. This may change in the future.
+ *
+ * Return value: whether the cookies are equal.
+ *
+ * Since: 1.10
+ */
+gboolean
+gst_http_cookie_equal (GstHttpCookie * cookie1, GstHttpCookie * cookie2)
+{
+ g_return_val_if_fail (cookie1, FALSE);
+ g_return_val_if_fail (cookie2, FALSE);
+
+ return (!strcmp (cookie1->name, cookie2->name) &&
+ !strcmp (cookie1->value, cookie2->value) &&
+ !strcmp (cookie1->path, cookie2->path));
+}
diff --git a/gst-libs/gst/http/gsthttpcookie.h b/gst-libs/gst/http/gsthttpcookie.h
new file mode 100644
index 000000000..ffceb01d4
--- /dev/null
+++ b/gst-libs/gst/http/gsthttpcookie.h
@@ -0,0 +1,111 @@
+/* GStreamer HTTP library
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * Copyright (C) 2016 Samsung Electronics. All rights reserved.
+ * Author: Thiago Santos <thiagoss@osg.samsung.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+/*
+ * This code was copied from libsoup at commit
+ * 45cf9db7d46ff6ecabd6bbd4e7ae99cfefbc1626
+ * on 20/01/2016.
+ *
+ * libsoup is LGPL v2.
+ */
+
+#ifndef GST_HTTP_COOKIE_H
+#define GST_HTTP_COOKIE_H 1
+
+#include <gst/gst.h>
+
+G_BEGIN_DECLS
+
+struct _GstHttpCookie {
+ char *name;
+ char *value;
+ char *domain;
+ char *path;
+ GDateTime *expires;
+ gboolean secure;
+ gboolean http_only;
+};
+
+typedef struct _GstHttpCookie GstHttpCookie;
+
+GType gst_http_cookie_get_type (void);
+#define GST_TYPE_HTTP_COOKIE (gst_http_cookie_get_type())
+
+GstHttpCookie *gst_http_cookie_new (const char *name,
+ const char *value,
+ const char *domain,
+ const char *path,
+ int max_age);
+
+GstHttpCookie *gst_http_cookie_copy (GstHttpCookie *cookie);
+
+
+const char *gst_http_cookie_get_name (GstHttpCookie *cookie);
+
+void gst_http_cookie_set_name (GstHttpCookie *cookie,
+ const char *name);
+
+const char *gst_http_cookie_get_value (GstHttpCookie *cookie);
+
+void gst_http_cookie_set_value (GstHttpCookie *cookie,
+ const char *value);
+
+const char *gst_http_cookie_get_domain (GstHttpCookie *cookie);
+
+void gst_http_cookie_set_domain (GstHttpCookie *cookie,
+ const char *domain);
+
+const char *gst_http_cookie_get_path (GstHttpCookie *cookie);
+
+void gst_http_cookie_set_path (GstHttpCookie *cookie,
+ const char *path);
+
+void gst_http_cookie_set_max_age (GstHttpCookie *cookie,
+ int max_age);
+
+GDateTime *gst_http_cookie_get_expires (GstHttpCookie *cookie);
+
+void gst_http_cookie_set_expires (GstHttpCookie *cookie,
+ GDateTime *expires);
+
+gboolean gst_http_cookie_get_secure (GstHttpCookie *cookie);
+
+void gst_http_cookie_set_secure (GstHttpCookie *cookie,
+ gboolean secure);
+
+gboolean gst_http_cookie_get_http_only (GstHttpCookie *cookie);
+
+void gst_http_cookie_set_http_only (GstHttpCookie *cookie,
+ gboolean http_only);
+
+
+gboolean gst_http_cookie_equal (GstHttpCookie *cookie1,
+ GstHttpCookie *cookie2);
+
+
+void gst_http_cookie_free (GstHttpCookie *cookie);
+
+
+void gst_http_cookies_free (GSList *cookies);
+
+G_END_DECLS
+
+#endif /* GST_HTTP_COOKIE_H */
diff --git a/gst-libs/gst/http/gsthttpcookiejar.c b/gst-libs/gst/http/gsthttpcookiejar.c
new file mode 100644
index 000000000..d737c0b49
--- /dev/null
+++ b/gst-libs/gst/http/gsthttpcookiejar.c
@@ -0,0 +1,381 @@
+/* GStreamer HTTP library
+ *
+ * Copyright (C) 2008 Red Hat, Inc.
+ * Copyright (C) 2016 Samsung Electronics. All rights reserved.
+ * Author: Thiago Santos <thiagoss@osg.samsung.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+/*
+ * This code was copied from libsoup at commit
+ * 45cf9db7d46ff6ecabd6bbd4e7ae99cfefbc1626
+ * on 20/01/2016.
+ *
+ * libsoup is LGPL v2.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <gst/gst.h>
+
+#include "gsthttpcookiejar.h"
+
+/**
+ * SECTION:gst-http-cookie-jar
+ * @short_description: Automatic cookie sharing
+ *
+ * A #GstHttpCookieJar stores #GstHttpCookie<!-- -->s.
+ *
+ * Note that the base #GstHttpCookieJar class does not support any form
+ * of long-term cookie persistence.
+ **/
+
+G_DEFINE_TYPE (GstHttpCookieJar, gst_http_cookie_jar, GST_TYPE_OBJECT);
+
+enum
+{
+ CHANGED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+typedef struct
+{
+ gboolean constructed;
+ GHashTable *domains, *serials;
+ guint serial;
+} GstHttpCookieJarPrivate;
+#define GST_HTTP_COOKIE_JAR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GST_TYPE_HTTP_COOKIE_JAR, GstHttpCookieJarPrivate))
+
+/**
+ * gst_http_str_case_hash:
+ * @key: ASCII string to hash
+ *
+ * Hashes @key in a case-insensitive manner.
+ *
+ * Return value: the hash code.
+ **/
+static guint
+gst_http_str_case_hash (gconstpointer key)
+{
+ const char *p = key;
+ guint h = g_ascii_toupper (*p);
+
+ if (h)
+ for (p += 1; *p != '\0'; p++)
+ h = (h << 5) - h + g_ascii_toupper (*p);
+
+ return h;
+}
+
+/**
+ * gst_http_str_case_equal:
+ * @v1: an ASCII string
+ * @v2: another ASCII string
+ *
+ * Compares @v1 and @v2 in a case-insensitive manner
+ *
+ * Return value: %TRUE if they are equal (modulo case)
+ **/
+static gboolean
+gst_http_str_case_equal (gconstpointer v1, gconstpointer v2)
+{
+ const char *string1 = v1;
+ const char *string2 = v2;
+
+ return g_ascii_strcasecmp (string1, string2) == 0;
+}
+
+
+static void
+gst_http_cookie_jar_init (GstHttpCookieJar * jar)
+{
+ GstHttpCookieJarPrivate *priv = GST_HTTP_COOKIE_JAR_GET_PRIVATE (jar);
+
+ priv->domains = g_hash_table_new_full (gst_http_str_case_hash,
+ gst_http_str_case_equal, g_free, NULL);
+ priv->serials = g_hash_table_new (NULL, NULL);
+}
+
+static void
+gst_http_cookie_jar_constructed (GObject * object)
+{
+ GstHttpCookieJarPrivate *priv = GST_HTTP_COOKIE_JAR_GET_PRIVATE (object);
+
+ priv->constructed = TRUE;
+}
+
+static void
+gst_http_cookie_jar_finalize (GObject * object)
+{
+ GstHttpCookieJarPrivate *priv = GST_HTTP_COOKIE_JAR_GET_PRIVATE (object);
+ GHashTableIter iter;
+ gpointer key, value;
+
+ g_hash_table_iter_init (&iter, priv->domains);
+ while (g_hash_table_iter_next (&iter, &key, &value))
+ gst_http_cookies_free (value);
+ g_hash_table_destroy (priv->domains);
+ g_hash_table_destroy (priv->serials);
+
+ G_OBJECT_CLASS (gst_http_cookie_jar_parent_class)->finalize (object);
+}
+
+static void
+gst_http_cookie_jar_class_init (GstHttpCookieJarClass * jar_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (jar_class);
+
+ g_type_class_add_private (jar_class, sizeof (GstHttpCookieJarPrivate));
+
+ object_class->constructed = gst_http_cookie_jar_constructed;
+ object_class->finalize = gst_http_cookie_jar_finalize;
+
+ /**
+ * GstHttpCookieJar::changed:
+ * @jar: the #GstHttpCookieJar
+ * @author: a pointer to the author of the change
+ * @old_cookie: the old #GstHttpCookie value
+ * @new_cookie: the new #GstHttpCookie value
+ *
+ * Emitted when @jar changes. If a cookie has been added,
+ * @new_cookie will contain the newly-added cookie and
+ * @old_cookie will be %NULL. If a cookie has been deleted,
+ * @old_cookie will contain the to-be-deleted cookie and
+ * @new_cookie will be %NULL. If a cookie has been changed,
+ * @old_cookie will contain its old value, and @new_cookie its
+ * new value.
+ *
+ * Signal listeners should check the author field to verify
+ * if the change was made by themselves and ignore that change
+ **/
+ signals[CHANGED] =
+ g_signal_new ("changed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GstHttpCookieJarClass, changed),
+ NULL, NULL,
+ NULL,
+ G_TYPE_NONE, 3,
+ G_TYPE_POINTER | G_SIGNAL_TYPE_STATIC_SCOPE,
+ GST_TYPE_HTTP_COOKIE | G_SIGNAL_TYPE_STATIC_SCOPE,
+ GST_TYPE_HTTP_COOKIE | G_SIGNAL_TYPE_STATIC_SCOPE);
+}
+
+/**
+ * gst_http_cookie_jar_new:
+ *
+ * Creates a new #GstHttpCookieJar. The base #GstHttpCookieJar class does
+ * not support persistent storage of cookies; use a subclass for that.
+ *
+ * Returns: a new #GstHttpCookieJar
+ *
+ * Since: 1.10
+ **/
+GstHttpCookieJar *
+gst_http_cookie_jar_new (void)
+{
+ return g_object_new (GST_TYPE_HTTP_COOKIE_JAR, NULL);
+}
+
+static void
+gst_http_cookie_jar_changed (GstHttpCookieJar * jar, gpointer author,
+ GstHttpCookie * old, GstHttpCookie * new)
+{
+ GstHttpCookieJarPrivate *priv = GST_HTTP_COOKIE_JAR_GET_PRIVATE (jar);
+
+ if (old && old != new)
+ g_hash_table_remove (priv->serials, old);
+ if (new) {
+ priv->serial++;
+ g_hash_table_insert (priv->serials, new, GUINT_TO_POINTER (priv->serial));
+ }
+
+ if (!priv->constructed)
+ return;
+
+ g_signal_emit (jar, signals[CHANGED], 0, author, old, new);
+}
+
+static gboolean
+date_time_is_past (GDateTime * dt)
+{
+ GDateTime *now = g_date_time_new_now_utc ();
+ GTimeSpan diff;
+
+ diff = g_date_time_difference (now, dt);
+
+ g_date_time_unref (now);
+
+ return diff > 0;
+}
+
+/**
+ * gst_http_cookie_jar_add_cookie:
+ * @jar: a #GstHttpCookieJar
+ * @cookie: (transfer full): a #GstHttpCookie
+ *
+ * Adds @cookie to @jar, emitting the 'changed' signal if we are modifying
+ * an existing cookie or adding a valid new cookie ('valid' means
+ * that the cookie's expire date is not in the past).
+ *
+ * @cookie will be 'stolen' by the jar, so don't free it afterwards.
+ *
+ * Since: 1.10
+ **/
+void
+gst_http_cookie_jar_add_cookie (GstHttpCookieJar * jar, gpointer author,
+ GstHttpCookie * cookie)
+{
+ GstHttpCookieJarPrivate *priv;
+ GSList *old_cookies, *oc, *last = NULL;
+ GstHttpCookie *old_cookie;
+
+ g_return_if_fail (GST_HTTP_IS_COOKIE_JAR (jar));
+ g_return_if_fail (cookie != NULL);
+
+#if 0
+ /* Never accept cookies for public domains. */
+ if (!g_hostname_is_ip_address (cookie->domain) &&
+ soup_tld_domain_is_public_suffix (cookie->domain)) {
+ gst_http_cookie_free (cookie);
+ return;
+ }
+#endif
+
+ priv = GST_HTTP_COOKIE_JAR_GET_PRIVATE (jar);
+ old_cookies = g_hash_table_lookup (priv->domains, cookie->domain);
+ for (oc = old_cookies; oc; oc = oc->next) {
+ old_cookie = oc->data;
+ if (!strcmp (cookie->name, old_cookie->name) &&
+ !g_strcmp0 (cookie->path, old_cookie->path)) {
+ if (cookie->expires && date_time_is_past (cookie->expires)) {
+ /* The new cookie has an expired date,
+ * this is the way the the server has
+ * of telling us that we have to
+ * remove the cookie.
+ */
+ old_cookies = g_slist_delete_link (old_cookies, oc);
+ g_hash_table_insert (priv->domains,
+ g_strdup (cookie->domain), old_cookies);
+ gst_http_cookie_jar_changed (jar, author, old_cookie, NULL);
+ gst_http_cookie_free (old_cookie);
+ gst_http_cookie_free (cookie);
+ } else {
+ oc->data = cookie;
+ /* TODO something else might have changed */
+ if (strcmp (cookie->value, old_cookie->value))
+ gst_http_cookie_jar_changed (jar, author, old_cookie, cookie);
+ gst_http_cookie_free (old_cookie);
+ }
+
+ return;
+ }
+ last = oc;
+ }
+
+ /* The new cookie is... a new cookie */
+ if (cookie->expires && date_time_is_past (cookie->expires)) {
+ gst_http_cookie_free (cookie);
+ return;
+ }
+
+ if (last)
+ last->next = g_slist_append (NULL, cookie);
+ else {
+ old_cookies = g_slist_append (NULL, cookie);
+ g_hash_table_insert (priv->domains, g_strdup (cookie->domain), old_cookies);
+ }
+
+ gst_http_cookie_jar_changed (jar, author, NULL, cookie);
+}
+
+/**
+ * gst_http_cookie_jar_all_cookies:
+ * @jar: a #GstHttpCookieJar
+ *
+ * Constructs a #GSList with every cookie inside the @jar.
+ * The cookies in the list are a copy of the original, so
+ * you have to free them when you are done with them.
+ *
+ * Return value: (transfer full) (element-type Soup.Cookie): a #GSList
+ * with all the cookies in the @jar.
+ *
+ * Since: 1.10
+ **/
+GSList *
+gst_http_cookie_jar_all_cookies (GstHttpCookieJar * jar)
+{
+ GstHttpCookieJarPrivate *priv;
+ GHashTableIter iter;
+ GSList *l = NULL;
+ gpointer key, value;
+
+ g_return_val_if_fail (GST_HTTP_IS_COOKIE_JAR (jar), NULL);
+
+ priv = GST_HTTP_COOKIE_JAR_GET_PRIVATE (jar);
+
+ g_hash_table_iter_init (&iter, priv->domains);
+
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ GSList *p, *cookies = value;
+ for (p = cookies; p; p = p->next)
+ l = g_slist_prepend (l, gst_http_cookie_copy (p->data));
+ }
+
+ return l;
+}
+
+/**
+ * gst_http_cookie_jar_delete_cookie:
+ * @jar: a #GstHttpCookieJar
+ * @cookie: a #GstHttpCookie
+ *
+ * Deletes @cookie from @jar, emitting the 'changed' signal.
+ *
+ * Since: 1.10
+ **/
+void
+gst_http_cookie_jar_delete_cookie (GstHttpCookieJar * jar, gpointer author,
+ GstHttpCookie * cookie)
+{
+ GstHttpCookieJarPrivate *priv;
+ GSList *cookies, *p;
+
+ g_return_if_fail (GST_HTTP_IS_COOKIE_JAR (jar));
+ g_return_if_fail (cookie != NULL);
+
+ priv = GST_HTTP_COOKIE_JAR_GET_PRIVATE (jar);
+
+ cookies = g_hash_table_lookup (priv->domains, cookie->domain);
+ if (cookies == NULL)
+ return;
+
+ for (p = cookies; p; p = p->next) {
+ GstHttpCookie *c = (GstHttpCookie *) p->data;
+ if (gst_http_cookie_equal (cookie, c)) {
+ cookies = g_slist_delete_link (cookies, p);
+ g_hash_table_insert (priv->domains, g_strdup (cookie->domain), cookies);
+ gst_http_cookie_jar_changed (jar, author, c, NULL);
+ gst_http_cookie_free (c);
+ return;
+ }
+ }
+}
diff --git a/gst-libs/gst/http/gsthttpcookiejar.h b/gst-libs/gst/http/gsthttpcookiejar.h
new file mode 100644
index 000000000..74a57e060
--- /dev/null
+++ b/gst-libs/gst/http/gsthttpcookiejar.h
@@ -0,0 +1,84 @@
+/* GStreamer HTTP library
+ *
+ * Copyright (C) 2008 Red Hat, Inc.
+ * Copyright (C) 2016 Samsung Electronics. All rights reserved.
+ * Author: Thiago Santos <thiagoss@osg.samsung.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+/*
+ * This code was copied from libsoup at commit
+ * 45cf9db7d46ff6ecabd6bbd4e7ae99cfefbc1626
+ * on 20/01/2016.
+ *
+ * libsoup is LGPL v2.
+ */
+
+#ifndef GST_HTTP_COOKIE_JAR_H
+#define GST_HTTP_COOKIE_JAR_H 1
+
+#include <gst/gst.h>
+#include "gsthttpcookie.h"
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_HTTP_COOKIE_JAR (gst_http_cookie_jar_get_type ())
+#define GST_HTTP_COOKIE_JAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_HTTP_COOKIE_JAR, GstHttpCookieJar))
+#define GST_HTTP_COOKIE_JAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_HTTP_COOKIE_JAR, GstHttpCookieJarClass))
+#define GST_HTTP_IS_COOKIE_JAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_HTTP_COOKIE_JAR))
+#define GST_HTTP_IS_COOKIE_JAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), GST_TYPE_HTTP_COOKIE_JAR))
+#define GST_HTTP_COOKIE_JAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_HTTP_COOKIE_JAR, GstHttpCookieJarClass))
+
+typedef struct _GstHttpCookieJar {
+ GstObject parent;
+
+} GstHttpCookieJar;
+
+typedef struct {
+ GstObjectClass parent_class;
+
+ /* signals */
+ void (*changed) (GstHttpCookieJar *jar,
+ gpointer author,
+ GstHttpCookie *old_cookie,
+ GstHttpCookie *new_cookie);
+
+ /* Padding for future expansion */
+ void (*_libsoup_reserved1) (void);
+ void (*_libsoup_reserved2) (void);
+} GstHttpCookieJarClass;
+
+GType gst_http_cookie_jar_get_type (void);
+
+GstHttpCookieJar * gst_http_cookie_jar_new (void);
+
+void gst_http_cookie_jar_add_cookie (GstHttpCookieJar *jar,
+ gpointer author,
+ GstHttpCookie *cookie);
+
+void gst_http_cookie_jar_add_cookie_with_first_party (GstHttpCookieJar *jar,
+ gchar *first_party,
+ GstHttpCookie *cookie);
+
+void gst_http_cookie_jar_delete_cookie (GstHttpCookieJar *jar,
+ gpointer author,
+ GstHttpCookie *cookie);
+
+GSList * gst_http_cookie_jar_all_cookies (GstHttpCookieJar *jar);
+
+G_END_DECLS
+
+#endif /* GST_HTTP_COOKIE_JAR_H */
diff --git a/pkgconfig/Makefile.am b/pkgconfig/Makefile.am
index 9976f95ef..73c1a41fc 100644
--- a/pkgconfig/Makefile.am
+++ b/pkgconfig/Makefile.am
@@ -4,6 +4,7 @@ pcverfiles = \
gstreamer-audio-@GST_API_VERSION@.pc \
gstreamer-app-@GST_API_VERSION@.pc \
gstreamer-fft-@GST_API_VERSION@.pc \
+ gstreamer-http-@GST_API_VERSION@.pc \
gstreamer-pbutils-@GST_API_VERSION@.pc \
gstreamer-riff-@GST_API_VERSION@.pc \
gstreamer-rtp-@GST_API_VERSION@.pc \
@@ -17,6 +18,7 @@ pcverfiles_uninstalled = \
gstreamer-audio-@GST_API_VERSION@-uninstalled.pc \
gstreamer-app-@GST_API_VERSION@-uninstalled.pc \
gstreamer-fft-@GST_API_VERSION@-uninstalled.pc \
+ gstreamer-http-@GST_API_VERSION@-uninstalled.pc \
gstreamer-pbutils-@GST_API_VERSION@-uninstalled.pc \
gstreamer-riff-@GST_API_VERSION@-uninstalled.pc \
gstreamer-rtp-@GST_API_VERSION@-uninstalled.pc \
@@ -43,10 +45,11 @@ pkgconfig_DATA = $(pcverfiles)
CLEANFILES = $(pcverfiles) $(pcverfiles_uninstalled)
pcinfiles = \
- gstreamer-allocators.pc.in gstreamer-allocators-uninstalled.pc.in \
+ gstreamer-allocators.pc.in gstreamer-allocators-uninstalled.pc.in \
gstreamer-audio.pc.in gstreamer-audio-uninstalled.pc.in \
gstreamer-app.pc.in gstreamer-app-uninstalled.pc.in \
gstreamer-fft.pc.in gstreamer-fft-uninstalled.pc.in \
+ gstreamer-http.pc.in gstreamer-http-uninstalled.pc.in \
gstreamer-pbutils.pc.in gstreamer-pbutils-uninstalled.pc.in \
gstreamer-riff.pc.in gstreamer-riff-uninstalled.pc.in \
gstreamer-rtp.pc.in gstreamer-rtp-uninstalled.pc.in \
diff --git a/pkgconfig/gstreamer-http-uninstalled.pc.in b/pkgconfig/gstreamer-http-uninstalled.pc.in
new file mode 100644
index 000000000..c1e406618
--- /dev/null
+++ b/pkgconfig/gstreamer-http-uninstalled.pc.in
@@ -0,0 +1,16 @@
+# the standard variables don't make sense for an uninstalled copy
+prefix=
+exec_prefix=
+libdir=
+# includedir is builddir because it is used to find gstconfig.h in places
+includedir=@abs_top_builddir@/gst-libs
+girdir=@abs_top_builddir@/gst-libs/gst/http
+typelibdir=@abs_top_builddir@/gst-libs/gst/http
+
+Name: GStreamer HTTP Library, Uninstalled
+Description: HTTP helper functions, uninstalled
+Version: @VERSION@
+Requires: gstreamer-@GST_API_VERSION@
+Libs: @abs_top_builddir@/gst-libs/gst/http/libgsthttp-@GST_API_VERSION@.la
+Cflags: -I@abs_top_srcdir@/gst-libs -I@abs_top_builddir@/gst-libs
+
diff --git a/pkgconfig/gstreamer-http.pc.in b/pkgconfig/gstreamer-http.pc.in
new file mode 100644
index 000000000..bdaa218ed
--- /dev/null
+++ b/pkgconfig/gstreamer-http.pc.in
@@ -0,0 +1,16 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@/gstreamer-@GST_API_VERSION@
+datarootdir=${prefix}/share
+datadir=${datarootdir}
+girdir=${datadir}/gir-1.0
+typelibdir=${libdir}/girepository-1.0
+
+Name: GStreamer HTTP Library
+Description: HTTP helper functions
+Requires: gstreamer-@GST_API_VERSION@
+Version: @VERSION@
+Libs: -L${libdir} -lgsthttp-@GST_API_VERSION@
+Cflags: -I${includedir}
+
diff --git a/pkgconfig/gstreamer-plugins-base-uninstalled.pc.in b/pkgconfig/gstreamer-plugins-base-uninstalled.pc.in
index 970c051bb..fd83167d9 100644
--- a/pkgconfig/gstreamer-plugins-base-uninstalled.pc.in
+++ b/pkgconfig/gstreamer-plugins-base-uninstalled.pc.in
@@ -10,7 +10,7 @@ Name: GStreamer Base Plugins Libraries, Uninstalled
Description: Streaming media framework, base plugins libraries, uninstalled
Version: @VERSION@
Requires: gstreamer-@GST_API_VERSION@
-Libs: -L@abs_top_builddir@/gst-libs/gst/allocators -L@abs_top_builddir@/gst-libs/gst/app -L@abs_top_builddir@/gst-libs/gst/audio -L@abs_top_builddir@/gst-libs/gst/fft -L@abs_top_builddir@/gst-libs/gst/pbutils -L@abs_top_builddir@/gst-libs/gst/riff -L@abs_top_builddir@/gst-libs/gst/rtp -L@abs_top_builddir@/gst-libs/gst/rtsp -L@abs_top_builddir@/gst-libs/gst/sdp -L@abs_top_builddir@/gst-libs/gst/tag -L@abs_top_builddir@/gst-libs/gst/video
+Libs: -L@abs_top_builddir@/gst-libs/gst/allocators -L@abs_top_builddir@/gst-libs/gst/app -L@abs_top_builddir@/gst-libs/gst/audio -L@abs_top_builddir@/gst-libs/gst/fft -L@abs_top_builddir@/gst-libs/gst/http -L@abs_top_builddir@/gst-libs/gst/pbutils -L@abs_top_builddir@/gst-libs/gst/riff -L@abs_top_builddir@/gst-libs/gst/rtp -L@abs_top_builddir@/gst-libs/gst/rtsp -L@abs_top_builddir@/gst-libs/gst/sdp -L@abs_top_builddir@/gst-libs/gst/tag -L@abs_top_builddir@/gst-libs/gst/video
Cflags: -I@abs_top_srcdir@/gst-libs -I@abs_top_builddir@/gst-libs
-libraries=allocators app audio fft pbutils riff rtp rtsp sdp tag video
+libraries=allocators app audio fft http pbutils riff rtp rtsp sdp tag video
diff --git a/pkgconfig/gstreamer-plugins-base.pc.in b/pkgconfig/gstreamer-plugins-base.pc.in
index e81774665..5da075c4f 100644
--- a/pkgconfig/gstreamer-plugins-base.pc.in
+++ b/pkgconfig/gstreamer-plugins-base.pc.in
@@ -11,4 +11,4 @@ Version: @VERSION@
Libs: -L${libdir}
Cflags: -I${includedir}
-libraries=allocators app audio fft pbutils riff rtp rtsp sdp tag video
+libraries=allocators app audio fft http pbutils riff rtp rtsp sdp tag video