Rick Potts wrote:

> hey scott,
> 
> I see your problem...  That basically 3rd party helper apps only 
> interact with the URILoader - not Necko or the rest of Mozilla...
> 
> I see a couple of issues with your proposal...  First, there are some 
> protocol handlers wich actually use nsSimpleURI (such as javascript) 
> so it would be difficult to distinguish between these and the 
> situation where no protocol handler was found... 

I don't care if someone else uses a simple URI as well. This won't 
interfere with the normal flow of loadiing urls at all.

> 
> 
> Second, unless the URILoader is ultimately used to open the URI, the 
> helper app will still not be launched... 

this doesn't have anything to do with helper apps per say. It has more 
to deal with giving a URL we don't have a protocol handler for over to 
the OS to handle. You are right though, my fix is in Docshell. If you 
don't click on a  link or otherwise force the url to get loaded via your 
docshell, we won't pass the url out to the registry.

> 
> 
> As far as I can see, your change is basically meant to allow NewURI to 
> always succeed, so the URILoader will be called allowing the helper 
> app to be located and invoked...
> 
> Personally, I think that the right thing is to move "some amount" of 
> helper app support down into Necko... So there is some mechinism for 
> associating a protocol (such as telnet://) with an application...
> 
> We can create a 3rd party "helper app" protocol which allows an 
> assocation between a protocol and an executable...  And have some 
> standardized rules for parsing the URI path and passing it as 
> argument(s) to the external app...
> 
> It seems like this "helper app protocol" will solve standard cases 
> (ie. mailto://, telnet://...)
> 
> I know creating a helper app protocol is a bit more work, but I think 
> that it is the direction we want to go...
> 
> what do you think? 

I'm not quite sure I see why writing a default helper app protocol is 
the right way to go. Yes it does seem like more work which is part of 
the reason but I don't see what the gain is?

Right now, all I'm proposing is that NS_NewURI  creates a simple URI if 
it can't get a protocol handler to create a url for us.

Then in docshell, I added a couple lines of code after we try to open 
the url. If we were unable to get a channel for the URL then we pass the 
URL to the OS.

Here's an excerpt showing that behavior:
  rv = NS_OpenURI(getter_AddRefs(channel), aURI, nsnull, loadGroup,
                  ifreq);
  if(NS_FAILED(rv))
     {
       if(NS_ERROR_DOM_RETVAL_UNDEFINED == rv) // if causing the channel 
changed the
          return NS_OK;                        // dom and there is 
nothing else to do
       else
       {
         // if we are unable to create a channel / protocol handler for 
the specified
         // url then we should attempt to pass the url off to any 
application registered
         // with the OS for this url scheme...
         if (!channel)
         {
           nsCOMPtr<nsIExternalProtocolService> extProtService 
(do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID));
           PRBool haveHandler = PR_FALSE;
           if (extProtService)
           {
             extProtService->ExternalProtocolHandlerExists(urlScheme, 
&haveHandler);
             if (haveHandler)
               return extProtService->LoadUrl(aURI);
           }
         }

          return NS_ERROR_FAILURE;
       }
     }

We won't break support of other protocol handlers that use nsSimpleURI 
'cause when we call NS_NewURI on them, we'll open the uri and everything 
will just work. It's only in the case that we were able to create a 
nsIURI but are unable to find a channel to open the data with that this 
code gets invoked.

I guess I'm fuzzy as to why we would want to write a default protocol 
handler for this case. Protocol handlers are used to create URIs and to 
create channels for the URIs which you can use to open the data. In this 
case we aren't opening the data at all. We never want to return a 
channel and allow the user to call AsyncRead on the channel so most of 
the functionality of the protocol handler would be empty.

Does my argument make sense?

-Scott

> 
> -- rick
> 
> Scott MacGregor wrote:
> 
>> 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;
>> newURI.diff
>> 
>> Content-Type:
>> 
>> text/plain
>> Content-Encoding:
>> 
>> 7bit
> 
> 


Reply via email to