51
1 Qt Network Access: Flexible and Powerful Access to Data on the Internet Thiago Macieira Qt Developer Days 2008

DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

Embed Size (px)

Citation preview

Page 1: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

1

Qt Network Access:Flexible and Powerful Access to Data on the Internet

Thiago Macieira

Qt Developer Days 2008

Page 2: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

2

Who am I?

•Senior Software Engineer at Qt Software / Nokia

•Degrees in Engineering and an MBA

•Almost 2 years with the company

•Part of the Core Team• Work mostly with Networking, I/O, IPC, Threading, Tool Classes

•Other official duties:• Liaison to the KDE Community

• Release Manager for Qt

Page 3: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

3

Agenda

What’s coming in Qt 4.5What’s coming in Qt 4.5

The API in useThe API in use

The Qt Network Access APIThe Qt Network Access API

Background and rationaleBackground and rationale

Page 4: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

4

Agenda

What’s coming in Qt 4.5

The API in use

The Qt Network Access API

Background and rationaleBackground and rationale

Page 5: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

5

Data on the Internet

•The Internet is full of data• Some good, some bad, but that's not the point

•Intranets and Extranets too• Not just the World Wide Web

•Applications often need to access data

Page 6: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

6

Data on the Internet

•The Internet is full of data• Some good, some bad, but that's not the point

•Intranets and Extranets too• Not just the World Wide Web

•Applications often need to access data• Download updates or optional features

• Upload results

• Obtain reports, weather forecast

Page 7: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

7

Before Qt Network Access...

•There was QHttp and QFtp

•Low-level access to HTTP and FTP communication• Ability to send any command

• Full access to the response (non-standard replies)

•In Qt 3.x, there was QUrlOperator

Page 8: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

8

But QHttp and QFtp could be better

•Operations are too low-level• Developer must know how HTTP and FTP work

• Easy to make mistakes

•Fragile• Easy to break

•Almost no parsing of replies• You must implement the rest

Page 9: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

9

Sample QHttp usage

•Things to remember:• Read everything at the requestFinished signal

• Match the contents with the “id” you saved

QHttp http;http.setHost(“trolltech.com”);int id1 = http.get(“/”);int id2 = http.get(“/qtdevdays2008”);connect(&http, SIGNAL(requestFinished(int,bool)), ...);

Page 10: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

10

And QHttp could support more of HTTP

•The HTTP protocol is full of features

•QHttp supports a small subset only

•Improving support was on the plans• It would require a full refactoring

Page 11: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

11

Then QtWebKit came along...

•WebKit required an abstraction layer• Early code worked with QHttp

• No support for FTP

• Separate code for dealing with files

•WebKit comes from KDE’s KHTML• Originally, KHTML used KIO

Page 12: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

12

We had no choice, did we?

•Requirements were:• Easy to use, but possible to extend

• HTTP/1.1, FTP, local files, “data:”

• Abstract the differences away

•WebKit also required some more features• Cookies

• Proxy handling

• Authentication cache

• Simultaneous requests

Page 13: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

13

Agenda

What’s coming in Qt 4.5

The API in use

The Qt Network Access APIThe Qt Network Access API

Background and rationale

Page 14: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

14

Enter Qt Network Access

•Three main classes

QNetworkAccessManager

QNetworkRequest QNetworkReply

Page 15: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

15

QNetworkRequest

•Represents one request to be sent

•Main component: one URL

•Meta-data to the request:• HTTP headers

• SSL options

• Settings controlling behaviour

Page 16: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

16

QNetworkReply

•Read-only sequential-access QIODevice

•Data of the reply

•Meta-data:• URL

• Request associated

• HTTP headers and status

• Encryption status

• Error conditions

Page 17: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

17

QNetworkReply (cont.)

•Already open, but not finished yet

•Emits readyRead() when data arrives

•Emits finished() when done

•Emits error() if problem occurs

•Progress signals: downloadProgress() and uploadProgress()

Page 18: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

18

QNetworkAccessManager

•Operations supported:• HEAD – obtain status

• GET – download

• PUT – upload

• POST – HTTP-only

•For each operation, there’s one method• QNetworkRequest as input

• Data to be uploaded (if appropriate)

• QNetworkReply as output

Page 19: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

19

QNetworkAccessManager (cont.)

•Manages request queue

•Centralises settings• Cookie Jar

• Proxy

• More in 4.5

•Caches previous authentication successes

•Keeps connections open for some time

Page 20: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

20

Cookies

•Documentation defines as:• “Cookies are small bits of information that stateless protocols like HTTP use

to maintain some persistent information across requests.”

•One class: QNetworkCookie

•Does the parsing for you

