curl: Add curlhttpsrc element

Merged from https://github.com/bbc/gst-curlhttpsrc commit
  f8aabcfc5c50a44f3362de831377d6e86dcd2d49

https://bugzilla.gnome.org/show_bug.cgi?id=744261
This commit is contained in:
Sam Hurst 2017-07-25 15:23:57 +01:00 committed by Sebastian Dröge
parent 2d67189073
commit e74b3a02dd
10 changed files with 2614 additions and 3 deletions

View file

@ -13,7 +13,10 @@ libgstcurl_la_SOURCES = gstcurl.c \
gstcurlfilesink.c \
gstcurlftpsink.c \
$(gstcurlsshsink_SOURCES) \
gstcurlsmtpsink.c
gstcurlsmtpsink.c \
gstcurlhttpsrc.c \
gstcurlqueue.c
libgstcurl_la_CFLAGS = \
$(GST_PLUGINS_BAD_CFLAGS) \
$(GST_BASE_CFLAGS) \
@ -36,4 +39,8 @@ noinst_HEADERS = gstcurlbasesink.h \
gstcurlftpsink.h \
gstcurlsmtpsink.h \
gstcurlsshsink.h \
gstcurlsftpsink.h
gstcurlsftpsink.h \
gstcurlhttpsrc.h \
curltask.h \
gstcurldefaults.h \
gstcurlqueue.h

107
ext/curl/curltask.h Normal file
View file

