2 * Copyright © 2000, 2001, 2002 Marco Pesenti Gritti
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2, or (at your option)
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * $Id: mozilla-embed-persist.cpp 6952 2007-03-11 19:42:02Z chpe $
21 #include "mozilla-config.h"
26 #include <nsStringAPI.h>
29 #include <nsComponentManagerUtils.h>
30 #include <nsCWebBrowserPersist.h>
31 #include <nsICacheEntryDescriptor.h>
32 #include <nsICacheService.h>
33 #include <nsICacheSession.h>
34 #include <nsIDOMSerializer.h>
36 #include <nsIHistoryEntry.h>
37 #include <nsIInputStream.h>
38 #include <nsIIOService.h>
39 #include <nsILocalFile.h>
40 #include <nsISHEntry.h>
42 #include <nsIWebBrowserPersist.h>
44 #include <nsNetError.h>
45 #include <nsServiceManagerUtils.h>
48 #include "EphyBrowser.h"
49 #include "EphyHeaderSniffer.h"
50 #include "EphyUtils.h"
51 #include "MozDownload.h"
53 #include "ephy-debug.h"
54 #include "ephy-embed-shell.h"
55 #include "ephy-file-helpers.h"
56 #include "mozilla-embed.h"
58 #include "mozilla-embed-persist.h"
61 mozilla_embed_persist_class_init (MozillaEmbedPersistClass
*klass
);
63 mozilla_embed_persist_init (MozillaEmbedPersist
*ges
);
65 mozilla_embed_persist_finalize (GObject
*object
);
67 #define MOZILLA_EMBED_PERSIST_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), MOZILLA_TYPE_EMBED_PERSIST, MozillaEmbedPersistPrivate))
69 struct MozillaEmbedPersistPrivate
71 nsCOMPtr
<nsIWebBrowserPersist
> mPersist
;
74 static GObjectClass
*parent_class
= NULL
;
77 mozilla_embed_persist_get_type (void)
79 static GType type
= 0;
81 if (G_UNLIKELY (type
== 0))
83 const GTypeInfo our_info
=
85 sizeof (MozillaEmbedPersistClass
),
87 NULL
, /* base_finalize */
88 (GClassInitFunc
) mozilla_embed_persist_class_init
,
89 NULL
, /* class_finalize */
90 NULL
, /* class_data */
91 sizeof (MozillaEmbedPersist
),
93 (GInstanceInitFunc
) mozilla_embed_persist_init
96 type
= g_type_register_static (EPHY_TYPE_EMBED_PERSIST
,
97 "MozillaEmbedPersist",
98 &our_info
, (GTypeFlags
) 0);
105 mozilla_embed_persist_init (MozillaEmbedPersist
*persist
)
107 persist
->priv
= MOZILLA_EMBED_PERSIST_GET_PRIVATE (persist
);
109 persist
->priv
->mPersist
= do_CreateInstance (NS_WEBBROWSERPERSIST_CONTRACTID
);
113 mozilla_embed_persist_finalize (GObject
*object
)
115 MozillaEmbedPersist
*persist
= MOZILLA_EMBED_PERSIST (object
);
117 persist
->priv
->mPersist
= nsnull
;
119 G_OBJECT_CLASS (parent_class
)->finalize (object
);
123 mozilla_embed_persist_completed (MozillaEmbedPersist
*persist
)
125 g_signal_emit_by_name (persist
, "completed");
126 g_object_unref (persist
);
130 mozilla_embed_persist_cancelled (MozillaEmbedPersist
*persist
)
132 g_signal_emit_by_name (persist
, "cancelled");
133 g_object_unref (persist
);
137 impl_cancel (EphyEmbedPersist
*persist
)
139 nsCOMPtr
<nsIWebBrowserPersist
> bpersist
=
140 MOZILLA_EMBED_PERSIST (persist
)->priv
->mPersist
;
141 nsCOMPtr
<nsICancelable
> cancelable (do_QueryInterface (bpersist
));
144 cancelable
->Cancel (NS_BINDING_ABORTED
);
147 g_object_unref (persist
);
151 impl_save (EphyEmbedPersist
*persist
)
158 EphyEmbedPersistFlags flags
;
159 EphyEmbedSingle
*single
;
161 single
= EPHY_EMBED_SINGLE (ephy_embed_shell_get_embed_single (embed_shell
));
163 g_object_ref (persist
);
165 g_object_get (persist
,
170 "max_size", &max_size
,
173 g_return_val_if_fail (!(flags
& EPHY_EMBED_PERSIST_COPY_PAGE
)
174 || embed
!= NULL
, FALSE
);
176 EphyBrowser
*browser
= NULL
;
179 browser
= (EphyBrowser
*) _mozilla_embed_get_ephy_browser (MOZILLA_EMBED(embed
));
181 g_object_unref (embed
);
183 NS_ENSURE_TRUE (browser
, FALSE
);
185 /* we must have one of uri or browser */
186 g_assert (browser
!= NULL
|| uri
!= NULL
);
188 /* Get the uri to save to */
189 nsCOMPtr
<nsIURI
> inURI
;
192 /* FIXME: origin charset!! */
193 rv
= EphyUtils::NewURI (getter_AddRefs(inURI
), nsCString(uri
));
194 NS_ENSURE_SUCCESS (rv
, FALSE
);
198 rv
= browser
->GetDocumentURI (getter_AddRefs (inURI
));
199 NS_ENSURE_SUCCESS (rv
, FALSE
);
203 nsCOMPtr
<nsIInputStream
> postData
;
204 /* FIXME: don't do this on COPY_PAGE to ensure we don't end up reposting? */
209 nsCOMPtr
<nsIWebNavigation
> webNav(do_QueryInterface(browser
->mWebBrowser
));
210 nsCOMPtr
<nsISHistory
> sessionHistory
;
211 webNav
->GetSessionHistory(getter_AddRefs(sessionHistory
));
212 nsCOMPtr
<nsIHistoryEntry
> entry
;
213 sessionHistory
->GetIndex(&sindex
);
214 sessionHistory
->GetEntryAtIndex(sindex
, PR_FALSE
, getter_AddRefs(entry
));
215 nsCOMPtr
<nsISHEntry
> shEntry(do_QueryInterface(entry
));
218 shEntry
->GetPostData(getter_AddRefs(postData
));
222 /* Get the DOM document if a uri is not specified */
223 nsCOMPtr
<nsIDOMDocument
> DOMDocument
;
226 if (flags
& EPHY_EMBED_PERSIST_MAINDOC
)
228 browser
->GetDocument (getter_AddRefs(DOMDocument
));
232 browser
->GetTargetDocument (getter_AddRefs(DOMDocument
));
234 NS_ENSURE_TRUE (DOMDocument
, FALSE
);
238 /* Get the current page descriptor */
239 nsCOMPtr
<nsISupports
> cacheDescriptor
;
242 browser
->GetPageDescriptor(getter_AddRefs (cacheDescriptor
));
245 /* Try to get a descriptor from the cache session */
246 /* FIXME: what about https?? */
247 PRBool isHttp
= PR_FALSE
, isHttps
= PR_FALSE
;
248 if (!cacheDescriptor
&&
249 (flags
& EPHY_EMBED_PERSIST_FROM_CACHE
) &&
251 ((NS_SUCCEEDED (inURI
->SchemeIs ("http", &isHttp
)) && isHttp
) ||
252 (NS_SUCCEEDED (inURI
->SchemeIs ("https", &isHttps
)) && isHttps
)))
254 nsCOMPtr
<nsICacheService
> cacheService
255 (do_GetService(NS_CACHESERVICE_CONTRACTID
));
258 nsCOMPtr
<nsICacheSession
> cacheSession
;
259 rv
= cacheService
->CreateSession ("HTTP",
260 nsICache::STORE_ANYWHERE
,
262 getter_AddRefs (cacheSession
));
263 if (NS_SUCCEEDED (rv
) && cacheSession
)
265 nsCOMPtr
<nsICacheEntryDescriptor
> descriptor
;
268 inURI
->GetSpec (spec
);
270 rv
= cacheSession
->OpenCacheEntry
272 nsICache::ACCESS_READ
,
273 PR_FALSE
, getter_AddRefs (descriptor
));
275 cacheDescriptor
= do_QueryInterface (descriptor
);
277 LOG ("Getting cache descriptor for '%s' rv=%x", spec
.get(), rv
);
282 LOG ("Cache descriptor %p", cacheDescriptor
.get());
284 /* if we have COPY_PAGE, we *need* to have a page descriptor, else we'll re-fetch
285 * the page, which will possibly give a different page than the original which we
286 * need for view source
288 NS_ENSURE_TRUE (!(flags
& EPHY_EMBED_PERSIST_COPY_PAGE
) || cacheDescriptor
, FALSE
);
290 if (filename
== NULL
|| filename
[0] == '\0')
292 /* Get a temp filename to save to */
293 char *tmp_filename
, *base
;
294 base
= g_build_filename (g_get_tmp_dir (), "sav-XXXXXX", (char *) NULL
);
295 tmp_filename
= ephy_file_tmp_filename (base
, "html");
297 if (tmp_filename
== NULL
) return FALSE
;
299 nsCOMPtr
<nsILocalFile
> tmpFile
= do_CreateInstance (NS_LOCAL_FILE_CONTRACTID
);
300 NS_ENSURE_TRUE (tmpFile
, FALSE
);
302 tmpFile
->InitWithNativePath (nsCString (tmp_filename
));
303 g_free (tmp_filename
);
305 /* Create an header sniffer and do the save */
306 nsCOMPtr
<nsIWebBrowserPersist
> webPersist
=
307 MOZILLA_EMBED_PERSIST (persist
)->priv
->mPersist
;
308 NS_ENSURE_TRUE (webPersist
, FALSE
);
310 EphyHeaderSniffer
* sniffer
= new EphyHeaderSniffer
311 (webPersist
, MOZILLA_EMBED_PERSIST (persist
),
312 tmpFile
, inURI
, DOMDocument
, postData
, single
);
313 if (!sniffer
) return FALSE
;
315 webPersist
->SetProgressListener(sniffer
);
316 rv
= webPersist
->SaveURI(inURI
, cacheDescriptor
, nsnull
/* FIXME: Referrer */, nsnull
, nsnull
, tmpFile
);
317 if (NS_FAILED (rv
)) return FALSE
;
321 /* Filename to save to */
322 nsCOMPtr
<nsILocalFile
> destFile
;
323 NS_NewNativeLocalFile (nsCString(filename
),
324 PR_TRUE
, getter_AddRefs(destFile
));
325 NS_ENSURE_TRUE (destFile
, FALSE
);
327 rv
= InitiateMozillaDownload (DOMDocument
, inURI
, destFile
,
328 nsnull
, inURI
, MOZILLA_EMBED_PERSIST (persist
),
329 postData
, cacheDescriptor
, max_size
);
330 if (NS_FAILED (rv
)) return FALSE
;
340 impl_to_string (EphyEmbedPersist
*persist
)
343 nsCOMPtr
<nsIDOMDocument
> DOMDocument
;
344 EphyEmbedPersistFlags flags
;
345 EphyBrowser
*browser
;
348 g_object_ref (persist
);
350 g_object_get (persist
,
354 g_object_unref (persist
);
355 g_return_val_if_fail (embed
!= NULL
, NULL
);
357 browser
= (EphyBrowser
*) _mozilla_embed_get_ephy_browser (MOZILLA_EMBED(embed
));
358 g_return_val_if_fail (browser
!= NULL
, NULL
);
360 if (flags
& EPHY_EMBED_PERSIST_MAINDOC
)
362 rv
= browser
->GetDocument (getter_AddRefs(DOMDocument
));
366 rv
= browser
->GetTargetDocument (getter_AddRefs(DOMDocument
));
369 nsCString cOutString
;
370 nsCOMPtr
<nsIDOMNode
> node
= do_QueryInterface(DOMDocument
);
374 nsCOMPtr
<nsIDOMSerializer
> serializer
;
375 serializer
= do_CreateInstance(NS_XMLSERIALIZER_CONTRACTID
, &rv
);
378 serializer
->SerializeToString(node
, outString
);
380 NS_UTF16ToCString (outString
, NS_CSTRING_ENCODING_UTF8
, cOutString
);
384 g_object_unref (embed
);
386 return g_strdup (cOutString
.get());
390 mozilla_embed_persist_constructor (GType type
, guint n_construct_properties
,
391 GObjectConstructParam
*construct_params
)
393 /* this will ensure that mozilla is started up */
394 ephy_embed_shell_get_embed_single (embed_shell
);
396 return parent_class
->constructor (type
, n_construct_properties
,
401 mozilla_embed_persist_class_init (MozillaEmbedPersistClass
*klass
)
403 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
404 EphyEmbedPersistClass
*persist_class
= EPHY_EMBED_PERSIST_CLASS (klass
);
406 parent_class
= (GObjectClass
*) g_type_class_peek_parent (klass
);
408 object_class
->finalize
= mozilla_embed_persist_finalize
;
409 object_class
->constructor
= mozilla_embed_persist_constructor
;
411 persist_class
->save
= impl_save
;
412 persist_class
->cancel
= impl_cancel
;
413 persist_class
->to_string
= impl_to_string
;
415 g_type_class_add_private (object_class
, sizeof(MozillaEmbedPersistPrivate
));