•Recreates the raw form

Page 21: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

21

Getting and setting cookies

•Set cookies in a QNetworkRequest

•Retrieve them from a QNetworkReplyQNetworkCookie cookie(“key”, “value 42”);qDebug() << cookie; // prints: key=“value 42”

QNetworkRequest request;request.setHeader(QNetworkRequest::SetCookieHeader, cookie);

QList<QNetworkCookie> cookies = reply->header(QNetworkRequest::CookieHeader) .value<QList<QNetworkCookie> >();

Page 22: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

22

Where do you keep your cookies?

•In the cookie jar!

•QNetworkCookieJar

•Basic security only

•Two virtual functions:• cookiesForUrl

• setCookiesFromUrl

Page 23: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

23

Extending Qt Network Access – Why?

•Handling special requests

•Using a different backend

•Applying policies/filtering to requests allowed

•Rewriting URLs

•Changing default behaviour

Page 24: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

24

How do I extend it?

•QNetworkAccessManager has one virtual function:• createRequest()

• All requests are queued and sent by this function

•QNetworkReply is abstract• Implement pure virtuals

• Emit readyRead() and other signals

Page 25: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

25

Agenda

What’s coming in Qt 4.5

The API in useThe API in use

The Qt Network Access API

Background and rationale

Page 26: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

26

How easy is it?

•Simplest ways:

