1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/netwerk/protocol/file/nsFileProtocolHandler.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,252 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +// vim:ts=4 sw=4 sts=4 et cin: 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "nsFileProtocolHandler.h" 1.11 +#include "nsFileChannel.h" 1.12 +#include "nsStandardURL.h" 1.13 +#include "nsURLHelper.h" 1.14 + 1.15 +#include "nsNetUtil.h" 1.16 + 1.17 +// URL file handling, copied and modified from xpfe/components/bookmarks/src/nsBookmarksService.cpp 1.18 +#ifdef XP_WIN 1.19 +#include <shlobj.h> 1.20 +#include <intshcut.h> 1.21 +#include "nsIFileURL.h" 1.22 +#ifdef CompareString 1.23 +#undef CompareString 1.24 +#endif 1.25 +#endif 1.26 + 1.27 +// URL file handling for freedesktop.org 1.28 +#ifdef XP_UNIX 1.29 +#include "nsINIParser.h" 1.30 +#define DESKTOP_ENTRY_SECTION "Desktop Entry" 1.31 +#endif 1.32 + 1.33 +//----------------------------------------------------------------------------- 1.34 + 1.35 +nsFileProtocolHandler::nsFileProtocolHandler() 1.36 +{ 1.37 +} 1.38 + 1.39 +nsresult 1.40 +nsFileProtocolHandler::Init() 1.41 +{ 1.42 + return NS_OK; 1.43 +} 1.44 + 1.45 +NS_IMPL_ISUPPORTS(nsFileProtocolHandler, 1.46 + nsIFileProtocolHandler, 1.47 + nsIProtocolHandler, 1.48 + nsISupportsWeakReference) 1.49 + 1.50 +//----------------------------------------------------------------------------- 1.51 +// nsIProtocolHandler methods: 1.52 + 1.53 +#if defined(XP_WIN) 1.54 +NS_IMETHODIMP 1.55 +nsFileProtocolHandler::ReadURLFile(nsIFile* aFile, nsIURI** aURI) 1.56 +{ 1.57 + nsAutoString path; 1.58 + nsresult rv = aFile->GetPath(path); 1.59 + if (NS_FAILED(rv)) 1.60 + return rv; 1.61 + 1.62 + if (path.Length() < 4) 1.63 + return NS_ERROR_NOT_AVAILABLE; 1.64 + if (!StringTail(path, 4).LowerCaseEqualsLiteral(".url")) 1.65 + return NS_ERROR_NOT_AVAILABLE; 1.66 + 1.67 + HRESULT result; 1.68 + 1.69 + rv = NS_ERROR_NOT_AVAILABLE; 1.70 + 1.71 + IUniformResourceLocatorW* urlLink = nullptr; 1.72 + result = ::CoCreateInstance(CLSID_InternetShortcut, nullptr, CLSCTX_INPROC_SERVER, 1.73 + IID_IUniformResourceLocatorW, (void**)&urlLink); 1.74 + if (SUCCEEDED(result) && urlLink) { 1.75 + IPersistFile* urlFile = nullptr; 1.76 + result = urlLink->QueryInterface(IID_IPersistFile, (void**)&urlFile); 1.77 + if (SUCCEEDED(result) && urlFile) { 1.78 + result = urlFile->Load(path.get(), STGM_READ); 1.79 + if (SUCCEEDED(result) ) { 1.80 + LPWSTR lpTemp = nullptr; 1.81 + 1.82 + // The URL this method will give us back seems to be already 1.83 + // escaped. Hence, do not do escaping of our own. 1.84 + result = urlLink->GetURL(&lpTemp); 1.85 + if (SUCCEEDED(result) && lpTemp) { 1.86 + rv = NS_NewURI(aURI, nsDependentString(lpTemp)); 1.87 + // free the string that GetURL alloc'd 1.88 + CoTaskMemFree(lpTemp); 1.89 + } 1.90 + } 1.91 + urlFile->Release(); 1.92 + } 1.93 + urlLink->Release(); 1.94 + } 1.95 + return rv; 1.96 +} 1.97 + 1.98 +#elif defined(XP_UNIX) 1.99 +NS_IMETHODIMP 1.100 +nsFileProtocolHandler::ReadURLFile(nsIFile* aFile, nsIURI** aURI) 1.101 +{ 1.102 + // We only support desktop files that end in ".desktop" like the spec says: 1.103 + // http://standards.freedesktop.org/desktop-entry-spec/latest/ar01s02.html 1.104 + nsAutoCString leafName; 1.105 + nsresult rv = aFile->GetNativeLeafName(leafName); 1.106 + if (NS_FAILED(rv) || 1.107 + !StringEndsWith(leafName, NS_LITERAL_CSTRING(".desktop"))) 1.108 + return NS_ERROR_NOT_AVAILABLE; 1.109 + 1.110 + nsINIParser parser; 1.111 + rv = parser.Init(aFile); 1.112 + if (NS_FAILED(rv)) 1.113 + return rv; 1.114 + 1.115 + nsAutoCString type; 1.116 + parser.GetString(DESKTOP_ENTRY_SECTION, "Type", type); 1.117 + if (!type.EqualsLiteral("Link")) 1.118 + return NS_ERROR_NOT_AVAILABLE; 1.119 + 1.120 + nsAutoCString url; 1.121 + rv = parser.GetString(DESKTOP_ENTRY_SECTION, "URL", url); 1.122 + if (NS_FAILED(rv) || url.IsEmpty()) 1.123 + return NS_ERROR_NOT_AVAILABLE; 1.124 + 1.125 + return NS_NewURI(aURI, url); 1.126 +} 1.127 + 1.128 +#else // other platforms 1.129 +NS_IMETHODIMP 1.130 +nsFileProtocolHandler::ReadURLFile(nsIFile* aFile, nsIURI** aURI) 1.131 +{ 1.132 + return NS_ERROR_NOT_AVAILABLE; 1.133 +} 1.134 +#endif // ReadURLFile() 1.135 + 1.136 +NS_IMETHODIMP 1.137 +nsFileProtocolHandler::GetScheme(nsACString &result) 1.138 +{ 1.139 + result.AssignLiteral("file"); 1.140 + return NS_OK; 1.141 +} 1.142 + 1.143 +NS_IMETHODIMP 1.144 +nsFileProtocolHandler::GetDefaultPort(int32_t *result) 1.145 +{ 1.146 + *result = -1; // no port for file: URLs 1.147 + return NS_OK; 1.148 +} 1.149 + 1.150 +NS_IMETHODIMP 1.151 +nsFileProtocolHandler::GetProtocolFlags(uint32_t *result) 1.152 +{ 1.153 + *result = URI_NOAUTH | URI_IS_LOCAL_FILE | URI_IS_LOCAL_RESOURCE; 1.154 + return NS_OK; 1.155 +} 1.156 + 1.157 +NS_IMETHODIMP 1.158 +nsFileProtocolHandler::NewURI(const nsACString &spec, 1.159 + const char *charset, 1.160 + nsIURI *baseURI, 1.161 + nsIURI **result) 1.162 +{ 1.163 + nsCOMPtr<nsIStandardURL> url = new nsStandardURL(true); 1.164 + if (!url) 1.165 + return NS_ERROR_OUT_OF_MEMORY; 1.166 + 1.167 + const nsACString *specPtr = &spec; 1.168 + 1.169 +#if defined(XP_WIN) 1.170 + nsAutoCString buf; 1.171 + if (net_NormalizeFileURL(spec, buf)) 1.172 + specPtr = &buf; 1.173 +#endif 1.174 + 1.175 + nsresult rv = url->Init(nsIStandardURL::URLTYPE_NO_AUTHORITY, -1, 1.176 + *specPtr, charset, baseURI); 1.177 + if (NS_FAILED(rv)) return rv; 1.178 + 1.179 + return CallQueryInterface(url, result); 1.180 +} 1.181 + 1.182 +NS_IMETHODIMP 1.183 +nsFileProtocolHandler::NewChannel(nsIURI *uri, nsIChannel **result) 1.184 +{ 1.185 + nsFileChannel *chan = new nsFileChannel(uri); 1.186 + if (!chan) 1.187 + return NS_ERROR_OUT_OF_MEMORY; 1.188 + NS_ADDREF(chan); 1.189 + 1.190 + nsresult rv = chan->Init(); 1.191 + if (NS_FAILED(rv)) { 1.192 + NS_RELEASE(chan); 1.193 + return rv; 1.194 + } 1.195 + 1.196 + *result = chan; 1.197 + return NS_OK; 1.198 +} 1.199 + 1.200 +NS_IMETHODIMP 1.201 +nsFileProtocolHandler::AllowPort(int32_t port, const char *scheme, bool *result) 1.202 +{ 1.203 + // don't override anything. 1.204 + *result = false; 1.205 + return NS_OK; 1.206 +} 1.207 + 1.208 +//----------------------------------------------------------------------------- 1.209 +// nsIFileProtocolHandler methods: 1.210 + 1.211 +NS_IMETHODIMP 1.212 +nsFileProtocolHandler::NewFileURI(nsIFile *file, nsIURI **result) 1.213 +{ 1.214 + NS_ENSURE_ARG_POINTER(file); 1.215 + nsresult rv; 1.216 + 1.217 + nsCOMPtr<nsIFileURL> url = new nsStandardURL(true); 1.218 + if (!url) 1.219 + return NS_ERROR_OUT_OF_MEMORY; 1.220 + 1.221 + // NOTE: the origin charset is assigned the value of the platform 1.222 + // charset by the SetFile method. 1.223 + rv = url->SetFile(file); 1.224 + if (NS_FAILED(rv)) return rv; 1.225 + 1.226 + return CallQueryInterface(url, result); 1.227 +} 1.228 + 1.229 +NS_IMETHODIMP 1.230 +nsFileProtocolHandler::GetURLSpecFromFile(nsIFile *file, nsACString &result) 1.231 +{ 1.232 + NS_ENSURE_ARG_POINTER(file); 1.233 + return net_GetURLSpecFromFile(file, result); 1.234 +} 1.235 + 1.236 +NS_IMETHODIMP 1.237 +nsFileProtocolHandler::GetURLSpecFromActualFile(nsIFile *file, 1.238 + nsACString &result) 1.239 +{ 1.240 + NS_ENSURE_ARG_POINTER(file); 1.241 + return net_GetURLSpecFromActualFile(file, result); 1.242 +} 1.243 + 1.244 +NS_IMETHODIMP 1.245 +nsFileProtocolHandler::GetURLSpecFromDir(nsIFile *file, nsACString &result) 1.246 +{ 1.247 + NS_ENSURE_ARG_POINTER(file); 1.248 + return net_GetURLSpecFromDir(file, result); 1.249 +} 1.250 + 1.251 +NS_IMETHODIMP 1.252 +nsFileProtocolHandler::GetFileFromURLSpec(const nsACString &spec, nsIFile **result) 1.253 +{ 1.254 + return net_GetFileFromURLSpec(spec, result); 1.255 +}