/* * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre * Copyright (c) Telecom ParisTech 2000-2012 * All rights reserved * * This file is part of GPAC / common tools sub-project * * GPAC is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * GPAC 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef _GF_DOWNLOAD_H_ #define _GF_DOWNLOAD_H_ /*! * \file <gpac/download.h> * \brief HTTP(S) Downloader. */ /*! * \addtogroup dld_grp Downloader * \ingroup utils_grp * \brief File Downloader objects * * This section documents the file downloading tools the GPAC framework. Currently HTTP is supported, HTTPS is under testing but may not be supported *depending on GPAC compilation options (HTTPS in GPAC needs OpenSSL installed on the system). * * @{ */ #ifdef __cplusplus extern "C" { #endif #include <gpac/tools.h> #include <gpac/config_file.h> #include <gpac/cache.h> /*!the download manager object. This is usually not used by GPAC modules*/ typedef struct __gf_download_manager GF_DownloadManager; /*!the download manager session.*/ typedef struct __gf_download_session GF_DownloadSession; typedef struct GF_URL_Info_Struct { const char * protocol; char * server_name; char * remotePath; char * canonicalRepresentation; char * userName; char * password; u16 port; } GF_URL_Info; /*! * Extracts the information from an URL. A call to gf_dm_url_info_init() must have been issue before calling this method. * \param url The URL to fill * \param info This structure will be initialized properly and filled with the data * \param baseURL The baseURL to use if any (can be null) * \return GF_OK if URL is well formed and supported by GPAC */ GF_Err gf_dm_get_url_info(const char * url, GF_URL_Info * info, const char * baseURL); /** * Init the GF_URL_Info structure before it can be used * \param info The structure to initialize */ void gf_dm_url_info_init(GF_URL_Info * info); /*! * Frees the inner structures of a GF_URL_Info_Struct * \param info The info to free */ void gf_dm_url_info_del(GF_URL_Info * info); /*! *\brief download manager constructor * *Creates a new download manager object. *\param cfg optional configuration file. Currently the download manager needs a configuration file for cache location and *other options. The cache directory must be indicated in the section "General", key "CacheDirectory" of the configuration *file. If the cache directory is not found, the cache will be disabled but the downloader will still work. *\return the download manager object */ GF_DownloadManager *gf_dm_new(GF_Config *cfg); /* *\brief download manager destructor * *Deletes the download manager. All running sessions are aborted *\param dm the download manager object */ void gf_dm_del(GF_DownloadManager *dm); /*! *\brief callback function for authentication * * 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 *\param usr_cbk opaque user data *\param site_url url of the site the user and password are requested for *\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. *\param password the password for this site and user. The allocated space for this buffer is 50 bytes. *\return 0 if user didn't fill in the information which will result in an authentication failure, 1 otherwise. */ typedef Bool (*gf_dm_get_usr_pass)(void *usr_cbk, const char *site_url, char *usr_name, char *password); /*! *\brief password retrieval assignment * *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. *\param dm the download manager object *\param get_pass \ref gf_dm_get_usr_pass callback function for user and password retrieval. *\param usr_cbk opaque user data passed to callback function */ void gf_dm_set_auth_callback(GF_DownloadManager *dm, gf_dm_get_usr_pass get_pass, void *usr_cbk); /*!downloader session message types*/ typedef enum { /*!signal that session is setup and waiting for connection request*/ GF_NETIO_SETUP = 0, /*!signal that session connection is done*/ GF_NETIO_CONNECTED, /*!request a protocol method from the user. Default value is "GET" for HTTP*/ GF_NETIO_GET_METHOD, /*!request a header from the user. */ GF_NETIO_GET_HEADER, /*!requesting content from the user, if any. Content is appended to the request*/ GF_NETIO_GET_CONTENT, /*!signal that request is sent and waiting for server reply*/ GF_NETIO_WAIT_FOR_REPLY, /*!signal a header to user. */ GF_NETIO_PARSE_HEADER, /*!signal request reply to user. The reply is always sent after the headers*/ GF_NETIO_PARSE_REPLY, /*!send data to the user*/ GF_NETIO_DATA_EXCHANGE, /*!all data has been transfered*/ GF_NETIO_DATA_TRANSFERED, /*!signal that the session has been deconnected*/ GF_NETIO_DISCONNECTED, /*!downloader session failed (error code set) or done/destroyed (no error code)*/ GF_NETIO_STATE_ERROR } GF_NetIOStatus; /*!session download flags*/ typedef enum { /*!session is not threaded, the user must explicitely fetch the data , either with the function gf_dm_sess_fetch_data or the function gf_dm_sess_process- if the session is threaded, the user must call gf_dm_sess_process to start the session*/ GF_NETIO_SESSION_NOT_THREADED = 1, /*! session data is cached or not */ GF_NETIO_SESSION_NOT_CACHED = 1<<1, /*! forces data notification even when session is threaded*/ GF_NETIO_SESSION_NOTIFY_DATA = 1<<2, /*indicates that the connection to the server should be kept once the download is successfully completed*/ GF_NETIO_SESSION_PERSISTENT = 1<<3, /*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. Memory cached files are destroyed upon downloader destruction*/ GF_NETIO_SESSION_MEMORY_CACHE = 1<<4, } GF_NetIOFlags; /*!protocol I/O parameter*/ typedef struct { /*!parameter message type*/ GF_NetIOStatus msg_type; /*error code if any. Valid for all message types.*/ GF_Err error; /*!data received or data to send. Only valid for GF_NETIO_GET_CONTENT and GF_NETIO_DATA_EXCHANGE (when no cache is setup) messages*/ const char *data; /*!size of associated data. Only valid for GF_NETIO_GET_CONTENT and GF_NETIO_DATA_EXCHANGE messages*/ u32 size; /*protocol header. Only valid for GF_NETIO_GET_HEADER, GF_NETIO_PARSE_HEADER and GF_NETIO_GET_METHOD*/ const char *name; /*protocol header value or server response. Only alid for GF_NETIO_GET_HEADER, GF_NETIO_PARSE_HEADER and GF_NETIO_PARSE_REPLY*/ char *value; /*message-dependend for GF_NETIO_PARSE_REPLY, response code for GF_NETIO_DATA_EXCHANGE Set to 1 in to indicate end of chunk transfer Set to 2 in GF_NETIO_DATA_EXCHANGE to indicate complete file is already received (replay of events from cache) for all other, usage is reserved */ u32 reply; /*download session for which the message is being sent*/ GF_DownloadSession *sess; } GF_NETIO_Parameter; /*! *\brief callback function for data reception and state signaling * * The gf_dm_user_io type is the type for the data callback function of a download session *\param usr_cbk opaque user data *\param parameter the input/output parameter structure */ typedef void (*gf_dm_user_io)(void *usr_cbk, GF_NETIO_Parameter *parameter); /*! *\brief download session constructor * *Creates a new download session *\param dm the download manager object *\param url file to retrieve (no PUT/POST yet, only downloading is supported) *\param dl_flags combination of session download flags *\param user_io \ref gf_dm_user_io callback function for data reception and service messages *\param usr_cbk opaque user data passed to callback function *\param error error for failure cases *\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 */ GF_DownloadSession * gf_dm_sess_new(GF_DownloadManager *dm, const char *url, u32 dl_flags, gf_dm_user_io user_io, void *usr_cbk, GF_Err *error); /*! *\brief download session simple constructor * *Creates a new download session *\param dm The download manager used to create the download session *\param url file to retrieve (no PUT/POST yet, only downloading is supported) *\param dl_flags combination of session download flags *\param user_io \ref gf_dm_user_io callback function for data reception and service messages *\param usr_cbk opaque user data passed to callback function *\param e error for failure cases *\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 */ GF_DownloadSession *gf_dm_sess_new_simple(GF_DownloadManager * dm, const char *url, u32 dl_flags, gf_dm_user_io user_io, void *usr_cbk, GF_Err *e); /*! *brief downloader session destructor * *Deletes the download session, cleaning the cache if indicated in the configuration file of the download manager (section "Downloader", key "CleanCache") *\param sess the download session */ void gf_dm_sess_del(GF_DownloadSession * sess); /*! *\brief aborts downloading * *Aborts all operations in the session, regardless of its state. The session cannot be reused once this is called. *\param sess the download session */ void gf_dm_sess_abort(GF_DownloadSession * sess); /*! *\brief sets private data * *associate private data with the session. *\param sess the download session *\param private_data the private data *\warning the private_data parameter is reserved for bandwidth statistics per service when used in the GPAC terminal. */ void gf_dm_sess_set_private(GF_DownloadSession * sess, void *private_data); /*! *\brief gets private data * *Gets private data associated with the session. *\param sess the download session *\return the private data *\warning the private_data parameter is reserved for bandwidth statistics per service when used in the GPAC terminal. */ void *gf_dm_sess_get_private(GF_DownloadSession * sess); /*! *\brief gets last session error * *Gets the last error that occured in the session *\param sess the download session *\return the last error */ GF_Err gf_dm_sess_last_error(GF_DownloadSession *sess); /*! *\brief is download manager thread dead? * *Indicates whether the thread has ended *\param sess the download session */ Bool gf_dm_is_thread_dead(GF_DownloadSession *sess); /*! *\brief fetches data on session * *Fetches data from the server. This will also performs connections and all needed exchange with server. *\param sess the download session *\param buffer destination buffer *\param buffer_size destination buffer allocated size *\param read_size amount of data actually fetched *\note this can only be used when the session is not threaded */ GF_Err gf_dm_sess_fetch_data(GF_DownloadSession * sess, char *buffer, u32 buffer_size, u32 *read_size); /*! *\brief get mime type as lower case * *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 *\param sess the download session *\return the mime type of the URL, or NULL if error. You should get the error with \ref gf_dm_sess_last_error */ const char *gf_dm_sess_mime_type(GF_DownloadSession * sess); /*! *\brief sets session range * *Sets the session byte range. This shll be called before processing the session. *\param sess the download session *\param start_range HTTP download start range in byte *\param end_range HTTP download end range in byte *\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 *\note this can only be used when the session is not threaded */ GF_Err gf_dm_sess_set_range(GF_DownloadSession *sess, u64 start_range, u64 end_range, Bool discontinue_cache); /*! *\brief get cache file name * * Gets the cache file name for the session. *\param sess the download session *\return the absolute path of the cache file, or NULL if the session is not cached*/ const char *gf_dm_sess_get_cache_name(GF_DownloadSession * sess); /*! * \brief Marks the cache file to be deleted once the file is not used anymore by any session * \param dm the download manager * \param url The URL associate to the cache entry to be deleted */ void gf_dm_delete_cached_file_entry(const GF_DownloadManager * dm, const char * url); /*! * Convenience function * \see gf_dm_delete_cached_file_entry *\param sess the download session * \param url The URL associate to the cache entry to be deleted */ void gf_dm_delete_cached_file_entry_session(const GF_DownloadSession * sess, const char * url); /*! * Get a range of a cache entry file * \param sess The session * \param startOffset The first byte of the request to get * \param endOffset The last byte of request to get * \return The temporary name for the file created to have a range of the file */ const char * gf_cache_get_cache_filename_range( const GF_DownloadSession * sess, u64 startOffset, u64 endOffset ); /*! *\brief get statistics * *Gets download statistics for the session. All output parameters are optional and may be set to NULL. *\param sess the download session *\param server the remote server address *\param path the path on the remote server *\param total_size the total size in bytes the file fetched, 0 if unknown. *\param bytes_done the amount of bytes received from the server *\param bytes_per_sec the average data rate in bytes per seconds *\param net_status the session status */ GF_Err gf_dm_sess_get_stats(GF_DownloadSession * sess, const char **server, const char **path, u32 *total_size, u32 *bytes_done, u32 *bytes_per_sec, GF_NetIOStatus *net_status); /*! *\brief get start time * *Gets session start time in UTC. If chunk-transfer is used, the start time is reset at each chunk start *\param sess the download session *\return UTC start time */ u64 gf_dm_sess_get_utc_start(GF_DownloadSession *sess); /*! *\brief fetch session object * *Fetches the session object (process all headers and data transfer). This is only usable if the session is not threaded *\param sess the download session *\return the last error in the session or 0 if none*/ GF_Err gf_dm_sess_process(GF_DownloadSession *sess); /*! *\brief fetch session object headers * *Fetch the session object headers and stops after that. This is only usable if the session is not threaded *\param sess the download session *\return the last error in the session or 0 if none*/ GF_Err gf_dm_sess_process_headers(GF_DownloadSession * sess); /*! *\brief fetch session status * *Fetch the session current status *\param sess the download session *\return the session status*/ u32 gf_dm_sess_get_status(GF_DownloadSession * sess); /*! *\brief Get session resource url * *Returns the original resource URL associated with the session *\param sess the download session *\return the associated URL */ const char *gf_dm_sess_get_resource_name(GF_DownloadSession *sess); /*! *\brief Get session original resource url * *Returns the original resource URL before any redirection associated with the session *\param sess the download session *\return the associated URL */ const char *gf_dm_sess_get_original_resource_name(GF_DownloadSession *sess); #ifndef GPAC_DISABLE_CORE_TOOLS /*! * \brief Download a file over the network using a download manager * \param dm The download manager to use, function will use all associated cache ressources * \param url The url to download * \param filename The filename to download * \param start_range start position of a byte range * \param end_range end position of a byte range * \param redirected_url If not NULL, \p redirected_url will be allocated and filled with the URL after redirection. Caller takes ownership * \return GF_OK if everything went fine, an error otherwise */ 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); /*! * \brief Same as gf_dm_wget_with_cache, but initializes the GF_DownloadManager by itself. * This function is deprecated, please use gf_dm_wget_with_cache instead * \param url The url to download * \param filename The filename to download * \param start_range start position of a byte range * \param end_range end position of a byte range * \param redirected_url If not NULL, \p redirected_url will be allocated and filled with the URL after redirection. Caller takes ownership * \return GF_OK if everything went fine, an error otherwise */ GF_Err gf_dm_wget(const char *url, const char *filename, u64 start_range, u64 end_range, char **redirected_url); #endif /* GPAC_DISABLE_CORE_TOOLS */ /*! *\brief Reset session * *Resets the session for new processing of the same url *\param sess the download session *\return error code if any */ GF_Err gf_dm_sess_reset(GF_DownloadSession *sess); /*! * \brief forces the refresh of a cache entry * The entry is still allocated in the session. * \param sess The session * \return a pointer to the entry of session refreshed */ DownloadedCacheEntry gf_dm_refresh_cache_entry(GF_DownloadSession *sess); /*! * Tells whether session can be cached on disk. * Typically, when request has no content length, it deserves being streamed an cannot be cached * (ICY or MPEG-streamed content * \param sess The session * \return True if a cache can be created */ Bool gf_dm_sess_can_be_cached_on_disk(const GF_DownloadSession *sess); /*! * Reassigns session flags and callbacks. This is only possible if the session is not threaded. * \param sess The session * \param flags The new flags for the session - if flags is 0xFFFFFFFF, existing flags are not modified * \param user_io The new callback function * \param cbk The new user data to ba used in the callback function * \return GF_OK or error */ GF_Err gf_dm_sess_reassign(GF_DownloadSession *sess, u32 flags, gf_dm_user_io user_io, void *cbk); /*! * 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. * \param sess The session * \param url The new url for the session * \return GF_OK or error */ GF_Err gf_dm_sess_setup_from_url(GF_DownloadSession *sess, const char *url); /* *\retrieves the HTTP header value for the given name * *Retrieves the HTTP header value for the given header name. *\param sess the current session *\param name the target header name * \return header value or NULL if not found */ const char *gf_dm_sess_get_header(GF_DownloadSession *sess, const char *name); /* *\brief sets download manager max rate per session * *Sets the maximum rate (per session only at the current time). *\param dm the download manager object *\param rate_in_bits_per_sec the new rate in bits per sec. If 0, HTTP rate will not be limited */ void gf_dm_set_data_rate(GF_DownloadManager *dm, u32 rate_in_bits_per_sec); /* *\brief gets download manager max rate per session * *Sets the maximum rate (per session only at the current time). *\param dm the download manager object *\return the rate in bits per sec. If 0, HTTP rate is not limited */ u32 gf_dm_get_data_rate(GF_DownloadManager *dm); /* *\brief gets cumultaed download rate for all sessions * *Gets the cumultated bitrate in of all active sessions. *\param dm the download manager object *\return the cumulated rate in bits per sec. */ u32 gf_dm_get_global_rate(GF_DownloadManager *dm); /* *\brief fetches remote file in memory * *Fetches remote file in memory. *\param url the data to fetch *\param out_data output data (allocated by function) *\param out_size output data size *\param out_mime if not NULL, pointer will contain the mime type (allocated by function) *\return error code if any */ GF_Err gf_dm_get_file_memory(const char *url, char **out_data, u32 *out_size, char **out_mime); /* *\brief Get header sizes and times stats for the session * *Get header sizes and times stats for the session *\param sess the current session *\param req_hdr_size request header size in bytes. May be NULL. *\param rsp_hdr_size response header size in bytes. May be NULL. *\param connect_time connection time in micro seconds. May be NULL. *\param reply_time elapsed time between request sent and response header received, in micro seconds. May be NULL. *\param download_time download time since request sent, in micro seconds. May be NULL. *\return error code if any */ 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); /*! @} */ #ifdef __cplusplus } #endif #endif /*_GF_DOWNLOAD_H_*/