1 //* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
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
15 * The Original Code is Mozilla Annotation Service
17 * The Initial Developer of the Original Code is
19 * Portions created by the Initial Developer are Copyright (C) 2005
20 * the Initial Developer. All Rights Reserved.
23 * Brett Wilson <brettw@gmail.com> (original author)
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 ***** */
40 * Implementation of moz-anno: URLs for accessing annotation values. This just
41 * reads binary data from the annotation service.
43 * There is a special case for favicons. Annotation URLs with the name "favicon"
44 * will be sent to the favicon service. If the favicon service doesn't have the
45 * data, a stream containing the default favicon will be returned.
48 #include "nsAnnoProtocolHandler.h"
49 #include "nsFaviconService.h"
50 #include "nsIChannel.h"
51 #include "nsIInputStreamChannel.h"
52 #include "nsILoadGroup.h"
53 #include "nsIStandardURL.h"
54 #include "nsIStringStream.h"
55 #include "nsISupportsUtils.h"
57 #include "nsNetUtil.h"
58 #include "nsServiceManagerUtils.h"
59 #include "nsStringStream.h"
61 NS_IMPL_ISUPPORTS1(nsAnnoProtocolHandler
, nsIProtocolHandler
)
63 // nsAnnoProtocolHandler::GetScheme
66 nsAnnoProtocolHandler::GetScheme(nsACString
& aScheme
)
68 aScheme
.AssignLiteral("moz-anno");
73 // nsAnnoProtocolHandler::GetDefaultPort
75 // There is no default port for annotation URLs
78 nsAnnoProtocolHandler::GetDefaultPort(PRInt32
*aDefaultPort
)
85 // nsAnnoProtocolHandler::GetProtocolFlags
88 nsAnnoProtocolHandler::GetProtocolFlags(PRUint32
*aProtocolFlags
)
90 *aProtocolFlags
= (URI_NORELATIVE
| URI_NOAUTH
| URI_DANGEROUS_TO_LOAD
);
95 // nsAnnoProtocolHandler::NewURI
98 nsAnnoProtocolHandler::NewURI(const nsACString
& aSpec
,
99 const char *aOriginCharset
,
100 nsIURI
*aBaseURI
, nsIURI
**_retval
)
102 nsCOMPtr
<nsIURI
> uri
= do_CreateInstance(NS_SIMPLEURI_CONTRACTID
);
104 return NS_ERROR_OUT_OF_MEMORY
;
105 nsresult rv
= uri
->SetSpec(aSpec
);
106 NS_ENSURE_SUCCESS(rv
, rv
);
114 // nsAnnoProtocolHandler::NewChannel
118 nsAnnoProtocolHandler::NewChannel(nsIURI
*aURI
, nsIChannel
**_retval
)
120 NS_ENSURE_ARG_POINTER(aURI
);
124 rv
= aURI
->GetPath(path
);
125 NS_ENSURE_SUCCESS(rv
, rv
);
127 nsCOMPtr
<nsIAnnotationService
> annotationService
= do_GetService(
128 "@mozilla.org/browser/annotation-service;1", &rv
);
129 NS_ENSURE_SUCCESS(rv
, rv
);
132 nsCOMPtr
<nsIURI
> annoURI
;
133 nsCAutoString annoName
;
134 rv
= ParseAnnoURI(aURI
, getter_AddRefs(annoURI
), annoName
);
135 NS_ENSURE_SUCCESS(rv
, rv
);
137 // get the data from the annotation service and hand it off to the stream
140 nsCAutoString mimeType
;
142 if (annoName
.EqualsLiteral(FAVICON_ANNOTATION_NAME
)) {
143 // special handling for favicons: ask favicon service
144 nsFaviconService
* faviconService
= nsFaviconService::GetFaviconService();
145 if (! faviconService
) {
146 NS_WARNING("Favicon service is unavailable.");
147 return GetDefaultIcon(_retval
);
149 rv
= faviconService
->GetFaviconData(annoURI
, mimeType
, &dataLen
, &data
);
151 return GetDefaultIcon(_retval
);
153 // don't allow icons without MIME types
154 if (mimeType
.IsEmpty()) {
156 return GetDefaultIcon(_retval
);
159 // normal handling for annotations
160 rv
= annotationService
->GetPageAnnotationBinary(annoURI
, annoName
, &data
,
162 NS_ENSURE_SUCCESS(rv
, rv
);
164 // disallow annotations with no MIME types
165 if (mimeType
.IsEmpty()) {
167 return NS_ERROR_NOT_AVAILABLE
;
171 nsCOMPtr
<nsIStringInputStream
> stream
= do_CreateInstance(
172 NS_STRINGINPUTSTREAM_CONTRACTID
, &rv
);
177 rv
= stream
->AdoptData((char*)data
, dataLen
);
183 nsCOMPtr
<nsIChannel
> channel
;
184 rv
= NS_NewInputStreamChannel(getter_AddRefs(channel
), aURI
, stream
, mimeType
);
185 NS_ENSURE_SUCCESS(rv
, rv
);
193 // nsAnnoProtocolHandler::AllowPort
195 // Don't override any bans on bad ports.
198 nsAnnoProtocolHandler::AllowPort(PRInt32 port
, const char *scheme
,
206 // nsAnnoProtocolHandler::ParseAnnoURI
208 // Splits an annotation URL into its URI and name parts
211 nsAnnoProtocolHandler::ParseAnnoURI(nsIURI
* aURI
,
212 nsIURI
** aResultURI
, nsCString
& aName
)
216 rv
= aURI
->GetPath(path
);
217 NS_ENSURE_SUCCESS(rv
, rv
);
219 PRInt32 firstColon
= path
.FindChar(':');
221 return NS_ERROR_MALFORMED_URI
;
223 rv
= NS_NewURI(aResultURI
, Substring(path
, firstColon
+ 1));
224 NS_ENSURE_SUCCESS(rv
, rv
);
226 aName
= Substring(path
, 0, firstColon
);
231 // nsAnnoProtocolHandler::GetDefaultIcon
233 // This creates a channel for the default web page favicon.
236 nsAnnoProtocolHandler::GetDefaultIcon(nsIChannel
** aChannel
)
239 nsCOMPtr
<nsIURI
> uri
;
240 rv
= NS_NewURI(getter_AddRefs(uri
), NS_LITERAL_CSTRING(FAVICON_DEFAULT_URL
));
241 NS_ENSURE_SUCCESS(rv
, rv
);
242 return NS_NewChannel(aChannel
, uri
);