Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / netwerk / protocol / about / src / nsAboutProtocolHandler.cpp
blob594fc9a90ee8c829eaa7b8aebdc7a34356c5b6cb
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
23 * Pierre Phaneuf <pp@ludusdesign.com>
25 * Alternatively, the contents of this file may be used under the terms of
26 * either the GNU General Public License Version 2 or later (the "GPL"), or
27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
37 * ***** END LICENSE BLOCK ***** */
39 #include "nsAboutProtocolHandler.h"
40 #include "nsIURI.h"
41 #include "nsIIOService.h"
42 #include "nsCRT.h"
43 #include "nsIComponentManager.h"
44 #include "nsIServiceManager.h"
45 #include "nsIAboutModule.h"
46 #include "nsString.h"
47 #include "nsReadableUtils.h"
48 #include "nsNetCID.h"
49 #include "nsAboutProtocolUtils.h"
50 #include "nsNetError.h"
51 #include "nsNetUtil.h"
52 #include "nsSimpleNestedURI.h"
54 static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID);
56 ////////////////////////////////////////////////////////////////////////////////
58 NS_IMPL_ISUPPORTS1(nsAboutProtocolHandler, nsIProtocolHandler)
60 ////////////////////////////////////////////////////////////////////////////////
61 // nsIProtocolHandler methods:
63 NS_IMETHODIMP
64 nsAboutProtocolHandler::GetScheme(nsACString &result)
66 result.AssignLiteral("about");
67 return NS_OK;
70 NS_IMETHODIMP
71 nsAboutProtocolHandler::GetDefaultPort(PRInt32 *result)
73 *result = -1; // no port for about: URLs
74 return NS_OK;
77 NS_IMETHODIMP
78 nsAboutProtocolHandler::GetProtocolFlags(PRUint32 *result)
80 *result = URI_NORELATIVE | URI_NOAUTH | URI_DANGEROUS_TO_LOAD;
81 return NS_OK;
84 NS_IMETHODIMP
85 nsAboutProtocolHandler::NewURI(const nsACString &aSpec,
86 const char *aCharset, // ignore charset info
87 nsIURI *aBaseURI,
88 nsIURI **result)
90 *result = nsnull;
91 nsresult rv;
93 // Use a simple URI to parse out some stuff first
94 nsCOMPtr<nsIURI> url = do_CreateInstance(kSimpleURICID, &rv);
95 if (NS_FAILED(rv)) return rv;
97 rv = url->SetSpec(aSpec);
98 if (NS_FAILED(rv)) {
99 return rv;
102 // Unfortunately, people create random about: URIs that don't correspond to
103 // about: modules... Since those URIs will never open a channel, might as
104 // well consider them unsafe for better perf, and just in case.
105 PRBool isSafe = PR_FALSE;
107 nsCOMPtr<nsIAboutModule> aboutMod;
108 rv = NS_GetAboutModule(url, getter_AddRefs(aboutMod));
109 if (NS_SUCCEEDED(rv)) {
110 // The standard return case
111 PRUint32 flags;
112 rv = aboutMod->GetURIFlags(url, &flags);
113 NS_ENSURE_SUCCESS(rv, rv);
115 isSafe =
116 ((flags & nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT) != 0);
119 if (isSafe) {
120 // We need to indicate that this baby is safe. Use an inner URI that
121 // no one but the security manager will see. Make sure to preserve our
122 // path, in case someone decides to hardcode checks for particular
123 // about: URIs somewhere.
124 nsCAutoString spec;
125 rv = url->GetPath(spec);
126 NS_ENSURE_SUCCESS(rv, rv);
128 spec.Insert("moz-safe-about:", 0);
130 nsCOMPtr<nsIURI> inner;
131 rv = NS_NewURI(getter_AddRefs(inner), spec);
132 NS_ENSURE_SUCCESS(rv, rv);
134 nsSimpleNestedURI* outer = new nsSimpleNestedURI(inner);
135 NS_ENSURE_TRUE(outer, NS_ERROR_OUT_OF_MEMORY);
137 // Take a ref to it in the COMPtr we plan to return
138 url = outer;
140 rv = outer->SetSpec(aSpec);
141 NS_ENSURE_SUCCESS(rv, rv);
144 // We don't want to allow mutation, since it would allow safe and
145 // unsafe URIs to change into each other...
146 NS_TryToSetImmutable(url);
147 url.swap(*result);
148 return NS_OK;
151 NS_IMETHODIMP
152 nsAboutProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
154 NS_ENSURE_ARG_POINTER(uri);
156 // about:what you ask?
157 nsCOMPtr<nsIAboutModule> aboutMod;
158 nsresult rv = NS_GetAboutModule(uri, getter_AddRefs(aboutMod));
159 if (NS_SUCCEEDED(rv)) {
160 // The standard return case:
161 return aboutMod->NewChannel(uri, result);
164 // mumble...
166 if (rv == NS_ERROR_FACTORY_NOT_REGISTERED) {
167 // This looks like an about: we don't know about. Convert
168 // this to an invalid URI error.
169 rv = NS_ERROR_MALFORMED_URI;
172 return rv;
175 NS_IMETHODIMP
176 nsAboutProtocolHandler::AllowPort(PRInt32 port, const char *scheme, PRBool *_retval)
178 // don't override anything.
179 *_retval = PR_FALSE;
180 return NS_OK;
183 ////////////////////////////////////////////////////////////////////////////////
184 // Safe about protocol handler impl
186 NS_IMPL_ISUPPORTS1(nsSafeAboutProtocolHandler, nsIProtocolHandler)
188 // nsIProtocolHandler methods:
190 NS_IMETHODIMP
191 nsSafeAboutProtocolHandler::GetScheme(nsACString &result)
193 result.AssignLiteral("moz-safe-about");
194 return NS_OK;
197 NS_IMETHODIMP
198 nsSafeAboutProtocolHandler::GetDefaultPort(PRInt32 *result)
200 *result = -1; // no port for moz-safe-about: URLs
201 return NS_OK;
204 NS_IMETHODIMP
205 nsSafeAboutProtocolHandler::GetProtocolFlags(PRUint32 *result)
207 *result = URI_NORELATIVE | URI_NOAUTH | URI_LOADABLE_BY_ANYONE;
208 return NS_OK;
211 NS_IMETHODIMP
212 nsSafeAboutProtocolHandler::NewURI(const nsACString &aSpec,
213 const char *aCharset, // ignore charset info
214 nsIURI *aBaseURI,
215 nsIURI **result)
217 nsresult rv;
219 nsCOMPtr<nsIURI> url = do_CreateInstance(kSimpleURICID, &rv);
220 if (NS_FAILED(rv)) return rv;
222 rv = url->SetSpec(aSpec);
223 if (NS_FAILED(rv)) {
224 return rv;
227 NS_TryToSetImmutable(url);
229 *result = nsnull;
230 url.swap(*result);
231 return rv;
234 NS_IMETHODIMP
235 nsSafeAboutProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
237 *result = nsnull;
238 return NS_ERROR_NOT_AVAILABLE;
241 NS_IMETHODIMP
242 nsSafeAboutProtocolHandler::AllowPort(PRInt32 port, const char *scheme, PRBool *_retval)
244 // don't override anything.
245 *_retval = PR_FALSE;
246 return NS_OK;