| /* | |
| * GPAC Multimedia Framework | |
| * | |
| * Authors: Jean Le Feuvre | |
| * Copyright (c) Telecom ParisTech 2005-2025 | |
| * All rights reserved | |
| * | |
| * This file is part of GPAC / downloader 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 _DOWNLOADER_H_ | |
| #define _DOWNLOADER_H_ | |
| #include <gpac/tools.h> | |
| //regular downloader | |
| #ifndef GPAC_DISABLE_NETWORK | |
| #include <gpac/download.h> | |
| #include <gpac/network.h> | |
| #include <gpac/token.h> | |
| #include <gpac/thread.h> | |
| #include <gpac/list.h> | |
| #include <gpac/base_coding.h> | |
| #include <gpac/filters.h> | |
| #include <gpac/crypt.h> | |
| #ifdef GPAC_HAS_SSL | |
| #ifdef GPAC_HAS_NGTCP2 | |
| #include <openssl/types.h> | |
| #endif | |
| #include <openssl/ssl.h> | |
| #include <openssl/x509.h> | |
| #include <openssl/x509v3.h> | |
| #include <openssl/err.h> | |
| #include <openssl/rand.h> | |
| #endif | |
| #ifdef GPAC_HAS_CURL | |
| #include <curl/curl.h> | |
| //we need multi API | |
| #if CURL_AT_LEAST_VERSION(7,80,0) | |
| #ifndef CURLPIPE_MULTIPLEX | |
| #define CURLPIPE_MULTIPLEX 0 | |
| #endif | |
| #else | |
| #undef GPAC_HAS_CURL | |
| #endif | |
| #endif //CURL | |
| #ifdef GPAC_HAS_HTTP2 | |
| #if defined(_MSC_VER) | |
| typedef SSIZE_T ssize_t; | |
| #define NGHTTP2_STATICLIB | |
| #else | |
| #if defined(WIN32) && defined(GPAC_STATIC_BUILD) | |
| #define NGHTTP2_STATICLIB | |
| #endif | |
| #endif | |
| #endif | |
| #ifdef __USE_POSIX | |
| #include <unistd.h> | |
| #endif | |
| #define SIZE_IN_STREAM ( 2 << 29 ) | |
| #define SESSION_RETRY_COUNT 10 | |
| #define SESSION_RETRY_SSL 8 | |
| #include <gpac/revision.h> | |
| #define GF_DOWNLOAD_AGENT_NAME "GPAC/"GPAC_VERSION "-rev" GPAC_GIT_REVISION | |
| #define GF_DOWNLOAD_BUFFER_SIZE 50000 | |
| #define GF_DOWNLOAD_BUFFER_SIZE_LIMIT_RATE GF_DOWNLOAD_BUFFER_SIZE/20 | |
| #if defined(GPAC_HAS_HTTP2) || defined(GPAC_HAS_NGTCP2) | |
| #define GPAC_HTTPMUX | |
| #endif | |
| enum { | |
| H3_MODE_NO=0, | |
| H3_MODE_FIRST, | |
| H3_MODE_AUTO, | |
| H3_MODE_ONLY, | |
| }; | |
| #ifdef GPAC_HTTPMUX | |
| typedef struct | |
| { | |
| u8 * data; | |
| u32 size, alloc, offset; | |
| } hmux_reagg_buffer; | |
| typedef struct _http_mux_session | |
| { | |
| Bool do_shutdown; | |
| GF_List *sessions; | |
| GF_DownloadSession *net_sess; | |
| GF_Mutex *mx; | |
| Bool copy; | |
| Bool connected; | |
| //underying implementation - all callbacks must be set | |
| GF_Err (*setup_session)(GF_DownloadSession *sess, Bool is_destroy); | |
| void (*close_session)(GF_DownloadSession *sess); | |
| //format request and submit it | |
| GF_Err (*submit_request)(GF_DownloadSession *sess, char *req_name, const char *url, const char *param_string, Bool has_body); | |
| //send reply and submit it | |
| GF_Err (*send_reply)(GF_DownloadSession *sess, u32 reply_code, const char *response_body, u32 body_len, Bool no_body); | |
| //write and send any pending packets / signaling / etc | |
| GF_Err (*write)(GF_DownloadSession *sess); | |
| //send stream reset | |
| void (*stream_reset)(GF_DownloadSession *sess, Bool is_abort); | |
| //move to active state if hmux_data_paused was set | |
| GF_Err (*resume)(GF_DownloadSession *sess); | |
| //close underlying connection (QUIC), can be NULL | |
| void (*close)(struct _http_mux_session *hmux); | |
| //destroy underlying muxed session object | |
| void (*destroy)(struct _http_mux_session *hmux); | |
| //notify that some data has been received for the parent muxed session | |
| GF_Err (*data_received)(GF_DownloadSession *sess, const u8 *data, u32 nb_bytes); | |
| //signal new data in hmux_send_data is available (data can be NULL for requests with no body) | |
| GF_Err (*send_pending_data)(GF_DownloadSession *sess); | |
| //try to flush pending data, return GF_IP_NETWORK_EMPTY if not all data is sent | |
| GF_Err (*async_flush)(GF_DownloadSession *sess, Bool for_close); | |
| //underlying muxed session object (nghttp2 session, h3 session, etc...) | |
| void *hmux_udta; | |
| } GF_HMUX_Session; | |
| #endif | |
| #define GF_NETIO_SESSION_USE_QUIC (1<<28) | |
| #define GF_NETIO_SESSION_RETRY_QUIC (1<<29) | |
| #define GF_NETIO_SESSION_NO_STORE (1<<30) | |
| /*internal flags*/ | |
| enum | |
| { | |
| GF_DOWNLOAD_SESSION_USE_SSL = 1<<10, | |
| GF_DOWNLOAD_SESSION_THREAD_DEAD = 1<<11, | |
| GF_DOWNLOAD_SESSION_SSL_FORCED = 1<<12, | |
| }; | |
| enum REQUEST_TYPE | |
| { | |
| GET = 0, | |
| HEAD = 1, | |
| OTHER = 2 | |
| }; | |
| /*!the structure used to store an HTTP header*/ | |
| typedef struct | |
| { | |
| char *name; | |
| char *value; | |
| } GF_HTTPHeader; | |
| /** | |
| * This structure handles partial downloads | |
| */ | |
| typedef struct __partialDownloadStruct { | |
| char * url; | |
| u64 startOffset; | |
| u64 endOffset; | |
| char * filename; | |
| } GF_PartialDownload ; | |
| typedef struct | |
| { | |
| //if null, task is detached and object must be discarded | |
| struct __gf_download_session *sess; | |
| Bool in_task; | |
| } GF_SessTask; | |
| struct __gf_download_session | |
| { | |
| /*this is always 0 and helps differenciating downloads from other interfaces (interfaceType != 0)*/ | |
| u32 reserved; | |
| struct __gf_download_manager *dm; | |
| GF_Thread *th; | |
| GF_Mutex *mx; | |
| GF_SessTask *ftask; | |
| Bool in_callback, destroy; | |
| u32 proxy_enabled; | |
| Bool allow_direct_reuse; | |
| #ifndef GPAC_DISABLE_LOG | |
| char *log_name; | |
| #endif | |
| char *server_name; | |
| u16 port; | |
| char *orig_url; | |
| char *orig_url_before_redirect; | |
| char *remote_path; | |
| GF_UserCredentials * creds; | |
| char cookie[GF_MAX_PATH]; | |
| DownloadedCacheEntry cache_entry; | |
| Bool reused_cache_entry; | |
| FILE *cached_file; | |
| u32 http_buf_size; | |
| //we alloc http_buf_size+1 for text dump | |
| char *http_buf; | |
| //mime type, only used when the session is not cached. | |
| char *mime_type; | |
| GF_List *headers; | |
| u32 rsp_code; | |
| const char *netcap_id; | |
| GF_Socket *sock; | |
| u32 num_retry; | |
| GF_NetIOStatus status; | |
| u32 flags; | |
| u32 total_size, bytes_done, icy_metaint, icy_count, icy_bytes, full_resource_size; | |
| u64 start_time; | |
| u32 nb_redirect; | |
| u32 bytes_per_sec; | |
| u32 max_data_rate; | |
| u64 start_time_utc; | |
| Bool rate_regulated; | |
| Bool last_chunk_found; | |
| Bool connection_close; | |
| Bool is_range_continuation; | |
| /*0: no cache reconfig before next GET request: 1: try to rematch the cache entry: 2: force to create a new cache entry (for byte-range cases)*/ | |
| u32 needs_cache_reconfig; | |
| /* Range information if needed for the download (cf flag) */ | |
| Bool needs_range; | |
| u64 range_start, range_end; | |
| u32 connect_time, ssl_setup_time, reply_time, total_time_since_req, req_hdr_size, rsp_hdr_size; | |
| /*0: GET | |
| 1: HEAD | |
| 2: all the rest | |
| */ | |
| enum REQUEST_TYPE http_read_type; | |
| GF_Err last_error; | |
| char *init_data; | |
| u32 init_data_size; | |
| Bool server_only_understand_get; | |
| /* True if cache file must be stored on disk */ | |
| Bool use_cache_file; | |
| Bool disable_cache; | |
| /*forces notification of data exchange to be sent regardless of threading mode*/ | |
| Bool force_data_write_callback; | |
| u32 connect_pending; | |
| #ifdef GPAC_HAS_SSL | |
| SSL *ssl; | |
| #endif | |
| void (*do_requests)(struct __gf_download_session *); | |
| /*callback for data reception - may not be NULL*/ | |
| gf_dm_user_io user_proc; | |
| void *usr_cbk; | |
| Bool reassigned; | |
| Bool chunked; | |
| u32 nb_left_in_chunk; | |
| u32 current_chunk_size; | |
| u64 current_chunk_start; | |
| u64 request_start_time, last_fetch_time; | |
| /*private extension*/ | |
| void *ext; | |
| char *remaining_data; | |
| u32 remaining_data_size; | |
| u32 conn_timeout, request_timeout; | |
| Bool local_cache_only; | |
| Bool server_mode; | |
| //0: not PUT/POST, 1: waiting for body to be completed, 2: body done | |
| u32 put_state; | |
| u64 last_cap_rate_time; | |
| u64 last_cap_rate_bytes; | |
| u32 last_cap_rate_bytes_per_sec; | |
| u64 last_chunk_start_time; | |
| u32 chunk_wnd_dur; | |
| u32 chunk_bytes, chunk_header_bytes, cumulated_chunk_header_bytes; | |
| //in bytes per seconds | |
| Double cumulated_chunk_rate; | |
| u32 connection_timeout_ms; | |
| u8 *async_req_reply; | |
| u32 async_req_reply_size; | |
| u8 *async_buf; | |
| u32 async_buf_size, async_buf_alloc; | |
| GF_SockGroup *sock_group; | |
| #ifdef GPAC_HTTPMUX | |
| //Muxed HTTP (H/2 or H/3) session used by this download session. If not NULL, the mutex, socket and ssl context are moved along sessions | |
| GF_HMUX_Session *hmux_sess; | |
| hmux_reagg_buffer hmux_buf; | |
| //negative value means detached | |
| s64 hmux_stream_id; | |
| u8 hmux_headers_seen, hmux_ready_to_send, hmux_is_eos, hmux_data_paused, hmux_data_done, hmux_switch_sess; | |
| u8 *hmux_send_data; | |
| u32 hmux_send_data_len; | |
| //per-hmux session user data | |
| void *hmux_priv; | |
| #endif | |
| #ifdef GPAC_HAS_HTTP2 | |
| //HTTP2 only | |
| u8 *h2_upgrade_settings; | |
| u32 h2_upgrade_settings_len; | |
| //0: upgrade not started; 1: upgrade headers send; 2: upgrade done; 3: upgrade retry without SSL APN; 4: H2 disabled for session | |
| u8 h2_upgrade_state; | |
| #endif | |
| #ifdef GPAC_HAS_CURL | |
| CURL *curl_hnd; | |
| GF_Err curl_closed; | |
| Bool curl_hnd_registered; | |
| struct curl_slist *curl_hdrs; | |
| Bool curl_not_http; | |
| u32 curl_fake_hcode; | |
| #endif | |
| #if defined(GPAC_HTTPMUX) || defined(GPAC_HAS_CURL) | |
| u8 *local_buf; | |
| u32 local_buf_len, local_buf_alloc; | |
| #endif | |
| }; | |
| #define PUSH_HDR(_name, _value) {\ | |
| GF_SAFEALLOC(hdr, GF_HTTPHeader)\ | |
| hdr->name = gf_strdup(_name);\ | |
| hdr->value = gf_strdup(_value);\ | |
| gf_list_add(sess->headers, hdr);\ | |
| } | |
| struct __gf_download_manager | |
| { | |
| //mutex protecting cache access and all_sessions list | |
| GF_Mutex *cache_mx; | |
| char *cache_directory; | |
| gf_dm_get_usr_pass get_user_password; | |
| void *usr_cbk; | |
| GF_List *all_sessions; | |
| Bool disable_cache, simulate_no_connection, allow_offline_cache; | |
| u32 limit_data_rate, read_buf_size; | |
| u64 max_cache_size, cur_cache_size; | |
| Bool allow_broken_certificate; | |
| u32 next_cache_clean, cache_clean_ms; | |
| GF_List *skip_proxy_servers; | |
| GF_List *credentials; | |
| GF_List *cache_entries; | |
| /* FIXME : should be placed in DownloadedCacheEntry maybe... */ | |
| GF_List *partial_downloads; | |
| #ifdef GPAC_HAS_SSL | |
| SSL_CTX *ssl_ctx; | |
| #endif | |
| GF_FilterSession *filter_session; | |
| Bool disable_http2; | |
| u32 h3_mode; | |
| Bool (*local_cache_url_provider_cbk)(void *udta, char *url, Bool cache_destroy); | |
| void *lc_udta; | |
| #ifdef GPAC_HAS_CURL | |
| CURLM *curl_multi; | |
| GF_Mutex *curl_mx; | |
| Bool curl_has_close; | |
| #endif | |
| }; | |
| #if 0 | |
| #define SET_LAST_ERR(_e) \ | |
| {\ | |
| GF_Err __e = _e;\ | |
| if (__e==GF_IP_NETWORK_EMPTY) {\ | |
| gf_assert(sess->status != GF_NETIO_STATE_ERROR); \ | |
| }\ | |
| sess->last_error = _e;\ | |
| }\ | |
| #else | |
| #define SET_LAST_ERR(_e) sess->last_error = _e; | |
| #endif | |
| //cache functions - NOT exported, only downloader has access to it | |
| s32 gf_cache_remove_session_from_cache_entry(DownloadedCacheEntry entry, GF_DownloadSession * sess); | |
| Bool gf_cache_set_mime(const DownloadedCacheEntry entry, const char *mime); | |
| Bool gf_cache_set_range(const DownloadedCacheEntry entry, u64 size, u64 start_range, u64 end_range); | |
| Bool gf_cache_set_content(const DownloadedCacheEntry entry, GF_Blob *blob, Bool copy, GF_Mutex *mx); | |
| Bool gf_cache_set_headers(const DownloadedCacheEntry entry, const char *headers); | |
| void gf_cache_set_downtime(const DownloadedCacheEntry entry, u32 download_time_ms); | |
| void gf_cache_set_max_age(const DownloadedCacheEntry entry, u32 max_age, Bool must_revalidate); | |
| Bool gf_cache_entry_persistent(const DownloadedCacheEntry entry); | |
| void gf_cache_delete_entry( const DownloadedCacheEntry entry ); | |
| GF_Err gf_cache_set_etag_on_server(const DownloadedCacheEntry entry, const char * eTag ); | |
| const char * gf_cache_get_mime_type(const DownloadedCacheEntry entry ); | |
| GF_Err gf_cache_set_mime_type(const DownloadedCacheEntry entry, const char * mime_type ); | |
| const char * gf_cache_get_url(const DownloadedCacheEntry entry ); | |
| GF_Err gf_cache_set_last_modified_on_server(const DownloadedCacheEntry entry, const char * newLastModified ); | |
| const char * gf_cache_get_cache_filename(const DownloadedCacheEntry entry ); | |
| u32 gf_cache_get_cache_filesize(const DownloadedCacheEntry entry); | |
| GF_Err gf_cache_set_content_length(const DownloadedCacheEntry entry, u32 length ); | |
| u32 gf_cache_get_content_length(const DownloadedCacheEntry entry); | |
| GF_Err gf_cache_get_http_headers(const DownloadedCacheEntry entry, const char **etag, const char **last_modif); | |
| u64 gf_cache_cleanup(const char * directory, u64 max_size); | |
| void gf_cache_entry_set_delete_files_when_deleted(const DownloadedCacheEntry entry); | |
| u64 gf_cache_get_start_range( const DownloadedCacheEntry entry ); | |
| u64 gf_cache_get_end_range( const DownloadedCacheEntry entry ); | |
| Bool gf_cache_are_headers_processed(const DownloadedCacheEntry entry); | |
| GF_Err gf_cache_set_headers_processed(const DownloadedCacheEntry entry); | |
| FILE *gf_cache_open_read(const DownloadedCacheEntry entry); | |
| Bool gf_cache_is_mem(const DownloadedCacheEntry entry); | |
| GF_Err gf_cache_write_to_cache( const DownloadedCacheEntry entry, const GF_DownloadSession * sess, const char * data, const u32 size, GF_Mutex *mx); | |
| GF_Err gf_cache_close_write_cache( const DownloadedCacheEntry entry, const GF_DownloadSession * sess, Bool success); | |
| GF_Err gf_cache_open_write_cache( const DownloadedCacheEntry entry, const GF_DownloadSession * sess ); | |
| void gf_cache_set_end_range(DownloadedCacheEntry entry, u64 range_end); | |
| Bool gf_cache_is_in_progress(const DownloadedCacheEntry entry); | |
| char *gf_cache_get_forced_headers(const DownloadedCacheEntry entry); | |
| u32 gf_cache_get_downtime(const DownloadedCacheEntry entry); | |
| u32 gf_cache_is_done(const DownloadedCacheEntry entry); | |
| Bool gf_cache_is_deleted(const DownloadedCacheEntry entry); | |
| const u8 *gf_cache_get_content(const DownloadedCacheEntry entry, u32 *size, u32 *max_valid_size, Bool *was_modified); | |
| void gf_cache_release_content(const DownloadedCacheEntry entry); | |
| void gf_cache_remove_entry_from_session(GF_DownloadSession * sess); | |
| void gf_dm_data_received(GF_DownloadSession *sess, u8 *payload, u32 payload_size, Bool store_in_init, u32 *rewrite_size, u8 *original_payload); | |
| GF_Err gf_dm_read_data(GF_DownloadSession *sess, char *data, u32 data_size, u32 *out_read); | |
| GF_Err gf_dm_sess_send(GF_DownloadSession *sess, u8 *data, u32 size); | |
| GF_Err gf_dm_sess_flush_async(GF_DownloadSession *sess, Bool no_select); | |
| GF_Err gf_dm_sess_flush_close(GF_DownloadSession *sess); | |
| void gf_dm_sess_set_header_ex(GF_DownloadSession *sess, const char *name, const char *value, Bool allow_overwrite); | |
| GF_Err dm_sess_write(GF_DownloadSession *sess, const u8 *buffer, u32 size); | |
| GF_Err gf_ssl_write(GF_DownloadSession *sess, const u8 *buffer, u32 size, u32 *written); | |
| void dm_sess_sk_del(GF_DownloadSession *sess); | |
| void gf_dm_sess_clear_headers(GF_DownloadSession *sess); | |
| GF_DownloadSession *gf_dm_sess_new_internal(GF_DownloadManager * dm, const char *url, u32 dl_flags, | |
| gf_dm_user_io user_io, void *usr_cbk, GF_Socket *server, Bool force_server, GF_Err *e); | |
| void gf_dm_sess_notify_state(GF_DownloadSession *sess, GF_NetIOStatus dnload_status, GF_Err error); | |
| void gf_dm_sess_set_header_ex(GF_DownloadSession *sess, const char *name, const char *value, Bool allow_overwrite); | |
| void gf_dm_sess_set_header(GF_DownloadSession *sess, const char *name, const char *value); | |
| void gf_dm_sess_reload_cached_headers(GF_DownloadSession *sess); | |
| GF_Err gf_dm_sess_send_reply(GF_DownloadSession *sess, u32 reply_code, const char *response_body, u32 body_len, Bool no_body); | |
| Bool gf_dm_sess_use_tls(GF_DownloadSession * sess); | |
| typedef enum | |
| { | |
| HTTP_NO_CLOSE=0, | |
| HTTP_CLOSE, | |
| HTTP_RESET_CONN, | |
| } HTTPCloseType; | |
| void gf_dm_disconnect(GF_DownloadSession *sess, HTTPCloseType close_type); | |
| GF_Err gf_dm_get_url_info(const char * url, GF_URL_Info * info, const char * baseURL); | |
| void http_do_requests(GF_DownloadSession *sess); | |
| void gf_dm_configure_cache(GF_DownloadSession *sess); | |
| //multiplexed HTTP support (H2, H3) | |
| #ifdef GPAC_HTTPMUX | |
| GF_DownloadSession *hmux_get_session(void *user_data, s64 stream_id, Bool can_reassign); | |
| void hmux_detach_session(GF_HMUX_Session *hmux_sess, GF_DownloadSession *sess); | |
| //get data from hmux session | |
| void hmux_fetch_data(GF_DownloadSession *sess, u8 *obuffer, u32 size, u32 *nb_bytes); | |
| //call gf_dm_data_received with local hmux buffer and set it to 0 | |
| void hmux_flush_internal_data(GF_DownloadSession *sess, Bool store_in_init); | |
| GF_Err hmux_send_payload(GF_DownloadSession *sess, u8 *data, u32 size); | |
| #endif | |
| //HTTP2 only | |
| #ifdef GPAC_HAS_HTTP2 | |
| GF_Err http2_check_upgrade(GF_DownloadSession *sess); | |
| void http2_set_upgrade_headers(GF_DownloadSession *sess); | |
| GF_Err http2_do_upgrade(GF_DownloadSession *sess, const char *body, u32 body_len); | |
| #endif | |
| #ifdef GPAC_HAS_NGTCP2 | |
| GF_Err http3_connect(GF_DownloadSession *sess, char *server, u32 server_port); | |
| #endif | |
| #ifdef GPAC_HAS_CURL | |
| GF_Err curl_setup_session(GF_DownloadSession* sess); | |
| void curl_flush(GF_DownloadSession *sess); | |
| void curl_destroy(GF_DownloadSession *sess); | |
| Bool curl_can_handle_url(const char *url); | |
| GF_Err curl_read_data(GF_DownloadSession *sess, char *data, u32 data_size, u32 *out_read); | |
| void curl_connect(GF_DownloadSession *sess); | |
| GF_Err curl_process_reply(GF_DownloadSession *sess, u32 *ContentLength); | |
| #endif | |
| #ifdef GPAC_HAS_SSL | |
| void *gf_dm_ssl_init(GF_DownloadManager *dm, Bool no_quic); | |
| Bool gf_ssl_check_cert(SSL *ssl, const char *server_name); | |
| void gf_dm_sess_server_setup_ssl(GF_DownloadSession *sess); | |
| GF_Err gf_ssl_read_data(GF_DownloadSession *sess, char *data, u32 data_size, u32 *out_read); | |
| typedef enum | |
| { | |
| SSL_CONNECT_OK=0, | |
| SSL_CONNECT_WAIT, | |
| SSL_CONNECT_RETRY | |
| } SSLConnectStatus; | |
| SSLConnectStatus gf_ssl_try_connect(GF_DownloadSession *sess, const char *proxy); | |
| #endif | |
| //exported for httpout | |
| //socket and SSL context ownership is transfered to the download session object | |
| GF_DownloadSession *gf_dm_sess_new_server(GF_DownloadManager *dm, GF_Socket *server, void *ssl_ctx, gf_dm_user_io user_io, void *usr_cbk, Bool async, GF_Err *e); | |
| GF_DownloadSession *gf_dm_sess_new_subsession(GF_DownloadSession *sess, s64 stream_id, void *usr_cbk, GF_Err *e); | |
| u32 gf_dm_sess_subsession_count(GF_DownloadSession *); | |
| void gf_dm_sess_set_timeout(GF_DownloadSession *sess, u32 timeout); | |
| GF_Socket *gf_dm_sess_get_socket(GF_DownloadSession *); | |
| GF_Err gf_dm_sess_send(GF_DownloadSession *sess, u8 *data, u32 size); | |
| void gf_dm_sess_clear_headers(GF_DownloadSession *sess); | |
| void gf_dm_sess_set_header(GF_DownloadSession *sess, const char *name, const char *value); | |
| void gf_dm_sess_set_header_ex(GF_DownloadSession *sess, const char *name, const char *value, Bool allow_overwrite); | |
| GF_Err gf_dm_sess_flush_async(GF_DownloadSession *sess, Bool no_select); | |
| u32 gf_dm_sess_async_pending(GF_DownloadSession *sess); | |
| GF_Err gf_dm_sess_send_reply(GF_DownloadSession *sess, u32 reply_code, const char *response_body, u32 body_len, Bool no_body); | |
| void gf_dm_sess_server_reset(GF_DownloadSession *sess); | |
| typedef enum | |
| { | |
| GF_SESS_TYPE_HTTP=0, | |
| GF_SESS_TYPE_HTTP2, | |
| GF_SESS_TYPE_HTTP3, | |
| } GF_HTTPSessionType; | |
| GF_HTTPSessionType gf_dm_sess_is_hmux(GF_DownloadSession *sess); | |
| void gf_dm_sess_close_hmux(GF_DownloadSession *sess); | |
| void gf_dm_sess_set_sock_group(GF_DownloadSession *sess, GF_SockGroup *sg); | |
| #ifdef GPAC_HAS_SSL | |
| void *gf_ssl_new(void *ssl_server_ctx, GF_Socket *client_sock, GF_Err *e); | |
| void *gf_ssl_server_context_new(const char *cert, const char *key, Bool for_quic); | |
| void gf_ssl_server_context_del(void *ssl_server_ctx); | |
| Bool gf_ssl_init_lib(); | |
| #endif | |
| #ifdef GPAC_HAS_NGTCP2 | |
| typedef struct __gf_quic_server GF_QuicServer; | |
| GF_Err gf_dm_quic_server_new(GF_DownloadManager *dm, void *ssl_ctx, GF_QuicServer **oq, const char *ip, u32 port, const char *netcap_id, | |
| Bool (*accept_conn)(void *udta, GF_DownloadSession *sess, const char *address, u32 port), | |
| void *udta); | |
| void gf_dm_quic_server_del(GF_QuicServer *qs); | |
| GF_Socket *gf_dm_quic_get_socket(GF_QuicServer *qs); | |
| GF_Err gf_dm_quic_process(GF_QuicServer *qs); | |
| GF_Err gf_dm_quic_verify(GF_QuicServer *qs); | |
| void gf_dm_sess_set_callback(GF_DownloadSession *sess, gf_dm_user_io user_io, void *usr_cbk); | |
| #endif | |
| //end GPAC_DISABLE_NETWORK, start EMSCRIPTEN | |
| #elif defined(GPAC_CONFIG_EMSCRIPTEN) | |
| #include <gpac/download.h> | |
| #include <gpac/list.h> | |
| #include <gpac/thread.h> | |
| #include <gpac/filters.h> | |
| struct __gf_download_manager | |
| { | |
| GF_FilterSession *fsess; | |
| GF_List *all_sessions; | |
| GF_Mutex *mx; | |
| }; | |
| typedef struct __cache_blob | |
| { | |
| GF_Blob blob; | |
| char *url, *cache_name; | |
| char *mime; | |
| u64 start_range, end_range; | |
| Bool persistent; | |
| } GF_CacheBlob; | |
| struct __gf_download_session | |
| { | |
| GF_DownloadManager *dm; | |
| gf_dm_user_io user_io; | |
| void *usr_cbk; | |
| char method[100]; | |
| char *req_url; | |
| char *rsp_url; | |
| /*request headers*/ | |
| char **req_hdrs; | |
| u32 nb_req_hdrs; | |
| u32 req_body_size; | |
| char *req_body; | |
| u64 start_range, end_range; | |
| /*response headers*/ | |
| char **rsp_hdrs; | |
| u32 nb_rsp_hdrs; | |
| char *mime; //pointer to content-type header or blob | |
| u32 state, bps; | |
| u64 start_time, start_time_utc; | |
| u64 total_size, bytes_done; | |
| GF_Err last_error; | |
| GF_NetIOStatus netio_status; | |
| u32 dl_flags; | |
| Bool reuse_cache; | |
| u32 ftask; | |
| GF_List *cached_blobs; | |
| GF_CacheBlob *active_cache; | |
| Bool destroy, in_callback; | |
| }; | |
| #endif // GPAC_CONFIG_EMSCRIPTEN | |
| #endif //_DOWNLOADER_H_ |