Initial import of ephy (rev# 7126) from svn
[ephy-soc.git] / embed / mozilla / .svn / text-base / EphyAboutModule.cpp.svn-base
blob6fb6a584998f1605e9aa3debe11627a25cd9369e
1 /*
2  *  Copyright © 2001 Matt Aubury, Philip Langdale
3  *  Copyright © 2004 Crispin Flowerday
4  *  Copyright © 2005 Christian Persch
5  *  Copyright © 2005 Adam Hooper
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2, or (at your option)
10  *  any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  *  $Id$
22  */
24 #include "mozilla-config.h"
25 #include "config.h"
27 #include <string.h>
29 #include <glib/gi18n.h>
30 #include <gtk/gtk.h>
32 // we need nsEscape which depends on internal strings :(((
33 #define MOZILLA_INTERNAL_API 1
34 #include <nsString.h>
36 #include <nsAutoPtr.h>
37 #include <nsCOMPtr.h>
38 #include <nsEscape.h>
39 #include <nsIChannel.h>
40 #include <nsIInputStreamChannel.h>
41 #include <nsIInputStream.h>
42 #include <nsIIOService.h>
43 #include <nsIOutputStream.h>
44 #include <nsIScriptSecurityManager.h>
45 #include <nsIStorageStream.h>
46 #include <nsIURI.h>
47 #include <nsNetCID.h>
48 #include <nsNetUtil.h>
49 #include <nsServiceManagerUtils.h>
51 #include "ephy-debug.h"
53 #include "EphyRedirectChannel.h"
55 #include "EphyAboutModule.h"
57 EphyAboutModule::EphyAboutModule()
59         LOG ("EphyAboutModule ctor [%p]\n", this);
62 EphyAboutModule::~EphyAboutModule()
64         LOG ("EphyAboutModule dtor [%p]\n", this);
67 NS_IMPL_ISUPPORTS1 (EphyAboutModule, nsIAboutModule)
69 /* nsIChannel newChannel (in nsIURI aURI); */
70 NS_IMETHODIMP
71 EphyAboutModule::NewChannel(nsIURI *aURI,
72                             nsIChannel **_retval)
74         NS_ENSURE_ARG(aURI);
76         nsCAutoString path;
77         aURI->GetPath (path);
79         if (strncmp (path.get(), "neterror?", strlen ("neterror?")) == 0)
80         {
81                 return CreateErrorPage (aURI, _retval);
82         }
84         if (strncmp (path.get (), "recover?", strlen ("recover?")) == 0)
85         {
86                 return CreateRecoverPage (aURI, _retval);
87         }
89         if (strcmp (path.get (), "epiphany") == 0)
90         {
91                 return Redirect (nsDependentCString ("file://" SHARE_DIR "/epiphany.xhtml"), _retval);
92         }
94         return NS_ERROR_ILLEGAL_VALUE;
97 #ifdef HAVE_GECKO_1_9
98 /* unsigned long getURIFlags(in nsIURI aURI); */
99 NS_IMETHODIMP
100 EphyAboutModule::GetURIFlags (nsIURI *aURI,
101                               PRUint32 *_result)
103         *_result = 0;
104         return NS_OK;
106 #endif
108 /* private functions */
110 nsresult
111 EphyAboutModule::Redirect(const nsACString &aURL,
112                           nsIChannel **_retval)
114         *_retval = nsnull;
116         nsresult rv;
117         nsCOMPtr<nsIURI> uri;
118         rv = NS_NewURI (getter_AddRefs (uri), aURL);
119         NS_ENSURE_SUCCESS (rv, rv);
121         nsCOMPtr<nsIChannel> tempChannel;
122         rv = NS_NewChannel (getter_AddRefs (tempChannel), uri);
123         NS_ENSURE_SUCCESS (rv, rv);
125         tempChannel->SetOriginalURI (uri);
127         nsCOMPtr<nsIScriptSecurityManager> securityManager = 
128                         do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
129         NS_ENSURE_SUCCESS (rv, rv);
131         nsCOMPtr<nsIPrincipal> principal;
132         rv = securityManager->GetCodebasePrincipal(uri, getter_AddRefs(principal));
133         NS_ENSURE_SUCCESS (rv, rv);
135         rv = tempChannel->SetOwner(principal);
136         NS_ENSURE_SUCCESS (rv, rv);
138         tempChannel.swap (*_retval);
140         return NS_OK;
143 nsresult
144 EphyAboutModule::ParseURL(const char *aURL,
145                           nsACString &aCode,
146                           nsACString &aRawOriginURL,
147                           nsACString &aOriginURL,
148                           nsACString &aOriginCharset,
149                           nsACString &aTitle)
151         /* The page URL is of the form "about:neterror?e=<errorcode>&u=<URL>&c=<charset>&d=<description>" */
152         const char *query = strstr (aURL, "?");
153         if (!query) return NS_ERROR_FAILURE;
154         
155         /* skip the '?' */
156         ++query;
157         
158         char **params = g_strsplit (query, "&", -1);
159         if (!params) return NS_ERROR_FAILURE;
160         
161         for (PRUint32 i = 0; params[i] != NULL; ++i)
162         {
163                 char *param = params[i];
164         
165                 if (strlen (param) <= 2) continue;
166         
167                 switch (param[0])
168                 {
169                         case 'e':
170                                 aCode.Assign (nsUnescape (param + 2));
171                                 break;
172                         case 'u':
173                                 aRawOriginURL.Assign (param + 2);
174                                 aOriginURL.Assign (nsUnescape (param + 2));
175                                 break;
176                         case 'c':
177                                 aOriginCharset.Assign (nsUnescape (param + 2));
178                                 break;
179                         /* The next one is not used in neterror but recover: */
180                         case 't':
181                                 aTitle.Assign (nsUnescape (param + 2));
182                                 break;
183                         case 'd':
184                                 /* we don't need mozilla's description parameter */
185                         default:
186                                 break;
187                 }
188         }
190         g_strfreev (params);
192         return NS_OK;
195 nsresult
196 EphyAboutModule::GetErrorMessage(nsIURI *aURI,
197                                  const char *aError,
198                                  char **aStockIcon,
199                                  char **aTitle,
200                                  char **aPrimary,
201                                  char **aSecondary,
202                                  char **aTertiary,
203                                  char **aLinkIntro)
205         *aStockIcon = GTK_STOCK_DIALOG_ERROR;
207         if (strcmp (aError, "protocolNotFound") == 0)
208         {
209                 nsCAutoString scheme;
210                 aURI->GetScheme (scheme);
212                 /* Translators: %s is the name of a protocol, like "http" etc. */
213                 *aTitle = g_strdup_printf (_("“%s” Protocol is not Supported"), scheme.get());
214                 /* Translators: %s is the name of a protocol, like "http" etc. */
215                 *aPrimary = g_strdup_printf (_("“%s” protocol is not supported."), scheme.get());
216                 /* FIXME: get the list of supported protocols from necko */
217                 *aSecondary = g_strdup (_("Supported protocols are “http”, “https”, “ftp”, “file”, “smb” "
218                                           "and “sftp”."));
219         }
220         else if (strcmp (aError, "fileNotFound") == 0)
221         {
222                 nsCAutoString path;
223                 aURI->GetPath (path);
225                 /* Translators: %s is the path and filename, for example "/home/user/test.html" */
226                 *aTitle = g_markup_printf_escaped (_("File “%s” not Found"), path.get());
227                 /* Translators: %s is the path and filename, for example "/home/user/test.html" */
228                 *aPrimary = g_markup_printf_escaped (_("File “%s” not found."), path.get());
229                 *aSecondary = g_strdup (_("Check the location of the file and try again."));
230         }
231         else if (strcmp (aError, "dnsNotFound") == 0)
232         {
233                 nsCAutoString host;
234                 aURI->GetHost (host);
236                 /* Translators: %s is the hostname, like "www.example.com" */
237                 *aTitle = g_markup_printf_escaped (_("“%s” Could not be Found"),
238                                                      host.get());
239                 /* Translators: %s is the hostname, like "www.example.com" */
240                 *aPrimary = g_markup_printf_escaped (_("“%s” could not be found."),
241                                                      host.get());
242                 *aSecondary = g_strdup (_("Check that you are connected to the internet, and "
243                                           "that the address is correct."));
244                 *aLinkIntro = _("If this page used to exist, you may find an archived version:");
245         }
246         else if (strcmp (aError, "connectionFailure") == 0)
247         {
248                 nsCAutoString host;
249                 aURI->GetHost (host);
251                 /* Translators: %s is the hostname, like "www.example.com" */
252                 *aTitle = g_markup_printf_escaped
253                         (_("“%s” Refused the Connection"),
254                          host.get());
255                 /* Translators: %s is the hostname, like "www.example.com" */
256                 *aPrimary = g_markup_printf_escaped
257                                 (_("“%s” refused the connection."),
258                                  host.get());
260                 /* FIXME what about 127.0.0.* ? */
261                 if (strcmp (host.get(), "localhost") == 0)
262                 {
263                         PRInt32 port;
264                         aURI->GetPort (&port);
266                         *aSecondary = g_strdup (_("Likely causes of the problem are"));
268                         /* Try to get the service name attached to that port */
269                         if (port != -1)
270                         {
271                                 struct servent *serv;
272                         
273                                 if ((serv = getservbyport (htons (port), NULL)) != NULL)
274                                 {
275                                         *aTertiary = g_markup_printf_escaped (
276                                                         _("<ul>"
277                                                            "<li>the service ""%s"" isn't started.</li>"
278                                                            "Try to start it using the Services Configuration Tool in "
279                                                            "System > Control Center, or</ul>"
280                                                            "<ul><li>the port number %d is wrong.</li>"
281                                                            "</ul>"),
282                                                         serv->s_name, port);
283                                 }
284                                 else
285                                 {
286                                         *aTertiary = g_markup_printf_escaped (
287                                                         _("<ul>"
288                                                            "<li>some service isn't started, or</li>"
289                                                            "<li>the port number %d is wrong.</li>"
290                                                            "</ul>"),
291                                                         port);
292                                 }
293                         }
294                         else
295                         {
296                                 *aTertiary = _("<ul>"
297                                                "<li>some service isn't started, or</li>"
298                                                "<li>you got the port number wrong.</li>"
299                                                "</ul>");
300                         }
301                 }
302                 else
303                 {
304                         *aSecondary = g_strdup (_("The server may be busy or you may have a "
305                                                   "network connection problem. Try again later."));
306                         *aLinkIntro = _("There may be an old version of the page you wanted:");
307                 }
308         }
309         else if (strcmp (aError, "netInterrupt") == 0)
310         {
311                 nsCAutoString host;
312                 aURI->GetHost (host);
314                 /* Translators: %s is the hostname, like "www.example.com" */
315                 *aTitle = g_markup_printf_escaped
316                                 (_("“%s” Interrupted the Connection"),
317                                  host.get());
318                 /* Translators: %s is the hostname, like "www.example.com" */
319                 *aPrimary = g_markup_printf_escaped
320                                 (_("“%s” interrupted the connection."),
321                                  host.get());
322                 *aSecondary = g_strdup (_("The server may be busy or you may have a "
323                                           "network connection problem. Try again later."));
324                 *aLinkIntro = _("There may be an old version of the page you wanted:");
325         }
326         else if (strcmp (aError, "netTimeout") == 0)
327         {
328                 nsCAutoString host;
329                 aURI->GetHost (host);
331                 /* Translators: %s is the hostname, like "www.example.com" */
332                 *aTitle = g_markup_printf_escaped
333                                 (_("“%s” is not Responding"),
334                                  host.get());
335                 /* Translators: %s is the hostname, like "www.example.com" */
336                 *aPrimary = g_markup_printf_escaped
337                                 (_("“%s” is not responding."),
338                                  host.get());
339                 *aSecondary = g_strdup (_("The connection was lost because the "
340                                           "server took too long to respond."));
341                 *aTertiary = _("The server may be busy or you may have a network "
342                                 "connection problem. Try again later.");
343                 *aLinkIntro = _("There may be an old version of the page you wanted:");
344         }
345         else if (strcmp (aError, "malformedURI") == 0)
346         {
347                 *aTitle = g_strdup (_("Invalid Address"));
348                 *aPrimary = g_strdup (_("Invalid address."));
349                 *aSecondary = g_strdup (_("The address you entered is not valid."));
350         }
351         else if (strcmp (aError, "redirectLoop") == 0)
352         {
353                 nsCAutoString host;
354                 aURI->GetHost (host);
356                 /* Translators: %s is the hostname, like "www.example.com" */
357                 *aTitle = g_markup_printf_escaped
358                                 (_("“%s” Redirected Too Many Times"),
359                                  host.get());
360                 /* Translators: %s is the hostname, like "www.example.com" */
361                 *aPrimary = g_strdup (_("This page cannot load because of a problem with the Web site."));
363                 *aSecondary = g_markup_printf_escaped
364                                 (_("The server “%s” is redirecting in a way that will never complete."),
365                                  host.get());
366                 *aLinkIntro = _("There may be an old version of the page you wanted:");
367         }
368         else if (strcmp (aError, "unknownSocketType") == 0)
369         {
370                 nsCAutoString host;
371                 aURI->GetHost (host);
373                 /* Translators: %s is the hostname, like "www.example.com" */
374                 *aTitle = g_markup_printf_escaped
375                                 (_("“%s” Requires an Encrypted Connection"),
376                                  host.get());
377                 /* Translators: %s is the hostname, like "www.example.com" */
378                 *aPrimary = g_markup_printf_escaped
379                                 (_("“%s” requires an encrypted connection."),
380                                  host.get());
381                 *aSecondary = g_strdup (_("The document could not be loaded because "
382                                           "encryption support is not installed."));
383         }
384         else if (strcmp (aError, "netReset") == 0)
385         {
386                 nsCAutoString host;
387                 aURI->GetHost (host);
389                 /* Translators: %s is the hostname, like "www.example.com" */
390                 *aTitle = g_markup_printf_escaped
391                                 (_("“%s” Dropped the Connection"),
392                                  host.get());
393                 /* Translators: %s is the hostname, like "www.example.com" */
394                 *aPrimary = g_markup_printf_escaped
395                                 (_("“%s” dropped the connection."),
396                                  host.get());
397                 *aSecondary = g_strdup (_("The server dropped the connection "
398                                           "before any data could be read."));
399                 *aTertiary = _("The server may be busy or you may have a "
400                                "network connection problem. Try again later.");
401                 *aLinkIntro = _("There may be an old version of the page you wanted:");
402         }
403         else if (strcmp (aError, "netOffline") == 0)
404         {
405                 /* Error is a bit too strong here */
406                 *aStockIcon = GTK_STOCK_DIALOG_INFO;
408                 *aTitle = g_strdup (_("Cannot Load Document Whilst Working Offline"));
409                 *aPrimary = g_strdup (_("Cannot load document whilst working offline."));
410                 *aSecondary = g_strdup (_("To view this document, disable “Work Offline” and try again."));
411         }
412         else if (strcmp (aError, "deniedPortAccess") == 0)
413         {
414                 nsCAutoString host;
415                 aURI->GetHost (host);
417                 PRInt32 port = -1;
418                 aURI->GetPort (&port);
420                 /* Translators: %s is the hostname, like "www.example.com" */
421                 *aTitle = g_markup_printf_escaped
422                                 (_("“%s” Denied Access to Port “%d”"),
423                                  host.get(), port > 0 ? port : 80);
424                 /* Translators: %s is the hostname, like "www.example.com" */
425                 *aPrimary = g_markup_printf_escaped
426                                 (_("“%s” denied access to port “%d”."),
427                                  host.get(), port > 0 ? port : 80);
428                 *aSecondary = g_strdup (_("The server dropped the connection "
429                                           "before any data could be read."));
430                 *aTertiary = _("The server may be busy or you may have a "
431                                "network connection problem. Try again later.");
432                 *aLinkIntro = _("There may be an old version of the page you wanted:");
433         }
434         else if (strcmp (aError, "proxyResolveFailure") == 0 ||
435                  strcmp (aError, "proxyConnectFailure") == 0)
436         {
437                 *aTitle = g_strdup (_("Could not Connect to Proxy Server"));
438                 *aPrimary = g_strdup (_("Could not connect to proxy server."));
439                 *aSecondary = g_strdup (_("Check your proxy server settings. "
440                                           "If the connection still fails, there may be "
441                                           "a problem with your proxy server or your "
442                                           "network connection."));
443         }
444         /* This was introduced in gecko 1.9 */
445         else if (strcmp (aError, "contentEncodingError") == 0)
446         {
447                 *aTitle = g_strdup (_("Could not Display Content"));
448                 *aPrimary = g_strdup (_("Could not display content."));
449                 *aSecondary = g_strdup (_("The page uses an unsupported or invalid form of compression."));
450         }
451         else
452         {
453                 return NS_ERROR_ILLEGAL_VALUE;
454         }
456         return NS_OK;
459 nsresult
460 EphyAboutModule::CreateErrorPage(nsIURI *aErrorURI,
461                                  nsIChannel **_retval)
463         *_retval = nsnull;
465         /* First parse the arguments */
466         nsresult rv;
467         nsCAutoString spec;
468         rv = aErrorURI->GetSpec (spec);
469         NS_ENSURE_TRUE (NS_SUCCEEDED (rv), rv);
471         nsCAutoString error, rawurl, url, charset, dummy;
472         rv = ParseURL (spec.get (), error, rawurl, url, charset, dummy);
473         if (NS_FAILED (rv)) return rv;
474         if (error.IsEmpty () || rawurl.IsEmpty () || url.IsEmpty()) return NS_ERROR_FAILURE;
476         nsCOMPtr<nsIURI> uri;
477         rv = NS_NewURI (getter_AddRefs (uri), url, charset.get());
478         /* FIXME can uri be NULL if the original url was invalid? */
479         NS_ENSURE_SUCCESS (rv, rv);
481         char *stock_id = nsnull, *title = nsnull, *primary = nsnull,
482              *secondary = nsnull, *tertiary = nsnull, *linkintro = nsnull;
483         rv = GetErrorMessage (uri, error.get(), &stock_id, &title, &primary,
484                               &secondary, &tertiary, &linkintro);
486         /* we don't know about this error code.
487          * FIXME: We'd like to forward to mozilla's about:neterror handler,
488          * but I don't know how to. So just redirect to the same page that
489          * mozilla's handler redirects to.
490          */
491         if (rv == NS_ERROR_ILLEGAL_VALUE)
492         {
493                 nsCAutoString newurl(spec);
495                 /* remove "about:neterror" part and insert mozilla's error page url */
496                 newurl.Cut(0, strlen ("about:neterror"));
497                 newurl.Insert("chrome://global/content/netError.xhtml", 0);
499                 return Redirect (newurl, _retval);
500         }
501         NS_ENSURE_SUCCESS (rv, rv);
502         NS_ENSURE_TRUE (primary && secondary, NS_ERROR_FAILURE);
504         nsCOMPtr<nsIChannel> channel;
505         rv = WritePage (aErrorURI, uri, aErrorURI, rawurl, title, stock_id, primary, secondary, tertiary, linkintro, getter_AddRefs (channel));
506         NS_ENSURE_SUCCESS (rv, rv);
508         g_free (title);
509         g_free (primary);
510         g_free (secondary);
512         channel.swap (*_retval);
514         return NS_OK;
517 nsresult
518 EphyAboutModule::CreateRecoverPage(nsIURI *aRecoverURI,
519                                    nsIChannel **_retval)
521         *_retval = nsnull;
523         /* First parse the arguments */
524         nsresult rv;
525         nsCAutoString spec;
526         rv = aRecoverURI->GetSpec (spec);
527         NS_ENSURE_TRUE (NS_SUCCEEDED (rv), rv);
529         nsCAutoString error, rawurl, url, charset, title;
530         rv = ParseURL (spec.get (), error, rawurl, url, charset, title);
531         if (NS_FAILED (rv)) return rv;
532         if (rawurl.IsEmpty () || url.IsEmpty()) return NS_ERROR_FAILURE;
534         nsCOMPtr<nsIURI> uri;
535         rv = NS_NewURI(getter_AddRefs (uri), url, charset.get());
536         NS_ENSURE_SUCCESS (rv, rv);
538         char *secondary = g_markup_printf_escaped
539                 (_("The page “%s” in this tab was not fully loaded yet when "
540                    "the web browser crashed; it could have caused the crash."),
541                  url.get());
543         nsCOMPtr<nsIChannel> channel;
544         rv = WritePage (aRecoverURI, uri, uri, rawurl, title.get(),
545                         GTK_STOCK_DIALOG_INFO, title.get() /* as primary */,
546                         secondary, nsnull, nsnull, getter_AddRefs (channel));
547         NS_ENSURE_SUCCESS (rv, rv);
549         nsRefPtr<EphyRedirectChannel> redirectChannel (new EphyRedirectChannel (channel));
550         if (!redirectChannel) return NS_ERROR_OUT_OF_MEMORY;
552         g_free (secondary);
554         NS_ADDREF(*_retval = redirectChannel);
556         return NS_OK;
559 nsresult
560 EphyAboutModule::WritePage(nsIURI *aOriginalURI,
561                            nsIURI *aURI,
562                            nsIURI *aChannelURI,
563                            const nsACString &aRawURL,
564                            const char *aTitle,
565                            const char *aStockIcon,
566                            const char *aPrimary,
567                            const char *aSecondary,
568                            const char *aTertiary,
569                            const char *aLinkIntro,
570                            nsIChannel **_retval)
572         *_retval = nsnull;
574         nsresult rv;
575         nsCOMPtr<nsIStorageStream> storageStream;
576         rv = NS_NewStorageStream (16384, (PRUint32) -1, getter_AddRefs (storageStream));
577         NS_ENSURE_SUCCESS (rv, rv);
579         nsCOMPtr<nsIOutputStream> stream;
580         rv = storageStream->GetOutputStream (0, getter_AddRefs (stream));
581         NS_ENSURE_SUCCESS (rv, rv);
583         char *language = g_strdup (pango_language_to_string (gtk_get_default_language ()));
584         g_strdelimit (language, "_-@", '\0');
586         Write (stream,
587                "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
588                "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" "
589                "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"
590                "<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"");
591         Write (stream, language);
592         Write (stream,
593                "\" xml:lang=\"");
594         Write (stream, language);
595         Write (stream,
596                "\">\n"
597                "<head>\n"
598                 "<title>");
599         Write (stream, aTitle);
600         /* no favicon for now, it would pollute the favicon cache */
601         /* "<link rel=\"icon\" type=\"image/png\" href=\"moz-icon://stock/gtk-dialog-error?size=16\" />\n" */
602         Write (stream,
603                 "</title>\n"
604                 "<style type=\"text/css\">\n"
605                 "div#body {\n"
606                         "top: 12px;\n"
607                         "right: 12px;\n"
608                         "bottom: 12px;\n"
609                         "left: 12px;\n"
610                         "overflow: auto;\n"
612                         "background: -moz-dialog url('moz-icon://stock/");
613         Write (stream, aStockIcon);
614         Write (stream,
615                         "?size=dialog') no-repeat 12px 12px;\n"
616                         "color: -moz-dialogtext;\n"
617                         "font: message-box;\n"
618                         "border: 1px solid -moz-dialogtext;\n"
620                         "padding: 12px 12px 12px 72px;\n"
621                 "}\n"
623                 "h1 {\n"
624                         "margin: 0;\n"
625                         "font-size: 1.2em;\n"
626                 "}\n"
627                 "</style>\n"
628                "</head>\n"
629                "<body dir=\"");
630         Write (stream,
631                gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL ? "rtl" : "ltr");
632         Write (stream,
633                "\">\n"
634                 "<div id=\"body\">"
635                 "<h1>");
636         Write (stream, aPrimary);
637         Write (stream,
638                "</h1>\n");
639         if (aSecondary)
640         {
641                 Write (stream, "<p>");
642                 Write (stream, aSecondary);
643                 if (aTertiary)
644                 {
645                         Write (stream, " ");
646                         Write (stream, aTertiary);
647                 }
648                 Write (stream, "</p>\n");
649         }
651         PRBool isHttp = PR_FALSE, isHttps = PR_FALSE;
652         aURI->SchemeIs ("http", &isHttp);
653         aURI->SchemeIs ("https", &isHttps);
654         if (aLinkIntro && (isHttp || isHttps))
655         {
656                 nsCString raw(aRawURL);
658                 Write (stream, "<p>");
659                 Write (stream, aLinkIntro);
660                 Write (stream, "<ul>\n");
661                 Write (stream, "<li><a href=\"http://www.google.com/search?q=cache:");
662                 Write (stream, raw.get());
663                 Write (stream, "\">");
664                 /* Translators: The text before the "|" is context to help you decide on
665                  * the correct translation. You MUST OMIT it in the translated string. */
666                 Write (stream, Q_("You may find an old version:|in the Google Cache"));
667                 Write (stream, "</a></li>\n");
669                 Write (stream, "<li><a href=\"http://web.archive.org/web/*/");
670                 Write (stream, raw.get());
671                 Write (stream, "\">");
672                 /* Translators: The text before the "|" is context to help you decide on
673                  * the correct translation. You MUST OMIT it in the translated string. */
674                 Write (stream, Q_("You may find an old version:|in the Internet Archive"));
675                 Write (stream, "</a></li>\n"
676                                "</ul>\n"
677                                "</p>");
678         }
680         Write (stream,
681                 "</div>\n"
682                "</body>\n"
683                "</html>\n");
685         g_free (language);
687         /* finish the rendering */
688         nsCOMPtr<nsIInputStream> inputStream;
689         rv = storageStream->NewInputStream (0, getter_AddRefs (inputStream));
690         NS_ENSURE_SUCCESS (rv, rv);
692         nsCOMPtr<nsIChannel> channel;
693         rv = NS_NewInputStreamChannel (getter_AddRefs (channel),
694                                        aChannelURI,
695                                        inputStream,
696                                        NS_LITERAL_CSTRING ("application/xhtml+xml"),
697                                        NS_LITERAL_CSTRING ("utf-8"));
698         NS_ENSURE_SUCCESS (rv, rv);
699         
700         rv = channel->SetOriginalURI (aOriginalURI);
701         NS_ENSURE_SUCCESS (rv, rv);
703         nsCOMPtr<nsIScriptSecurityManager> securityManager 
704                 (do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv));
705         NS_ENSURE_SUCCESS (rv, rv);
707         nsCOMPtr<nsIPrincipal> principal;
708         rv = securityManager->GetCodebasePrincipal (aOriginalURI, getter_AddRefs (principal));
709         NS_ENSURE_SUCCESS (rv, rv);
711         rv = channel->SetOwner(principal);
712         NS_ENSURE_SUCCESS (rv, rv);
714         channel.swap (*_retval);
716         return NS_OK;
719 nsresult
720 EphyAboutModule::Write(nsIOutputStream *aStream,
721                        const char *aText)
723         PRUint32 bytesWritten;
724         return aStream->Write (aText, strlen (aText), &bytesWritten);