[webkit-reviews] review requested: [Bug 89873] [WK2][GTK] Implement new API to save a web page using MHTML : [Attachment 149501] Patch Proposal + Unit Tests + Documentation

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Tue Jun 26 03:09:42 PDT 2012


Mario Sanchez Prada <msanchez at igalia.com> has asked  for review:
Bug 89873: [WK2][GTK] Implement new API to save a web page using MHTML
https://bugs.webkit.org/show_bug.cgi?id=89873

Attachment 149501: Patch Proposal + Unit Tests + Documentation
https://bugs.webkit.org/attachment.cgi?id=149501&action=review

------- Additional Comments from Mario Sanchez Prada <msanchez at igalia.com>
Attaching new patch addressing these issues. See comments below...

(In reply to comment #5)
> (From update of attachment 149284 [details])
> View in context:
https://bugs.webkit.org/attachment.cgi?id=149284&action=review
> 
> > Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp:2184
> > +static void webViewFileSavedCallback(GObject *object, GAsyncResult
*result, gpointer data)
> 
> The * are placed wrongly here. Also, I would call this something like
replaceContentsCallback to make it clear this is the callback of
g_file_replace_contents_async()

Fixed.

> > Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp:2190
> > +	 if (!g_file_replace_contents_finish(file, result, NULL, &error)) {
> 
> Use 0 instead of NULL

Fixed.
 
> > Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp:2192
> > +	     return;
> 
> Don't return here, or the operation will never complete.

Fixed.

> > Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp:2198
> > +static void webViewMHTMLDataGotCallback(WKDataRef wkData, WKErrorRef,
void* context)
> 
> getContentsAsMHTMLDataCallback?

Fixed.
 
> > Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp:2208
> > +	     /* We need to retain the data until the asyncronous process
> > +		initiated by the user has finished completely. */
> 
> Use C++ style comments

Fixed.
 
> > Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp:2211
> > +	     /* If we are saving to a file we need to write the data on disk
before finishing. */
> 
> Ditto.

Fixed.

> > Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp:2215
> > +		 GFile* file = g_file_new_for_path(data->filePath.get());
> 
> Use GRefPtr for the file, since you are leaking it.
g_file_replace_contents_async() will take a reference of the file, so you can
just adopt the ref here.
> 

Fixed.

> > Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp:2217
> > +		 g_file_replace_contents_async(file, reinterpret_cast<const
gchar*>(WKDataGetBytes(data->wkData.get())), WKDataGetSize(data->wkData.get()),
NULL, FALSE, G_FILE_CREATE_REPLACE_DESTINATION,
> > +					       data->cancellable.get(),
webViewFileSavedCallback, g_object_ref(result.get()));
> 
> Use 0 instead of NULL.
> 

Fixed.

> > Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp:2241
> > +void webkit_web_view_save(WebKitWebView *webView, WebKitWebViewSaveMode
saveMode, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer
userData)
> 
> WebKitWebView *webView -> WebKitWebView* webView
> 

Fixed.

> > Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp:2247
> > +	 /* We only support MHTML at the moment */
> > +	 if (saveMode != WEBKIT_SAVE_MODE_MHTML)
> > +	     return;
> 
> Use g_return_if_fail for this check.
> 

Fixed.

> > Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp:2256
> > +	 WKPageGetContentsAsMHTMLData(wkPage, false, result,
webViewMHTMLDataGotCallback);
> 
> Just curiosity, why not using binary mode?
> 

It will work either way in WebKit based browers, both for writing a valid .mht
file and for being able to read it later on with a MHTML capable browser.
However, considering the .mht is a file with content type text/html, I think
it's better not to use binary encoding for the resources, so you can easily
inspect it with a text editor (as the content type seems to suggest you should
be able to do it).

Also, as per the following comment in Source/WebKit/public/WebPageSerializer.h,
it seems binary encoding could be unsupported in some other browsers:

    [...]
    // Serializes the WebView contents to a MHTML representation.
    WEBKIT_EXPORT static WebCString serializeToMHTML(WebView*);

    // Similar to serializeToMHTML but uses binary encoding for the MHTML
parts.
    // This results in a smaller MHTML file but it might not be supported by
other browsers.
    WEBKIT_EXPORT static WebCString
serializeToMHTMLUsingBinaryEncoding(WebView*);
    [...]

So, my vote goes for using printable characters for the .mht file.

> > Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp:2288
> > +	 GInputStream* dataStream = 0;
> > +	 ViewSaveAsyncData* data =
static_cast<ViewSaveAsyncData*>(g_simple_async_result_get_op_res_gpointer(simpl
e));
> > +	 if (data) {
> > +	     gsize length = WKDataGetSize(data->wkData.get());
> > +	     dataStream =
g_memory_input_stream_new_from_data(g_memdup(WKDataGetBytes(data->wkData.get())
, length), length, g_free);
> > +	 }
> > +
> > +	 return dataStream;
> 
> We are saying that the function returns NULL in case of error, but here it
can return NULL for a valid empty page. If data is NULL, we could just return
an empty memory stream
> 

Fixed.

> > Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp:2294
> > + * @path: a string containing a relative or absolute path for the file
where the current web page should be saved to. The string must be encoded in
the glib filename encoding.
> 
> I'm wondering whether we should receive a GFile instead, and use it directly
in g_file_replace_contents
>  

Fixed.

> > Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp:2316
> > +	 /* We only support MHTML at the moment */
> > +	 if (saveMode != WEBKIT_SAVE_MODE_MHTML)
> > +	     return;
> 
> Use g_return_if_fail() for this check
>  

Fixed.
 
> > Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h:130
> > +typedef enum {
> > +	 WEBKIT_SAVE_MODE_MHTML
> > +} WebKitWebViewSaveMode;
> 
> Maybe WebKitSaveMode? or WebKitWebSaveMode and WEBKIT_WEB_SAVE_MODE_MHTML?
>   

Fixed. I used WebKitSaveMode.

> > Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp:867
> > +static void webViewSavedToFileCallback(GObject *object, GAsyncResult *res,
WebViewTest* test)
> 
> GObject *object -> GObject* object
> GAsyncResult *res -> GAsyncResult* result
>   

Fixed.

> > Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp:873
> > +	 g_main_loop_quit(test->m_mainLoop);
> 
> We have test->quitMainLoop() now.
>   

Fixed.

> > Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp:879
> > +	 GInputStream* inputStream =
webkit_web_view_save_finish(test->m_webView, res, &error);
> 
> Use GRefPtr and adopt the ref to not leak it.
>   

Fixed.

> > Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp:884
> > +	 GFile* file = g_file_new_for_path(kSaveDestinationFilePath);
> 
> Ditto.
>   

Fixed.

> > Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp:885
> > +	 GInputStream* savedFileInputStream = G_INPUT_STREAM(g_file_read(file,
NULL, &error));
> 
> Ditto. And use 0 instead of NULL
>   

Fixed.

> > Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp:894
> > +	 GOwnPtr<gchar> buffer1(g_new0(gchar, 512));
> > +	 GOwnPtr<gchar> buffer2(g_new0(gchar, 512));
> 
> Why not stack allocated buffers? 512 is small enough to use the stack, I'd
say.
> 

When I first started writing this unit test I considered bigger sizes for that
buffer and so that's why I ended up using the heap here. But I agree that 512
bytes is not that big, specially considering this is just an unit test, and
code is simpler.  

Fixed.

> > Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp:898
> > +	 while (readBytes = g_input_stream_read(inputStream, buffer1.outPtr(),
512, NULL, &error)) {
> 
> Use 0 instead of NULL
>   

Fixed.

> > Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp:901
> > +	     totalBytesFromFile += g_input_stream_read(savedFileInputStream,
buffer2.outPtr(), 512, NULL, &error);
> 
> Ditto.
>   

Fixed.

> > Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp:913
> > +	 // Check that the same minimum amount of bytes are received.
> > +	 g_assert_cmpint(totalBytesFromStream, ==, totalBytesFromFile);
> > +	 g_assert_cmpint(totalBytesFromStream, >=, 2048);
> > +
> > +	 g_input_stream_close(inputStream, NULL, NULL);
> > +	 g_input_stream_close(savedFileInputStream, NULL, NULL);
> 
> Since you are not going to compare the contents, I think this could be a lot
simpler if you just get the size of the file without reading it and only read
from the input stream
> 

Ok. I changed this test following your suggestions.

> > Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp:937
> > +	 test->waitUntilMainLoopFinishes();
> > +}
> 
> You should unlink and free the kSaveDestinationFilePath, or
g_rmdir(kTempDirectory); will fail

Fixed.


More information about the webkit-reviews mailing list