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 if HTTP protocol not used! */ 102 GSTCURL_HTTP_VERSION_MAX 103 } GstCurlHttpVersion; 104 105 typedef enum _GstCGstCurlHttpSrcSeekable 106 { 107 GSTCURL_SEEKABLE_UNKNOWN, 108 GSTCURL_SEEKABLE_TRUE, 109 GSTCURL_SEEKABLE_FALSE 110 } GstCGstCurlHttpSrcSeekable; 111 112 struct _GstCurlHttpSrcMultiTaskContext 113 { 114 GstTask *task; 115 GRecMutex task_rec_mutex; 116 GMutex mutex; 117 #ifdef OHOS_OPT_STABLE 118 /* ohos.opt.stable.0003 for multiple instances ref/unref mutex */ 119 GMutex multiple_mutex; 120 #endif 121 guint refcount; 122 GCond signal; 123 124 GstCurlHttpSrcQueueElement *queue; 125 126 enum 127 { 128 GSTCURL_MULTI_LOOP_STATE_RUNNING, 129 GSTCURL_MULTI_LOOP_STATE_STOP 130 } state; 131 132 /* < private > */ 133 CURLM *multi_handle; 134 }; 135 136 struct _GstCurlHttpSrcClass 137 { 138 GstPushSrcClass parent_class; 139 140 GstCurlHttpSrcMultiTaskContext multi_task_context; 141 }; 142 143 /* 144 * Our instance class. 145 */ 146 struct _GstCurlHttpSrc 147 { 148 GstPushSrc element; 149 150 /* < private > */ 151 GMutex uri_mutex; /* Make the URIHandler get/set thread safe */ 152 /* 153 * Things to tell libcURL about to build up the request message. 154 */ 155 /* Type Name Curl Option */ 156 gchar *uri; /* CURLOPT_URL */ 157 gchar *redirect_uri; /* CURLINFO_REDIRECT_URL */ 158 gchar *username; /* CURLOPT_USERNAME */ 159 gchar *password; /* CURLOPT_PASSWORD */ 160 gchar *proxy_uri; /* CURLOPT_PROXY */ 161 gchar *no_proxy_list; /* CURLOPT_NOPROXY */ 162 gchar *proxy_user; /* CURLOPT_PROXYUSERNAME */ 163 gchar *proxy_pass; /* CURLOPT_PROXYPASSWORD */ 164 165 /* Header options */ 166 gchar **cookies; /* CURLOPT_COOKIELIST */ 167 gint number_cookies; 168 gchar *user_agent; /* CURLOPT_USERAGENT */ 169 GstStructure *request_headers; /* CURLOPT_HTTPHEADER */ 170 struct curl_slist *slist; 171 gboolean accept_compressed_encodings; /* CURLOPT_ACCEPT_ENCODING */ 172 #ifdef OHOS_EXT_FUNC 173 /* ohos.ext.func.0025 support https seek: */ 174 guint64 request_position; /* Seek to this position. */ 175 guint64 orig_request_pos; /* Original request position. */ 176 guint64 read_position; /* Current position. */ 177 #else 178 gint64 request_position; /* Seek to this position. */ 179 #endif 180 gint64 stop_position; /* Stop at this position. */ 181 182 /* Connection options */ 183 glong allow_3xx_redirect; /* CURLOPT_FOLLOWLOCATION */ 184 glong max_3xx_redirects; /* CURLOPT_MAXREDIRS */ 185 gboolean keep_alive; /* CURLOPT_TCP_KEEPALIVE */ 186 gint timeout_secs; /* CURLOPT_TIMEOUT */ 187 gboolean strict_ssl; /* CURLOPT_SSL_VERIFYPEER */ 188 gchar* custom_ca_file; /* CURLOPT_CAINFO */ 189 190 gint total_retries; 191 gint retries_remaining; 192 193 /*TODO As the following are all multi options, move these to curl task */ 194 guint max_connection_time; /* */ 195 guint max_conns_per_server; /* CURLMOPT_MAX_HOST_CONNECTIONS */ 196 guint max_conns_per_proxy; /* ?!? */ 197 guint max_conns_global; /* CURLMOPT_MAXCONNECTS */ 198 /* END multi options */ 199 200 /* Some stuff for HTTP/2 */ 201 GstCurlHttpVersion preferred_http_version; 202 203 enum 204 { 205 GSTCURL_NONE, 206 GSTCURL_OK, 207 GSTCURL_DONE, 208 GSTCURL_UNLOCK, 209 GSTCURL_REMOVED, 210 GSTCURL_BAD_QUEUE_REQUEST, 211 GSTCURL_TOTAL_ERROR, 212 GSTCURL_PIPELINE_NULL, 213 GSTCURL_MAX 214 } state, pending_state; 215 CURL *curl_handle; 216 GMutex buffer_mutex; 217 GCond buffer_cond; 218 gchar *buffer; 219 guint buffer_len; 220 gboolean transfer_begun; 221 gboolean data_received; 222 enum { 223 GSTCURL_NOT_CONNECTED, 224 GSTCURL_CONNECTED, 225 GSTCURL_WANT_REMOVAL 226 } connection_status; 227 228 /* 229 * Response Headers 230 */ 231 GstStructure *http_headers; 232 gchar *content_type; 233 guint status_code; 234 gchar *reason_phrase; 235 gboolean hdrs_updated; 236 guint64 content_size; 237 GstCGstCurlHttpSrcSeekable seekable; 238 239 CURLcode curl_result; 240 char curl_errbuf[CURL_ERROR_SIZE]; 241 242 GstCaps *caps; 243 }; 244 245 GType gst_curl_http_src_get_type (void); 246 247 G_END_DECLS 248 #endif /* GSTCURLHTTPSRC_H_ */ 249