1 /* 2 * GstCurlHttpSrc 3 * Copyright 2017 British Broadcasting Corporation - Research and Development 4 * 5 * Author: Sam Hurst <samuelh@rd.bbc.co.uk> 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included in 15 * all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 * DEALINGS IN THE SOFTWARE. 24 * 25 * Alternatively, the contents of this file may be used under the 26 * GNU Lesser General Public License Version 2.1 (the "LGPL"), in 27 * which case the following provisions apply instead of the ones 28 * mentioned above: 29 * 30 * This library is free software; you can redistribute it and/or 31 * modify it under the terms of the GNU Library General Public 32 * License as published by the Free Software Foundation; either 33 * version 2 of the License, or (at your option) any later version. 34 * 35 * This library is distributed in the hope that it will be useful, 36 * but WITHOUT ANY WARRANTY; without even the implied warranty of 37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 38 * Library General Public License for more details. 39 * 40 * You should have received a copy of the GNU Library General Public 41 * License along with this library; if not, write to the 42 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 43 * Boston, MA 02111-1307, USA. 44 */ 45 46 /* 47 * This header file contains definitions only for 48 */ 49 50 #ifndef GSTCURLHTTPSRC_H_ 51 #define GSTCURLHTTPSRC_H_ 52 53 #include <gst/gst.h> 54 #include <string.h> 55 #include <ctype.h> 56 #include <stdlib.h> 57 #include <unistd.h> 58 #include <gst/base/gstpushsrc.h> 59 60 #include "curltask.h" 61 62 G_BEGIN_DECLS 63 /* #defines don't like whitespacey bits */ 64 #define GST_TYPE_CURLHTTPSRC \ 65 (gst_curl_http_src_get_type()) 66 #define GST_CURLHTTPSRC(obj) \ 67 (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_CURLHTTPSRC,GstCurlHttpSrc)) 68 #define GST_CURLHTTPSRC_CLASS(klass) \ 69 (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_CURLHTTPSRC,GstCurlHttpSrcClass)) 70 #define GST_IS_CURLHTTPSRC(obj) \ 71 (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_CURLHTTPSRC)) 72 #define GST_IS_CURLHTTPSRC_CLASS(klass) \ 73 (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CURLHTTPSRC)) 74 75 #if GSTCURL_FUNCTIONTRACE 76 #define GSTCURL_FUNCTION_ENTRY(x) GST_DEBUG_OBJECT(x, "Entering function"); 77 #define GSTCURL_FUNCTION_EXIT(x) GST_DEBUG_OBJECT(x, "Leaving function"); 78 #else 79 #define GSTCURL_FUNCTION_ENTRY(x) 80 #define GSTCURL_FUNCTION_EXIT(x) 81 #endif 82 typedef struct _GstCurlHttpSrc GstCurlHttpSrc; 83 typedef struct _GstCurlHttpSrcClass GstCurlHttpSrcClass; 84 typedef struct _GstCurlHttpSrcMultiTaskContext GstCurlHttpSrcMultiTaskContext; 85 typedef struct _GstCurlHttpSrcQueueElement GstCurlHttpSrcQueueElement; 86 87 #define HTTP_HEADERS_NAME "http-headers" 88 #define HTTP_STATUS_CODE "http-status-code" 89 #define URI_NAME "uri" 90 #define REQUEST_HEADERS_NAME "request-headers" 91 #define RESPONSE_HEADERS_NAME "response-headers" 92 #define REDIRECT_URI_NAME "redirection-uri" 93 94 typedef enum 95 { 96 GSTCURL_HTTP_VERSION_1_0, 97 GSTCURL_HTTP_VERSION_1_1, 98 #ifdef CURL_VERSION_HTTP2 99 GSTCURL_HTTP_VERSION_2_0, 100 #endif 101 GSTCURL_HTTP_NOT, /* For future use, incase not HTTP protocol! */ 102 GSTCURL_HTTP_VERSION_MAX 103 } GstCurlHttpVersion; 104 105 struct _GstCurlHttpSrcMultiTaskContext 106 { 107 GstTask *task; 108 GRecMutex task_rec_mutex; 109 GMutex mutex; 110 guint refcount; 111 GCond signal; 112 113 GstCurlHttpSrcQueueElement *queue; 114 115 enum 116 { 117 GSTCURL_MULTI_LOOP_STATE_RUNNING, 118 GSTCURL_MULTI_LOOP_STATE_STOP 119 } state; 120 121 /* < private > */ 122 CURLM *multi_handle; 123 }; 124 125 struct _GstCurlHttpSrcClass 126 { 127 GstPushSrcClass parent_class; 128 129 GstCurlHttpSrcMultiTaskContext multi_task_context; 130 }; 131 132 /* 133 * Our instance class. 134 */ 135 struct _GstCurlHttpSrc 136 { 137 GstPushSrc element; 138 139 /* < private > */ 140 GMutex uri_mutex; /* Make the URIHandler get/set thread safe */ 141 /* 142 * Things to tell libcURL about to build up the request message. 143 */ 144 /* Type Name Curl Option */ 145 gchar *uri; /* CURLOPT_URL */ 146 gchar *redirect_uri; /* CURLINFO_REDIRECT_URL */ 147 gchar *username; /* CURLOPT_USERNAME */ 148 gchar *password; /* CURLOPT_PASSWORD */ 149 gchar *proxy_uri; /* CURLOPT_PROXY */ 150 gchar *no_proxy_list; /* CURLOPT_NOPROXY */ 151 gchar *proxy_user; /* CURLOPT_PROXYUSERNAME */ 152 gchar *proxy_pass; /* CURLOPT_PROXYPASSWORD */ 153 154 /* Header options */ 155 gchar **cookies; /* CURLOPT_COOKIELIST */ 156 gint number_cookies; 157 gchar *user_agent; /* CURLOPT_USERAGENT */ 158 GstStructure *request_headers; /* CURLOPT_HTTPHEADER */ 159 struct curl_slist *slist; 160 gboolean accept_compressed_encodings; /* CURLOPT_ACCEPT_ENCODING */ 161 162 /* Connection options */ 163 glong allow_3xx_redirect; /* CURLOPT_FOLLOWLOCATION */ 164 glong max_3xx_redirects; /* CURLOPT_MAXREDIRS */ 165 gboolean keep_alive; /* CURLOPT_TCP_KEEPALIVE */ 166 gint timeout_secs; /* CURLOPT_TIMEOUT */ 167 gboolean strict_ssl; /* CURLOPT_SSL_VERIFYPEER */ 168 gchar* custom_ca_file; /* CURLOPT_CAINFO */ 169 170 gint total_retries; 171 gint retries_remaining; 172 173 /*TODO As the following are all multi options, move these to curl task */ 174 guint max_connection_time; /* */ 175 guint max_conns_per_server; /* CURLMOPT_MAX_HOST_CONNECTIONS */ 176 guint max_conns_per_proxy; /* ?!? */ 177 guint max_conns_global; /* CURLMOPT_MAXCONNECTS */ 178 /* END multi options */ 179 180 /* Some stuff for HTTP/2 */ 181 GstCurlHttpVersion preferred_http_version; 182 183 enum 184 { 185 GSTCURL_NONE, 186 GSTCURL_OK, 187 GSTCURL_DONE, 188 GSTCURL_UNLOCK, 189 GSTCURL_REMOVED, 190 GSTCURL_BAD_QUEUE_REQUEST, 191 GSTCURL_TOTAL_ERROR, 192 GSTCURL_PIPELINE_NULL, 193 GSTCURL_MAX 194 } state, pending_state; 195 CURL *curl_handle; 196 GMutex buffer_mutex; 197 GCond buffer_cond; 198 gchar *buffer; 199 guint buffer_len; 200 gboolean transfer_begun; 201 gboolean data_received; 202 enum { 203 GSTCURL_NOT_CONNECTED, 204 GSTCURL_CONNECTED, 205 GSTCURL_WANT_REMOVAL 206 } connection_status; 207 208 /* 209 * Response Headers 210 */ 211 GstStructure *http_headers; 212 gchar *content_type; 213 guint status_code; 214 gchar *reason_phrase; 215 gboolean hdrs_updated; 216 217 CURLcode curl_result; 218 char curl_errbuf[CURL_ERROR_SIZE]; 219 220 GstCaps *caps; 221 }; 222 223 GType gst_curl_http_src_get_type (void); 224 225 G_END_DECLS 226 #endif /* GSTCURLHTTPSRC_H_ */ 227