1 /* 2 * GPAC - Multimedia Framework C SDK 3 * 4 * Authors: Jean Le Feuvre 5 * Copyright (c) Telecom ParisTech 2000-2019 6 * All rights reserved 7 * 8 * This file is part of GPAC / common tools sub-project 9 * 10 * GPAC is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU Lesser General Public License as published by 12 * the Free Software Foundation; either version 2, or (at your option) 13 * any later version. 14 * 15 * GPAC is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License for more details. 19 * 20 * You should have received a copy of the GNU Lesser General Public 21 * License along with this library; see the file COPYING. If not, write to 22 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 23 * 24 */ 25 26 #ifndef _GF_DOWNLOAD_H_ 27 #define _GF_DOWNLOAD_H_ 28 29 /*! 30 \file <gpac/download.h> 31 \brief HTTP(S) Downloader. 32 */ 33 34 /*! 35 36 \addtogroup download_grp 37 \brief HTTP Downloader 38 39 This section documents the file downloading tools the GPAC framework. Currently HTTP and HTTPS are supported. HTTPS may not be supported depending on GPAC compilation options (HTTPS in GPAC needs OpenSSL installed on the system). 40 41 @{ 42 43 */ 44 45 46 #ifdef __cplusplus 47 extern "C" { 48 #endif 49 50 #include <gpac/tools.h> 51 #include <gpac/config_file.h> 52 #include <gpac/cache.h> 53 54 /*!the download manager object. This is usually not used by GPAC modules*/ 55 typedef struct __gf_download_manager GF_DownloadManager; 56 /*!the download manager session.*/ 57 typedef struct __gf_download_session GF_DownloadSession; 58 /*!the optional filter session.*/ 59 typedef struct __gf_filter_session GF_DownloadFilterSession; 60 61 /*! URL information object*/ 62 typedef struct GF_URL_Info_Struct { 63 const char * protocol; 64 char * server_name; 65 char * remotePath; 66 char * canonicalRepresentation; 67 char * userName; 68 char * password; 69 u16 port; 70 } GF_URL_Info; 71 72 /*! 73 Extracts the information from an URL. A call to gf_dm_url_info_init() must have been issue before calling this method. 74 \param url The URL to fill 75 \param info This structure will be initialized properly and filled with the data 76 \param baseURL The baseURL to use if any (can be null) 77 \return GF_OK if URL is well formed and supported by GPAC 78 */ 79 GF_Err gf_dm_get_url_info(const char * url, GF_URL_Info * info, const char * baseURL); 80 81 /** 82 Inits the GF_URL_Info structure before it can be used 83 \param info The structure to initialize 84 */ 85 void gf_dm_url_info_init(GF_URL_Info * info); 86 87 /*! 88 Frees the inner structures of a GF_URL_Info_Struct 89 \param info The info to free 90 */ 91 void gf_dm_url_info_del(GF_URL_Info * info); 92 93 /*! 94 \brief download manager constructor 95 96 Creates a new download manager object. 97 \param fsess optional filter session. If not NULL, the filter session will be used for async downloads. Otherwise, threads will be created 98 \return the download manager object 99 */ 100 GF_DownloadManager *gf_dm_new(GF_DownloadFilterSession *fsess); 101 /*! 102 \brief download manager destructor 103 104 Deletes the download manager. All running sessions are aborted 105 \param dm the download manager object 106 */ 107 void gf_dm_del(GF_DownloadManager *dm); 108 109 /*! 110 \brief callback function for authentication 111 112 The gf_dm_get_usr_pass type is the type for the callback of the \ref gf_dm_set_auth_callback function used for password retrieval 113 \param usr_cbk opaque user data 114 \param site_url url of the site the user and password are requested for 115 \param usr_name the user name for this site. The allocated space for this buffer is 50 bytes. \note this varaibale may already be formatted. 116 \param password the password for this site and user. The allocated space for this buffer is 50 bytes. 117 \return 0 if user didn't fill in the information which will result in an authentication failure, 1 otherwise. 118 */ 119 typedef Bool (*gf_dm_get_usr_pass)(void *usr_cbk, const char *site_url, char *usr_name, char *password); 120 121 /*! 122 \brief password retrieval assignment 123 124 Assigns the callback function used for user password retrieval. If no such function is assigned to the download manager, all downloads requiring authentication will fail. 125 \param dm the download manager object 126 \param get_pass specifies \ref gf_dm_get_usr_pass callback function for user and password retrieval. 127 \param usr_cbk opaque user data passed to callback function 128 */ 129 void gf_dm_set_auth_callback(GF_DownloadManager *dm, gf_dm_get_usr_pass get_pass, void *usr_cbk); 130 131 /*!downloader session message types*/ 132 typedef enum 133 { 134 /*!signal that session is setup and waiting for connection request*/ 135 GF_NETIO_SETUP = 0, 136 /*!signal that session connection is done*/ 137 GF_NETIO_CONNECTED, 138 /*!request a protocol method from the user. Default value is "GET" for HTTP*/ 139 GF_NETIO_GET_METHOD, 140 /*!request a header from the user. */ 141 GF_NETIO_GET_HEADER, 142 /*!requesting content from the user, if any. Content is appended to the request*/ 143 GF_NETIO_GET_CONTENT, 144 /*!signal that request is sent and waiting for server reply*/ 145 GF_NETIO_WAIT_FOR_REPLY, 146 /*!signal a header to user. */ 147 GF_NETIO_PARSE_HEADER, 148 /*!signal request reply to user. The reply is always sent after the headers*/ 149 GF_NETIO_PARSE_REPLY, 150 /*!send data to the user*/ 151 GF_NETIO_DATA_EXCHANGE, 152 /*!all data has been transfered*/ 153 GF_NETIO_DATA_TRANSFERED, 154 /*!signal that the session has been deconnected*/ 155 GF_NETIO_DISCONNECTED, 156 /*!downloader session failed (error code set) or done/destroyed (no error code)*/ 157 GF_NETIO_STATE_ERROR 158 } GF_NetIOStatus; 159 160 /*!session download flags*/ 161 typedef enum 162 { 163 /*!session is not threaded, the user must explicitely fetch the data , either with the function gf_dm_sess_fetch_data 164 or the function gf_dm_sess_process- if the session is threaded, the user must call gf_dm_sess_process to start the session*/ 165 GF_NETIO_SESSION_NOT_THREADED = 1, 166 /*! session data is cached or not */ 167 GF_NETIO_SESSION_NOT_CACHED = 1<<1, 168 /*! forces data notification even when session is threaded*/ 169 GF_NETIO_SESSION_NOTIFY_DATA = 1<<2, 170 /*indicates that the connection to the server should be kept once the download is successfully completed*/ 171 GF_NETIO_SESSION_PERSISTENT = 1<<3, 172 /*file is stored in memory, and the cache name is set to gpac://%u@%p, where %d is the size in bytes and %d is the the pointer to the memory. 173 Memory cached files are destroyed upon downloader destruction*/ 174 GF_NETIO_SESSION_MEMORY_CACHE = 1<<4, 175 } GF_NetIOFlags; 176 177 178 /*!protocol I/O parameter*/ 179 typedef struct 180 { 181 /*!parameter message type*/ 182 GF_NetIOStatus msg_type; 183 /*error code if any. Valid for all message types.*/ 184 GF_Err error; 185 /*!data received or data to send. Only valid for GF_NETIO_GET_CONTENT and GF_NETIO_DATA_EXCHANGE (when no cache is setup) messages*/ 186 const u8 *data; 187 /*!size of associated data. Only valid for GF_NETIO_GET_CONTENT and GF_NETIO_DATA_EXCHANGE messages*/ 188 u32 size; 189 /*protocol header. Only valid for GF_NETIO_GET_HEADER, GF_NETIO_PARSE_HEADER and GF_NETIO_GET_METHOD*/ 190 const char *name; 191 /*protocol header value or server response. Only alid for GF_NETIO_GET_HEADER, GF_NETIO_PARSE_HEADER and GF_NETIO_PARSE_REPLY*/ 192 char *value; 193 /*message-dependend 194 for GF_NETIO_PARSE_REPLY, response code 195 for GF_NETIO_DATA_EXCHANGE 196 Set to 1 in to indicate end of chunk transfer 197 Set to 2 in GF_NETIO_DATA_EXCHANGE to indicate complete file is already received (replay of events from cache) 198 for all other, usage is reserved 199 */ 200 u32 reply; 201 /*download session for which the message is being sent*/ 202 GF_DownloadSession *sess; 203 } GF_NETIO_Parameter; 204 205 /*! 206 \brief callback function for data reception and state signaling 207 208 The gf_dm_user_io type is the type for the data callback function of a download session 209 \param usr_cbk opaque user data 210 \param parameter the input/output parameter structure 211 */ 212 typedef void (*gf_dm_user_io)(void *usr_cbk, GF_NETIO_Parameter *parameter); 213 214 215 216 /*! 217 \brief download session constructor 218 219 Creates a new download session 220 \param dm the download manager object 221 \param url file to retrieve (no PUT/POST yet, only downloading is supported) 222 \param dl_flags combination of session download flags 223 \param user_io specifies \ref gf_dm_user_io callback function for data reception and service messages 224 \param usr_cbk opaque user data passed to callback function 225 \param error error for failure cases 226 \return the session object or NULL if error. If no error is indicated and a NULL session is returned, this means the file is local 227 */ 228 GF_DownloadSession * gf_dm_sess_new(GF_DownloadManager *dm, const char *url, u32 dl_flags, 229 gf_dm_user_io user_io, 230 void *usr_cbk, 231 GF_Err *error); 232 233 /*! 234 \brief download session simple constructor 235 236 Creates a new download session 237 \param dm The download manager used to create the download session 238 \param url file to retrieve (no PUT/POST yet, only downloading is supported) 239 \param dl_flags combination of session download flags 240 \param user_io specifies \ref gf_dm_user_io callback function for data reception and service messages 241 \param usr_cbk opaque user data passed to callback function 242 \param e error for failure cases 243 \return the session object or NULL if error. If no error is indicated and a NULL session is returned, this means the file is local 244 */ 245 GF_DownloadSession *gf_dm_sess_new_simple(GF_DownloadManager * dm, const char *url, u32 dl_flags, 246 gf_dm_user_io user_io, 247 void *usr_cbk, 248 GF_Err *e); 249 250 /*! 251 \brief downloader session destructor 252 253 Deletes the download session, cleaning the cache if indicated in the configuration file of the download manager (section "Downloader", key "CleanCache") 254 \param sess the download session 255 */ 256 void gf_dm_sess_del(GF_DownloadSession * sess); 257 258 /*! 259 \brief aborts downloading 260 261 Aborts all operations in the session, regardless of its state. The session cannot be reused once this is called. 262 \param sess the download session 263 */ 264 void gf_dm_sess_abort(GF_DownloadSession * sess); 265 266 /*! 267 \brief gets last session error 268 269 Gets the last error that occured in the session 270 \param sess the download session 271 \return the last error 272 */ 273 GF_Err gf_dm_sess_last_error(GF_DownloadSession *sess); 274 275 276 /*! 277 \brief fetches data on session 278 279 Fetches data from the server. This will also performs connections and all needed exchange with server. 280 \param sess the download session 281 \param buffer destination buffer 282 \param buffer_size destination buffer allocated size 283 \param read_size amount of data actually fetched 284 \note this can only be used when the session is not threaded 285 \return error if any 286 */ 287 GF_Err gf_dm_sess_fetch_data(GF_DownloadSession * sess, char *buffer, u32 buffer_size, u32 *read_size); 288 289 /*! 290 \brief get mime type as lower case 291 292 Fetches the mime type of the URL this session is fetching, value will be returned lower case, so application/x-mpegURL will be returned as application/x-mpegurl 293 \param sess the download session 294 \return the mime type of the URL, or NULL if error. You should get the error with \ref gf_dm_sess_last_error 295 */ 296 const char *gf_dm_sess_mime_type(GF_DownloadSession * sess); 297 298 /*! 299 \brief sets session range 300 301 Sets the session byte range. This shll be called before processing the session. 302 \param sess the download session 303 \param start_range HTTP download start range in byte 304 \param end_range HTTP download end range in byte 305 \param discontinue_cache If set, forces a new cache entry if byte range are not continuous. Otherwise a single cache entry is used to reconstruct the file 306 \note this can only be used when the session is not threaded 307 \return error if any 308 */ 309 GF_Err gf_dm_sess_set_range(GF_DownloadSession *sess, u64 start_range, u64 end_range, Bool discontinue_cache); 310 /*! 311 \brief get cache file name 312 313 Gets the cache file name for the session. 314 \param sess the download session 315 \return the absolute path of the cache file, or NULL if the session is not cached*/ 316 const char *gf_dm_sess_get_cache_name(GF_DownloadSession * sess); 317 318 /*! 319 \brief Marks the cache file to be deleted once the file is not used anymore by any session 320 \param dm the download manager 321 \param url The URL associate to the cache entry to be deleted 322 */ 323 void gf_dm_delete_cached_file_entry(const GF_DownloadManager * dm, const char * url); 324 325 /*! 326 Marks the cache file for this session to be deleted once the file is not used anymore by any session 327 \param sess the download session 328 \param url The URL associate to the cache entry to be deleted 329 */ 330 void gf_dm_delete_cached_file_entry_session(const GF_DownloadSession * sess, const char * url); 331 332 /*! 333 \brief get statistics 334 335 Gets download statistics for the session. All output parameters are optional and may be set to NULL. 336 \param sess the download session 337 \param server the remote server address 338 \param path the path on the remote server 339 \param total_size the total size in bytes the file fetched, 0 if unknown. 340 \param bytes_done the amount of bytes received from the server 341 \param bytes_per_sec the average data rate in bytes per seconds 342 \param net_status the session status 343 \return error if any 344 */ 345 GF_Err gf_dm_sess_get_stats(GF_DownloadSession * sess, const char **server, const char **path, u64 *total_size, u64 *bytes_done, u32 *bytes_per_sec, GF_NetIOStatus *net_status); 346 347 /*! 348 \brief get start time 349 350 Gets session start time in UTC. If chunk-transfer is used, the start time is reset at each chunk start 351 \param sess the download session 352 \return UTC start time 353 */ 354 u64 gf_dm_sess_get_utc_start(GF_DownloadSession *sess); 355 356 357 /*! 358 \brief fetch session object 359 360 Fetches the session object (process all headers and data transfer). This is only usable if the session is not threaded 361 \param sess the download session 362 \return the last error in the session or 0 if none*/ 363 GF_Err gf_dm_sess_process(GF_DownloadSession *sess); 364 365 /*! 366 \brief fetch session object headers 367 368 Fetch the session object headers and stops after that. This is only usable if the session is not threaded 369 \param sess the download session 370 \return the last error in the session or 0 if none*/ 371 GF_Err gf_dm_sess_process_headers(GF_DownloadSession * sess); 372 373 /*! 374 \brief Get session resource url 375 376 Returns the original resource URL associated with the session 377 \param sess the download session 378 \return the associated URL 379 */ 380 const char *gf_dm_sess_get_resource_name(GF_DownloadSession *sess); 381 382 #ifndef GPAC_DISABLE_CORE_TOOLS 383 /*! 384 Downloads a file over the network using a download manager 385 \param dm The download manager to use, function will use all associated cache ressources 386 \param url The url to download 387 \param filename The filename to download 388 \param start_range start position of a byte range 389 \param end_range end position of a byte range 390 \param redirected_url If not NULL, \p redirected_url will be allocated and filled with the URL after redirection. Caller takes ownership 391 \return GF_OK if everything went fine, an error otherwise 392 */ 393 GF_Err gf_dm_wget_with_cache(GF_DownloadManager * dm, const char *url, const char *filename, u64 start_range, u64 end_range, char **redirected_url); 394 395 /*! 396 \brief Same as gf_dm_wget_with_cache, but initializes the GF_DownloadManager by itself. 397 398 This function is deprecated, please use gf_dm_wget_with_cache instead 399 \param url The url to download 400 \param filename The filename to download 401 \param start_range start position of a byte range 402 \param end_range end position of a byte range 403 \param redirected_url If not NULL, \p redirected_url will be allocated and filled with the URL after redirection. Caller takes ownership 404 \return GF_OK if everything went fine, an error otherwise 405 */ 406 GF_Err gf_dm_wget(const char *url, const char *filename, u64 start_range, u64 end_range, char **redirected_url); 407 408 #endif /* GPAC_DISABLE_CORE_TOOLS */ 409 410 /*! 411 Re-setup an existing, completed session to download a new URL. If same server/port/protocol is used, the same socket will be reused if the session has the GF_NETIO_SESSION_PERSISTENT flag set. This is only possible if the session is not threaded. 412 \param sess The session 413 \param url The new url for the session 414 \param allow_direct_reuse Allow reuse of cache entry without checking cache directives 415 \return GF_OK or error 416 */ 417 GF_Err gf_dm_sess_setup_from_url(GF_DownloadSession *sess, const char *url, Bool allow_direct_reuse); 418 419 /*! 420 \brief retrieves the HTTP header value for the given name 421 422 Retrieves the HTTP header value for the given header name. 423 \param sess the current session 424 \param name the target header name 425 \return header value or NULL if not found 426 */ 427 const char *gf_dm_sess_get_header(GF_DownloadSession *sess, const char *name); 428 429 /*! 430 \brief enumerates the HTTP headers for a session 431 432 Retrieves the HTTP header name and value for the given header index. 433 \param sess the current session 434 \param idx index for the enumeration, must be initialized to 0 for the first call 435 \param hdr_name where name of header is stored - do not free 436 \param hdr_val where value of header is stored - do not free 437 \return error code, GF_OK or GF_EOS if no more headers 438 */ 439 GF_Err gf_dm_sess_enum_headers(GF_DownloadSession *sess, u32 *idx, const char **hdr_name, const char **hdr_val); 440 441 /*! 442 \brief sets download manager max rate per session 443 444 Sets the maximum rate (per session only at the current time). 445 \param dm the download manager object 446 \param rate_in_bits_per_sec the new rate in bits per sec. If 0, HTTP rate will not be limited 447 */ 448 void gf_dm_set_data_rate(GF_DownloadManager *dm, u32 rate_in_bits_per_sec); 449 450 /*! 451 \brief gets download manager max rate per session 452 453 Sets the maximum rate (per session only at the current time). 454 \param dm the download manager object 455 \return the rate in bits per sec. If 0, HTTP rate is not limited 456 */ 457 u32 gf_dm_get_data_rate(GF_DownloadManager *dm); 458 459 460 /*! 461 \brief gets cumultaed download rate for all sessions 462 463 Gets the cumultated bitrate in of all active sessions. 464 \param dm the download manager object 465 \return the cumulated rate in bits per sec. 466 */ 467 u32 gf_dm_get_global_rate(GF_DownloadManager *dm); 468 469 470 /*! 471 \brief Get header sizes and times stats for the session 472 473 Get header sizes and times stats for the session 474 \param sess the current session 475 \param req_hdr_size request header size in bytes. May be NULL. 476 \param rsp_hdr_size response header size in bytes. May be NULL. 477 \param connect_time connection time in micro seconds. May be NULL. 478 \param reply_time elapsed time between request sent and response header received, in micro seconds. May be NULL. 479 \param download_time download time since request sent, in micro seconds. May be NULL. 480 \return error code if any 481 */ 482 GF_Err gf_dm_sess_get_header_sizes_and_times(GF_DownloadSession *sess, u32 *req_hdr_size, u32 *rsp_hdr_size, u32 *connect_time, u32 *reply_time, u32 *download_time); 483 484 /*! 485 \brief Forces session to use memory storage 486 487 Forces session to use memory storage for future downloads 488 \param sess the current session 489 */ 490 void gf_dm_sess_force_memory_mode(GF_DownloadSession *sess); 491 492 /*! 493 Registers a locacl cache provider (bypassing the http session), used when populating cache from input data (atsc for example) 494 495 \param dm the download manager 496 \param local_cache_url_provider_cbk callback function to the cache provider. The callback function shall return GF_TRUE if the requested URL is provided by this local cache 497 \param lc_udta opaque pointer passed to the callback function 498 \return error code if any 499 */ 500 GF_Err gf_dm_set_localcache_provider(GF_DownloadManager *dm, Bool (*local_cache_url_provider_cbk)(void *udta, char *url, Bool is_cache_destroy), void *lc_udta); 501 502 /*! 503 Adds a local entry in the cache 504 505 \param dm the download manager 506 \param szURL the URL this resource is caching 507 \param data data of the resource 508 \param size size of the resource 509 \param start_range start range of the data in the resource 510 \param end_range start range of the data in the resource. If both start_range and end_range are 0, the data is the complete resource 511 \param mime associated MIME type if any 512 \param clone_memory indicates that the data shall be cloned in the cache because the caller will discard it 513 \param download_time_ms indicates the download time of the associated resource, if known, 0 otherwise. 514 \return a cache entry structure 515 */ 516 const DownloadedCacheEntry gf_dm_add_cache_entry(GF_DownloadManager *dm, const char *szURL, u8 *data, u64 size, u64 start_range, u64 end_range, const char *mime, Bool clone_memory, u32 download_time_ms); 517 518 /*! 519 Forces HTTP headers for a given cache entry 520 521 \param dm the download manager 522 \param entry the cache entry to update 523 \param headers the header string, including CRLF delimiters, to force 524 \return error code if any 525 */ 526 GF_Err gf_dm_force_headers(GF_DownloadManager *dm, const DownloadedCacheEntry entry, const char *headers); 527 528 /*! HTTP methods*/ 529 enum 530 { 531 /*! unsupported*/ 532 GF_HTTP_UNKNOWN = 0, 533 /*! GET*/ 534 GF_HTTP_GET, 535 /*! HEAD*/ 536 GF_HTTP_HEAD, 537 /*! OPTIONS*/ 538 GF_HTTP_OPTIONS, 539 /*! CONNECT*/ 540 GF_HTTP_CONNECT, 541 /*! TRACE*/ 542 GF_HTTP_TRACE, 543 /*! PUT*/ 544 GF_HTTP_PUT, 545 /*! POST*/ 546 GF_HTTP_POST, 547 /*! DELETE*/ 548 GF_HTTP_DELETE 549 }; 550 551 /*! @} */ 552 553 #ifdef __cplusplus 554 } 555 #endif 556 557 558 #endif /*_GF_DOWNLOAD_H_*/ 559 560