Exemplo n.º 1
0
static char *get_mime_type(GF_Terminal *term, const char *url, GF_Err *ret_code, GF_DownloadSession **the_session)
{
	char * ret = NULL;
	GF_DownloadSession * sess;
	(*ret_code) = GF_OK;
	if (strnicmp(url, "http", 4)) return NULL;

	/*don't use any NetIO and don't issue a HEAD command, always go for GET and store the session */
	sess = gf_dm_sess_new(term->downloader, (char *) url, GF_NETIO_SESSION_NOT_THREADED | GF_NETIO_SESSION_NOT_CACHED, NULL, NULL, ret_code);
	if (!sess) {
		if (strstr(url, "rtsp://") || strstr(url, "rtp://") || strstr(url, "udp://") || strstr(url, "tcp://") ) (*ret_code) = GF_OK;
		return NULL;
	} else {
		/*start processing the resource, and stop if error or as soon as we get data*/
		while (1) {
			*ret_code = gf_dm_sess_process_headers(sess);
			if (*ret_code) break;
			if (gf_dm_sess_get_status(sess)>=GF_NETIO_DATA_EXCHANGE) {
				const char * mime = gf_dm_sess_mime_type(sess);
				/* The mime type is returned lower case */
				if (mime){
					ret = gf_strdup(mime);
				}
				break;
			}
		}
	}

	if (the_session && (*ret_code == GF_OK)) {
		*the_session = sess;
	} else {
		gf_dm_sess_del(sess);
	}
	return ret;
}
Exemplo n.º 2
0
void gf_term_delete_net_service(GF_ClientService *ns)
{
	const char *sOpt = gf_cfg_get_key(ns->term->user->config, "StreamingCache", "AutoSave");
	if (ns->cache) gf_term_service_cache_close(ns, (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0);

	if (ns->pending_service_session) gf_dm_sess_del(ns->pending_service_session);

	assert(!ns->nb_odm_users);
	assert(!ns->nb_ch_users);
	assert(!ns->owner);

	gf_modules_close_interface((GF_BaseInterface *)ns->ifce);
	gf_free(ns->url);


	/*delete all the clocks*/
	while (gf_list_count(ns->Clocks)) {
		GF_Clock *ck = (GF_Clock *)gf_list_get(ns->Clocks, 0);
		gf_list_rem(ns->Clocks, 0);
		gf_clock_del(ck);
	}
	gf_list_del(ns->Clocks);

	assert(!gf_list_count(ns->dnloads));
	gf_list_del(ns->dnloads);
	gf_free(ns);
}
Exemplo n.º 3
0
void gf_term_service_del(GF_ClientService *ns)
{
	/*this is a downloader session*/
	if (! * (u32 *) ns) {
		gf_dm_sess_del((GF_DownloadSession * ) ns);
	} else {
		gf_term_delete_net_service(ns);
	}
}
Exemplo n.º 4
0
void gf_dm_del(GF_DownloadManager *dm)
{
	/*destroy all pending sessions*/
	while (gf_list_count(dm->sessions)) {
		GF_DownloadSession *sess = (GF_DownloadSession *) gf_list_get(dm->sessions, 0);
		gf_dm_sess_del(sess);
	}
	gf_list_del(dm->sessions);

	free(dm->cache_directory);

#ifdef GPAC_HAS_SSL
	if (dm->ssl_ctx) SSL_CTX_free(dm->ssl_ctx);
#endif

	free(dm);
}
Exemplo n.º 5
0
GF_DownloadSession *gf_dm_sess_new(GF_DownloadManager *dm, char *url, u32 dl_flags,
									  gf_dm_user_io user_io,
									  void *usr_cbk,
									  GF_Err *e)
{
	GF_DownloadSession *sess;

	*e = GF_OK;
	if (gf_dm_is_local(dm, url)) return NULL;

	if (!gf_dm_can_handle_url(dm, url)) {
		*e = GF_NOT_SUPPORTED;
		return NULL;
	}
	if (!user_io) {
		*e = GF_BAD_PARAM;
		return NULL;
	}


	sess = (GF_DownloadSession *)malloc(sizeof(GF_DownloadSession));
	memset((void *)sess, 0, sizeof(GF_DownloadSession));
	sess->flags = dl_flags;
	sess->user_proc = user_io;
	sess->usr_cbk = usr_cbk;
	sess->dm = dm;
	gf_list_add(dm->sessions, sess);

	*e = gf_dm_setup_from_url(sess, url);
	if (*e) {
		gf_dm_sess_del(sess);
		return NULL;
	}
	if (!(sess->flags & GF_NETIO_SESSION_NOT_THREADED) ) {
		sess->th = gf_th_new();
		sess->mx = gf_mx_new();
		gf_th_run(sess->th, gf_dm_session_thread, sess);
	}
	sess->num_retry = SESSION_RETRY_COUNT;
	return sess;
}
Exemplo n.º 6
0
static GF_InputService *gf_term_can_handle_service(GF_Terminal *term, const char *url, const char *parent_url, Bool no_mime_check, char **out_url, GF_Err *ret_code, GF_DownloadSession **the_session)
{
	u32 i;
	GF_Err e;
	char *sURL, *qm, *frag, *ext, *mime_type, *url_res;
	char szExt[50];
	const char *force_module = NULL;
	GF_InputService *ifce;
	Bool skip_mime = 0;
	memset(szExt, 0, sizeof(szExt));

	(*ret_code) = GF_OK;
	ifce = NULL;
	mime_type = NULL;
	GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Looking for plugin for URL %s\n", url));
	*out_url = NULL;
	sURL = NULL;
	if (!url || !strncmp(url, "\\\\", 2) ) {
		(*ret_code) = GF_URL_ERROR;
		goto exit;
	}

	if (!strnicmp(url, "libplayer://", 12)) {
		force_module = "LibPlayer";
	}

	/*used by GUIs scripts to skip URL concatenation*/
	if (!strncmp(url, "gpac://", 7)) sURL = gf_strdup(url+7);
	/*opera-style localhost URLs*/
	else if (!strncmp(url, "file://localhost", 16)) sURL = gf_strdup(url+16);

	else if (parent_url) sURL = gf_url_concatenate(parent_url, url);

	/*path absolute*/
	if (!sURL) sURL = gf_strdup(url);

	if (gf_url_is_local(sURL))
		gf_url_to_fs_path(sURL);

	if (the_session) *the_session = NULL;
	if (no_mime_check) {
		mime_type = NULL;
	} else {
		/*fetch a mime type if any. If error don't even attempt to open the service
		TRYTOFIXME: it would be nice to reuse the downloader created while fetching the mime type, however
		we don't know if the plugin will want it threaded or not....
		*/
		mime_type = get_mime_type(term, sURL, &e, the_session);
		if (e) {
			(*ret_code) = e;
			goto exit;
		}
	}

	if (mime_type &&
		(!stricmp(mime_type, "text/plain")
			|| !stricmp(mime_type, "video/quicktime")
			|| !stricmp(mime_type, "application/octet-stream")
		)
	) {
		skip_mime = 1;
	}

	ifce = NULL;

	/*load from mime type*/
	if (mime_type && !skip_mime) {
		const char *sPlug = gf_cfg_get_key(term->user->config, "MimeTypes", mime_type);
		GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Mime type found: %s\n", mime_type));
		if (!sPlug) {
			gf_free(mime_type);
			mime_type=NULL;
		}
		if (sPlug) sPlug = strrchr(sPlug, '"');
		if (sPlug) {
			sPlug += 2;
			GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("%s:%d FOUND matching module %s\n", __FILE__, __LINE__, sPlug));
			ifce = (GF_InputService *) gf_modules_load_interface_by_name(term->user->modules, sPlug, GF_NET_CLIENT_INTERFACE);
			if (force_module && ifce && !strstr(ifce->module_name, force_module)) {
				gf_modules_close_interface((GF_BaseInterface *) ifce);
				ifce = NULL;
			}
			if (ifce && !net_check_interface(ifce) ) {
				gf_modules_close_interface((GF_BaseInterface *) ifce);
				ifce = NULL;
			}
		}
	}

	/* The file extension, if any, is before '?' if any or before '#' if any.*/
	url_res = strrchr(sURL, '/');
	if (!url_res) url_res = strrchr(sURL, '\\');
	if (!url_res) url_res = sURL;
	qm = strchr(url_res, '?');
	if (qm) {
		qm[0] = 0;
		ext = strrchr(url_res, '.');
		qm[0] = '?';
	} else {
		frag = strchr(url_res, '#');
		if (frag) {
			frag[0] = 0;
			ext = strrchr(url_res, '.');
			frag[0] = '#';
		} else {
			ext = strrchr(url_res, '.');
		}
	}
	if (ext && !stricmp(ext, ".gz")) {
		char *anext;
		ext[0] = 0;
		anext = strrchr(sURL, '.');
		ext[0] = '.';
		ext = anext;
	}
	/*no mime type: either local or streaming. If streaming discard extension checking*/
	if (!ifce && !mime_type && strstr(sURL, "://") && strnicmp(sURL, "file://", 7)) ext = NULL;

	/*browse extensions for prefered module*/
	if (!ifce && ext) {
		u32 keyCount;
		strncpy(szExt, &ext[1], 49);
		ext = strrchr(szExt, '?');
		if (ext) ext[0] = 0;
		ext = strrchr(szExt, '#');
		if (ext) ext[0] = 0;

		GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] No mime type found - checking by extension %s\n", szExt));
		assert( term && term->user && term->user->modules);
		keyCount = gf_cfg_get_key_count(term->user->config, "MimeTypes");
		for (i=0; i<keyCount; i++) {
			char *sPlug;
			const char *sKey;
			const char *sMime;
			sMime = gf_cfg_get_key_name(term->user->config, "MimeTypes", i);
			if (!sMime) continue;
			sKey = gf_cfg_get_key(term->user->config, "MimeTypes", sMime);
			if (!sKey) continue;
			if (!check_extension(sKey, szExt)) continue;
			sPlug = strrchr(sKey, '"');
			if (!sPlug) continue;	/*bad format entry*/
			sPlug += 2;

			GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Trying module[%i]=%s, mime=%s\n", i, sPlug, sMime));
			ifce = (GF_InputService *) gf_modules_load_interface_by_name(term->user->modules, sPlug, GF_NET_CLIENT_INTERFACE);
			if (!ifce){
				GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] module[%i]=%s, mime=%s, cannot be loaded for GF_NET_CLIENT_INTERFACE.\n", i, sPlug, sMime));
				continue;
			}
			if (force_module && ifce && !strstr(ifce->module_name, force_module)) {
				gf_modules_close_interface((GF_BaseInterface *) ifce);
				ifce = NULL;
				continue;
			}
			if (ifce && !net_check_interface(ifce)) {
				gf_modules_close_interface((GF_BaseInterface *) ifce);
				ifce = NULL;
				continue;
			}
			break;
		}
	}

	/*browse all modules*/
	if (!ifce) {
		GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Not found any interface, trying browsing all modules...\n"));
		for (i=0; i< gf_modules_get_count(term->user->modules); i++) {
			ifce = (GF_InputService *) gf_modules_load_interface(term->user->modules, i, GF_NET_CLIENT_INTERFACE);
			if (!ifce) continue;
			GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Checking if module %s supports URL %s\n", ifce->module_name, sURL));
			if (force_module && ifce && !strstr(ifce->module_name, force_module)) {
			}
			else if (net_check_interface(ifce) && ifce->CanHandleURL(ifce, sURL)) {
				break;
			}
			gf_modules_close_interface((GF_BaseInterface *) ifce);
			ifce = NULL;
		}
	}
exit:
	if (!ifce){
  	    GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("[Terminal] Did not find any input plugin for URL %s (%s)\n", sURL ? sURL : url, mime_type ? mime_type : "no mime type"));
	    if (sURL) gf_free(sURL);
		if ( (*ret_code) == GF_OK) (*ret_code) = GF_NOT_SUPPORTED;
	    *out_url = NULL;

		if (the_session && *the_session) {
			gf_dm_sess_del(*the_session);
		}
	} else {
	    *out_url = sURL;
	    GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("[Terminal] Found input plugin %s for URL %s (%s)\n", ifce->module_name, sURL, mime_type ? mime_type : "no mime type"));
	}
	if (mime_type)
	  gf_free(mime_type);
	mime_type = NULL;
	return ifce;
}