@ -0,0 +1,107 @@
/*
* GstCurlHttpSrc
* Copyright 2014 British Broadcasting Corporation - Research and Development
*
* Author: Sam Hurst <samuelh@rd.bbc.co.uk>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Alternatively, the contents of this file may be used under the
* GNU Lesser General Public License Version 2.1 (the "LGPL"), in
* which case the following provisions apply instead of the ones
* mentioned above:
*
* 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.
*/
#ifndef CURLTASK_H_
#define CURLTASK_H_
#include <curl/curl.h>
#include "gstcurldefaults.h"
#define GSTCURL_ERROR_PRINT(...) GST_CAT_ERROR (gst_curl_loop_debug, __VA_ARGS__)
#define GSTCURL_WARNING_PRINT(...) GST_CAT_WARNING (gst_curl_loop_debug, __VA_ARGS__)
#define GSTCURL_INFO_PRINT(...) GST_CAT_INFO (gst_curl_loop_debug, __VA_ARGS__)
#define GSTCURL_DEBUG_PRINT(...) GST_CAT_DEBUG (gst_curl_loop_debug, __VA_ARGS__)
#define GSTCURL_TRACE_PRINT(...) GST_CAT_TRACE (gst_curl_loop_debug, __VA_ARGS__)
#define gst_curl_setopt_str(s,handle,type,option) \
if(option != NULL) { \
if(curl_easy_setopt(handle,type,option) != CURLE_OK) { \
GST_WARNING_OBJECT (s, "Cannot set unsupported option %s", #type ); \
} \
} \
#define gst_curl_setopt_int(s,handle, type, option) \
if((option >= GSTCURL_HANDLE_MIN_##type) && (option <= GSTCURL_HANDLE_MAX_##type)) { \
if(curl_easy_setopt(handle,type,option) != CURLE_OK) { \
GST_WARNING_OBJECT (s, "Cannot set unsupported option %s", #type ); \
} \
} \
#define gst_curl_setopt_str_default(s,handle,type,option) \
if((option == NULL) && (GSTCURL_HANDLE_DEFAULT_##type != NULL)) { \
if(curl_easy_setopt(handle,type,GSTCURL_HANDLE_DEFAULT_##type) != CURLE_OK) { \
GST_WARNING_OBJECT(s, "Cannot set unsupported option %s,", #type ); \
} \
} \
else { \
if(curl_easy_setopt(handle,type,option) != CURLE_OK) { \
GST_WARNING_OBJECT (s, "Cannot set unsupported option %s", #type ); \
} \
} \
#define gst_curl_setopt_int_default(s,handle,type,option) \
if((option < GSTCURL_HANDLE_MIN_##type) || (option > GSTCURL_HANDLE_MAX_##type)) { \
GST_WARNING_OBJECT(s, "Value of %ld out of acceptable range for %s", option, \
#type ); \
if(curl_easy_setopt(handle,type,GSTCURL_HANDLE_DEFAULT_##type) != CURLE_OK) { \
GST_WARNING_OBJECT(s, "Cannot set unsupported option %s,", #type ); \
} \
} \
else { \
if(curl_easy_setopt(handle,type,option) != CURLE_OK) { \
GST_WARNING_OBJECT (s, "Cannot set unsupported option %s", #type ); \
} \
} \
#define GSTCURL_ASSERT_MUTEX(x) if(g_atomic_pointer_get(&x->p) == NULL) GSTCURL_DEBUG_PRINT("ASSERTION: No valid mutex handle in GMutex %p", x);
/* As gboolean is either 0x0 or 0xffffffff, this sanitises things for curl. */
#define GSTCURL_BINARYBOOL(x) ((x != 0)?1:0)
/*
* Function definitions
*/
#endif /* CURLTASK_H_ */

View file

@ -29,6 +29,7 @@
#ifdef HAVE_SSH2
#include "gstcurlsftpsink.h"
#endif
#include "gstcurlhttpsrc.h"
static gboolean
plugin_init (GstPlugin * plugin)
@ -55,6 +56,9 @@ plugin_init (GstPlugin * plugin)
GST_TYPE_CURL_SFTP_SINK))
return FALSE;
#endif
if (!gst_element_register (plugin, "curlhttpsrc", GST_RANK_SECONDARY,
GST_TYPE_CURLHTTPSRC))
return FALSE;
return TRUE;
}

View file

@ -714,7 +714,7 @@ gst_curl_base_sink_transfer_set_common_options_unlocked (GstCurlBaseSink * sink)
return FALSE;
}
res = curl_easy_setopt (sink->curl, CURLOPT_LOW_SPEED_TIME,
(long)sink->timeout);
(long) sink->timeout);
if (res != CURLE_OK) {
sink->error = g_strdup_printf ("failed to set low speed time: %s",
curl_easy_strerror (res));

125
ext/curl/gstcurldefaults.h Normal file
View file

@ -0,0 +1,125 @@
/*
* GstCurlHttpSrc
* Copyright 2017 British Broadcasting Corporation - Research and Development
*
* Author: Sam Hurst <samuelh@rd.bbc.co.uk>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Alternatively, the contents of this file may be used under the
* GNU Lesser General Public License Version 2.1 (the "LGPL"), in
* which case the following provisions apply instead of the ones
* mentioned above:
*
* 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.
*/
#ifndef GSTCURLDEFAULTS_H_
#define GSTCURLDEFAULTS_H_
/*
* This file contains a list of all the default values used. These are used to
* initialise an object in its init call.
*
* Must all conform to GSTCURL_HANDLE_DEFAULT_##type for macro sillyness in
* curltask.h, where "type" is the CURLOPT_<something> string.
*/
/* Defaults from http://curl.haxx.se/libcurl/c/curl_easy_setopt.html */
#define GSTCURL_HANDLE_DEFAULT_CURLOPT_URL ((void *)0)
#define GSTCURL_HANDLE_DEFAULT_CURLOPT_USERNAME ((void *)0)
#define GSTCURL_HANDLE_DEFAULT_CURLOPT_PASSWORD ((void *)0)
#define GSTCURL_HANDLE_DEFAULT_CURLOPT_PROXY ((void *)0)
#define GSTCURL_HANDLE_DEFAULT_CURLOPT_PROXYUSERNAME ((void *)0)
#define GSTCURL_HANDLE_DEFAULT_CURLOPT_PROXYPASSWORD ((void *)0)
#define GSTCURL_HANDLE_DEFAULT_CURLOPT_USERAGENT gst_curl_http_src_default_useragent
#define GSTCURL_HANDLE_DEFAULT_CURLOPT_ACCEPT_ENCODING FALSE
#define GSTCURL_HANDLE_DEFAULT_CURLOPT_FOLLOWLOCATION 1L
#define GSTCURL_HANDLE_DEFAULT_CURLOPT_MAXREDIRS -1
#define GSTCURL_HANDLE_DEFAULT_CURLOPT_TCP_KEEPALIVE 1L
#define GSTCURL_HANDLE_DEFAULT_CURLOPT_TIMEOUT 0
#define GSTCURL_HANDLE_DEFAULT_CURLOPT_SSL_VERIFYPEER 1
#define GSTCURL_HANDLE_DEFAULT_CURLOPT_CAINFO ((void *)0)
#ifdef CURL_VERSION_HTTP2
#define GSTCURL_HANDLE_DEFAULT_CURLOPT_HTTP_VERSION 2.0
#else
#define GSTCURL_HANDLE_DEFAULT_CURLOPT_HTTP_VERSION 1.1
#endif
/* Defaults from http://curl.haxx.se/libcurl/c/curl_multi_setopt.html */
#define GSTCURL_HANDLE_DEFAULT_CURLMOPT_PIPELINING 1L
#define GSTCURL_HANDLE_DEFAULT_CURLMOPT_MAXCONNECTS 255L
#define GSTCURL_HANDLE_DEFAULT_CURLMOPT_MAX_HOST_CONNECTIONS 0L
#define GSTCURL_HANDLE_DEFAULT_CURLMOPT_MAX_PIPELINE_LENGTH 5L
#define GSTCURL_HANDLE_DEFAULT_CURLMOPT_MAX_TOTAL_CONNECTIONS 255L
/* Not a CURLOPT, is something I've implemented which curl doesn't */
#define GSTCURL_HANDLE_DEFAULT_RETRIES -1
/*
* Now set acceptable ranges. Defaults can lie outside the range, in which case
* it is expected that the programmer will use the gst_curl_setopt and not the
* gst_curl_setopt_default macro, as if the value supplied lies outside of the
* default range, it won't bother to set it. If the _default macro is used,
* then the offending value is replaced by the default type above.
*/
#define GSTCURL_HANDLE_MIN_CURLOPT_FOLLOWLOCATION 0L
#define GSTCURL_HANDLE_MAX_CURLOPT_FOLLOWLOCATION 1L
#define GSTCURL_HANDLE_MIN_CURLOPT_MAXREDIRS -1
#define GSTCURL_HANDLE_MAX_CURLOPT_MAXREDIRS 255
#define GSTCURL_HANDLE_MIN_CURLOPT_TCP_KEEPALIVE 0L
#define GSTCURL_HANDLE_MAX_CURLOPT_TCP_KEEPALIVE 1L
#define GSTCURL_HANDLE_MIN_CURLOPT_TIMEOUT 0
#define GSTCURL_HANDLE_MAX_CURLOPT_TIMEOUT 3600
#define GSTCURL_HANDLE_MIN_CURLOPT_SSL_VERIFYPEER 0
#define GSTCURL_HANDLE_MAX_CURLOPT_SSL_VERIFYPEER 1
#define GSTCURL_HANDLE_MIN_CURLOPT_HTTP_VERSION CURL_HTTP_VERSION_1_0
#ifdef CURL_VERSION_HTTP2
#define GSTCURL_HANDLE_MAX_CURLOPT_HTTP_VERSION CURL_HTTP_VERSION_2_0
#else
#define GSTCURL_HANDLE_MAX_CURLOPT_HTTP_VERSION CURL_HTTP_VERSION_1_1
#endif
#define GSTCURL_HANDLE_MIN_CURLMOPT_PIPELINING 0L
#define GSTCURL_HANDLE_MAX_CURLMOPT_PIPELINING 1L
#define GSTCURL_HANDLE_MIN_CURLMOPT_MAXCONNECTS 32L
#define GSTCURL_HANDLE_MAX_CURLMOPT_MAXCONNECTS 255L
#define GSTCURL_HANDLE_MIN_CURLMOPT_MAX_HOST_CONNECTIONS 1L
#define GSTCURL_HANDLE_MAX_CURLMOPT_MAX_HOST_CONNECTIONS 127L
#define GSTCURL_HANDLE_MIN_CURLMOPT_MAX_PIPELINE_LENGTH 1L
#define GSTCURL_HANDLE_MAX_CURLMOPT_MAX_PIPELINE_LENGTH 200L
#define GSTCURL_HANDLE_MIN_CURLMOPT_MAX_TOTAL_CONNECTIONS 32L
#define GSTCURL_HANDLE_MAX_CURLMOPT_MAX_TOTAL_CONNECTIONS 255L
#define GSTCURL_HANDLE_MIN_RETRIES -1
#define GSTCURL_HANDLE_MAX_RETRIES 9999
#endif /* GSTCURLDEFAULTS_H_ */

1841
ext/curl/gstcurlhttpsrc.c Normal file

File diff suppressed because it is too large Load diff

275
ext/curl/gstcurlhttpsrc.h Normal file
View file

@ -0,0 +1,275 @@
/*
* GstCurlHttpSrc
* Copyright 2017 British Broadcasting Corporation - Research and Development
*
* Author: Sam Hurst <samuelh@rd.bbc.co.uk>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Alternatively, the contents of this file may be used under the
* GNU Lesser General Public License Version 2.1 (the "LGPL"), in
* which case the following provisions apply instead of the ones
* mentioned above:
*
* 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.
*/
/*
* This header file contains definitions only for
*/
#ifndef GSTCURLHTTPSRC_H_
#define GSTCURLHTTPSRC_H_
#include <gst/gst.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <gst/base/gstpushsrc.h>
#include "curltask.h"
G_BEGIN_DECLS
/* #defines don't like whitespacey bits */
#define GST_TYPE_CURLHTTPSRC \
(gst_curl_http_src_get_type())
#define GST_CURLHTTPSRC(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_CURLHTTPSRC,GstCurlHttpSrc))
#define GST_CURLHTTPSRC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_CURLHTTPSRC,GstCurlHttpSrcClass))
#define GST_IS_CURLHTTPSRC(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_CURLHTTPSRC))
#define GST_IS_CURLHTTPSRC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CURLHTTPSRC))
/* Because g_param_spec_int requires min/max bounding... */
#define GSTCURL_MIN_REDIRECTIONS -1
#define GSTCURL_MAX_REDIRECTIONS 255
#define GSTCURL_MIN_CONNECTION_TIME 2
#define GSTCURL_MAX_CONNECTION_TIME 60
#define GSTCURL_MIN_CONNECTIONS_SERVER 1
#define GSTCURL_MAX_CONNECTIONS_SERVER 60
#define GSTCURL_MIN_CONNECTIONS_PROXY 1
#define GSTCURL_MAX_CONNECTIONS_PROXY 60
#define GSTCURL_MIN_CONNECTIONS_GLOBAL 1
#define GSTCURL_MAX_CONNECTIONS_GLOBAL 255
#define GSTCURL_DEFAULT_CONNECTION_TIME 30
#define GSTCURL_DEFAULT_CONNECTIONS_SERVER 5
#define GSTCURL_DEFAULT_CONNECTIONS_PROXY 30
#define GSTCURL_DEFAULT_CONNECTIONS_GLOBAL 255
#define GSTCURL_INFO_RESPONSE(x) ((x >= 100) && (x <= 199))
#define GSTCURL_SUCCESS_RESPONSE(x) ((x >= 200) && (x <=299))
#define GSTCURL_REDIRECT_RESPONSE(x) ((x >= 300) && (x <= 399))
#define GSTCURL_CLIENT_ERR_RESPONSE(x) ((x >= 400) && (x <= 499))
#define GSTCURL_SERVER_ERR_RESPONSE(x) ((x >= 500) && (x <= 599))
#define GSTCURL_FUNCTIONTRACE 0
#if GSTCURL_FUNCTIONTRACE
#define GSTCURL_FUNCTION_ENTRY(x) GST_DEBUG_OBJECT(x, "Entering function");
#define GSTCURL_FUNCTION_EXIT(x) GST_DEBUG_OBJECT(x, "Leaving function");
#else
#define GSTCURL_FUNCTION_ENTRY(x)
#define GSTCURL_FUNCTION_EXIT(x)
#endif
typedef struct _GstCurlHttpSrc GstCurlHttpSrc;
typedef struct _GstCurlHttpSrcClass GstCurlHttpSrcClass;
typedef struct _GstCurlHttpSrcMultiTaskContext GstCurlHttpSrcMultiTaskContext;
typedef struct _GstCurlHttpSrcQueueElement GstCurlHttpSrcQueueElement;
#define HTTP_HEADERS_NAME "http-headers"
#define HTTP_STATUS_CODE "http-status-code"
#define URI_NAME "uri"
#define REQUEST_HEADERS_NAME "request-headers"
#define RESPONSE_HEADERS_NAME "response-headers"
#define REDIRECT_URI_NAME "redirection-uri"
struct _GstCurlHttpSrcMultiTaskContext
{
GstTask *task;
GRecMutex task_rec_mutex;
GMutex mutex;
guint refcount;
GCond signal;
GstCurlHttpSrc *request_removal_element;
GstCurlHttpSrcQueueElement *queue;
enum
{
GSTCURL_MULTI_LOOP_STATE_WAIT = 0,
GSTCURL_MULTI_LOOP_STATE_QUEUE_EVENT,
GSTCURL_MULTI_LOOP_STATE_RUNNING,
GSTCURL_MULTI_LOOP_STATE_REQUEST_REMOVAL,
GSTCURL_MULTI_LOOP_STATE_STOP,
GSTCURL_MULTI_LOOP_STATE_MAX
} state;
/* < private > */
CURLM *multi_handle;
};
struct _GstCurlHttpSrcClass
{
GstPushSrcClass parent_class;
GstCurlHttpSrcMultiTaskContext multi_task_context;
};
/*
* Our instance class.
*/
struct _GstCurlHttpSrc
{
GstPushSrc element;
/* < private > */
GMutex uri_mutex; /* Make the URIHandler get/set thread safe */
/*
* Things to tell libcURL about to build up the request message.
*/
/* Type Name Curl Option */
gchar *uri; /* CURLOPT_URL */
gchar *redirect_uri; /* CURLINFO_REDIRECT_URL */
gchar *username; /* CURLOPT_USERNAME */
gchar *password; /* CURLOPT_PASSWORD */
gchar *proxy_uri; /* CURLOPT_PROXY */
gchar *no_proxy_list; /* CURLOPT_NOPROXY */
gchar *proxy_user; /* CURLOPT_PROXYUSERNAME */
gchar *proxy_pass; /* CURLOPT_PROXYPASSWORD */
/* Header options */
gchar **cookies; /* CURLOPT_COOKIELIST */
gint number_cookies;
gchar *user_agent; /* CURLOPT_USERAGENT */
GstStructure *request_headers; /* CURLOPT_HTTPHEADER */
struct curl_slist *slist;
gboolean accept_compressed_encodings; /* CURLOPT_ACCEPT_ENCODING */
/* Connection options */
glong allow_3xx_redirect; /* CURLOPT_FOLLOWLOCATION */
glong max_3xx_redirects; /* CURLOPT_MAXREDIRS */
gboolean keep_alive; /* CURLOPT_TCP_KEEPALIVE */
gint timeout_secs; /* CURLOPT_TIMEOUT */
gboolean strict_ssl; /* CURLOPT_SSL_VERIFYPEER */
gchar* custom_ca_file; /* CURLOPT_CAINFO */
gint total_retries;
gint retries_remaining;
/*TODO As the following are all multi options, move these to curl task */
guint max_connection_time; /* */
guint max_conns_per_server; /* CURLMOPT_MAX_HOST_CONNECTIONS */
guint max_conns_per_proxy; /* ?!? */
guint max_conns_global; /* CURLMOPT_MAXCONNECTS */
/* END multi options */
/* Some stuff for HTTP/2 */
enum
{
GSTCURL_HTTP_VERSION_1_0,
GSTCURL_HTTP_VERSION_1_1,
#ifdef CURL_VERSION_HTTP2
GSTCURL_HTTP_VERSION_2_0,
#endif
GSTCURL_HTTP_NOT, /* For future use, incase not HTTP protocol! */
GSTCURL_HTTP_VERSION_MAX
} preferred_http_version; /* CURLOPT_HTTP_VERSION */
enum
{
GSTCURL_NONE,
GSTCURL_OK,
GSTCURL_DONE,
GSTCURL_UNLOCK,
GSTCURL_REMOVED,
GSTCURL_BAD_QUEUE_REQUEST,
GSTCURL_TOTAL_ERROR,
GSTCURL_PIPELINE_NULL,
GSTCURL_MAX
} state, pending_state;
CURL *curl_handle;
GMutex buffer_mutex;
GCond signal;
gchar *buffer;
guint buffer_len;
gboolean transfer_begun;
gboolean data_received;
/*
* Response Headers
*/
GstStructure *http_headers;
gchar *content_type;
guint status_code;
gboolean hdrs_updated;
CURLcode curl_result;
char curl_errbuf[CURL_ERROR_SIZE];
GstCaps *caps;
};
enum
{
PROP_0,
PROP_URI,
PROP_USERNAME,
PROP_PASSWORD,
PROP_PROXYURI,
PROP_PROXYUSERNAME,
PROP_PROXYPASSWORD,
PROP_COOKIES,
PROP_USERAGENT,
PROP_HEADERS,
PROP_COMPRESS,
PROP_REDIRECT,
PROP_MAXREDIRECT,
PROP_KEEPALIVE,
PROP_TIMEOUT,
PROP_STRICT_SSL,
PROP_SSL_CA_FILE,
PROP_RETRIES,
PROP_CONNECTIONMAXTIME,
PROP_MAXCONCURRENT_SERVER,
PROP_MAXCONCURRENT_PROXY,
PROP_MAXCONCURRENT_GLOBAL,
PROP_HTTPVERSION,
PROP_MAX
};
curl_version_info_data *gst_curl_http_src_curl_capabilities;
gfloat pref_http_ver;
gchar *gst_curl_http_src_default_useragent;
GType gst_curl_http_src_get_type (void);
G_END_DECLS
#endif /* GSTCURLHTTPSRC_H_ */

185
ext/curl/gstcurlqueue.c Normal file
View file

@ -0,0 +1,185 @@
/*
* GstCurlHttpSrc
* Copyright 2017 British Broadcasting Corporation - Research and Development
*
* Author: Sam Hurst <samuelh@rd.bbc.co.uk>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Alternatively, the contents of this file may be used under the
* GNU Lesser General Public License Version 2.1 (the "LGPL"), in
* which case the following provisions apply instead of the ones
* mentioned above:
*
* 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.
*/
#include "gstcurlqueue.h"
/**
* Function to add an item to a queue. If the queue is empty (i.e. NULL), then
* it creates the new head of the queue, otherwise it scans to the end and adds
* the entry there.
* @param queue The queue to add an item to. Can be NULL.
* @param s The item to be added to the queue.
* @return Returns TRUE (0) on success, FALSE (!0) is an error.
*/
gboolean
gst_curl_http_src_add_queue_item (GstCurlHttpSrcQueueElement ** queue,
GstCurlHttpSrc * s)
{
GstCurlHttpSrcQueueElement *insert_point;
if (*queue == NULL) {
/* Queue is currently empty, so create a new item on the head */
*queue = (GstCurlHttpSrcQueueElement *)
g_malloc (sizeof (GstCurlHttpSrcQueueElement));
if (*queue == NULL) {
return FALSE;
}
insert_point = *queue;
} else {
insert_point = *queue;
while (insert_point->next != NULL) {
insert_point = insert_point->next;
}
insert_point->next = (GstCurlHttpSrcQueueElement *)
g_malloc (sizeof (GstCurlHttpSrcQueueElement));
if (insert_point->next == NULL) {
return FALSE;
}
insert_point = insert_point->next;
}
insert_point->p = s;
g_mutex_init (&insert_point->running);
insert_point->next = NULL;
return TRUE;
}
/**
* Function to remove an item from a queue.
* @param queue The queue to remove an item from.
* @param s The item to be removed.
* @return Returns TRUE if item removed, FALSE if item couldn't be found.
*/
gboolean
gst_curl_http_src_remove_queue_item (GstCurlHttpSrcQueueElement ** queue,
GstCurlHttpSrc * s)
{
GstCurlHttpSrcQueueElement *prev_qelement, *this_qelement;
prev_qelement = NULL;
this_qelement = *queue;
while (this_qelement->p != s) {
if (this_qelement == NULL) {
/* Reached end of list without finding anything */
return FALSE;
}
prev_qelement = this_qelement;
this_qelement = this_qelement->next;
}
/* First queue item matched. */
if (prev_qelement == NULL) {
/* First and only element? If so, free the element and make queue NULL */
if (this_qelement->next == NULL) {
g_free (*queue);
*queue = NULL;
return TRUE;
} else {
*queue = this_qelement->next;
}
} else {
prev_qelement->next = this_qelement->next;
}
g_free (this_qelement);
return TRUE;
}
/**
* Convenience function to remove an item from a queue by it's contained curl
* handle. Only ever called from within the multi loop when the CURL handle
* returns, so it's safe to assume that the transfer completed and the result
* can be set as GSTCURL_RETURN_DONE (which doesn't necessarily mean that the
* transfer was a success, just that CURL is finished with it)
* @param queue The queue to remove an item from.
* @param s The item to be removed.
* @return Returns TRUE if item removed, FALSE if item couldn't be found.
*/
gboolean
gst_curl_http_src_remove_queue_handle (GstCurlHttpSrcQueueElement ** queue,
CURL * handle, CURLcode result)
{
GstCurlHttpSrcQueueElement *prev_qelement, *this_qelement;
prev_qelement = NULL;
this_qelement = *queue;
while (this_qelement->p->curl_handle != handle) {
if (this_qelement == NULL) {
/* Reached end of list without finding anything */
return FALSE;
}
prev_qelement = this_qelement;
this_qelement = this_qelement->next;
}
/*GST_DEBUG_OBJECT (this_qelement->p,
"Removing queue item via curl handle for URI %s",
this_qelement->p->uri); */
/* First, signal the transfer owner thread to wake up */
g_mutex_lock (&this_qelement->p->buffer_mutex);
g_cond_signal (&this_qelement->p->signal);
if (this_qelement->p->state != GSTCURL_UNLOCK) {
this_qelement->p->state = GSTCURL_DONE;
} else {
this_qelement->p->pending_state = GSTCURL_DONE;
}
this_qelement->p->curl_result = result;
g_mutex_unlock (&this_qelement->p->buffer_mutex);
/* First queue item matched. */
if (prev_qelement == NULL) {
/* First and only element? If so, free the element and make queue NULL */
if (this_qelement->next == NULL) {
g_free (*queue);
*queue = NULL;
return TRUE;
} else {
*queue = this_qelement->next;
}
} else {
prev_qelement->next = this_qelement->next;
}
g_free (this_qelement);
return TRUE;
}

65
ext/curl/gstcurlqueue.h Normal file
View file

@ -0,0 +1,65 @@
/*
* GstCurlHttpSrc
* Copyright 2017 British Broadcasting Corporation - Research and Development
*
* Author: Sam Hurst <samuelh@rd.bbc.co.uk>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Alternatively, the contents of this file may be used under the
* GNU Lesser General Public License Version 2.1 (the "LGPL"), in
* which case the following provisions apply instead of the ones
* mentioned above:
*
* 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.
*/
#ifndef GSTCURLQUEUE_H_
#define GSTCURLQUEUE_H_
#include "gstcurlhttpsrc.h"
struct _GstCurlHttpSrcQueueElement
{
GstCurlHttpSrc *p;
GMutex running;
GstCurlHttpSrcQueueElement *next;
};
gboolean gst_curl_http_src_add_queue_item (GstCurlHttpSrcQueueElement **queue,
GstCurlHttpSrc *s);
gboolean gst_curl_http_src_remove_queue_item (
GstCurlHttpSrcQueueElement **queue, GstCurlHttpSrc *s);
gboolean gst_curl_http_src_remove_queue_handle (
GstCurlHttpSrcQueueElement **queue, CURL *handle, CURLcode result);
#endif /* GSTCURLQUEUE_H_ */

View file

@ -8,6 +8,8 @@ curl_sources = [
'gstcurlsmtpsink.c',
'gstcurlsshsink.c',
'gstcurltlssink.c',
'gstcurlhttpsrc.c',
'gstcurlqueue.c',
]
curl_dep = dependency('libcurl', version : '>= 7.35.0', required : false)