QNetworkAccessManager manager;QNetworkReply *reply = manager.get(QUrl(“http://trolltech.com”));connect(reply, SIGNAL(finished()), ...);

QNetworkAccessManager manager;connect(&manager, SIGNAL(finished(QNetworkReply*)), ...);manager.get(QUrl(“http://trolltech.com”));manager.get(QUrl(“http://trolltech.com/qtdevdays2008”));

Page 27: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

27

Old versus new

•Code does the same operation

QHttp http;http.setHost(“trolltech.com”);int id1 = http.get(“/”);int id2 = http.get(“/qtdevdays2008”);connect(&http, SIGNAL(requestFinished(int,bool)), ...);

QNetworkAccessManager manager;connect(&manager, SIGNAL(finished(QNetworkReply*)), ...);manager.get(QUrl(“http://trolltech.com”));manager.get(QUrl(“http://trolltech.com/qtdevdays2008”));

Page 28: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

28

Full example – Downloader classclass Download: public QObject{ Q_OBJECT QNetworkAccessManager manager;public: Download() { connect(&manager, SIGNAL(finished(QNetworkReply*)), SLOT(finished(QNetworkReply*))); }

void download(const QUrl &url) { manager.get(url); }

private slots: void finished(QNetworkReply *reply) { reply->deleteLater(); emit done(reply->url(), reply->readAll()); }

signals: void done(const QUrl &url, const QByteArray &data);};

Page 29: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

29

Full example – Downloader classclass Download: public QObject{ Q_OBJECT QNetworkAccessManager manager;public: Download() { connect(&manager, SIGNAL(finished(QNetworkReply*)), SLOT(finished(QNetworkReply*))); }

void download(const QUrl &url) { manager.get(url); }

private slots: void finished(QNetworkReply *reply) { reply->deleteLater(); emit done(reply->url(), reply->readAll()); }

signals: void done(const QUrl &url, const QByteArray &data);};

QNetworkAccessManager manager;public: Download() { connect(&manager, SIGNAL(finished(QNetworkReply*)), SLOT(finished(QNetworkReply*))); }

Page 30: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

30

Full example – Downloader classclass Download: public QObject{ Q_OBJECT QNetworkAccessManager manager;public: Download() { connect(&manager, SIGNAL(finished(QNetworkReply*)), SLOT(finished(QNetworkReply*))); }

void download(const QUrl &url) { manager.get(url); }

private slots: void finished(QNetworkReply *reply) { reply->deleteLater(); emit done(reply->url(), reply->readAll()); }

signals: void done(const QUrl &url, const QByteArray &data);};

void download(const QUrl &url) { manager.get(url); }

signals: void done(const QUrl &url, const QByteArray &data);

Page 31: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

31

Full example – Downloader classclass Download: public QObject{ Q_OBJECT QNetworkAccessManager manager;public: Download() { connect(&manager, SIGNAL(finished(QNetworkReply*)), SLOT(finished(QNetworkReply*))); }

void download(const QUrl &url) { manager.get(url); }

private slots: void finished(QNetworkReply *reply) { reply->deleteLater(); emit done(reply->url(), reply->readAll()); }

signals: void done(const QUrl &url, const QByteArray &data);};

private slots: void finished(QNetworkReply *reply) { reply->deleteLater(); emit done(reply->url(), reply->readAll()); }

Page 32: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

32

Full example – Downloader class

class Download: public QObject{ Q_OBJECT QNetworkAccessManager manager;public: Download() { connect(&manager, SIGNAL(finished(QNetworkReply*)), SLOT(finished(QNetworkReply*))); }

void download(const QUrl &url) { manager.get(url); }

private slots: void finished(QNetworkReply *reply) { reply->deleteLater(); emit done(reply->url(), reply->readAll()); }

signals: void done(const QUrl &url, const QByteArray &data);};

Page 33: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

33

Downloader class – improving it

•Handle authentication challenges

•Handle error conditions

•Handle SSL issues

•Allow access to the meta-data

•Use a shared QNetworkAccessManager

Page 34: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

34

QNetworkAccessManager manager;public: Download() { connect(&manager, SIGNAL(finished(QNetworkReply*)), SLOT(finished(QNetworkReply*))); }

Downloader class – authentication challenges

•Just connect to the extra signals

Page 35: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

QNetworkAccessManager manager;public: Download() { connect(&manager, SIGNAL(finished(QNetworkReply*)), SLOT(finished(QNetworkReply*))); connect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), ...); connect(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), ...); }

Downloader class – authentication challenges

•Just connect to the extra signals

Page 36: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

private slots: void finished(QNetworkReply *reply) { reply->deleteLater(); if (reply->error() != QNetworkReply::NoError) { // do something about this error } else emit done(reply->url(), reply->readAll()); }

Downloader class – error handling (alternative 1)

•The “finished” signal is still emitted

•The error code is saved in the reply

Page 37: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

37

Downloader class – error handling (alternative 2)

•Or you can use the “error” signal

•That one is per reply

void download(const QUrl &url) { QNetworkReply *reply = manager.get(url); connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), ...); }

Page 38: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

38

Synchronous downloading

•No “waitFor” functions – you must use the event loop

QByteArray synchronousDownload(const QNetworkRequest &request){ QNetworkReply *reply = manager.get(request);

QEventLoop loop; connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); loop.exec();

return reply->readAll();}

Page 39: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

39

Agenda

What’s coming in Qt 4.5What’s coming in Qt 4.5

The API in use

The Qt Network Access API

Background and rationale

Page 40: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

40

What’s coming in Qt 4.5?

•Page caching

•Proxy factory

Page 41: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

41

Data caching

•Problematic: • Network transfers are costly

• Therefore, we should avoid re-transferring

•New abstract base class: QAbstractNetworkCache

•Integrated with QNetworkAccessManager • setCache(QAbstractNetworkCache *)

• Automatically uses the cache

Page 42: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

42

Cache access policies

•Four policies to choose from:• AlwaysNetwork

• PreferNetwork

• PreferCache

• AlwaysCache

•In a web browser• Default: PreferNetwork

• Reload button: AlwaysNetwork

• Offline browsing: AlwaysCache

Page 43: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

43

Caching on disk

•Public class: QNetworkDiskCache

•Sample implementation of data caching

•Saves all data to one directory on disk

•Controls cache size

•Should work from multiple processes...

Page 44: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

44

Proxy factory

•Problematic:• Different destinations accessed via different proxies

• Support for Proxy Auto Configuration (PAC) scripts

•One single proxy for all requests doesn’t cut it...

•New abstract class: QNetworkProxyFactory

•Integrated with QNetworkAccessManager: • setProxyFactory(QNetworkProxyFactory *)

Page 45: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

45

How does it work?

•For each request, obtain a list of proxies to try

•Currently we use the suitable one

Proxy factoryRequestQNetworkReplyQNetworkReplyQNetworkReplyQNetworkProxy

Page 46: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

46

Proxy Auto Configuration scripts

•Basically JavaScript code to choose a proxy

•Maps to the QNetworkProxyFactory model

•Interpreter provided on Labs

JavaScriptHostname,URL

QNetworkReplyQNetworkReplyQNetworkReplyQNetworkProxy

Page 47: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

47

Qt 4.5 is just around the corner

•Technical Preview just released

•Updates and fixes available via Snapshots

Page 48: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

48

Agenda

SummarySummary

Page 49: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

49

Summary

•Qt Network Access is very powerful

•Easily extensible

Page 50: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

Extra slidesExtra slides

Appendix

Page 51: DevDays2008 - Qt Network AccessFlexible and Powerful Access to Data on the Internet

51

Uniform Resource Locator (URL)

•Data is identified by a URL

•The Qt class for this is QUrl

•Examples:http://www.example.net/faq.html#question13

ftp://ftp.example.com/pub/something/

ftp://tray:[email protected]:2021

mailto:[email protected]