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;

Reply via email to