From d47b2f5e65e5cc94bbdb237ab964b674ab7648fc Mon Sep 17 00:00:00 2001 From: "darin%netscape.com" Date: Fri, 13 Sep 2002 19:32:45 +0000 Subject: [PATCH] fixes bug 166792 "move nsIIOService::GetURLSpecFromFile, etc. to nsIFileProtocolHandler" r=dougt sr=alecf --- .../ui/composer/content/ComposerCommands.js | 13 +- editor/ui/composer/content/editorUtilities.js | 7 + editor/ui/dialogs/content/EdDialogCommon.js | 4 +- .../ui/helperAppDlg/nsHelperAppDlg.js | 3 +- .../inspector/resources/content/inspector.js | 6 +- .../content/jsutil/system/DiskSearch.js | 6 +- .../resources/content/prefs/pref-sidebar.js | 3 +- .../content/search/inSearchModule.js | 3 +- .../resources/content/venkman-utils.js | 5 +- .../resources/content/MsgComposeCommands.js | 4 +- modules/libjar/nsJARURI.cpp | 20 +- netwerk/base/public/nsIIOService.idl | 38 +- netwerk/base/public/nsNetUtil.h | 39 +- netwerk/base/src/Makefile.in | 6 +- netwerk/base/src/nsDirectoryIndexStream.cpp | 3 +- netwerk/base/src/nsIOService.cpp | 356 +---------------- netwerk/base/src/nsIOService.h | 27 +- netwerk/base/src/nsStandardURL.cpp | 100 ++--- netwerk/base/src/nsStandardURL.h | 4 - netwerk/base/src/nsURLHelper.cpp | 358 +++++++++++++----- netwerk/base/src/nsURLHelper.h | 85 +++-- ...{nsIOServiceMac.cpp => nsURLHelperMac.cpp} | 12 +- ...{nsIOServiceOS2.cpp => nsURLHelperOS2.cpp} | 12 +- ...sIOServiceUnix.cpp => nsURLHelperUnix.cpp} | 12 +- ...{nsIOServiceWin.cpp => nsURLHelperWin.cpp} | 12 +- netwerk/base/src/nsURLParsers.cpp | 2 +- netwerk/build/nsNetModule.cpp | 72 +--- netwerk/macbuild/netwerk.xml | 18 +- .../file/public/nsIFileProtocolHandler.idl | 16 + netwerk/protocol/file/src/Makefile.in | 4 + .../file/src/nsFileProtocolHandler.cpp | 13 + netwerk/protocol/http/src/nsHttp.h | 8 - netwerk/protocol/jar/src/nsJARURI.cpp | 20 +- .../protocol/res/src/nsResProtocolHandler.cpp | 3 +- .../streamconv/converters/nsIndexedToHTML.cpp | 5 +- .../bookmarks/resources/addBookmark.js | 4 +- .../content/pref-applications-edit.xul | 3 +- .../content/pref-applications-new.js | 3 +- .../resources/content/pref-applications.js | 5 +- .../sidebar/resources/sidebarOverlay.js | 3 +- xpfe/components/sidebar/src/nsSidebar.js | 3 +- 41 files changed, 543 insertions(+), 777 deletions(-) rename netwerk/base/src/{nsIOServiceMac.cpp => nsURLHelperMac.cpp} (94%) rename netwerk/base/src/{nsIOServiceOS2.cpp => nsURLHelperOS2.cpp} (95%) rename netwerk/base/src/{nsIOServiceUnix.cpp => nsURLHelperUnix.cpp} (93%) rename netwerk/base/src/{nsIOServiceWin.cpp => nsURLHelperWin.cpp} (94%) diff --git a/editor/ui/composer/content/ComposerCommands.js b/editor/ui/composer/content/ComposerCommands.js index 8506673d077c..740ffff065ce 100644 --- a/editor/ui/composer/content/ComposerCommands.js +++ b/editor/ui/composer/content/ComposerCommands.js @@ -930,6 +930,7 @@ function PromptForSaveLocation(aDoSaveAsText, aEditorType, aMIMEType, ahtmlDocum // assuming we have information needed (like prior saved location) try { var ioService = GetIOService(); + var fileHandler = GetFileProtocolHandler(); var isLocalFile = true; try { @@ -941,7 +942,7 @@ function PromptForSaveLocation(aDoSaveAsText, aEditorType, aMIMEType, ahtmlDocum var parentLocation = null; if (isLocalFile) { - var fileLocation = ioService.getFileFromURLSpec(aDocumentURLString); // this asserts if url is not local + var fileLocation = fileHandler.getFileFromURLSpec(aDocumentURLString); // this asserts if url is not local parentLocation = fileLocation.parent; } if (parentLocation) @@ -964,7 +965,7 @@ function PromptForSaveLocation(aDoSaveAsText, aEditorType, aMIMEType, ahtmlDocum if (dialogResult.filepickerClick != nsIFilePicker.returnCancel) { // reset urlstring to new save location - dialogResult.resultingURIString = ioService.getURLSpecFromFile(fp.file); + dialogResult.resultingURIString = fileHandler.getURLSpecFromFile(fp.file); dialogResult.resultingLocalFile = fp.file; SaveFilePickerDirectory(fp, aEditorType); } @@ -1757,8 +1758,8 @@ function SaveDocument(aSaveAs, aSaveCopy, aMimeType) if (docURI.schemeIs("file")) { - ioService = GetIOService(); - tempLocalFile = ioService.getFileFromURLSpec(urlstring).QueryInterface(Components.interfaces.nsILocalFile); + var fileHandler = GetFileProtocolHandler(); + tempLocalFile = fileHandler.getFileFromURLSpec(urlstring).QueryInterface(Components.interfaces.nsILocalFile); } } @@ -2433,8 +2434,8 @@ var nsValidateCommand = // See if it's a file: var ifile; try { - var ioService = GetIOService(); - ifile = ioService.getFileFromURLSpec(URL2Validate); + var fileHandler = GetFileProtocolHandler(); + ifile = fileHandler.getFileFromURLSpec(URL2Validate); // nsIFile throws an exception if it's not a file url } catch (e) { ifile = null; } if (ifile) diff --git a/editor/ui/composer/content/editorUtilities.js b/editor/ui/composer/content/editorUtilities.js index 3b9e25fe63c2..3773fb8ef594 100644 --- a/editor/ui/composer/content/editorUtilities.js +++ b/editor/ui/composer/content/editorUtilities.js @@ -305,6 +305,13 @@ function GetIOService() return gIOService; } +function GetFileProtocolHandler() +{ + var ios = GetIOService(); + var handler = ios.getProtocolHandler("file"); + return handler.QueryInterface(Components.interfaces.nsIFileProtocolHandler); +} + function GetPrefsService() { if (gPrefsService) diff --git a/editor/ui/dialogs/content/EdDialogCommon.js b/editor/ui/dialogs/content/EdDialogCommon.js index c29e1816888e..af874d224293 100644 --- a/editor/ui/dialogs/content/EdDialogCommon.js +++ b/editor/ui/dialogs/content/EdDialogCommon.js @@ -538,8 +538,8 @@ function GetLocalFileURL(filterType) } SaveFilePickerDirectory(fp, fileType); - var ioService = GetIOService(); - return fp.file ? ioService.getURLSpecFromFile(fp.file) : null; + var fileHandler = GetFileProtocolHandler(); + return fp.file ? fileHandler.getURLSpecFromFile(fp.file) : null; } function GetMetaElement(name) diff --git a/embedding/components/ui/helperAppDlg/nsHelperAppDlg.js b/embedding/components/ui/helperAppDlg/nsHelperAppDlg.js index a6e395042302..5e8cfef2fc77 100644 --- a/embedding/components/ui/helperAppDlg/nsHelperAppDlg.js +++ b/embedding/components/ui/helperAppDlg/nsHelperAppDlg.js @@ -550,7 +550,8 @@ nsHelperAppDialog.prototype = { // Get the data source; load it synchronously if it must be // initialized. var ioService = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService); - var fileurl = ioService.getURLSpecFromFile(file); + var fileHandler = ioService.getProtocolHandler("file").QueryInterface(Components.interfaces.nsIFileProtocolHandler); + var fileurl = fileHandler.getURLSpecFromFile(file); var ds = rdf.GetDataSourceBlocking( fileurl ); diff --git a/extensions/inspector/resources/content/inspector.js b/extensions/inspector/resources/content/inspector.js index 8b7ac1899eea..d5270585e0e2 100644 --- a/extensions/inspector/resources/content/inspector.js +++ b/extensions/inspector/resources/content/inspector.js @@ -175,10 +175,10 @@ InspectorApp.prototype = var file = FilePickerUtils.pickFile("Find Search File", path, ["filterXML"], "Open"); if (file) { var ioService = XPCU.getService("@mozilla.org/network/io-service;1","nsIIOService"); + var fileHandler = XPCU.QI(ioService.getProtocolHandler("file"), "nsIFileProtocolHandler"); + + var url = fileHandler.getURLSpecFromFile(file); - var url = ioService.getURLSpecFromFile(file); - // XX temporary until 56354 is fixed - url = url.replace("file://", "file:///"); this.startSearchModule(url); } }, diff --git a/extensions/inspector/resources/content/jsutil/system/DiskSearch.js b/extensions/inspector/resources/content/jsutil/system/DiskSearch.js index 0c43bc79763f..8ee1a4ccea32 100644 --- a/extensions/inspector/resources/content/jsutil/system/DiskSearch.js +++ b/extensions/inspector/resources/content/jsutil/system/DiskSearch.js @@ -61,7 +61,9 @@ var DiskSearch = for (var i = 0; i < aExtList.length; i++) { extHash[aExtList[i]] = true; } - this.ioService = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService); + + var ios = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService); + this.fileHandler = ios.getProtocolHandler("file").QueryInterface(Components.interfaces.nsIFileProtocolHandler); // recursively build the list of results var results = []; @@ -81,7 +83,7 @@ var DiskSearch = ext = this.getExtension(entry.leafName); if (ext) { if (aExtHash[ext]) - aResults.push(this.ioService.getURLSpecFromFile(entry)); + aResults.push(this.fileHandler.getURLSpecFromFile(entry)); } } }, diff --git a/extensions/inspector/resources/content/prefs/pref-sidebar.js b/extensions/inspector/resources/content/prefs/pref-sidebar.js index 2c8071139384..c6c4f8098acb 100644 --- a/extensions/inspector/resources/content/prefs/pref-sidebar.js +++ b/extensions/inspector/resources/content/prefs/pref-sidebar.js @@ -145,8 +145,9 @@ SidebarPrefs.prototype = return null; var ioService = XPCU.getService("@mozilla.org/network/io-service;1", "nsIIOService"); + var fileHandler = XPCU.QI(ioService.getProtocolHandler("file"), "nsIFileProtocolHandler"); - return ioService.getURLSpecFromFile(file); + return fileHandler.getURLSpecFromFile(file); } catch (ex) { return null; diff --git a/extensions/inspector/resources/content/search/inSearchModule.js b/extensions/inspector/resources/content/search/inSearchModule.js index 997c4f10ac16..384703791a42 100644 --- a/extensions/inspector/resources/content/search/inSearchModule.js +++ b/extensions/inspector/resources/content/search/inSearchModule.js @@ -518,8 +518,9 @@ inSearchModule.prototype = var file = XPCU.QI(file, "nsIFile"); var ioService = XPCU.getService("@mozilla.org/network/io-service;1", "nsIIOService"); + var fileHandler = XPCU.QI(ioService.getProtocolHandler("file"), "nsIFileProtocolHandler"); - this.mDialogURL = ioService.getURLSpecFromFile(basefile); + this.mDialogURL = fileHandler.getURLSpecFromFile(basefile); */ } diff --git a/extensions/venkman/resources/content/venkman-utils.js b/extensions/venkman/resources/content/venkman-utils.js index 69a5bb32caca..3926b7767552 100644 --- a/extensions/venkman/resources/content/venkman-utils.js +++ b/extensions/venkman/resources/content/venkman-utils.js @@ -496,6 +496,7 @@ function getURLSpecFromFile (file) const nsIIOService = Components.interfaces.nsIIOService; const nsILocalFile = Components.interfaces.nsILocalFile; + const nsIFileProtocolHandler = Components.interfaces.nsIFileProtocolHandler; if (typeof file == "string") { @@ -506,7 +507,9 @@ function getURLSpecFromFile (file) } var service = Components.classes[IOS_CTRID].getService(nsIIOService); - return service.getURLSpecFromFile(file); + var fileHandler = service.getProtocolHandler("file") + .QueryInterface(nsIFileProtocolHandler); + return fileHandler.getURLSpecFromFile(file); } function getCommonPfx (list) diff --git a/mailnews/compose/resources/content/MsgComposeCommands.js b/mailnews/compose/resources/content/MsgComposeCommands.js index 6ec3137106a1..157e028d9ace 100644 --- a/mailnews/compose/resources/content/MsgComposeCommands.js +++ b/mailnews/compose/resources/content/MsgComposeCommands.js @@ -2677,7 +2677,9 @@ var attachmentBucketObserver = { { var ioService = Components.classes["@mozilla.org/network/io-service;1"] .getService(Components.interfaces.nsIIOService); - rawData = ioService.getURLSpecFromFile(rawData); + var fileHandler = ioService.getProtocolHandler("file") + .QueryInterface(Components.interfaces.nsIFileProtocolHandler); + rawData = fileHandler.getURLSpecFromFile(rawData); } else { diff --git a/modules/libjar/nsJARURI.cpp b/modules/libjar/nsJARURI.cpp index 6e0082c96208..22732c875413 100644 --- a/modules/libjar/nsJARURI.cpp +++ b/modules/libjar/nsJARURI.cpp @@ -96,7 +96,7 @@ nsJARURI::SetSpec(const nsACString &aSpec) if (NS_FAILED(rv)) return rv; nsCAutoString scheme; - rv = ::ExtractURLScheme(aSpec, nsnull, nsnull, &scheme); + rv = net_ExtractURLScheme(aSpec, nsnull, nsnull, &scheme); if (NS_FAILED(rv)) return rv; if (strcmp("jar", scheme.get()) != 0) @@ -127,9 +127,9 @@ nsJARURI::SetSpec(const nsACString &aSpec) while (*delim_end == '/') ++delim_end; - rv = ::ResolveRelativePath(Substring(delim_end, end), - NS_LITERAL_CSTRING(""), - mJAREntry); + rv = net_ResolveRelativePath(Substring(delim_end, end), + NS_LITERAL_CSTRING(""), + mJAREntry); return rv; } @@ -329,7 +329,7 @@ nsJARURI::Resolve(const nsACString &relativePath, nsACString &result) nsresult rv; nsCAutoString scheme; - rv = ::ExtractURLScheme(relativePath, nsnull, nsnull, &scheme); + rv = net_ExtractURLScheme(relativePath, nsnull, nsnull, &scheme); if (NS_SUCCEEDED(rv)) { // then aSpec is absolute result = relativePath; @@ -344,8 +344,8 @@ nsJARURI::Resolve(const nsACString &relativePath, nsACString &result) path = ""; nsCAutoString resolvedEntry; - rv = ::ResolveRelativePath(relativePath, path, - resolvedEntry); + rv = net_ResolveRelativePath(relativePath, path, + resolvedEntry); if (NS_FAILED(rv)) return rv; return FormatSpec(resolvedEntry, result); @@ -385,9 +385,9 @@ nsJARURI::SetJAREntry(const nsACString &entryPath) { mJAREntry.Truncate(); - return ::ResolveRelativePath(entryPath, - NS_LITERAL_CSTRING(""), - mJAREntry); + return net_ResolveRelativePath(entryPath, + NS_LITERAL_CSTRING(""), + mJAREntry); } //////////////////////////////////////////////////////////////////////////////// diff --git a/netwerk/base/public/nsIIOService.idl b/netwerk/base/public/nsIIOService.idl index 3a021f0c6c2d..b00c75270b04 100644 --- a/netwerk/base/public/nsIIOService.idl +++ b/netwerk/base/public/nsIIOService.idl @@ -56,10 +56,6 @@ interface nsIFile; [scriptable, uuid(bddeda3f-9020-4d12-8c70-984ee9f7935e)] interface nsIIOService : nsISupports { - /************************************************************************* - * Protocol handler utilities - */ - /** * Returns a protocol handler for a given URI scheme. * @@ -133,44 +129,18 @@ interface nsIIOService : nsISupports */ boolean allowPort(in long aPort, in string aScheme); - - /************************************************************************* - * URL parsing utilities - * - * The set of methods provided here is intentionally limited. Most of - * Necko's URL parsing functionality is provided via nsIURI. This is - * done to ensure a common point of access to URL parsing, which is - * protocol dependent. Do not try to parse a random URL string as the - * result will likely differ (perhaps only in some subtle way) from the - * value of the corresponding nsIURI attribute. Violating this rule - * may make your code vulnerable to various kinds of security exploits. - * DON'T RISK IT! --darin - */ - /** * Utility to extract the scheme from a URL string, consistently and * according to spec (see RFC 2396). * + * NOTE: Most URL parsing is done via nsIURI, and in fact the scheme + * can also be extracted from a URL string via nsIURI. This method + * is provided purely as an optimization. + * * @param aSpec the URL string to parse * @return URL scheme * * @throws NS_ERROR_MALFORMED_URI if URL string is not of the right form. */ ACString extractScheme(in AUTF8String urlString); - - /** - * Converts the nsIFile to the corresponding URL string. NOTE: under - * some platforms this is a lossy conversion (e.g., Mac Carbon build). - * If the nsIFile is a local file, then the result will be a file:// - * URL string. - * - * The resulting string may contain URL-escaped characters. - */ - AUTF8String getURLSpecFromFile(in nsIFile file); - - /** - * Converts the URL string into the corresponding nsIFile if possible. - * A local file will be created if the URL string begins with file://. - */ - nsIFile getFileFromURLSpec(in AUTF8String url); }; diff --git a/netwerk/base/public/nsNetUtil.h b/netwerk/base/public/nsNetUtil.h index 6b46267703c5..fb99368ec2c9 100644 --- a/netwerk/base/public/nsNetUtil.h +++ b/netwerk/base/public/nsNetUtil.h @@ -68,6 +68,7 @@ #include "nsIStreamIO.h" #include "nsIPipe.h" #include "nsIProtocolHandler.h" +#include "nsIFileProtocolHandler.h" #include "nsIStringStream.h" #include "nsILocalFile.h" #include "nsIFileStreams.h" @@ -763,31 +764,45 @@ NS_NewProxyInfo(const char* type, const char* host, PRInt32 port, nsIProxyInfo* } inline nsresult -NS_GetFileFromURLSpec(const nsACString &inURL, nsIFile **result, - nsIIOService *ioService=nsnull) +NS_GetFileProtocolHandler(nsIFileProtocolHandler **result, + nsIIOService *ioService=nsnull) { + nsresult rv; + nsCOMPtr serv; if (ioService == nsnull) { - nsresult rv; serv = do_GetIOService(&rv); if (NS_FAILED(rv)) return rv; ioService = serv.get(); } - return ioService->GetFileFromURLSpec(inURL, result); + + nsCOMPtr handler; + rv = ioService->GetProtocolHandler("file", getter_AddRefs(handler)); + if (NS_FAILED(rv)) return rv; + + return CallQueryInterface(handler, result); +} + +inline nsresult +NS_GetFileFromURLSpec(const nsACString &inURL, nsIFile **result, + nsIIOService *ioService=nsnull) +{ + nsCOMPtr fileHandler; + nsresult rv = NS_GetFileProtocolHandler(getter_AddRefs(fileHandler), ioService); + if (NS_FAILED(rv)) return rv; + + return fileHandler->GetFileFromURLSpec(inURL, result); } inline nsresult NS_GetURLSpecFromFile(nsIFile* aFile, nsACString &aUrl, nsIIOService *ioService=nsnull) { - nsCOMPtr serv; - if (ioService == nsnull) { - nsresult rv; - serv = do_GetIOService(&rv); - if (NS_FAILED(rv)) return rv; - ioService = serv.get(); - } - return ioService->GetURLSpecFromFile(aFile, aUrl); + nsCOMPtr fileHandler; + nsresult rv = NS_GetFileProtocolHandler(getter_AddRefs(fileHandler), ioService); + if (NS_FAILED(rv)) return rv; + + return fileHandler->GetURLSpecFromFile(aFile, aUrl); } inline nsresult diff --git a/netwerk/base/src/Makefile.in b/netwerk/base/src/Makefile.in index cab69e5a461a..a7f75f592dc4 100644 --- a/netwerk/base/src/Makefile.in +++ b/netwerk/base/src/Makefile.in @@ -74,14 +74,14 @@ CPPSRCS = \ $(NULL) ifeq ($(MOZ_WIDGET_TOOLKIT),os2) - CPPSRCS += nsIOServiceOS2.cpp + CPPSRCS += nsURLHelperOS2.cpp else ifeq ($(MOZ_WIDGET_TOOLKIT),windows) - CPPSRCS += nsIOServiceWin.cpp + CPPSRCS += nsURLHelperWin.cpp CPPSRCS += nsNativeConnectionHelper.cpp CPPSRCS += nsAutodialWin.cpp else - CPPSRCS += nsIOServiceUnix.cpp + CPPSRCS += nsURLHelperUnix.cpp endif endif diff --git a/netwerk/base/src/nsDirectoryIndexStream.cpp b/netwerk/base/src/nsDirectoryIndexStream.cpp index d9ec2000a61d..64fac5b1b4b6 100644 --- a/netwerk/base/src/nsDirectoryIndexStream.cpp +++ b/netwerk/base/src/nsDirectoryIndexStream.cpp @@ -62,6 +62,7 @@ static PRLogModuleInfo* gLog; #include "nsCollationCID.h" #include "nsIPlatformCharset.h" #include "nsReadableUtils.h" +#include "nsURLHelper.h" #include "nsNetUtil.h" #include "nsCRT.h" @@ -216,7 +217,7 @@ nsDirectoryIndexStream::Init(nsIFile* aDir) mBuf.Append("300: "); nsCAutoString url; - rv = NS_GetURLSpecFromFile(mDir, url); + rv = net_GetURLSpecFromFile(mDir, url); if (NS_FAILED(rv)) return rv; mBuf.Append(url); mBuf.Append('\n'); diff --git a/netwerk/base/src/nsIOService.cpp b/netwerk/base/src/nsIOService.cpp index fe2af5948b42..a0d675fe0b12 100644 --- a/netwerk/base/src/nsIOService.cpp +++ b/netwerk/base/src/nsIOService.cpp @@ -58,7 +58,6 @@ #include "nsIPrefBranchInternal.h" #include "nsIPrefLocalizedString.h" #include "nsICategoryManager.h" -#include "nsIURLParser.h" #include "nsXPCOM.h" #include "nsISupportsPrimitives.h" #include "nsIProxiedProtocolHandler.h" @@ -267,13 +266,6 @@ nsIOService::Init() nsIOService::~nsIOService() { - // mURLParsers is a voidarray; we must release ourselves - for (PRInt32 i = 0; i < mURLParsers.Count(); i++) - { - nsISupports *temp; - temp = NS_STATIC_CAST(nsISupports*, mURLParsers[i]); - NS_IF_RELEASE(temp); - } } NS_METHOD @@ -324,7 +316,7 @@ NS_IMPL_THREADSAFE_ISUPPORTS3(nsIOService, //////////////////////////////////////////////////////////////////////////////// -NS_IMETHODIMP +nsresult nsIOService::CacheProtocolHandler(const char *scheme, nsIProtocolHandler *handler) { for (unsigned int i=0; i catmgr(do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv)); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr parserList; - rv = catmgr->EnumerateCategory(NS_IURLPARSER_KEY, getter_AddRefs(parserList)); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr entry; - - // Walk the list of parsers... - while (1) { - rv = parserList->GetNext(getter_AddRefs(entry)); - if (NS_FAILED(rv)) break; - - // get the entry string - nsCAutoString entryString; - rv = entry->GetData(entryString); - if (NS_FAILED(rv)) break; - - if (entryString.Equals(scheme)) { - nsXPIDLCString contractID; - rv = catmgr->GetCategoryEntry(NS_IURLPARSER_KEY, entryString.get(), getter_Copies(contractID)); - if (NS_FAILED(rv)) break; - - rv = nsServiceManager::GetService(contractID, NS_GET_IID(nsIURLParser), (nsISupports **)_retval); - if (NS_FAILED(rv)) - return rv; - if (*_retval) - CacheURLParser(scheme, *_retval); - return *_retval ? NS_OK : NS_ERROR_FAILURE; - } - } - - // no registered url parser. Just use the default... - if (!mDefaultURLParser) { - rv = nsServiceManager::GetService(kStdURLParserCID, - NS_GET_IID(nsIURLParser), - getter_AddRefs(mDefaultURLParser)); - if (NS_FAILED(rv)) return rv; - } - - *_retval = mDefaultURLParser; - NS_ADDREF(*_retval); - CacheURLParser(scheme, *_retval); - return NS_OK; -} - -#if 0 -static inline void -ExtractUrlPart_Helper(const nsACString &src, PRUint32 pos, PRInt32 len, nsACString &result) -{ - if (len >= 0) - result = Substring(src, pos, len); -} - -NS_IMETHODIMP -nsIOService::ExtractUrlPart(const nsACString &urlString, PRInt16 flag, nsACString &urlPart) -{ - nsresult rv; - nsCAutoString scheme; - - rv = ExtractURLScheme(urlString, nsnull, nsnull, &scheme); - if (NS_FAILED(rv)) return rv; - - if (flag == url_Scheme) { - urlPart = scheme; - return NS_OK; - } - - urlPart.Truncate(); - - nsCOMPtr parser; - rv = GetParserForScheme(scheme.get(), getter_AddRefs(parser)); - if (NS_FAILED(rv)) return rv; - - // we work only with flat strings around these parts - const nsPromiseFlatCString &flat = PromiseFlatCString(urlString); - const char *url = flat.get(); - - PRUint32 authPos, pathPos; - PRInt32 authLen, pathLen; - - rv = parser->ParseURL(url, -1, - nsnull, nsnull, - &authPos, &authLen, - &pathPos, &pathLen); - if (NS_FAILED(rv)) return rv; - - if (flag == url_Path) - ExtractUrlPart_Helper(urlString, pathPos, pathLen, urlPart); - else if (flag < url_Directory || flag & url_Port) { - PRUint32 usernamePos, passwordPos, hostnamePos; - PRInt32 usernameLen, passwordLen, hostnameLen; - PRInt32 port; - - if (authLen < 0) - return NS_OK; - - rv = parser->ParseAuthority(url + authPos, authLen, - &usernamePos, &usernameLen, - &passwordPos, &passwordLen, - &hostnamePos, &hostnameLen, - &port); - if (NS_FAILED(rv)) return rv; - - usernamePos += authPos; - passwordPos += authPos; - hostnamePos += authPos; - - switch (flag) { - case url_Username: - ExtractUrlPart_Helper(urlString, usernamePos, usernameLen, urlPart); - break; - case url_Password: - ExtractUrlPart_Helper(urlString, passwordPos, passwordLen, urlPart); - break; - case url_Host: - ExtractUrlPart_Helper(urlString, hostnamePos, hostnameLen, urlPart); - break; - case url_Port: - if (port != -1) { - PRInt32 pos = hostnamePos + hostnameLen + 1; - ExtractUrlPart_Helper(urlString, pos, pathPos - pos, urlPart); - } - break; - case url_Host | url_Port: - if (port != -1 && hostnameLen > 0) { - urlPart = Substring(urlString, hostnamePos, hostnameLen) - + NS_LITERAL_CSTRING(":") - + nsPrintfCString("%d", port); - } - else - ExtractUrlPart_Helper(urlString, hostnamePos, hostnameLen, urlPart); - break; - default: - NS_NOTREACHED("unexpected flag"); - return NS_ERROR_UNEXPECTED; - } - } - else { - PRUint32 filepathPos, paramPos, queryPos, refPos; - PRInt32 filepathLen, paramLen, queryLen, refLen; - - if (pathLen < 0) - return NS_OK; - - rv = parser->ParsePath(url + pathPos, pathLen, - &filepathPos, &filepathLen, - ¶mPos, ¶mLen, - &queryPos, &queryLen, - &refPos, &refLen); - if (NS_FAILED(rv)) return rv; - - filepathPos += pathPos; - paramPos += pathPos; - queryPos += pathPos; - refPos += pathPos; - - if (flag < url_Param) { - PRUint32 directoryPos, basenamePos, extensionPos; - PRInt32 directoryLen, basenameLen, extensionLen; - - rv = parser->ParseFilePath(url + filepathPos, filepathLen, - &directoryPos, &directoryLen, - &basenamePos, &basenameLen, - &extensionPos, &extensionLen); - - directoryPos += filepathPos; - basenamePos += filepathPos; - extensionPos += filepathPos; - - switch (flag) { - case url_Directory: - ExtractUrlPart_Helper(urlString, directoryPos, directoryLen, urlPart); - break; - case url_FileBaseName: - ExtractUrlPart_Helper(urlString, basenamePos, basenameLen, urlPart); - break; - case url_FileExtension: - ExtractUrlPart_Helper(urlString, extensionPos, extensionLen, urlPart); - break; - default: - NS_NOTREACHED("unexpected flag"); - return NS_ERROR_UNEXPECTED; - } - } - else { - switch (flag) { - case url_Param: - ExtractUrlPart_Helper(urlString, paramPos, paramLen, urlPart); - break; - case url_Query: - ExtractUrlPart_Helper(urlString, queryPos, queryLen, urlPart); - break; - case url_Ref: - ExtractUrlPart_Helper(urlString, refPos, refLen, urlPart); - break; - default: - NS_NOTREACHED("unexpected flag"); - return NS_ERROR_UNEXPECTED; - } - } - } - return NS_OK; -} -#endif - NS_IMETHODIMP nsIOService::GetProtocolFlags(const char* scheme, PRUint32 *flags) { @@ -716,7 +435,6 @@ nsIOService::GetProtocolFlags(const char* scheme, PRUint32 *flags) return rv; } - nsresult nsIOService::NewURI(const nsACString &aSpec, const char *aCharset, nsIURI *aBaseURI, nsIURI **result) { @@ -1005,71 +723,3 @@ nsIOService::Observe(nsISupports *subject, } return NS_OK; } - -nsresult -nsIOService::ParseFileURL(const nsACString &inURL, - nsACString &outDirectory, - nsACString &outFileBaseName, - nsACString &outFileExtension) -{ - nsresult rv; - - outDirectory.Truncate(); - outFileBaseName.Truncate(); - outFileExtension.Truncate(); - - nsCAutoString scheme; - rv = ExtractScheme(inURL, scheme); - if (NS_FAILED(rv)) return rv; - - if (strcmp(scheme.get(), "file") != 0) { - NS_ERROR("must be a file:// url"); - return NS_ERROR_UNEXPECTED; - } - - const nsPromiseFlatCString &flatURL = PromiseFlatCString(inURL); - const char *url = flatURL.get(); - - nsCOMPtr parser; - rv = GetParserForScheme(scheme.get(), getter_AddRefs(parser)); - if (NS_FAILED(rv)) return rv; - - PRUint32 pathPos, filepathPos, directoryPos, basenamePos, extensionPos; - PRInt32 pathLen, filepathLen, directoryLen, basenameLen, extensionLen; - - // invoke the parser to extract the URL path - rv = parser->ParseURL(url, -1, - nsnull, nsnull, // dont care about scheme - nsnull, nsnull, // dont care about authority - &pathPos, &pathLen); - if (NS_FAILED(rv)) return rv; - - // invoke the parser to extract filepath from the path - rv = parser->ParsePath(url + pathPos, pathLen, - &filepathPos, &filepathLen, - nsnull, nsnull, // dont care about param - nsnull, nsnull, // dont care about query - nsnull, nsnull); // dont care about ref - if (NS_FAILED(rv)) return rv; - - filepathPos += pathPos; - - // invoke the parser to extract the directory and filename from filepath - rv = parser->ParseFilePath(url + filepathPos, filepathLen, - &directoryPos, &directoryLen, - &basenamePos, &basenameLen, - &extensionPos, &extensionLen); - if (NS_FAILED(rv)) return rv; - - if (directoryLen > 0) - outDirectory = Substring(inURL, filepathPos + directoryPos, directoryLen); - if (basenameLen > 0) - outFileBaseName = Substring(inURL, filepathPos + basenamePos, basenameLen); - if (extensionLen > 0) - outFileExtension = Substring(inURL, filepathPos + extensionPos, extensionLen); - // since we are using a no-auth url parser, there will never be a host - // XXX not strictly true... file://localhost/foo/bar.html is a valid URL - - return NS_OK; -} - diff --git a/netwerk/base/src/nsIOService.h b/netwerk/base/src/nsIOService.h index 3259d13d30cb..35265038cacd 100644 --- a/netwerk/base/src/nsIOService.h +++ b/netwerk/base/src/nsIOService.h @@ -87,45 +87,30 @@ public: nsIURI* *result, nsIProtocolHandler* *hdlrResult); protected: - NS_METHOD GetCachedProtocolHandler(const char *scheme, + nsresult GetCachedProtocolHandler(const char *scheme, nsIProtocolHandler* *hdlrResult, PRUint32 start=0, PRUint32 end=0); - NS_METHOD CacheProtocolHandler(const char *scheme, + nsresult CacheProtocolHandler(const char *scheme, nsIProtocolHandler* hdlr); - NS_METHOD GetCachedURLParser(const char *scheme, - nsIURLParser* *hdlrResult); - - NS_METHOD CacheURLParser(const char *scheme, - nsIURLParser* hdlr); - - NS_METHOD GetParserForScheme(const char *scheme, nsIURLParser **); - // Prefs wrangling void PrefsChanged(nsIPrefBranch *prefs, const char *pref = nsnull); void GetPrefBranch(nsIPrefBranch **); void ParsePortList(nsIPrefBranch *prefBranch, const char *pref, PRBool remove); - nsresult ParseFileURL(const nsACString &inURL, - nsACString &outDirectory, - nsACString &outFileBaseName, - nsACString &outFileExtension); protected: - PRPackedBool mOffline; - PRPackedBool mOfflineForProfileChange; + PRPackedBool mOffline; + PRPackedBool mOfflineForProfileChange; nsCOMPtr mSocketTransportService; nsCOMPtr mFileTransportService; nsCOMPtr mDNSService; nsCOMPtr mProxyService; - nsCOMPtr mEventQueueService; + nsCOMPtr mEventQueueService; // Cached protocol handlers - nsWeakPtr mWeakHandler[NS_N(gScheme)]; + nsWeakPtr mWeakHandler[NS_N(gScheme)]; - // Cached url handlers - nsCOMPtr mDefaultURLParser; - nsAutoVoidArray mURLParsers; nsVoidArray mRestrictedPortList; public: diff --git a/netwerk/base/src/nsStandardURL.cpp b/netwerk/base/src/nsStandardURL.cpp index 0a512bc6334b..3f95d0853ae5 100644 --- a/netwerk/base/src/nsStandardURL.cpp +++ b/netwerk/base/src/nsStandardURL.cpp @@ -57,10 +57,6 @@ static NS_DEFINE_CID(kThisImplCID, NS_THIS_STANDARDURL_IMPL_CID); static NS_DEFINE_CID(kStandardURLCID, NS_STANDARDURL_CID); -nsIIOService *nsStandardURL::gIOService = nsnull; -nsIURLParser *nsStandardURL::gNoAuthParser = nsnull; -nsIURLParser *nsStandardURL::gAuthParser = nsnull; -nsIURLParser *nsStandardURL::gStdParser = nsnull; nsIIDNService *nsStandardURL::gIDNService = nsnull; nsICharsetConverterManager2 *nsStandardURL::gCharsetMgr = nsnull; PRBool nsStandardURL::gInitialized = PR_FALSE; @@ -329,7 +325,7 @@ nsStandardURL::nsStandardURL() } // default parser in case nsIStandardURL::Init is never called - mParser = gStdParser; + mParser = net_GetStdURLParser(); } nsStandardURL::~nsStandardURL() @@ -342,36 +338,6 @@ nsStandardURL::~nsStandardURL() void nsStandardURL::InitGlobalObjects() { - nsCOMPtr parser; - - parser = do_GetService(NS_NOAUTHURLPARSER_CONTRACTID); - NS_ASSERTION(parser, "failed getting 'noauth' url parser"); - if (parser) { - gNoAuthParser = parser.get(); - NS_ADDREF(gNoAuthParser); - } - - parser = do_GetService(NS_AUTHURLPARSER_CONTRACTID); - NS_ASSERTION(parser, "failed getting 'auth' url parser"); - if (parser) { - gAuthParser = parser.get(); - NS_ADDREF(gAuthParser); - } - - parser = do_GetService(NS_STDURLPARSER_CONTRACTID); - NS_ASSERTION(parser, "failed getting 'std' url parser"); - if (parser) { - gStdParser = parser.get(); - NS_ADDREF(gStdParser); - } - - nsCOMPtr serv(do_GetIOService()); - NS_ASSERTION(serv, "failed getting IO service"); - if (serv) { - gIOService = serv.get(); - NS_ADDREF(gIOService); - } - nsCOMPtr prefService( do_GetService(NS_PREFSERVICE_CONTRACTID) ); if (prefService) { nsCOMPtr prefBranch; @@ -390,10 +356,6 @@ nsStandardURL::InitGlobalObjects() void nsStandardURL::ShutdownGlobalObjects() { - NS_IF_RELEASE(gIOService); - NS_IF_RELEASE(gNoAuthParser); - NS_IF_RELEASE(gAuthParser); - NS_IF_RELEASE(gStdParser); NS_IF_RELEASE(gIDNService); NS_IF_RELEASE(gCharsetMgr); } @@ -453,7 +415,7 @@ nsStandardURL::EncodeHost(const char *host, nsCString &result) void nsStandardURL::CoalescePath(char *path) { - CoalesceDirsAbs(path); + net_CoalesceDirsAbs(path); PRInt32 newLen = strlen(path); if (newLen < mPath.mLen) { PRInt32 diff = newLen - mPath.mLen; @@ -549,7 +511,7 @@ nsStandardURL::BuildNormalizedSpec(const char *spec) if (mScheme.mLen > 0) { i = AppendSegmentToBuf(buf, i, spec, mScheme); - ToLowerCase(buf + mScheme.mPos, mScheme.mLen); + net_ToLowerCase(buf + mScheme.mPos, mScheme.mLen); i = AppendToBuf(buf, i, "://", 3); } @@ -567,7 +529,7 @@ nsStandardURL::BuildNormalizedSpec(const char *spec) } if (mHost.mLen > 0) { i = AppendSegmentToBuf(buf, i, spec, mHost); - ToLowerCase(buf + mHost.mPos, mHost.mLen); + net_ToLowerCase(buf + mHost.mPos, mHost.mLen); if (mPort != -1 && mPort != mDefaultPort) { nsCAutoString portbuf; portbuf.AppendInt(mPort); @@ -1087,7 +1049,7 @@ nsStandardURL::SetScheme(const nsACString &input) return NS_ERROR_NOT_INITIALIZED; } - if (!IsValidScheme(scheme)) { + if (!net_IsValidScheme(scheme)) { NS_ERROR("the given url scheme contains invalid characters"); return NS_ERROR_UNEXPECTED; } @@ -1105,7 +1067,7 @@ nsStandardURL::SetScheme(const nsACString &input) // // XXX the string code unfortunately doesn't provide a ToLowerCase // that operates on a substring. - ToLowerCase((char *) mSpec.get(), mScheme.mLen); + net_ToLowerCase((char *) mSpec.get(), mScheme.mLen); return NS_OK; } @@ -1542,7 +1504,7 @@ nsStandardURL::Resolve(const nsACString &in, nsACString &out) LOG(("nsStandardURL::Resolve [this=%p spec=%s relpath=%s]\n", this, mSpec.get(), relpath)); - NS_ASSERTION(gNoAuthParser, "no parser: unitialized"); + NS_ASSERTION(mParser, "no parser: unitialized"); // NOTE: there is no need for this function to produce normalized // output. normalization will occur when the result is used to @@ -1562,10 +1524,10 @@ nsStandardURL::Resolve(const nsACString &in, nsACString &out) // relative urls should never contain a host, so we always want to use // the noauth url parser. // use it to extract a possible scheme - rv = gNoAuthParser->ParseURL(relpath, flat.Length(), - &scheme.mPos, &scheme.mLen, - nsnull, nsnull, - nsnull, nsnull); + rv = mParser->ParseURL(relpath, flat.Length(), + &scheme.mPos, &scheme.mLen, + nsnull, nsnull, + nsnull, nsnull); // if the parser fails (for example because there is no valid scheme) // reset the scheme and assume a relative url @@ -1638,14 +1600,14 @@ nsStandardURL::Resolve(const nsACString &in, nsACString &out) return NS_ERROR_OUT_OF_MEMORY; if (resultPath) - CoalesceDirsRel(resultPath); + net_CoalesceDirsRel(resultPath); else { // locate result path resultPath = PL_strstr(*result, "://"); if (resultPath) { resultPath = PL_strchr(resultPath + 3, '/'); if (resultPath) - CoalesceDirsRel(resultPath); + net_CoalesceDirsRel(resultPath); } } // XXX avoid extra copy @@ -1888,10 +1850,10 @@ nsStandardURL::SetFilePath(const nsACString &input) PRInt32 dirLen, baseLen, extLen; nsresult rv; - rv = gNoAuthParser->ParseFilePath(filepath, -1, - &dirPos, &dirLen, - &basePos, &baseLen, - &extPos, &extLen); + rv = mParser->ParseFilePath(filepath, -1, + &dirPos, &dirLen, + &basePos, &baseLen, + &extPos, &extLen); if (NS_FAILED(rv)) return rv; // build up new candidate spec @@ -2110,9 +2072,9 @@ nsStandardURL::SetFileName(const nsACString &input) URLSegment basename, extension; // let the parser locate the basename and extension - rv = gNoAuthParser->ParseFileName(filename, -1, - &basename.mPos, &basename.mLen, - &extension.mPos, &extension.mLen); + rv = mParser->ParseFileName(filename, -1, + &basename.mPos, &basename.mLen, + &extension.mPos, &extension.mLen); if (NS_FAILED(rv)) return rv; if (basename.mLen < 0) { @@ -2207,7 +2169,7 @@ nsStandardURL::GetFile(nsIFile **result) return NS_ERROR_FAILURE; } - nsresult rv = gIOService->GetFileFromURLSpec(mSpec, result); + nsresult rv = net_GetFileFromURLSpec(mSpec, result); // XXX ultimately, we should probably cache this result to speed // up subsequent calls, but past attempts to do so have been @@ -2240,7 +2202,7 @@ nsStandardURL::SetFile(nsIFile *file) nsresult rv; nsCAutoString url; - rv = gIOService->GetURLSpecFromFile(file, url); + rv = net_GetURLSpecFromFile(file, url); if (NS_FAILED(rv)) return rv; rv = SetSpec(url); @@ -2274,13 +2236,13 @@ nsStandardURL::Init(PRUint32 urlType, switch (urlType) { case URLTYPE_STANDARD: - mParser = gStdParser; + mParser = net_GetStdURLParser(); break; case URLTYPE_AUTHORITY: - mParser = gAuthParser; + mParser = net_GetAuthURLParser(); break; case URLTYPE_NO_AUTHORITY: - mParser = gNoAuthParser; + mParser = net_GetNoAuthURLParser(); break; default: NS_NOTREACHED("bad urlType"); @@ -2309,11 +2271,11 @@ nsStandardURL::Init(PRUint32 urlType, if (baseURI) { PRUint32 start, end; // pull out the scheme and where it ends - nsresult rv = ExtractURLScheme(spec, &start, &end, nsnull); - if (NS_SUCCEEDED(rv) && spec.Length() > end+1) { + nsresult rv = net_ExtractURLScheme(spec, &start, &end, nsnull); + if (NS_SUCCEEDED(rv) && spec.Length() > end+2) { nsACString::const_iterator slash; spec.BeginReading(slash); - slash.advance(end); + slash.advance(end+1); // then check if // follows // if it follows, aSpec is really absolute ... // ignore aBaseURI in this case @@ -2360,13 +2322,13 @@ nsStandardURL::Read(nsIObjectInputStream *stream) if (NS_FAILED(rv)) return rv; switch (mURLType) { case URLTYPE_STANDARD: - mParser = gStdParser; + mParser = net_GetStdURLParser(); break; case URLTYPE_AUTHORITY: - mParser = gAuthParser; + mParser = net_GetAuthURLParser(); break; case URLTYPE_NO_AUTHORITY: - mParser = gNoAuthParser; + mParser = net_GetNoAuthURLParser(); break; default: NS_NOTREACHED("bad urlType"); diff --git a/netwerk/base/src/nsStandardURL.h b/netwerk/base/src/nsStandardURL.h index 585208ce1f4c..45e1f3f45a9e 100644 --- a/netwerk/base/src/nsStandardURL.h +++ b/netwerk/base/src/nsStandardURL.h @@ -240,10 +240,6 @@ private: // global objects. don't use COMPtr as its destructor will cause a // coredump if we leak it. - static nsIIOService *gIOService; - static nsIURLParser *gNoAuthParser; - static nsIURLParser *gAuthParser; - static nsIURLParser *gStdParser; static nsIIDNService *gIDNService; static nsICharsetConverterManager2 *gCharsetMgr; static PRBool gInitialized; diff --git a/netwerk/base/src/nsURLHelper.cpp b/netwerk/base/src/nsURLHelper.cpp index af14340b5a0f..8de2b366790d 100644 --- a/netwerk/base/src/nsURLHelper.cpp +++ b/netwerk/base/src/nsURLHelper.cpp @@ -20,6 +20,7 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): + * Darin Fisher * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or @@ -36,22 +37,178 @@ * ***** END LICENSE BLOCK ***** */ #include "nsURLHelper.h" -#include "prprf.h" -#include "nsCRT.h" -#include "nsMemory.h" +#include "nsIServiceManager.h" #include "nsIIOService.h" +#include "nsIURLParser.h" #include "nsIURI.h" +#include "nsMemory.h" #include "nsEscape.h" +#include "nsCOMPtr.h" +#include "nsCRT.h" +#include "nsNetCID.h" #include "netCore.h" +#include "prprf.h" #if defined(XP_WIN) #include // ::IsDBCSLeadByte need #endif +//---------------------------------------------------------------------------- +// Init/Shutdown +//---------------------------------------------------------------------------- + +static PRBool gInitialized = PR_FALSE; +static nsIURLParser *gNoAuthURLParser = nsnull; +static nsIURLParser *gAuthURLParser = nsnull; +static nsIURLParser *gStdURLParser = nsnull; + +static void +InitGlobals() +{ + nsCOMPtr parser; + + parser = do_GetService(NS_NOAUTHURLPARSER_CONTRACTID); + NS_ASSERTION(parser, "failed getting 'noauth' url parser"); + if (parser) { + gNoAuthURLParser = parser.get(); + NS_ADDREF(gNoAuthURLParser); + } + + parser = do_GetService(NS_AUTHURLPARSER_CONTRACTID); + NS_ASSERTION(parser, "failed getting 'auth' url parser"); + if (parser) { + gAuthURLParser = parser.get(); + NS_ADDREF(gAuthURLParser); + } + + parser = do_GetService(NS_STDURLPARSER_CONTRACTID); + NS_ASSERTION(parser, "failed getting 'std' url parser"); + if (parser) { + gStdURLParser = parser.get(); + NS_ADDREF(gStdURLParser); + } + + gInitialized = PR_TRUE; +} + +void +net_ShutdownURLHelper() +{ + if (gInitialized) { + NS_IF_RELEASE(gNoAuthURLParser); + NS_IF_RELEASE(gAuthURLParser); + NS_IF_RELEASE(gStdURLParser); + gInitialized = PR_FALSE; + } +} + +//---------------------------------------------------------------------------- +// nsIURLParser getters +//---------------------------------------------------------------------------- + +nsIURLParser * +net_GetAuthURLParser() +{ + if (!gInitialized) + InitGlobals(); + return gAuthURLParser; +} + +nsIURLParser * +net_GetNoAuthURLParser() +{ + if (!gInitialized) + InitGlobals(); + return gNoAuthURLParser; +} + +nsIURLParser * +net_GetStdURLParser() +{ + if (!gInitialized) + InitGlobals(); + return gStdURLParser; +} + +//---------------------------------------------------------------------------- +// file:// URL parsing +//---------------------------------------------------------------------------- + +nsresult +net_ParseFileURL(const nsACString &inURL, + nsACString &outDirectory, + nsACString &outFileBaseName, + nsACString &outFileExtension) +{ + nsresult rv; + + outDirectory.Truncate(); + outFileBaseName.Truncate(); + outFileExtension.Truncate(); + + // XXX optimization: no need to copy scheme + PRUint32 schemeBeg, schemeEnd; + rv = net_ExtractURLScheme(inURL, &schemeBeg, &schemeEnd, nsnull); + if (NS_FAILED(rv)) return rv; + + if (Substring(inURL, schemeBeg, schemeBeg + schemeEnd) != NS_LITERAL_CSTRING("file")) { + NS_ERROR("must be a file:// url"); + return NS_ERROR_UNEXPECTED; + } + + const nsPromiseFlatCString &flatURL = PromiseFlatCString(inURL); + const char *url = flatURL.get(); + + nsIURLParser *parser = net_GetNoAuthURLParser(); + NS_ENSURE_TRUE(parser, NS_ERROR_UNEXPECTED); + + PRUint32 pathPos, filepathPos, directoryPos, basenamePos, extensionPos; + PRInt32 pathLen, filepathLen, directoryLen, basenameLen, extensionLen; + + // invoke the parser to extract the URL path + rv = parser->ParseURL(url, flatURL.Length(), + nsnull, nsnull, // dont care about scheme + nsnull, nsnull, // dont care about authority + &pathPos, &pathLen); + if (NS_FAILED(rv)) return rv; + + // invoke the parser to extract filepath from the path + rv = parser->ParsePath(url + pathPos, pathLen, + &filepathPos, &filepathLen, + nsnull, nsnull, // dont care about param + nsnull, nsnull, // dont care about query + nsnull, nsnull); // dont care about ref + if (NS_FAILED(rv)) return rv; + + filepathPos += pathPos; + + // invoke the parser to extract the directory and filename from filepath + rv = parser->ParseFilePath(url + filepathPos, filepathLen, + &directoryPos, &directoryLen, + &basenamePos, &basenameLen, + &extensionPos, &extensionLen); + if (NS_FAILED(rv)) return rv; + + if (directoryLen > 0) + outDirectory = Substring(inURL, filepathPos + directoryPos, directoryLen); + if (basenameLen > 0) + outFileBaseName = Substring(inURL, filepathPos + basenamePos, basenameLen); + if (extensionLen > 0) + outFileExtension = Substring(inURL, filepathPos + extensionPos, extensionLen); + // since we are using a no-auth url parser, there will never be a host + // XXX not strictly true... file://localhost/foo/bar.html is a valid URL + + return NS_OK; +} + +//---------------------------------------------------------------------------- +// path manipulation functions +//---------------------------------------------------------------------------- + // Replace all /./ with a / while resolving relative URLs // But only till #? void -CoalesceDirsRel(char* io_Path) +net_CoalesceDirsRel(char* io_Path) { /* Stolen from the old netlib's mkparse.c. * @@ -125,7 +282,7 @@ CoalesceDirsRel(char* io_Path) // Replace all /./ with a / while resolving absolute URLs // But only till #? void -CoalesceDirsAbs(char* io_Path) +net_CoalesceDirsAbs(char* io_Path) { /* Stolen from the old netlib's mkparse.c. * @@ -214,97 +371,10 @@ CoalesceDirsAbs(char* io_Path) *(urlPtr-1) = '\0'; } -static inline -void ToLower(char &c) -{ - if ((unsigned)(c - 'A') <= (unsigned)('Z' - 'A')) - c += 'a' - 'A'; -} - -void -ToLowerCase(char *str, PRUint32 length) -{ - for (char *end = str + length; str < end; ++str) - ToLower(*str); -} - -void -ToLowerCase(char *str) -{ - for (; *str; ++str) - ToLower(*str); -} - -/* Extract URI-Scheme if possible */ -nsresult ExtractURLScheme(const nsACString &inURI, PRUint32 *startPos, - PRUint32 *endPos, nsACString *scheme) -{ - // search for something up to a colon, and call it the scheme - const nsPromiseFlatCString flatURI( PromiseFlatCString(inURI) ); - const char* uri_start = flatURI.get(); - const char* uri = uri_start; - - // skip leading white space - while (nsCRT::IsAsciiSpace(*uri)) - uri++; - - PRUint32 start = uri - uri_start; - if (startPos) { - *startPos = start; - } - - PRUint32 length = 0; - char c; - while ((c = *uri++) != '\0') { - // First char must be Alpha - if (length == 0 && nsCRT::IsAsciiAlpha(c)) { - length++; - } - // Next chars can be alpha + digit + some special chars - else if (length > 0 && (nsCRT::IsAsciiAlpha(c) || - nsCRT::IsAsciiDigit(c) || c == '+' || - c == '.' || c == '-')) { - length++; - } - // stop if colon reached but not as first char - else if (c == ':' && length > 0) { - if (endPos) { - *endPos = start + length + 1; - } - - if (scheme) - scheme->Assign(Substring(inURI, start, length)); - return NS_OK; - } - else - break; - } - return NS_ERROR_MALFORMED_URI; -} - -PRBool -IsValidScheme(const char *scheme, PRUint32 schemeLen) -{ - // first char much be alpha - if (!nsCRT::IsAsciiAlpha(*scheme)) - return PR_FALSE; - - for (; schemeLen && *scheme; ++scheme, --schemeLen) { - if (!(nsCRT::IsAsciiAlpha(*scheme) || - nsCRT::IsAsciiDigit(*scheme) || - *scheme == '+' || - *scheme == '.' || - *scheme == '-')) - return PR_FALSE; - } - - return PR_TRUE; -} - nsresult -ResolveRelativePath(const nsACString &relativePath, - const nsACString &basePath, - nsACString &result) +net_ResolveRelativePath(const nsACString &relativePath, + const nsACString &basePath, + nsACString &result) { nsCAutoString name; nsCAutoString path(basePath); @@ -370,3 +440,101 @@ ResolveRelativePath(const nsACString &relativePath, result = path; return NS_OK; } + +//---------------------------------------------------------------------------- +// scheme fu +//---------------------------------------------------------------------------- + +/* Extract URI-Scheme if possible */ +nsresult +net_ExtractURLScheme(const nsACString &inURI, + PRUint32 *startPos, + PRUint32 *endPos, + nsACString *scheme) +{ + // search for something up to a colon, and call it the scheme + const nsPromiseFlatCString flatURI( PromiseFlatCString(inURI) ); + const char* uri_start = flatURI.get(); + const char* uri = uri_start; + + // skip leading white space + while (nsCRT::IsAsciiSpace(*uri)) + uri++; + + PRUint32 start = uri - uri_start; + if (startPos) { + *startPos = start; + } + + PRUint32 length = 0; + char c; + while ((c = *uri++) != '\0') { + // First char must be Alpha + if (length == 0 && nsCRT::IsAsciiAlpha(c)) { + length++; + } + // Next chars can be alpha + digit + some special chars + else if (length > 0 && (nsCRT::IsAsciiAlpha(c) || + nsCRT::IsAsciiDigit(c) || c == '+' || + c == '.' || c == '-')) { + length++; + } + // stop if colon reached but not as first char + else if (c == ':' && length > 0) { + if (endPos) { + *endPos = start + length; + } + + if (scheme) + scheme->Assign(Substring(inURI, start, length)); + return NS_OK; + } + else + break; + } + return NS_ERROR_MALFORMED_URI; +} + +PRBool +net_IsValidScheme(const char *scheme, PRUint32 schemeLen) +{ + // first char much be alpha + if (!nsCRT::IsAsciiAlpha(*scheme)) + return PR_FALSE; + + for (; schemeLen && *scheme; ++scheme, --schemeLen) { + if (!(nsCRT::IsAsciiAlpha(*scheme) || + nsCRT::IsAsciiDigit(*scheme) || + *scheme == '+' || + *scheme == '.' || + *scheme == '-')) + return PR_FALSE; + } + + return PR_TRUE; +} + +//---------------------------------------------------------------------------- +// miscellaneous (i.e., stuff that should really be elsewhere) +//---------------------------------------------------------------------------- + +static inline +void ToLower(char &c) +{ + if ((unsigned)(c - 'A') <= (unsigned)('Z' - 'A')) + c += 'a' - 'A'; +} + +void +net_ToLowerCase(char *str, PRUint32 length) +{ + for (char *end = str + length; str < end; ++str) + ToLower(*str); +} + +void +net_ToLowerCase(char *str) +{ + for (; *str; ++str) + ToLower(*str); +} diff --git a/netwerk/base/src/nsURLHelper.h b/netwerk/base/src/nsURLHelper.h index 3dcfd5261d44..236939771bb7 100644 --- a/netwerk/base/src/nsURLHelper.h +++ b/netwerk/base/src/nsURLHelper.h @@ -35,35 +35,41 @@ * * ***** END LICENSE BLOCK ***** */ -#ifndef _nsURLHelper_h_ -#define _nsURLHelper_h_ +#ifndef nsURLHelper_h__ +#define nsURLHelper_h__ -#include "prtypes.h" -#include "nscore.h" -#include "nsCRT.h" #include "nsString.h" +class nsIFile; +class nsIURLParser; + +//---------------------------------------------------------------------------- +// This module contains some private helper functions related to URL parsing. +//---------------------------------------------------------------------------- + +/* shutdown frees URL parser */ +void net_ShutdownURLHelper(); + +/* access URL parsers */ +nsIURLParser *net_GetAuthURLParser(); +nsIURLParser *net_GetNoAuthURLParser(); +nsIURLParser *net_GetStdURLParser(); + +/* convert between nsIFile and file:// URL spec */ +nsresult net_GetURLSpecFromFile(nsIFile *, nsACString &); +nsresult net_GetFileFromURLSpec(const nsACString &, nsIFile **); + +/* extract file path components from file:// URL */ +nsresult net_ParseFileURL(const nsACString &inURL, + nsACString &outDirectory, + nsACString &outFileBaseName, + nsACString &outFileExtension); + /* handle .. in dirs while resolving relative URLs */ -void CoalesceDirsRel(char* io_Path); +void net_CoalesceDirsRel(char* io_Path); /* handle .. in dirs while resolving absolute URLs */ -void CoalesceDirsAbs(char* io_Path); - -/* convert to lower case */ -void ToLowerCase(char* str, PRUint32 length); -void ToLowerCase(char* str); - -/* Extract URI-Scheme if possible */ -nsresult ExtractURLScheme(const nsACString &inURI, PRUint32 *startPos, - PRUint32 *endPos, nsACString *scheme = nsnull); - -/* check that the given scheme conforms to RFC 2396 */ -PRBool IsValidScheme(const char *scheme, PRUint32 schemeLen); - -inline PRBool IsValidScheme(const nsAFlatCString &scheme) -{ - return IsValidScheme(scheme.get(), scheme.Length()); -} +void net_CoalesceDirsAbs(char* io_Path); /** * Resolves a relative path string containing "." and ".." @@ -78,8 +84,33 @@ inline PRBool IsValidScheme(const nsAFlatCString &scheme) * * @return a new string, representing canonical uri */ -nsresult ResolveRelativePath(const nsACString &relativePath, - const nsACString &basePath, - nsACString &result); +nsresult net_ResolveRelativePath(const nsACString &relativePath, + const nsACString &basePath, + nsACString &result); -#endif +/** + * Extract URI-Scheme if possible + * + * @param inURI URI spec + * @param startPos start of scheme (may be null) + * @param endPos end of scheme; index of colon (may be null) + * @param scheme scheme copied to this buffer on return (may be null) + */ +nsresult net_ExtractURLScheme(const nsACString &inURI, + PRUint32 *startPos, + PRUint32 *endPos, + nsACString *scheme = nsnull); + +/* check that the given scheme conforms to RFC 2396 */ +PRBool net_IsValidScheme(const char *scheme, PRUint32 schemeLen); + +inline PRBool net_IsValidScheme(const nsAFlatCString &scheme) +{ + return net_IsValidScheme(scheme.get(), scheme.Length()); +} + +/* convert to lower case (XXX this needs to be factored out) */ +void net_ToLowerCase(char* str, PRUint32 length); +void net_ToLowerCase(char* str); + +#endif // !nsURLHelper_h__ diff --git a/netwerk/base/src/nsIOServiceMac.cpp b/netwerk/base/src/nsURLHelperMac.cpp similarity index 94% rename from netwerk/base/src/nsIOServiceMac.cpp rename to netwerk/base/src/nsURLHelperMac.cpp index f23422d01fab..c14c1b5cc68e 100644 --- a/netwerk/base/src/nsIOServiceMac.cpp +++ b/netwerk/base/src/nsURLHelperMac.cpp @@ -38,7 +38,7 @@ * ***** END LICENSE BLOCK ***** */ /* Mac-specific local file url parsing */ -#include "nsIOService.h" +#include "nsURLHelper.h" #include "nsEscape.h" #include "nsILocalFile.h" @@ -65,8 +65,8 @@ static void PascalStringCopy(Str255 dst, const char *src) } -NS_IMETHODIMP -nsIOService::GetURLSpecFromFile(nsIFile *aFile, nsACString &aURL) +nsresult +net_GetURLSpecFromFile(nsIFile *aFile, nsACString &aURL) { nsresult rv; NS_ENSURE_ARG(aFile); @@ -109,8 +109,8 @@ nsIOService::GetURLSpecFromFile(nsIFile *aFile, nsACString &aURL) return NS_OK; } -NS_IMETHODIMP -nsIOService::GetFileFromURLSpec(const nsACString &aURL, nsIFile **result) +nsresult +net_GetFileFromURLSpec(const nsACString &aURL, nsIFile **result) { nsresult rv; @@ -123,7 +123,7 @@ nsIOService::GetFileFromURLSpec(const nsACString &aURL, nsIFile **result) nsCAutoString directory, fileBaseName, fileExtension; - rv = ParseFileURL(aURL, directory, fileBaseName, fileExtension); + rv = net_ParseFileURL(aURL, directory, fileBaseName, fileExtension); if (NS_FAILED(rv)) return rv; nsCAutoString path; diff --git a/netwerk/base/src/nsIOServiceOS2.cpp b/netwerk/base/src/nsURLHelperOS2.cpp similarity index 95% rename from netwerk/base/src/nsIOServiceOS2.cpp rename to netwerk/base/src/nsURLHelperOS2.cpp index 55f3f6ec386b..538d4c639a06 100644 --- a/netwerk/base/src/nsIOServiceOS2.cpp +++ b/netwerk/base/src/nsURLHelperOS2.cpp @@ -40,14 +40,14 @@ /* OS/2-specific local file uri parsing */ #define INCL_DOSERRORS #define INCL_DOS -#include "nsIOService.h" +#include "nsURLHelper.h" #include "nsEscape.h" #include "nsILocalFile.h" static int isleadbyte(int c); -NS_IMETHODIMP -nsIOService::GetURLSpecFromFile(nsIFile *aFile, nsACString &result) +nsresult +net_GetURLSpecFromFile(nsIFile *aFile, nsACString &result) { nsresult rv; nsCAutoString ePath; @@ -95,8 +95,8 @@ nsIOService::GetURLSpecFromFile(nsIFile *aFile, nsACString &result) return NS_OK; } -NS_IMETHODIMP -nsIOService::GetFileFromURLSpec(const nsACString &aURL, nsIFile **result) +nsresult +net_GetFileFromURLSpec(const nsACString &aURL, nsIFile **result) { nsresult rv; @@ -109,7 +109,7 @@ nsIOService::GetFileFromURLSpec(const nsACString &aURL, nsIFile **result) nsCAutoString directory, fileBaseName, fileExtension; - rv = ParseFileURL(aURL, directory, fileBaseName, fileExtension); + rv = net_ParseFileURL(aURL, directory, fileBaseName, fileExtension); if (NS_FAILED(rv)) return rv; nsCAutoString path; diff --git a/netwerk/base/src/nsIOServiceUnix.cpp b/netwerk/base/src/nsURLHelperUnix.cpp similarity index 93% rename from netwerk/base/src/nsIOServiceUnix.cpp rename to netwerk/base/src/nsURLHelperUnix.cpp index b1d15e3eac46..9beb1bbe7132 100644 --- a/netwerk/base/src/nsIOServiceUnix.cpp +++ b/netwerk/base/src/nsURLHelperUnix.cpp @@ -38,12 +38,12 @@ * ***** END LICENSE BLOCK ***** */ /* Unix-specific local file uri parsing */ -#include "nsIOService.h" +#include "nsURLHelper.h" #include "nsEscape.h" #include "nsILocalFile.h" -NS_IMETHODIMP -nsIOService::GetURLSpecFromFile(nsIFile *aFile, nsACString &result) +nsresult +net_GetURLSpecFromFile(nsIFile *aFile, nsACString &result) { nsresult rv; nsCAutoString ePath; @@ -79,8 +79,8 @@ nsIOService::GetURLSpecFromFile(nsIFile *aFile, nsACString &result) return NS_OK; } -NS_IMETHODIMP -nsIOService::GetFileFromURLSpec(const nsACString &aURL, nsIFile **result) +nsresult +net_GetFileFromURLSpec(const nsACString &aURL, nsIFile **result) { nsresult rv; @@ -93,7 +93,7 @@ nsIOService::GetFileFromURLSpec(const nsACString &aURL, nsIFile **result) nsCAutoString directory, fileBaseName, fileExtension, path; - rv = ParseFileURL(aURL, directory, fileBaseName, fileExtension); + rv = net_ParseFileURL(aURL, directory, fileBaseName, fileExtension); if (NS_FAILED(rv)) return rv; if (!directory.IsEmpty()) diff --git a/netwerk/base/src/nsIOServiceWin.cpp b/netwerk/base/src/nsURLHelperWin.cpp similarity index 94% rename from netwerk/base/src/nsIOServiceWin.cpp rename to netwerk/base/src/nsURLHelperWin.cpp index 182f19613b7e..3adc5ed11516 100644 --- a/netwerk/base/src/nsIOServiceWin.cpp +++ b/netwerk/base/src/nsURLHelperWin.cpp @@ -38,13 +38,13 @@ * ***** END LICENSE BLOCK ***** */ /* Windows-specific local file uri parsing */ -#include "nsIOService.h" +#include "nsURLHelper.h" #include "nsEscape.h" #include "nsILocalFile.h" #include -NS_IMETHODIMP -nsIOService::GetURLSpecFromFile(nsIFile *aFile, nsACString &result) +nsresult +net_GetURLSpecFromFile(nsIFile *aFile, nsACString &result) { nsresult rv; nsCAutoString ePath; @@ -92,8 +92,8 @@ nsIOService::GetURLSpecFromFile(nsIFile *aFile, nsACString &result) return NS_OK; } -NS_IMETHODIMP -nsIOService::GetFileFromURLSpec(const nsACString &aURL, nsIFile **result) +nsresult +net_GetFileFromURLSpec(const nsACString &aURL, nsIFile **result) { nsresult rv; @@ -106,7 +106,7 @@ nsIOService::GetFileFromURLSpec(const nsACString &aURL, nsIFile **result) nsCAutoString directory, fileBaseName, fileExtension; - rv = ParseFileURL(aURL, directory, fileBaseName, fileExtension); + rv = net_ParseFileURL(aURL, directory, fileBaseName, fileExtension); if (NS_FAILED(rv)) return rv; nsCAutoString path; diff --git a/netwerk/base/src/nsURLParsers.cpp b/netwerk/base/src/nsURLParsers.cpp index 83d939a2f8b3..d174806bf3c6 100644 --- a/netwerk/base/src/nsURLParsers.cpp +++ b/netwerk/base/src/nsURLParsers.cpp @@ -144,7 +144,7 @@ nsBaseURLParser::ParseURL(const char *spec, PRInt32 specLen, // spec = : // spec = : // - if (!IsValidScheme(spec, colon - spec) || (*(colon+1) == ':')) { + if (!net_IsValidScheme(spec, colon - spec) || (*(colon+1) == ':')) { NS_WARNING("malformed uri"); return NS_ERROR_MALFORMED_URI; } diff --git a/netwerk/build/nsNetModule.cpp b/netwerk/build/nsNetModule.cpp index f1554156143a..039ac028d742 100644 --- a/netwerk/build/nsNetModule.cpp +++ b/netwerk/build/nsNetModule.cpp @@ -147,71 +147,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsResumableEntityID) /////////////////////////////////////////////////////////////////////////////// -static NS_METHOD -RegisterBuiltInURLParsers(nsIComponentManager *aCompMgr, - nsIFile *aPath, - const char *registryLocation, - const char *componentType, - const nsModuleComponentInfo *info) -{ - nsresult rv; - nsCOMPtr catman = - do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv); - if (NS_FAILED(rv)) return rv; - - nsXPIDLCString previous; - - catman->AddCategoryEntry(NS_IURLPARSER_KEY, - "file", - NS_NOAUTHURLPARSER_CONTRACTID, - PR_TRUE, - PR_TRUE, - getter_Copies(previous)); - - catman->AddCategoryEntry(NS_IURLPARSER_KEY, - "ftp", - NS_AUTHURLPARSER_CONTRACTID, - PR_TRUE, - PR_TRUE, - getter_Copies(previous)); - - catman->AddCategoryEntry(NS_IURLPARSER_KEY, - "http", - NS_AUTHURLPARSER_CONTRACTID, - PR_TRUE, - PR_TRUE, - getter_Copies(previous)); - - catman->AddCategoryEntry(NS_IURLPARSER_KEY, - "https", - NS_AUTHURLPARSER_CONTRACTID, - PR_TRUE, - PR_TRUE, - getter_Copies(previous)); - return NS_OK; -} - -static NS_METHOD -UnregisterBuiltInURLParsers(nsIComponentManager *aCompMgr, - nsIFile *aPath, - const char *registryLocation, - const nsModuleComponentInfo *info) -{ - nsresult rv; - nsCOMPtr catman = - do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv); - if (NS_FAILED(rv)) return rv; - - catman->DeleteCategoryEntry(NS_IURLPARSER_KEY, "file", PR_TRUE); - catman->DeleteCategoryEntry(NS_IURLPARSER_KEY, "ftp", PR_TRUE); - catman->DeleteCategoryEntry(NS_IURLPARSER_KEY, "http", PR_TRUE); - catman->DeleteCategoryEntry(NS_IURLPARSER_KEY, "https", PR_TRUE); - - return NS_OK; -} - -/////////////////////////////////////////////////////////////////////////////// - #include "nsFileChannel.h" #include "nsFileProtocolHandler.h" #include "nsDataHandler.h" @@ -554,6 +489,9 @@ static void PR_CALLBACK nsNeckoShutdown(nsIModule *neckoModule) // Release buffer cache NS_IF_RELEASE(nsIOService::gBufferCache); + + // Release global state used by the URL helper module. + net_ShutdownURLHelper(); } static const nsModuleComponentInfo gNetModuleInfo[] = { @@ -671,9 +609,7 @@ static const nsModuleComponentInfo gNetModuleInfo[] = { { NS_STDURLPARSER_CLASSNAME, NS_STDURLPARSER_CID, NS_STDURLPARSER_CONTRACTID, - nsStdURLParserConstructor, - RegisterBuiltInURLParsers, - UnregisterBuiltInURLParsers}, + nsStdURLParserConstructor}, { NS_NOAUTHURLPARSER_CLASSNAME, NS_NOAUTHURLPARSER_CID, NS_NOAUTHURLPARSER_CONTRACTID, diff --git a/netwerk/macbuild/netwerk.xml b/netwerk/macbuild/netwerk.xml index 3ee812361a41..aa4ace9c62bc 100644 --- a/netwerk/macbuild/netwerk.xml +++ b/netwerk/macbuild/netwerk.xml @@ -1599,7 +1599,7 @@ Name - nsIOServiceMac.cpp + nsURLHelperMac.cpp MacOS Text Debug @@ -2065,7 +2065,7 @@ Name - nsIOServiceMac.cpp + nsURLHelperMac.cpp MacOS @@ -3621,7 +3621,7 @@ Name - nsIOServiceMac.cpp + nsURLHelperMac.cpp MacOS Text Debug @@ -4087,7 +4087,7 @@ Name - nsIOServiceMac.cpp + nsURLHelperMac.cpp MacOS @@ -5629,7 +5629,7 @@ Name - nsIOServiceMac.cpp + nsURLHelperMac.cpp MacOS Text Debug @@ -6085,7 +6085,7 @@ Name - nsIOServiceMac.cpp + nsURLHelperMac.cpp MacOS @@ -7627,7 +7627,7 @@ Name - nsIOServiceMac.cpp + nsURLHelperMac.cpp MacOS Text Debug @@ -8083,7 +8083,7 @@ Name - nsIOServiceMac.cpp + nsURLHelperMac.cpp MacOS @@ -8161,7 +8161,7 @@ Necko.shlb Name - nsIOServiceMac.cpp + nsURLHelperMac.cpp MacOS diff --git a/netwerk/protocol/file/public/nsIFileProtocolHandler.idl b/netwerk/protocol/file/public/nsIFileProtocolHandler.idl index 280b09fed6df..fc6bf2a10dbc 100644 --- a/netwerk/protocol/file/public/nsIFileProtocolHandler.idl +++ b/netwerk/protocol/file/public/nsIFileProtocolHandler.idl @@ -50,4 +50,20 @@ interface nsIFileProtocolHandler : nsIProtocolHandler * @return reference to a new nsIURI object */ nsIURI newFileURI(in nsIFile aFile); + + /** + * Converts the nsIFile to the corresponding URL string. NOTE: under + * some platforms this is a lossy conversion (e.g., Mac Carbon build). + * If the nsIFile is a local file, then the result will be a file:// + * URL string. + * + * The resulting string may contain URL-escaped characters. + */ + AUTF8String getURLSpecFromFile(in nsIFile file); + + /** + * Converts the URL string into the corresponding nsIFile if possible. + * A local file will be created if the URL string begins with file://. + */ + nsIFile getFileFromURLSpec(in AUTF8String url); }; diff --git a/netwerk/protocol/file/src/Makefile.in b/netwerk/protocol/file/src/Makefile.in index 4421193e6f2b..bdc214c2d9a7 100644 --- a/netwerk/protocol/file/src/Makefile.in +++ b/netwerk/protocol/file/src/Makefile.in @@ -44,6 +44,10 @@ CPPSRCS = \ # static lib. FORCE_STATIC_LIB = 1 +LOCAL_INCLUDES = \ + -I$(topsrcdir)/netwerk/base/src \ + $(NULL) + include $(topsrcdir)/config/rules.mk ifeq ($(OS_ARCH),WINNT) diff --git a/netwerk/protocol/file/src/nsFileProtocolHandler.cpp b/netwerk/protocol/file/src/nsFileProtocolHandler.cpp index b37173aa9232..73d442a4f98a 100644 --- a/netwerk/protocol/file/src/nsFileProtocolHandler.cpp +++ b/netwerk/protocol/file/src/nsFileProtocolHandler.cpp @@ -55,6 +55,7 @@ #include "nsAutoLock.h" #include "nsXPIDLString.h" #include "nsNetCID.h" +#include "nsURLHelper.h" static NS_DEFINE_CID(kStandardURLCID, NS_STANDARDURL_CID); static NS_DEFINE_CID(kPrefCID, NS_PREF_CID); @@ -204,3 +205,15 @@ nsFileProtocolHandler::NewFileURI(nsIFile *file, nsIURI **result) return CallQueryInterface(url, result); } + +NS_IMETHODIMP +nsFileProtocolHandler::GetURLSpecFromFile(nsIFile *aFile, nsACString &result) +{ + return net_GetURLSpecFromFile(aFile, result); +} + +NS_IMETHODIMP +nsFileProtocolHandler::GetFileFromURLSpec(const nsACString &aURL, nsIFile **result) +{ + return net_GetFileFromURLSpec(aURL, result); +} diff --git a/netwerk/protocol/http/src/nsHttp.h b/netwerk/protocol/http/src/nsHttp.h index f5b10208e3bb..11aeb4531541 100644 --- a/netwerk/protocol/http/src/nsHttp.h +++ b/netwerk/protocol/http/src/nsHttp.h @@ -123,14 +123,6 @@ struct nsHttp // utilities... //----------------------------------------------------------------------------- -static inline nsresult -DupString(const char *src, char **dst) -{ - NS_ENSURE_ARG_POINTER(dst); - *dst = PL_strdup(src); - return *dst ? NS_OK : NS_ERROR_OUT_OF_MEMORY; -} - static inline PRUint32 PRTimeToSeconds(PRTime t_usec) { diff --git a/netwerk/protocol/jar/src/nsJARURI.cpp b/netwerk/protocol/jar/src/nsJARURI.cpp index 6e0082c96208..22732c875413 100644 --- a/netwerk/protocol/jar/src/nsJARURI.cpp +++ b/netwerk/protocol/jar/src/nsJARURI.cpp @@ -96,7 +96,7 @@ nsJARURI::SetSpec(const nsACString &aSpec) if (NS_FAILED(rv)) return rv; nsCAutoString scheme; - rv = ::ExtractURLScheme(aSpec, nsnull, nsnull, &scheme); + rv = net_ExtractURLScheme(aSpec, nsnull, nsnull, &scheme); if (NS_FAILED(rv)) return rv; if (strcmp("jar", scheme.get()) != 0) @@ -127,9 +127,9 @@ nsJARURI::SetSpec(const nsACString &aSpec) while (*delim_end == '/') ++delim_end; - rv = ::ResolveRelativePath(Substring(delim_end, end), - NS_LITERAL_CSTRING(""), - mJAREntry); + rv = net_ResolveRelativePath(Substring(delim_end, end), + NS_LITERAL_CSTRING(""), + mJAREntry); return rv; } @@ -329,7 +329,7 @@ nsJARURI::Resolve(const nsACString &relativePath, nsACString &result) nsresult rv; nsCAutoString scheme; - rv = ::ExtractURLScheme(relativePath, nsnull, nsnull, &scheme); + rv = net_ExtractURLScheme(relativePath, nsnull, nsnull, &scheme); if (NS_SUCCEEDED(rv)) { // then aSpec is absolute result = relativePath; @@ -344,8 +344,8 @@ nsJARURI::Resolve(const nsACString &relativePath, nsACString &result) path = ""; nsCAutoString resolvedEntry; - rv = ::ResolveRelativePath(relativePath, path, - resolvedEntry); + rv = net_ResolveRelativePath(relativePath, path, + resolvedEntry); if (NS_FAILED(rv)) return rv; return FormatSpec(resolvedEntry, result); @@ -385,9 +385,9 @@ nsJARURI::SetJAREntry(const nsACString &entryPath) { mJAREntry.Truncate(); - return ::ResolveRelativePath(entryPath, - NS_LITERAL_CSTRING(""), - mJAREntry); + return net_ResolveRelativePath(entryPath, + NS_LITERAL_CSTRING(""), + mJAREntry); } //////////////////////////////////////////////////////////////////////////////// diff --git a/netwerk/protocol/res/src/nsResProtocolHandler.cpp b/netwerk/protocol/res/src/nsResProtocolHandler.cpp index e9213fa64d36..46108f25af9f 100644 --- a/netwerk/protocol/res/src/nsResProtocolHandler.cpp +++ b/netwerk/protocol/res/src/nsResProtocolHandler.cpp @@ -49,6 +49,7 @@ #include "nsIFile.h" #include "nsDirectoryServiceDefs.h" #include "nsNetUtil.h" +#include "nsURLHelper.h" static nsResProtocolHandler *gResHandler = nsnull; @@ -91,7 +92,7 @@ nsResURL::GetFile(nsIFile **result) rv = gResHandler->ResolveURI(this, spec); if (NS_FAILED(rv)) return rv; - return NS_GetFileFromURLSpec(spec, result, gResHandler->mIOService); + return net_GetFileFromURLSpec(spec, result); } //---------------------------------------------------------------------------- diff --git a/netwerk/streamconv/converters/nsIndexedToHTML.cpp b/netwerk/streamconv/converters/nsIndexedToHTML.cpp index b2f8fc395514..c956587be9e7 100644 --- a/netwerk/streamconv/converters/nsIndexedToHTML.cpp +++ b/netwerk/streamconv/converters/nsIndexedToHTML.cpp @@ -44,6 +44,7 @@ #include "nsIDirIndex.h" #include "prtime.h" #include "nsDateTimeFormatCID.h" +#include "nsURLHelper.h" #include "nsCRT.h" NS_IMPL_THREADSAFE_ISUPPORTS4(nsIndexedToHTML, @@ -208,7 +209,7 @@ nsIndexedToHTML::OnStartRequest(nsIRequest* request, nsISupports *aContext) { if (NS_FAILED(rv)) return rv; nsCAutoString url; - rv = NS_GetURLSpecFromFile(file, url); + rv = net_GetURLSpecFromFile(file, url); if (NS_FAILED(rv)) return rv; baseUri.Assign(url); @@ -216,7 +217,7 @@ nsIndexedToHTML::OnStartRequest(nsIRequest* request, nsISupports *aContext) { rv = file->GetParent(getter_AddRefs(parent)); if (parent && NS_SUCCEEDED(rv)) { - NS_GetURLSpecFromFile(parent, url); + net_GetURLSpecFromFile(parent, url); if (NS_FAILED(rv)) return rv; parentStr.Assign(url); } diff --git a/xpfe/components/bookmarks/resources/addBookmark.js b/xpfe/components/bookmarks/resources/addBookmark.js index 25b645d3c80c..fc10552e4f8f 100644 --- a/xpfe/components/bookmarks/resources/addBookmark.js +++ b/xpfe/components/bookmarks/resources/addBookmark.js @@ -281,7 +281,9 @@ function getNormalizedURL(url) kLF.initWithPath(url); if (kLF.exists()) { var ioService = Components.classes["@mozilla.org/network/io-service;1"] - .getService(Components.classes.nsIIOService); + .getService(Components.interfaces.nsIIOService); + var fileHandler = ioService.getProtocolHandler("file") + .QueryInterface(Components.interfaces.nsIFileProtocolHandler); url = ioService.getURLSpecFromFile(kLF); } diff --git a/xpfe/components/prefwindow/resources/content/pref-applications-edit.xul b/xpfe/components/prefwindow/resources/content/pref-applications-edit.xul index 8fc759908788..5aed2dfe8bee 100644 --- a/xpfe/components/prefwindow/resources/content/pref-applications-edit.xul +++ b/xpfe/components/prefwindow/resources/content/pref-applications-edit.xul @@ -183,7 +183,8 @@ fileLocator = fileLocator.QueryInterface(Components.interfaces.nsIProperties); var file = fileLocator.get(mimeTypes, Components.interfaces.nsIFile); var ioService = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService); - gDS = gRDF.GetDataSource(ioService.getURLSpecFromFile(file)); + var fileHandler = ioService.getProtocolHandler("file").QueryInterface(Components.interfaces.nsIFileProtocolHandler); + gDS = gRDF.GetDataSource(fileHandler.getURLSpecFromFile(file)); } function onAccept() diff --git a/xpfe/components/prefwindow/resources/content/pref-applications-new.js b/xpfe/components/prefwindow/resources/content/pref-applications-new.js index 910905ca8536..62ba15c0f7bc 100644 --- a/xpfe/components/prefwindow/resources/content/pref-applications-new.js +++ b/xpfe/components/prefwindow/resources/content/pref-applications-new.js @@ -99,8 +99,9 @@ function onOK() var file = fileLocator.get(mimeTypes, Components.interfaces.nsIFile); var ioService = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService); + var fileHandler = ioService.getProtocolHandler("file").QueryInterface(Components.interfaces.nsIFileProtocolHandler); - gDS = gRDF.GetDataSource(ioService.getURLSpecFromFile(file)); + gDS = gRDF.GetDataSource(fileHandler.getURLSpecFromFile(file)); gMIMEField.value = gMIMEField.value.toLowerCase(); diff --git a/xpfe/components/prefwindow/resources/content/pref-applications.js b/xpfe/components/prefwindow/resources/content/pref-applications.js index e0d38ed12783..5104f4ed3554 100644 --- a/xpfe/components/prefwindow/resources/content/pref-applications.js +++ b/xpfe/components/prefwindow/resources/content/pref-applications.js @@ -89,8 +89,9 @@ function Startup() var file = fileLocator.get(mimeTypes, Components.interfaces.nsIFile); var ioService = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService); - dump("spec is " + ioService.getURLSpecFromFile(file)); - gDS = gRDF.GetDataSource(ioService.getURLSpecFromFile(file)); + var fileHandler = ioService.getProtocolHandler("file").QueryInterface(Components.interfaces.nsIFileProtocolHandler); + dump("spec is " + fileHandler.getURLSpecFromFile(file)); + gDS = gRDF.GetDataSource(fileHandler.getURLSpecFromFile(file)); // intialize the listbox gList.database.AddDataSource(gDS); diff --git a/xpfe/components/sidebar/resources/sidebarOverlay.js b/xpfe/components/sidebar/resources/sidebarOverlay.js index a8fcd3afe6a8..194f7198e50a 100644 --- a/xpfe/components/sidebar/resources/sidebarOverlay.js +++ b/xpfe/components/sidebar/resources/sidebarOverlay.js @@ -868,8 +868,9 @@ function get_sidebar_datasource_uri() { var sidebar_file = sidebar_get_panels_file(); var ioService = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService); + var fileHandler = ioService.getProtocolHandler("file").QueryInterface(Components.interfaces.nsIFileProtocolHandler); - return ioService.getURLSpecFromFile(sidebar_file); + return fileHandler.getURLSpecFromFile(sidebar_file); } catch (ex) { // This should not happen debug("Error: Unable to load panels file.\n"); diff --git a/xpfe/components/sidebar/src/nsSidebar.js b/xpfe/components/sidebar/src/nsSidebar.js index 672f00ebb5c0..f1e2904344c0 100644 --- a/xpfe/components/sidebar/src/nsSidebar.js +++ b/xpfe/components/sidebar/src/nsSidebar.js @@ -429,7 +429,8 @@ function getSidebarDatasourceURI(panels_file_id) } var io_service = Components.classes[IO_SERV_CONTRACTID].getService(Components.interfaces.nsIIOService); - var sidebar_uri = io_service.getURLSpecFromFile(sidebar_file); + var file_handler = io_service.getProtocolHandler("file").QueryInterface(Components.interfaces.nsIFileProtocolHandler); + var sidebar_uri = file_handler.getURLSpecFromFile(sidebar_file); debug("sidebar uri is " + sidebar_uri); return sidebar_uri; }