[Interest] Using different QNetworkAccessManager instances for multiple QML's WebView items

Jan Kundrát jkt at flaska.net
Mon Apr 30 20:18:33 CEST 2012


Hi,
my desktop e-mail application [1] currently uses QWebView for rendering
of the contents of the HTML e-mails. Whenever the user opens a new
message, a new instance of a subclass of QNetworkAccessManager gets
created (which is private for the message view); this QNAM is tied
(through QPersistentModelIndex) to an instance of a QAbstractItemModel
subclass which is responsible for providing the actual data. The GUI
code creates a QWebView which loads data through a special URL like
"trojita-imap://msg/1.2.HEADER".

By design, the URL does *not* contain any identification of the target
message, mailbox or account -- the access is limited to just parts of
the same message, so that an HTML mail can reference an enclosed image,
but does not have an access to any other messages -- if this limitation
wasn't in place, a malicious message could use links like
"trojita-imap://message-uid-12345/1.BODY" to display data from other
e-mails the user has in her mailbox, which would have obvious security
implications, if only for phishing purposes.

This whole thing means that when the user opens three messages at once,
there are three completely different QNAM instances around. In future,
when my client supports multiple accounts, these instances might not
even share the same QAIM model. Such a design is possible because the
QWebView widgets allow me to specify the QNAM on a per-widget basis.

I'm trying to port this code to QML for use on cell phones. According to
src/3rdparty/webkit/WebKit/qt/declarative/qdeclarativewebview.cpp, the
QML WebView element apparently doesn't support specifying a QNAM on a
per-item basis; there's a QDeclarativeNetworkAccessManagerFactory which
can be set for a QDeclarativeView, but there doesn't appear to be
anything which would allow me to change this on the fly and just for one
WebView.

Furthermore, the documentation is pretty clear that the QDNAMF's
create() function shall be reentrant. My interpretation is that even
though I can create a "new" instance of my (future) QNAM subclass, all
of these instances would still share the single source model, and that
would lead to multiple threads (created by the QML engine somehow,
apparently) accessing my single Model instance without any sort of
locking, leading to the usual race conditions.

I could probably workaround this threading stuff by creating some
"forwarding" QNetworkReply dummies and doing all of the locking in some
bridging class. That'd be ugly, IMHO, but doable. The problem is that it
won't be enough for a use case where user opens two messages "at once",
ie. there are going to be two independent "message views", each of them
looking at a specific message. I absolutely have to prevent each of them
from accessing data of the other message, yet the single
QNAM-producing-factory assigned to the QDeclarativeView has no means of
enforcing that.

Right now, one way out of this (while still using the webkit engine)
which I can think around is to have the webkit work entirely outside the
QML realm and just let QML render the resulting pixmap. I guess that
doing that would lead to terrible performance and would bring issues on
its own (like not being able to select and copy/paste text around).

Another thing would be to build on top of the QDeclarativeWebViewPrivate
class, letting it use a specific QNAM -- that must be doable, but looks
like a huge amount of work (I haven't used *graphical* items implemented
in C++ from QML yet, just some basic QObjects).

The last thing would be to say "there's gonna be no HTML in the mobile
version" and work just with the basic text elements; doing so would
however needlessly limit my client, which is, again, suboptimal.

If the above makes sense, I'd be grateful for any pointers about how to
fix that. If my description is not clear, please let me know and I'll do
my best to clarify.

With kind regards,
Jan

[1] http://trojita.flaska.net/

-- 
Trojita, a fast e-mail client -- http://trojita.flaska.net/

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 262 bytes
Desc: OpenPGP digital signature
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20120430/2b79ecd1/attachment.sig>


More information about the Interest mailing list