Exemple #1
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;
}
Exemple #2
0
LPNETSERVICE NM_NewService(struct _m4_client *term, struct _od_manager *owner, const char *url, LPNETSERVICE parent_service, M4Err *ret_code)
{
	LPNETSERVICE serv;
	u32 i;
	M4Err e;
	char *sURL, *ext, *mime_type;
	char szExt[50];
	NetClientPlugin *ifce;

	if (!url) {
		(*ret_code) = M4URLNotFound;
		return NULL;
	}

	if (parent_service && parent_service->url) {
		sURL = URL_Concatenate(parent_service->url, url);
		/*path was absolute*/
		if (!sURL) sURL = strdup(url);
	} else {
		sURL = strdup(url);
	}

	/*fetch a mime type if any. If error don't even attempt to open the service*/
	mime_type = NM_GetMimeType(term, sURL, &e);
	if (e) {
		free(sURL);
		(*ret_code) = e;
		return NULL;
	}
	
	if (mime_type && !stricmp(mime_type, "text/plain")) {
		free(mime_type);
		mime_type = NULL;
	}

	ifce = NULL;

	/*load from mime type*/
	if (mime_type) {
		char *sPlug = IF_GetKey(term->user->config, "MimeTypes", mime_type);
		if (sPlug) sPlug = strrchr(sPlug, '"');
		if (sPlug) {
			sPlug += 2;
			PM_LoadInterfaceByName(term->user->plugins, sPlug, M4STREAMINGCLIENT, (void **) &ifce);
			if (ifce && !net_check_interface(ifce) ) {
				PM_ShutdownInterface(ifce);
				ifce = NULL;
			}
		}
	}

	ext = strrchr(sURL, '.');
	/*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 plugin*/
	if (!ifce && ext) {
		u32 keyCount;
		strcpy(szExt, &ext[1]);
		ext = strrchr(szExt, '#');
		if (ext) ext[0] = 0;

		keyCount = IF_GetKeyCount(term->user->config, "MimeTypes");
		for (i=0; i<keyCount; i++) {
			char *sMime, *sKey, *sPlug;
			sMime = (char *) IF_GetKeyName(term->user->config, "MimeTypes", i);
			if (!sMime) continue;
			sKey = IF_GetKey(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;

			PM_LoadInterfaceByName(term->user->plugins, sPlug, M4STREAMINGCLIENT, (void **) &ifce);
			if (!ifce) continue;
			if (!net_check_interface(ifce)) {
				PM_ShutdownInterface(ifce);
				ifce = NULL;
				continue;
			}
			break;
		}
	}

	/*browse all plugins*/
	if (!ifce) {
		for (i=0; i< PM_GetPluginsCount(term->user->plugins); i++) {
			PM_LoadInterface(term->user->plugins, i, M4STREAMINGCLIENT, (void **) &ifce);
			if (!ifce) continue;
			if (net_check_interface(ifce) && ifce->CanHandleURL(ifce, sURL)) break;
			PM_ShutdownInterface(ifce);
			ifce = NULL;
		}
	}

	if (mime_type) free(mime_type);

	if (!ifce) {
		free(sURL);
		(*ret_code) = M4UnsupportedURL;
		return NULL;
	}
	serv = malloc(sizeof(NetService));
	memset(serv, 0, sizeof(NetService));
	serv->term = term;
	serv->owner = owner;
	serv->ifce = ifce;
	serv->url = sURL;
	serv->Clocks = NewChain();
	serv->dnloads = NewChain();
	ChainAddEntry(term->net_services, serv);
	return serv;
}