[go: nahoru, domu]

Open Bug 902688 Opened 11 years ago Updated 2 years ago

nsIIOService.newURI() unable to parse IMAP URLs with port numbers?

Categories

(MailNews Core :: Networking, defect)

defect

Tracking

(Not tracked)

UNCONFIRMED

People

(Reporter: jfitzell, Unassigned)

Details

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36

Steps to reproduce:

Components.classes['@mozilla.org/network/io-service;1'].
    getService(Components.interfaces.nsIIOService).
    newURI('imap://imap.gmail.com:143',null,null).
    host


Actual results:

NS_ERROR_FAILURE: Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIIOService.newURI]


Expected results:

return 'imap.gmail.com'
nsIIOService is part of Gecko or Toolkit. But maybe mailnews adds the mail specific protocol support. Neil, do you know if the port is supposed to work by design?
Component: Untriaged → Networking
OS: Mac OS X → All
Product: Thunderbird → MailNews Core
Hardware: x86 → All
I don't think the port is the problem, more likely the problem is that we only allow IMAP URLs that match an existing account.
Oh, interesting. So I get an error in Firefox as well, and that seems to fail with or without the port, which kind of supports your theory, since presumably Firefox doesn't have any "existing accounts"...

Why would the ProtocolHandler not handle parsing a url that isn't added as a mail account though? I'm having to manually check whether a URL starts with imap:// and manually create a URI object for it myself...
(In reply to Julian Fitzell from comment #3)
> Oh, interesting. So I get an error in Firefox as well, and that seems to
> fail with or without the port, which kind of supports your theory, since
> presumably Firefox doesn't have any "existing accounts"...
Firefox probably fails because it can't find a handler at all (Firefox itself obviously doesn't handle them, and so it asks the OS whether there is an application that handles them).

> Why would the ProtocolHandler not handle parsing a url that isn't added as a
> mail account though?
It probably could, but for some reason it gives up. The reason it looks for a server is so that it can go on to find the message folder to see whether your URL is for a message that has been cached locally, among other reasons.

I seem to remember that news: URLs that don't map to accounts don't work either, but in that case I think what happens is that a stub account gets created and you get prompted to complete the account setup.
Ok, maybe I'm just missing something. I apologize if so. Is there another way to parse URIs?

The nsIURI docs say:

"This is an interface for an uniform resource identifier with internationalization support, offering attributes that allow setting and querying the basic components of a URI, and methods for performing basic operations on URIs."

Which sounds like what I want, but it doesn't seem like this works at all if you can't parse arbitrary URIs with it. I thought Firefox was working with even made up schemas, but testing further now it seems like it returns an instance that responds to spec() but errors if you ask for any individual components. I seem to be able to create new URI objects manually and they work fine, but the docs say not to do so and the known schemas don't get the default port set that way.

However, if I'm using this incorrectly then maybe it isn't a bug at all...
(In reply to Julian Fitzell from comment #5)
> Which sounds like what I want, but it doesn't seem like this works at all if
> you can't parse arbitrary URIs with it.
When you ask the IO service for a new URI, then you're right, we don't accept arbitrary URIs. We only accept URIs that we stand a chance of handling.

If you want to parse a string in a known URI format, then you probably want to use one of the nsIURLParser services. The default parser has contract id @mozilla.org/network/url-parser;1?auth=maybe but you can also use yes and no.
Ok, thanks for the pointer Neil. Despite a pretty awkward JS interface, that seems to work ok for parsing. In some cases, though, I'd still like to be able to use nsIURI for its URI normalization functionality. Is it ok to use nsIURI with createInstance() and init() directly? The docs seem to suggest you should only use the IOService but that doesn't seem to be practical in this case. (ironically I think I'll still have to use nsIURLParser in order to get the scheme in order to work out the default port to pass in to nsIURI.init())
(In reply to Julian Fitzell from comment #7)
> In some cases, though, I'd still like to be
> able to use nsIURI for its URI normalization functionality.

I'm not sure what you mean by normalization functionality. Currently each protocol has its own idea of what a URI should look like.

I'm also unsure what you're hoping to achieve by creating an nsIURI for an unsupported resource.

Then there is also the case of the URL object, which currently delegates to nsIURI, but which in future might work with arbitrary protocols.
Sorry, that was written too quickly, too late at night: I've been using nsIStandardURL. By normalization, I  mean that all the following produce identical URLs:

url.init(uri.URLTYPE_STANDARD, 80, 'http://localhost:80/foo/../bar/', null, null);
url.init(url.URLTYPE_STANDARD, 80, 'http://localhost/foo/../bar/', null, null);
url.init(url.URLTYPE_STANDARD, 80, 'http://localhost/bar/', null, null);

That's the main advantage for me over nsIURLParser, which just returns strings, though using URL objects also means you can, for example, calculate common bases between two URLs or update parts of the URL and have the changes reflected in the full spec string.

nsIURL docs suggest the only valid way to create an instance is via nsIIOService, but that's pretty frustrating if I can't represent URLs that the application doesn't know how to handle (or even worse with IMAP if the URL needs to be a registered account). If I'm ok creating instances of nsIStandardURL myself, then I can manage, though it still seems a bit unfortunate that I have to manually specify the default port for schemes (like http) that are already supported by the application.
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.