In order to create a url object for a spec, nsIOService::NewURI attempts to find a protocol handler for the scheme of the url and then use it to create the url. If there is no registered protocol handler then we fail to create a nsIURI for the spec and we return an error. This makes it very hard for 3rd party applications to get their urls to run in the mozilla application because they have to write protocol handler stubs for mozilla. 3rd party apps typically go through internet config and the windows registry to list themselves as applications which can handle particular url schemes. I already have code for nsDocShell::LoadURI where a failure to create a channel causes us to pass the URL out to the operating system and lets it attempt to load the url using this information. Unfortunately we never reach this code because any call to create a nsIURI object for a protocol scheme which mozilla doesn't know about already returns an error (nsIOService::NewURI). Gagan and I wanted to propose a change to the behavior of this method. In the event that we can't find a protocol handler to create a url for the passed in url, then let's create a simple URL object which can represent the URL. Then when we attempt to actually try to run that url and create a channel for it, we'll fail and kick out to the OS. An example of this would behavior would be someone who doesn't have mozilla mail/news installed so they don't have a mailto protocol handler registered. If they click on a mailto link we should use the default mailto application as specified by the OS. Today, nothing will happen if you click on mailto urls without mozilla mail/news installed (or another mozilla app which registers mailto protocols). Here's a possible patch. -Scott
Index: nsIOService.cpp =================================================================== RCS file: /cvsroot/mozilla/netwerk/base/src/nsIOService.cpp,v retrieving revision 1.87 diff -u -r1.87 nsIOService.cpp --- nsIOService.cpp 2001/01/17 23:42:42 1.87 +++ nsIOService.cpp 2001/02/05 01:07:15 @@ -41,6 +41,7 @@ static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID); static NS_DEFINE_CID(kDNSServiceCID, NS_DNSSERVICE_CID); static NS_DEFINE_CID(kErrorServiceCID, NS_ERRORSERVICE_CID); +static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID); //////////////////////////////////////////////////////////////////////////////// @@ -262,7 +263,18 @@ nsCOMPtr<nsIProtocolHandler> handler; rv = GetProtocolHandler(scheme, getter_AddRefs(handler)); nsCRT::free(scheme); - if (NS_FAILED(rv)) return rv; + if (NS_FAILED(rv) || !handler) { + // we don't know how to create a url for this scheme so create + // a simple URL + rv = nsComponentManager::CreateInstance(kSimpleURICID, nsnull, + NS_GET_IID(nsIURI), + (void**) result); + if (NS_FAILED(rv)) return rv; + rv = (*result)->SetSpec(aSpec); + if (hdlrResult) + *hdlrResult = nsnull; + return rv; + } if (hdlrResult) { *hdlrResult = handler;