Changeset 561 for trunk/src/network
- Timestamp:
- Feb 11, 2010, 11:19:06 PM (16 years ago)
- Location:
- trunk
- Files:
-
- 127 edited
- 16 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk
-
Property svn:mergeinfo
set to (toggle deleted branches)
/branches/vendor/nokia/qt/4.6.1 merged eligible /branches/vendor/nokia/qt/current merged eligible /branches/vendor/trolltech/qt/current 3-149
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
trunk/src/network/access/access.pri
r2 r561 3 3 HEADERS += access/qftp.h \ 4 4 access/qhttp.h \ 5 access/qhttpnetworkheader_p.h \ 6 access/qhttpnetworkrequest_p.h \ 7 access/qhttpnetworkreply_p.h \ 5 8 access/qhttpnetworkconnection_p.h \ 9 access/qhttpnetworkconnectionchannel_p.h \ 10 access/qfilenetworkreply_p.h \ 6 11 access/qnetworkaccessmanager.h \ 7 12 access/qnetworkaccessmanager_p.h \ … … 16 21 access/qnetworkcookie.h \ 17 22 access/qnetworkcookie_p.h \ 23 access/qnetworkcookiejar.h \ 24 access/qnetworkcookiejar_p.h \ 18 25 access/qnetworkrequest.h \ 19 26 access/qnetworkrequest_p.h \ … … 28 35 SOURCES += access/qftp.cpp \ 29 36 access/qhttp.cpp \ 37 access/qhttpnetworkheader.cpp \ 38 access/qhttpnetworkrequest.cpp \ 39 access/qhttpnetworkreply.cpp \ 30 40 access/qhttpnetworkconnection.cpp \ 41 access/qhttpnetworkconnectionchannel.cpp \ 42 access/qfilenetworkreply.cpp \ 31 43 access/qnetworkaccessmanager.cpp \ 32 44 access/qnetworkaccesscache.cpp \ … … 39 51 access/qnetworkaccesshttpbackend.cpp \ 40 52 access/qnetworkcookie.cpp \ 53 access/qnetworkcookiejar.cpp \ 41 54 access/qnetworkrequest.cpp \ 42 55 access/qnetworkreply.cpp \ … … 49 62 INCLUDEPATH += ../3rdparty/zlib 50 63 } else:!contains(QT_CONFIG, no-zlib) { 51 unix:LIBS += -lz64 unix:LIBS_PRIVATE += -lz 52 65 # win32:LIBS += libz.lib 53 66 } -
trunk/src/network/access/qabstractnetworkcache.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 284 284 285 285 /*! 286 \since 4.6 287 286 288 Returns all the attributes stored with this cache item. 287 289 … … 294 296 295 297 /*! 298 \since 4.6 299 296 300 Sets all attributes of this cache item to be the map \a attributes. 297 301 -
trunk/src/network/access/qabstractnetworkcache.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** -
trunk/src/network/access/qabstractnetworkcache_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** -
trunk/src/network/access/qftp.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 315 315 bytesFromSocket.clear(); 316 316 317 if (socket) 317 if (socket) { 318 318 delete socket; 319 socket = 0; 320 } 319 321 socket = new QTcpSocket(this); 320 322 socket->setObjectName(QLatin1String("QFtpDTP Passive state socket")); … … 870 872 // qDebug("QFtpPI state: %d [connected()]", state); 871 873 #endif 874 // try to improve performance by setting TCP_NODELAY 875 commandSocket.setSocketOption(QAbstractSocket::LowDelayOption, 1); 876 872 877 emit connectState(QFtp::Connected); 873 878 } … … 1292 1297 \brief The QFtp class provides an implementation of the client side of FTP protocol. 1293 1298 1294 \ingroup io1299 \ingroup network 1295 1300 \inmodule QtNetwork 1296 \mainclass 1301 1297 1302 1298 1303 This class provides a direct interface to FTP that allows you to … … 1341 1346 their results. 1342 1347 1343 Example: If you want to download the INSTALL file from Trolltech's1348 Example: If you want to download the INSTALL file from the Qt 1344 1349 FTP server, you would write this: 1345 1350 … … 1386 1391 non-Unix FTP servers. 1387 1392 1388 \sa Q Http, QNetworkAccessManager, QNetworkRequest, QNetworkReply,1393 \sa QNetworkAccessManager, QNetworkRequest, QNetworkReply, 1389 1394 {FTP Example} 1390 1395 */ … … 1659 1664 int QFtp::connectToHost(const QString &host, quint16 port) 1660 1665 { 1661 d_func()->pi.transferConnectionExtended = true;1662 1666 QStringList cmds; 1663 1667 cmds << host; 1664 1668 cmds << QString::number((uint)port); 1665 return d_func()->addCommand(new QFtpCommand(ConnectToHost, cmds)); 1669 int id = d_func()->addCommand(new QFtpCommand(ConnectToHost, cmds)); 1670 d_func()->pi.transferConnectionExtended = true; 1671 return id; 1666 1672 } 1667 1673 … … 1722 1728 int QFtp::setTransferMode(TransferMode mode) 1723 1729 { 1730 int id = d_func()->addCommand(new QFtpCommand(SetTransferMode, QStringList())); 1724 1731 d_func()->pi.transferConnectionExtended = true; 1725 1732 d_func()->transferMode = mode; 1726 return d_func()->addCommand(new QFtpCommand(SetTransferMode, QStringList()));1733 return id; 1727 1734 } 1728 1735 … … 1731 1738 port. Calling this function with \a host empty disables proxying. 1732 1739 1733 QFtp does not support FTP-over-HTTP proxy servers. Use QHttp for1734 this.1740 QFtp does not support FTP-over-HTTP proxy servers. Use 1741 QNetworkAccessManager for this. 1735 1742 */ 1736 1743 int QFtp::setProxy(const QString &host, quint16 port) -
trunk/src/network/access/qftp.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** -
trunk/src/network/access/qhttp.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 65 65 #endif 66 66 67 #ifndef QT_NO_HTTP 68 67 69 QT_BEGIN_NAMESPACE 68 69 #ifndef QT_NO_HTTP70 70 71 71 class QHttpNormalRequest; … … 122 122 void _q_slotClosed(); 123 123 void _q_slotBytesWritten(qint64 numBytes); 124 #ifndef QT_NO_OPENSSL 125 void _q_slotEncryptedBytesWritten(qint64 numBytes); 126 #endif 124 127 void _q_slotDoFinished(); 125 128 void _q_slotSendRequest(); … … 135 138 void closeConn(); 136 139 void setSock(QTcpSocket *sock); 140 141 void postMoreData(); 137 142 138 143 QTcpSocket *socket; … … 514 519 /*! 515 520 \class QHttpHeader 521 \obsolete 516 522 \brief The QHttpHeader class contains header information for HTTP. 517 523 518 \ingroup io524 \ingroup network 519 525 \inmodule QtNetwork 520 526 … … 625 631 QHttpHeader::~QHttpHeader() 626 632 { 627 delete d_ptr;628 633 } 629 634 … … 951 956 952 957 /*! 953 Returns true if the header has an entry for the thespecial HTTP958 Returns true if the header has an entry for the special HTTP 954 959 header field \c content-type; otherwise returns false. 955 960 … … 1008 1013 /*! 1009 1014 \class QHttpResponseHeader 1015 \obsolete 1010 1016 \brief The QHttpResponseHeader class contains response header information for HTTP. 1011 1017 1012 \ingroup io1018 \ingroup network 1013 1019 \inmodule QtNetwork 1014 1020 … … 1153 1159 } 1154 1160 1155 /*! \ reimp1161 /*! \internal 1156 1162 */ 1157 1163 bool QHttpResponseHeader::parseLine(const QString &line, int number) … … 1212 1218 /*! 1213 1219 \class QHttpRequestHeader 1220 \obsolete 1214 1221 \brief The QHttpRequestHeader class contains request header information for HTTP. 1215 1222 1216 \ingroup io1223 \ingroup network 1217 1224 \inmodule QtNetwork 1218 1225 … … 1367 1374 } 1368 1375 1369 /*! \ reimp1376 /*! \internal 1370 1377 */ 1371 1378 bool QHttpRequestHeader::parseLine(const QString &line, int number) … … 1414 1421 /*! 1415 1422 \class QHttp 1423 \obsolete 1416 1424 \reentrant 1417 1425 1418 1426 \brief The QHttp class provides an implementation of the HTTP protocol. 1419 1427 1420 \ingroup io1428 \ingroup network 1421 1429 \inmodule QtNetwork 1422 \mainclass 1430 1423 1431 1424 1432 This class provides a direct interface to HTTP that allows you to 1425 have more control over the requests and that allows you to access1426 the response header fields.However, for new applications, it is1433 download and upload data with the HTTP protocol. 1434 However, for new applications, it is 1427 1435 recommended to use QNetworkAccessManager and QNetworkReply, as 1428 those classes possess a simpler, yet more powerful API. 1436 those classes possess a simpler, yet more powerful API 1437 and a more modern protocol implementation. 1429 1438 1430 1439 The class works asynchronously, so there are no blocking … … 1447 1456 1448 1457 To make an HTTP request you must set up suitable HTTP headers. The 1449 following example demonstrates, how to request the main HTML page 1450 from the Trolltech home page (i.e., the URL 1451 \c http://qtsoftware.com/index.html): 1458 following example demonstrates how to request the main HTML page 1459 from the Qt website (i.e., the URL \c http://qt.nokia.com/index.html): 1452 1460 1453 1461 \snippet doc/src/snippets/code/src_network_access_qhttp.cpp 2 … … 1593 1601 This enum is used to specify the mode of connection to use: 1594 1602 1595 \value ConnectionModeHttp The connection is a regular H ttpconnection to the server1596 \value ConnectionModeHttps The H ttpsprotocol is used and the connection is encrypted using SSL.1597 1598 When using the H ttpsmode, care should be taken to connect to the sslErrors signal, and1599 handle possible S slerrors.1603 \value ConnectionModeHttp The connection is a regular HTTP connection to the server 1604 \value ConnectionModeHttps The HTTPS protocol is used and the connection is encrypted using SSL. 1605 1606 When using the HTTPS mode, care should be taken to connect to the sslErrors signal, and 1607 handle possible SSL errors. 1600 1608 1601 1609 \sa QSslSocket … … 2035 2043 2036 2044 If port is 0, it will use the default port for the \a mode used 2037 (80 for H ttp and 443 fopr Https).2045 (80 for HTTP and 443 for HTTPS). 2038 2046 2039 2047 The function does not block; instead, it returns immediately. The request … … 2162 2170 2163 2171 \a path must be a absolute path like \c /index.html or an 2164 absolute URI like \c http:// qtsoftware.com/index.html and2172 absolute URI like \c http://example.com/index.html and 2165 2173 must be encoded with either QUrl::toPercentEncoding() or 2166 2174 QUrl::encodedPath(). … … 2201 2209 2202 2210 \a path must be an absolute path like \c /index.html or an 2203 absolute URI like \c http:// qtsoftware.com/index.html and2211 absolute URI like \c http://example.com/index.html and 2204 2212 must be encoded with either QUrl::toPercentEncoding() or 2205 2213 QUrl::encodedPath(). … … 2252 2260 2253 2261 \a path must be an absolute path like \c /index.html or an 2254 absolute URI like \c http:// qtsoftware.com/index.html.2262 absolute URI like \c http://example.com/index.html. 2255 2263 2256 2264 The function does not block; instead, it returns immediately. The request … … 2657 2665 } 2658 2666 2667 #ifndef QT_NO_OPENSSL 2668 void QHttpPrivate::_q_slotEncryptedBytesWritten(qint64 written) 2669 { 2670 Q_UNUSED(written); 2671 postMoreData(); 2672 } 2673 #endif 2674 2659 2675 void QHttpPrivate::_q_slotBytesWritten(qint64 written) 2660 2676 { … … 2662 2678 bytesDone += written; 2663 2679 emit q->dataSendProgress(bytesDone, bytesTotal); 2664 2680 postMoreData(); 2681 } 2682 2683 // Send the POST data 2684 void QHttpPrivate::postMoreData() 2685 { 2665 2686 if (pendingPost) 2666 2687 return; … … 2669 2690 return; 2670 2691 2692 // the following is backported code from Qt 4.6 QNetworkAccessManager. 2693 // We also have to check the encryptedBytesToWrite() if it is an SSL socket. 2694 #ifndef QT_NO_OPENSSL 2695 QSslSocket *sslSocket = qobject_cast<QSslSocket*>(socket); 2696 // if it is really an ssl socket, check more than just bytesToWrite() 2697 if ((socket->bytesToWrite() + (sslSocket ? sslSocket->encryptedBytesToWrite() : 0)) == 0) { 2698 #else 2671 2699 if (socket->bytesToWrite() == 0) { 2700 #endif 2672 2701 int max = qMin<qint64>(4096, postDevice->size() - postDevice->pos()); 2673 2702 QByteArray arr; … … 3087 3116 q, SLOT(_q_slotBytesWritten(qint64))); 3088 3117 #ifndef QT_NO_NETWORKPROXY 3089 QObject::connect(socket, SIGNAL(proxyAuthenticationRequired( const QNetworkProxy &, QAuthenticator*)),3090 q, SIGNAL(proxyAuthenticationRequired( const QNetworkProxy &, QAuthenticator*)));3118 QObject::connect(socket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), 3119 q, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); 3091 3120 #endif 3092 3121 3093 3122 #ifndef QT_NO_OPENSSL 3094 3123 if (qobject_cast<QSslSocket *>(socket)) { 3095 QObject::connect(socket, SIGNAL(sslErrors(const QList<QSslError> &)), 3096 q, SIGNAL(sslErrors(const QList<QSslError> &))); 3124 QObject::connect(socket, SIGNAL(sslErrors(QList<QSslError>)), 3125 q, SIGNAL(sslErrors(QList<QSslError>))); 3126 QObject::connect(socket, SIGNAL(encryptedBytesWritten(qint64)), 3127 q, SLOT(_q_slotEncryptedBytesWritten(qint64))); 3097 3128 } 3098 3129 #endif -
trunk/src/network/access/qhttp.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 47 47 #include <QtCore/qmap.h> 48 48 #include <QtCore/qpair.h> 49 #include <QtCore/qscopedpointer.h> 49 50 50 51 QT_BEGIN_HEADER … … 109 110 QHttpHeader(QHttpHeaderPrivate &dd, const QString &str = QString()); 110 111 QHttpHeader(QHttpHeaderPrivate &dd, const QHttpHeader &header); 111 Q HttpHeaderPrivate *d_ptr;112 QScopedPointer<QHttpHeaderPrivate> d_ptr; 112 113 113 114 private: … … 290 291 Q_PRIVATE_SLOT(d_func(), void _q_slotClosed()) 291 292 Q_PRIVATE_SLOT(d_func(), void _q_slotBytesWritten(qint64 numBytes)) 293 #ifndef QT_NO_OPENSSL 294 Q_PRIVATE_SLOT(d_func(), void _q_slotEncryptedBytesWritten(qint64 numBytes)) 295 #endif 292 296 Q_PRIVATE_SLOT(d_func(), void _q_slotDoFinished()) 293 297 Q_PRIVATE_SLOT(d_func(), void _q_slotSendRequest()) -
trunk/src/network/access/qhttpnetworkconnection.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 41 41 42 42 #include "qhttpnetworkconnection_p.h" 43 #include "qhttpnetworkconnectionchannel_p.h" 44 #include "private/qnoncontiguousbytedevice_p.h" 43 45 #include <private/qnetworkrequest_p.h> 44 46 #include <private/qobject_p.h> … … 46 48 #include <qnetworkproxy.h> 47 49 #include <qauthenticator.h> 48 #include <qbytearraymatcher.h> 50 49 51 #include <qbuffer.h> 50 52 #include <qpair.h> … … 60 62 #endif 61 63 62 #ifndef QT_NO_COMPRESS 63 # include <zlib.h> 64 static const unsigned char gz_magic[2] = {0x1f, 0x8b}; // gzip magic header 65 // gzip flag byte 66 #define HEAD_CRC 0x02 // bit 1 set: header CRC present 67 #define EXTRA_FIELD 0x04 // bit 2 set: extra field present 68 #define ORIG_NAME 0x08 // bit 3 set: original file name present 69 #define COMMENT 0x10 // bit 4 set: file comment present 70 #define RESERVED 0xE0 // bits 5..7: reserved 71 #define CHUNK 16384 64 65 66 QT_BEGIN_NAMESPACE 67 68 #ifdef Q_OS_SYMBIAN 69 const int QHttpNetworkConnectionPrivate::defaultChannelCount = 3; 70 #else 71 const int QHttpNetworkConnectionPrivate::defaultChannelCount = 6; 72 72 #endif 73 73 74 QT_BEGIN_NAMESPACE 75 76 class QHttpNetworkHeaderPrivate : public QSharedData 77 { 78 public: 79 QUrl url; 80 QList<QPair<QByteArray, QByteArray> > fields; 81 82 QHttpNetworkHeaderPrivate(const QUrl &newUrl = QUrl()); 83 QHttpNetworkHeaderPrivate(const QHttpNetworkHeaderPrivate &other); 84 inline qint64 contentLength() const; 85 inline void setContentLength(qint64 length); 86 87 inline QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const; 88 inline QList<QByteArray> headerFieldValues(const QByteArray &name) const; 89 inline void setHeaderField(const QByteArray &name, const QByteArray &data); 90 bool operator==(const QHttpNetworkHeaderPrivate &other) const; 91 92 }; 93 94 QHttpNetworkHeaderPrivate::QHttpNetworkHeaderPrivate(const QUrl &newUrl) 95 :url(newUrl) 96 { 97 } 98 99 QHttpNetworkHeaderPrivate::QHttpNetworkHeaderPrivate(const QHttpNetworkHeaderPrivate &other) 100 :QSharedData(other) 101 { 102 url = other.url; 103 fields = other.fields; 104 } 105 106 qint64 QHttpNetworkHeaderPrivate::contentLength() const 107 { 108 bool ok = false; 109 QByteArray value = headerField("content-length"); 110 qint64 length = value.toULongLong(&ok); 111 if (ok) 112 return length; 113 return -1; // the header field is not set 114 } 115 116 void QHttpNetworkHeaderPrivate::setContentLength(qint64 length) 117 { 118 setHeaderField("Content-Length", QByteArray::number(length)); 119 } 120 121 QByteArray QHttpNetworkHeaderPrivate::headerField(const QByteArray &name, const QByteArray &defaultValue) const 122 { 123 QList<QByteArray> allValues = headerFieldValues(name); 124 if (allValues.isEmpty()) 125 return defaultValue; 126 127 QByteArray result; 128 bool first = true; 129 foreach (QByteArray value, allValues) { 130 if (!first) 131 result += ", "; 132 first = false; 133 result += value; 134 } 135 return result; 136 } 137 138 QList<QByteArray> QHttpNetworkHeaderPrivate::headerFieldValues(const QByteArray &name) const 139 { 140 QList<QByteArray> result; 141 QByteArray lowerName = name.toLower(); 142 QList<QPair<QByteArray, QByteArray> >::ConstIterator it = fields.constBegin(), 143 end = fields.constEnd(); 144 for ( ; it != end; ++it) 145 if (lowerName == it->first.toLower()) 146 result += it->second; 147 148 return result; 149 } 150 151 void QHttpNetworkHeaderPrivate::setHeaderField(const QByteArray &name, const QByteArray &data) 152 { 153 QByteArray lowerName = name.toLower(); 154 QList<QPair<QByteArray, QByteArray> >::Iterator it = fields.begin(); 155 while (it != fields.end()) { 156 if (lowerName == it->first.toLower()) 157 it = fields.erase(it); 158 else 159 ++it; 160 } 161 fields.append(qMakePair(name, data)); 162 } 163 164 bool QHttpNetworkHeaderPrivate::operator==(const QHttpNetworkHeaderPrivate &other) const 165 { 166 return (url == other.url); 167 } 168 169 // QHttpNetworkRequestPrivate 170 class QHttpNetworkRequestPrivate : public QHttpNetworkHeaderPrivate 171 { 172 public: 173 QHttpNetworkRequestPrivate(QHttpNetworkRequest::Operation op, 174 QHttpNetworkRequest::Priority pri, const QUrl &newUrl = QUrl()); 175 QHttpNetworkRequestPrivate(const QHttpNetworkRequestPrivate &other); 176 ~QHttpNetworkRequestPrivate(); 177 bool operator==(const QHttpNetworkRequestPrivate &other) const; 178 QByteArray methodName() const; 179 QByteArray uri(bool throughProxy) const; 180 181 static QByteArray header(const QHttpNetworkRequest &request, bool throughProxy); 182 183 QHttpNetworkRequest::Operation operation; 184 QHttpNetworkRequest::Priority priority; 185 mutable QIODevice *data; 186 bool autoDecompress; 187 }; 188 189 QHttpNetworkRequestPrivate::QHttpNetworkRequestPrivate(QHttpNetworkRequest::Operation op, 190 QHttpNetworkRequest::Priority pri, const QUrl &newUrl) 191 : QHttpNetworkHeaderPrivate(newUrl), operation(op), priority(pri), data(0), 192 autoDecompress(false) 193 { 194 } 195 196 QHttpNetworkRequestPrivate::QHttpNetworkRequestPrivate(const QHttpNetworkRequestPrivate &other) 197 : QHttpNetworkHeaderPrivate(other) 198 { 199 operation = other.operation; 200 priority = other.priority; 201 data = other.data; 202 autoDecompress = other.autoDecompress; 203 } 204 205 QHttpNetworkRequestPrivate::~QHttpNetworkRequestPrivate() 206 { 207 } 208 209 bool QHttpNetworkRequestPrivate::operator==(const QHttpNetworkRequestPrivate &other) const 210 { 211 return QHttpNetworkHeaderPrivate::operator==(other) 212 && (operation == other.operation) 213 && (data == other.data); 214 } 215 216 QByteArray QHttpNetworkRequestPrivate::methodName() const 217 { 218 QByteArray ba; 219 switch (operation) { 220 case QHttpNetworkRequest::Options: 221 ba += "OPTIONS"; 222 break; 223 case QHttpNetworkRequest::Get: 224 ba += "GET"; 225 break; 226 case QHttpNetworkRequest::Head: 227 ba += "HEAD"; 228 break; 229 case QHttpNetworkRequest::Post: 230 ba += "POST"; 231 break; 232 case QHttpNetworkRequest::Put: 233 ba += "PUT"; 234 break; 235 case QHttpNetworkRequest::Delete: 236 ba += "DELETE"; 237 break; 238 case QHttpNetworkRequest::Trace: 239 ba += "TRACE"; 240 break; 241 case QHttpNetworkRequest::Connect: 242 ba += "CONNECT"; 243 break; 244 default: 245 break; 246 } 247 return ba; 248 } 249 250 QByteArray QHttpNetworkRequestPrivate::uri(bool throughProxy) const 251 { 252 QUrl::FormattingOptions format(QUrl::RemoveFragment); 253 254 // for POST, query data is send as content 255 if (operation == QHttpNetworkRequest::Post && !data) 256 format |= QUrl::RemoveQuery; 257 // for requests through proxy, the Request-URI contains full url 258 if (throughProxy) 259 format |= QUrl::RemoveUserInfo; 260 else 261 format |= QUrl::RemoveScheme | QUrl::RemoveAuthority; 262 QByteArray uri = url.toEncoded(format); 263 if (uri.isEmpty() || (throughProxy && url.path().isEmpty())) 264 uri += '/'; 265 return uri; 266 } 267 268 QByteArray QHttpNetworkRequestPrivate::header(const QHttpNetworkRequest &request, bool throughProxy) 269 { 270 QByteArray ba = request.d->methodName(); 271 QByteArray uri = request.d->uri(throughProxy); 272 ba += " " + uri; 273 274 QString majorVersion = QString::number(request.majorVersion()); 275 QString minorVersion = QString::number(request.minorVersion()); 276 ba += " HTTP/" + majorVersion.toLatin1() + "." + minorVersion.toLatin1() + "\r\n"; 277 278 QList<QPair<QByteArray, QByteArray> > fields = request.header(); 279 QList<QPair<QByteArray, QByteArray> >::const_iterator it = fields.constBegin(); 280 for (; it != fields.constEnd(); ++it) 281 ba += it->first + ": " + it->second + "\r\n"; 282 if (request.d->operation == QHttpNetworkRequest::Post) { 283 // add content type, if not set in the request 284 if (request.headerField("content-type").isEmpty()) 285 ba += "Content-Type: application/x-www-form-urlencoded\r\n"; 286 if (!request.d->data && request.d->url.hasQuery()) { 287 QByteArray query = request.d->url.encodedQuery(); 288 ba += "Content-Length: "+ QByteArray::number(query.size()) + "\r\n"; 289 ba += "\r\n"; 290 ba += query; 291 } else { 292 ba += "\r\n"; 293 } 294 } else { 295 ba += "\r\n"; 296 } 297 return ba; 298 } 299 300 class QHttpNetworkReplyPrivate : public QObjectPrivate, public QHttpNetworkHeaderPrivate 301 { 302 public: 303 QHttpNetworkReplyPrivate(const QUrl &newUrl = QUrl()); 304 ~QHttpNetworkReplyPrivate(); 305 qint64 readStatus(QAbstractSocket *socket); 306 void parseStatus(const QByteArray &status); 307 qint64 readHeader(QAbstractSocket *socket); 308 void parseHeader(const QByteArray &header); 309 qint64 readBody(QAbstractSocket *socket, QIODevice *out); 310 bool findChallenge(bool forProxy, QByteArray &challenge) const; 311 QAuthenticatorPrivate::Method authenticationMethod(bool isProxy) const; 312 void clear(); 313 314 qint64 transferRaw(QIODevice *in, QIODevice *out, qint64 size); 315 qint64 transferChunked(QIODevice *in, QIODevice *out); 316 qint64 getChunkSize(QIODevice *in, qint64 *chunkSize); 317 318 qint64 bytesAvailable() const; 319 bool isChunked(); 320 bool connectionCloseEnabled(); 321 bool isGzipped(); 322 #ifndef QT_NO_COMPRESS 323 bool gzipCheckHeader(QByteArray &content, int &pos); 324 int gunzipBodyPartially(QByteArray &compressed, QByteArray &inflated); 325 #endif 326 void removeAutoDecompressHeader(); 327 328 enum ReplyState { 329 NothingDoneState, 330 ReadingStatusState, 331 ReadingHeaderState, 332 ReadingDataState, 333 AllDoneState 334 } state; 335 336 QHttpNetworkRequest request; 337 int statusCode; 338 int majorVersion; 339 int minorVersion; 340 QString errorString; 341 QString reasonPhrase; 342 qint64 bodyLength; 343 qint64 contentRead; 344 qint64 totalProgress; 345 QByteArray fragment; 346 qint64 currentChunkSize; 347 qint64 currentChunkRead; 348 QPointer<QHttpNetworkConnection> connection; 349 bool initInflate; 350 bool streamEnd; 351 #ifndef QT_NO_COMPRESS 352 z_stream inflateStrm; 353 #endif 354 bool autoDecompress; 355 356 QByteArray responseData; // uncompressed body 357 QByteArray compressedData; // compressed body (temporary) 358 QBuffer requestDataBuffer; 359 bool requestIsBuffering; 360 bool requestIsPrepared; 361 }; 362 363 QHttpNetworkReplyPrivate::QHttpNetworkReplyPrivate(const QUrl &newUrl) 364 : QHttpNetworkHeaderPrivate(newUrl), state(NothingDoneState), statusCode(100), 365 majorVersion(0), minorVersion(0), bodyLength(0), contentRead(0), totalProgress(0), 366 currentChunkSize(0), currentChunkRead(0), connection(0), initInflate(false), 367 autoDecompress(false), requestIsBuffering(false), requestIsPrepared(false) 368 { 369 } 370 371 QHttpNetworkReplyPrivate::~QHttpNetworkReplyPrivate() 372 { 373 } 374 375 void QHttpNetworkReplyPrivate::clear() 376 { 377 state = NothingDoneState; 378 statusCode = 100; 379 bodyLength = 0; 380 contentRead = 0; 381 totalProgress = 0; 382 currentChunkSize = 0; 383 currentChunkRead = 0; 384 connection = 0; 385 #ifndef QT_NO_COMPRESS 386 if (initInflate) 387 inflateEnd(&inflateStrm); 388 #endif 389 initInflate = false; 390 streamEnd = false; 391 autoDecompress = false; 392 fields.clear(); 393 } 394 395 // QHttpNetworkReplyPrivate 396 qint64 QHttpNetworkReplyPrivate::bytesAvailable() const 397 { 398 return (state != ReadingDataState ? 0 : fragment.size()); 399 } 400 401 bool QHttpNetworkReplyPrivate::isGzipped() 402 { 403 QByteArray encoding = headerField("content-encoding"); 404 return encoding.toLower() == "gzip"; 405 } 406 407 void QHttpNetworkReplyPrivate::removeAutoDecompressHeader() 408 { 409 // The header "Content-Encoding = gzip" is retained. 410 // Content-Length is removed since the actual one send by the server is for compressed data 411 QByteArray name("content-length"); 412 QByteArray lowerName = name.toLower(); 413 QList<QPair<QByteArray, QByteArray> >::Iterator it = fields.begin(), 414 end = fields.end(); 415 while (it != end) { 416 if (name == it->first.toLower()) { 417 fields.erase(it); 418 break; 419 } 420 ++it; 421 } 422 423 } 424 425 bool QHttpNetworkReplyPrivate::findChallenge(bool forProxy, QByteArray &challenge) const 426 { 427 challenge.clear(); 428 // find out the type of authentication protocol requested. 429 QByteArray header = forProxy ? "proxy-authenticate" : "www-authenticate"; 430 // pick the best protocol (has to match parsing in QAuthenticatorPrivate) 431 QList<QByteArray> challenges = headerFieldValues(header); 432 for (int i = 0; i<challenges.size(); i++) { 433 QByteArray line = challenges.at(i); 434 if (!line.toLower().startsWith("negotiate")) 435 challenge = line; 436 } 437 return !challenge.isEmpty(); 438 } 439 440 QAuthenticatorPrivate::Method QHttpNetworkReplyPrivate::authenticationMethod(bool isProxy) const 441 { 442 // The logic is same as the one used in void QAuthenticatorPrivate::parseHttpResponse() 443 QAuthenticatorPrivate::Method method = QAuthenticatorPrivate::None; 444 QByteArray header = isProxy ? "proxy-authenticate" : "www-authenticate"; 445 QList<QByteArray> challenges = headerFieldValues(header); 446 for (int i = 0; i<challenges.size(); i++) { 447 QByteArray line = challenges.at(i).trimmed().toLower(); 448 if (method < QAuthenticatorPrivate::Basic 449 && line.startsWith("basic")) { 450 method = QAuthenticatorPrivate::Basic; 451 } else if (method < QAuthenticatorPrivate::Ntlm 452 && line.startsWith("ntlm")) { 453 method = QAuthenticatorPrivate::Ntlm; 454 } else if (method < QAuthenticatorPrivate::DigestMd5 455 && line.startsWith("digest")) { 456 method = QAuthenticatorPrivate::DigestMd5; 457 } 458 } 459 return method; 460 } 461 462 #ifndef QT_NO_COMPRESS 463 bool QHttpNetworkReplyPrivate::gzipCheckHeader(QByteArray &content, int &pos) 464 { 465 int method = 0; // method byte 466 int flags = 0; // flags byte 467 bool ret = false; 468 469 // Assure two bytes in the buffer so we can peek ahead -- handle case 470 // where first byte of header is at the end of the buffer after the last 471 // gzip segment 472 pos = -1; 473 QByteArray &body = content; 474 int maxPos = body.size()-1; 475 if (maxPos < 1) { 476 return ret; 477 } 478 479 // Peek ahead to check the gzip magic header 480 if (body[0] != char(gz_magic[0]) || 481 body[1] != char(gz_magic[1])) { 482 return ret; 483 } 484 pos += 2; 485 // Check the rest of the gzip header 486 if (++pos <= maxPos) 487 method = body[pos]; 488 if (pos++ <= maxPos) 489 flags = body[pos]; 490 if (method != Z_DEFLATED || (flags & RESERVED) != 0) { 491 return ret; 492 } 493 494 // Discard time, xflags and OS code: 495 pos += 6; 496 if (pos > maxPos) 497 return ret; 498 if ((flags & EXTRA_FIELD) && ((pos+2) <= maxPos)) { // skip the extra field 499 unsigned len = (unsigned)body[++pos]; 500 len += ((unsigned)body[++pos])<<8; 501 pos += len; 502 if (pos > maxPos) 503 return ret; 504 } 505 if ((flags & ORIG_NAME) != 0) { // skip the original file name 506 while(++pos <= maxPos && body[pos]) {} 507 } 508 if ((flags & COMMENT) != 0) { // skip the .gz file comment 509 while(++pos <= maxPos && body[pos]) {} 510 } 511 if ((flags & HEAD_CRC) != 0) { // skip the header crc 512 pos += 2; 513 if (pos > maxPos) 514 return ret; 515 } 516 ret = (pos < maxPos); // return failed, if no more bytes left 517 return ret; 518 } 519 520 int QHttpNetworkReplyPrivate::gunzipBodyPartially(QByteArray &compressed, QByteArray &inflated) 521 { 522 int ret = Z_DATA_ERROR; 523 unsigned have; 524 unsigned char out[CHUNK]; 525 int pos = -1; 526 527 if (!initInflate) { 528 // check the header 529 if (!gzipCheckHeader(compressed, pos)) 530 return ret; 531 // allocate inflate state 532 inflateStrm.zalloc = Z_NULL; 533 inflateStrm.zfree = Z_NULL; 534 inflateStrm.opaque = Z_NULL; 535 inflateStrm.avail_in = 0; 536 inflateStrm.next_in = Z_NULL; 537 ret = inflateInit2(&inflateStrm, -MAX_WBITS); 538 if (ret != Z_OK) 539 return ret; 540 initInflate = true; 541 streamEnd = false; 542 } 543 544 //remove the header. 545 compressed.remove(0, pos+1); 546 // expand until deflate stream ends 547 inflateStrm.next_in = (unsigned char *)compressed.data(); 548 inflateStrm.avail_in = compressed.size(); 549 do { 550 inflateStrm.avail_out = sizeof(out); 551 inflateStrm.next_out = out; 552 ret = inflate(&inflateStrm, Z_NO_FLUSH); 553 switch (ret) { 554 case Z_NEED_DICT: 555 ret = Z_DATA_ERROR; 556 // and fall through 557 case Z_DATA_ERROR: 558 case Z_MEM_ERROR: 559 inflateEnd(&inflateStrm); 560 initInflate = false; 561 return ret; 562 } 563 have = sizeof(out) - inflateStrm.avail_out; 564 inflated.append(QByteArray((const char *)out, have)); 565 } while (inflateStrm.avail_out == 0); 566 // clean up and return 567 if (ret <= Z_ERRNO || ret == Z_STREAM_END) { 568 inflateEnd(&inflateStrm); 569 initInflate = false; 570 } 571 streamEnd = (ret == Z_STREAM_END); 572 return ret; 573 } 574 #endif 575 576 qint64 QHttpNetworkReplyPrivate::readStatus(QAbstractSocket *socket) 577 { 578 qint64 bytes = 0; 579 char c; 580 581 while (socket->bytesAvailable()) { 582 // allow both CRLF & LF (only) line endings 583 if (socket->peek(&c, 1) == 1 && c == '\n') { 584 bytes += socket->read(&c, 1); // read the "n" 585 // remove the CR at the end 586 if (fragment.endsWith('\r')) { 587 fragment.truncate(fragment.length()-1); 588 } 589 parseStatus(fragment); 590 state = ReadingHeaderState; 591 fragment.clear(); // next fragment 592 break; 593 } else { 594 c = 0; 595 bytes += socket->read(&c, 1); 596 fragment.append(c); 597 } 598 } 599 return bytes; 600 } 601 602 void QHttpNetworkReplyPrivate::parseStatus(const QByteArray &status) 603 { 604 const QByteArrayMatcher sp(" "); 605 int i = sp.indexIn(status); 606 const QByteArray version = status.mid(0, i); 607 int j = sp.indexIn(status, i + 1); 608 const QByteArray code = status.mid(i + 1, j - i - 1); 609 const QByteArray reason = status.mid(j + 1, status.count() - j); 610 611 const QByteArrayMatcher slash("/"); 612 int k = slash.indexIn(version); 613 const QByteArrayMatcher dot("."); 614 int l = dot.indexIn(version, k); 615 const QByteArray major = version.mid(k + 1, l - k - 1); 616 const QByteArray minor = version.mid(l + 1, version.count() - l); 617 618 majorVersion = QString::fromAscii(major.constData()).toInt(); 619 minorVersion = QString::fromAscii(minor.constData()).toInt(); 620 statusCode = QString::fromAscii(code.constData()).toInt(); 621 reasonPhrase = QString::fromAscii(reason.constData()); 622 } 623 624 qint64 QHttpNetworkReplyPrivate::readHeader(QAbstractSocket *socket) 625 { 626 qint64 bytes = 0; 627 char crlfcrlf[5]; 628 crlfcrlf[4] = '\0'; 629 char c = 0; 630 bool allHeaders = false; 631 while (!allHeaders && socket->bytesAvailable()) { 632 if (socket->peek(&c, 1) == 1 && c == '\n') { 633 // check for possible header endings. As per HTTP rfc, 634 // the header endings will be marked by CRLFCRLF. But 635 // we will allow CRLFLF, LFLF & CRLFCRLF 636 if (fragment.endsWith("\n\r") || fragment.endsWith('\n')) 637 allHeaders = true; 638 } 639 bytes += socket->read(&c, 1); 640 fragment.append(c); 641 } 642 // we received all headers now parse them 643 if (allHeaders) { 644 parseHeader(fragment); 645 state = ReadingDataState; 646 fragment.clear(); // next fragment 647 bodyLength = contentLength(); // cache the length 648 } 649 return bytes; 650 } 651 652 void QHttpNetworkReplyPrivate::parseHeader(const QByteArray &header) 653 { 654 // see rfc2616, sec 4 for information about HTTP/1.1 headers. 655 // allows relaxed parsing here, accepts both CRLF & LF line endings 656 const QByteArrayMatcher lf("\n"); 657 const QByteArrayMatcher colon(":"); 658 int i = 0; 659 while (i < header.count()) { 660 int j = colon.indexIn(header, i); // field-name 661 if (j == -1) 662 break; 663 const QByteArray field = header.mid(i, j - i).trimmed(); 664 j++; 665 // any number of LWS is allowed before and after the value 666 QByteArray value; 667 do { 668 i = lf.indexIn(header, j); 669 if (i == -1) 670 break; 671 if (!value.isEmpty()) 672 value += ' '; 673 // check if we have CRLF or only LF 674 bool hasCR = (i && header[i-1] == '\r'); 675 int length = i -(hasCR ? 1: 0) - j; 676 value += header.mid(j, length).trimmed(); 677 j = ++i; 678 } while (i < header.count() && (header.at(i) == ' ' || header.at(i) == '\t')); 679 if (i == -1) 680 break; // something is wrong 681 682 fields.append(qMakePair(field, value)); 683 } 684 } 685 686 bool QHttpNetworkReplyPrivate::isChunked() 687 { 688 return headerField("transfer-encoding").toLower().contains("chunked"); 689 } 690 691 bool QHttpNetworkReplyPrivate::connectionCloseEnabled() 692 { 693 return (headerField("connection").toLower().contains("close") || 694 headerField("proxy-connection").toLower().contains("close")); 695 } 696 697 qint64 QHttpNetworkReplyPrivate::readBody(QAbstractSocket *socket, QIODevice *out) 698 { 699 qint64 bytes = 0; 700 if (isChunked()) { 701 bytes += transferChunked(socket, out); // chunked transfer encoding (rfc 2616, sec 3.6) 702 } else if (bodyLength > 0) { // we have a Content-Length 703 bytes += transferRaw(socket, out, bodyLength - contentRead); 704 if (contentRead + bytes == bodyLength) 705 state = AllDoneState; 706 } else { 707 bytes += transferRaw(socket, out, socket->bytesAvailable()); 708 } 709 if (state == AllDoneState) 710 socket->readAll(); // Read the rest to clean (CRLF) 711 contentRead += bytes; 712 return bytes; 713 } 714 715 qint64 QHttpNetworkReplyPrivate::transferRaw(QIODevice *in, QIODevice *out, qint64 size) 716 { 717 qint64 bytes = 0; 718 Q_ASSERT(in); 719 Q_ASSERT(out); 720 721 int toBeRead = qMin<qint64>(128*1024, qMin<qint64>(size, in->bytesAvailable())); 722 QByteArray raw(toBeRead, 0); 723 while (size > 0) { 724 qint64 read = in->read(raw.data(), raw.size()); 725 if (read == 0) 726 return bytes; 727 // ### error checking here 728 qint64 written = out->write(raw.data(), read); 729 if (written == 0) 730 return bytes; 731 if (read != written) 732 qDebug() << "### read" << read << "written" << written; 733 bytes += read; 734 size -= read; 735 out->waitForBytesWritten(-1); // throttle 736 } 737 return bytes; 738 739 } 740 741 qint64 QHttpNetworkReplyPrivate::transferChunked(QIODevice *in, QIODevice *out) 742 { 743 qint64 bytes = 0; 744 while (in->bytesAvailable()) { // while we can read from input 745 // if we are done with the current chunk, get the size of the new chunk 746 if (currentChunkRead >= currentChunkSize) { 747 currentChunkSize = 0; 748 currentChunkRead = 0; 749 if (bytes) { 750 char crlf[2]; 751 bytes += in->read(crlf, 2); // read the "\r\n" after the chunk 752 } 753 bytes += getChunkSize(in, ¤tChunkSize); 754 if (currentChunkSize == -1) 755 break; 756 } 757 // if the chunk size is 0, end of the stream 758 if (currentChunkSize == 0) { 759 state = AllDoneState; 760 break; 761 } 762 // otherwise, read data 763 qint64 readSize = qMin(in->bytesAvailable(), currentChunkSize - currentChunkRead); 764 QByteArray buffer(readSize, 0); 765 qint64 read = in->read(buffer.data(), readSize); 766 bytes += read; 767 currentChunkRead += read; 768 qint64 written = out->write(buffer); 769 Q_UNUSED(written); // Avoid compile warning when building release 770 Q_ASSERT(read == written); 771 // ### error checking here 772 out->waitForBytesWritten(-1); 773 } 774 return bytes; 775 } 776 777 qint64 QHttpNetworkReplyPrivate::getChunkSize(QIODevice *in, qint64 *chunkSize) 778 { 779 qint64 bytes = 0; 780 char crlf[2]; 781 *chunkSize = -1; 782 int bytesAvailable = in->bytesAvailable(); 783 while (bytesAvailable > bytes) { 784 qint64 sniffedBytes = in->peek(crlf, 2); 785 int fragmentSize = fragment.size(); 786 // check the next two bytes for a "\r\n", skip blank lines 787 if ((fragmentSize && sniffedBytes == 2 && crlf[0] == '\r' && crlf[1] == '\n') 788 ||(fragmentSize > 1 && fragment.endsWith('\r') && crlf[0] == '\n')) 789 { 790 bytes += in->read(crlf, 1); // read the \r or \n 791 if (crlf[0] == '\r') 792 bytes += in->read(crlf, 1); // read the \n 793 bool ok = false; 794 // ignore the chunk-extension 795 fragment = fragment.mid(0, fragment.indexOf(';')).trimmed(); 796 *chunkSize = fragment.toLong(&ok, 16); 797 fragment.clear(); 798 break; // size done 799 } else { 800 // read the fragment to the buffer 801 char c = 0; 802 bytes += in->read(&c, 1); 803 fragment.append(c); 804 } 805 } 806 return bytes; 807 } 808 809 // QHttpNetworkConnectionPrivate 810 811 typedef QPair<QHttpNetworkRequest, QHttpNetworkReply*> HttpMessagePair; 812 813 class QHttpNetworkConnectionPrivate : public QObjectPrivate 814 { 815 Q_DECLARE_PUBLIC(QHttpNetworkConnection) 816 public: 817 QHttpNetworkConnectionPrivate(const QString &hostName, quint16 port, bool encrypt); 818 ~QHttpNetworkConnectionPrivate(); 819 void init(); 820 void connectSignals(QAbstractSocket *socket); 821 822 enum SocketState { 823 IdleState = 0, // ready to send request 824 ConnectingState = 1, // connecting to host 825 WritingState = 2, // writing the data 826 WaitingState = 4, // waiting for reply 827 ReadingState = 8, // reading the reply 828 Wait4AuthState = 0x10, // blocked for send till the current authentication slot is done 829 BusyState = (ConnectingState|WritingState|WaitingState|ReadingState|Wait4AuthState) 830 }; 831 832 enum { ChunkSize = 4096 }; 833 834 int indexOf(QAbstractSocket *socket) const; 835 bool isSocketBusy(QAbstractSocket *socket) const; 836 bool isSocketWriting(QAbstractSocket *socket) const; 837 bool isSocketWaiting(QAbstractSocket *socket) const; 838 bool isSocketReading(QAbstractSocket *socket) const; 839 840 QHttpNetworkReply *queueRequest(const QHttpNetworkRequest &request); 841 void unqueueRequest(QAbstractSocket *socket); 842 void prepareRequest(HttpMessagePair &request); 843 bool sendRequest(QAbstractSocket *socket); 844 void receiveReply(QAbstractSocket *socket, QHttpNetworkReply *reply); 845 void resendCurrentRequest(QAbstractSocket *socket); 846 void closeChannel(int channel); 847 void copyCredentials(int fromChannel, QAuthenticator *auth, bool isProxy); 848 849 // private slots 850 void _q_bytesWritten(qint64 bytes); // proceed sending 851 void _q_readyRead(); // pending data to read 852 void _q_disconnected(); // disconnected from host 853 void _q_startNextRequest(); // send the next request from the queue 854 void _q_restartPendingRequest(); // send the currently blocked request 855 void _q_connected(); // start sending request 856 void _q_error(QAbstractSocket::SocketError); // error from socket 857 #ifndef QT_NO_NETWORKPROXY 858 void _q_proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth); // from transparent proxy 859 #endif 860 void _q_dataReadyReadNoBuffer(); 861 void _q_dataReadyReadBuffer(); 862 863 void createAuthorization(QAbstractSocket *socket, QHttpNetworkRequest &request); 864 bool ensureConnection(QAbstractSocket *socket); 865 QString errorDetail(QNetworkReply::NetworkError errorCode, QAbstractSocket *socket); 866 void eraseData(QHttpNetworkReply *reply); 867 #ifndef QT_NO_COMPRESS 868 bool expand(QAbstractSocket *socket, QHttpNetworkReply *reply, bool dataComplete); 869 #endif 870 void bufferData(HttpMessagePair &request); 871 void removeReply(QHttpNetworkReply *reply); 872 873 QString hostName; 874 quint16 port; 875 bool encrypt; 876 877 struct Channel { 878 QAbstractSocket *socket; 879 SocketState state; 880 QHttpNetworkRequest request; // current request 881 QHttpNetworkReply *reply; // current reply for this request 882 qint64 written; 883 qint64 bytesTotal; 884 bool resendCurrent; 885 int lastStatus; // last status received on this channel 886 bool pendingEncrypt; // for https (send after encrypted) 887 int reconnectAttempts; // maximum 2 reconnection attempts 888 QAuthenticatorPrivate::Method authMehtod; 889 QAuthenticatorPrivate::Method proxyAuthMehtod; 890 QAuthenticator authenticator; 891 QAuthenticator proxyAuthenticator; 892 #ifndef QT_NO_OPENSSL 893 bool ignoreSSLErrors; 894 #endif 895 Channel() :state(IdleState), reply(0), written(0), bytesTotal(0), resendCurrent(false), reconnectAttempts(2), 896 authMehtod(QAuthenticatorPrivate::None), proxyAuthMehtod(QAuthenticatorPrivate::None) 897 #ifndef QT_NO_OPENSSL 898 , ignoreSSLErrors(false) 899 #endif 900 {} 901 }; 902 static const int channelCount; 903 Channel channels[2]; // maximum of 2 socket connections to the server 904 bool pendingAuthSignal; // there is an incomplete authentication signal 905 bool pendingProxyAuthSignal; // there is an incomplete proxy authentication signal 906 907 void appendData(QHttpNetworkReply &reply, const QByteArray &fragment, bool compressed); 908 qint64 bytesAvailable(const QHttpNetworkReply &reply, bool compressed = false) const; 909 qint64 read(QHttpNetworkReply &reply, QByteArray &data, qint64 maxSize, bool compressed); 910 void emitReplyError(QAbstractSocket *socket, QHttpNetworkReply *reply, QNetworkReply::NetworkError errorCode); 911 bool handleAuthenticateChallenge(QAbstractSocket *socket, QHttpNetworkReply *reply, bool isProxy, bool &resend); 912 void allDone(QAbstractSocket *socket, QHttpNetworkReply *reply); 913 void handleStatus(QAbstractSocket *socket, QHttpNetworkReply *reply); 914 inline bool emitSignals(QHttpNetworkReply *reply); 915 inline bool expectContent(QHttpNetworkReply *reply); 916 917 #ifndef QT_NO_OPENSSL 918 void _q_encrypted(); // start sending request (https) 919 void _q_sslErrors(const QList<QSslError> &errors); // ssl errors from the socket 920 QSslConfiguration sslConfiguration(const QHttpNetworkReply &reply) const; 921 #endif 922 923 #ifndef QT_NO_NETWORKPROXY 924 QNetworkProxy networkProxy; 925 #endif 926 927 //The request queues 928 QList<HttpMessagePair> highPriorityQueue; 929 QList<HttpMessagePair> lowPriorityQueue; 930 }; 931 932 const int QHttpNetworkConnectionPrivate::channelCount = 2; 74 // the maximum amount of requests that might be pipelined into a socket 75 // from what was suggested, 3 seems to be OK 76 const int QHttpNetworkConnectionPrivate::defaultPipelineLength = 3; 77 933 78 934 79 QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(const QString &hostName, quint16 port, bool encrypt) 935 80 : hostName(hostName), port(port), encrypt(encrypt), 81 channelCount(defaultChannelCount), 936 82 pendingAuthSignal(false), pendingProxyAuthSignal(false) 937 83 #ifndef QT_NO_NETWORKPROXY … … 939 85 #endif 940 86 { 941 } 87 channels = new QHttpNetworkConnectionChannel[channelCount]; 88 } 89 90 QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(quint16 channelCount, const QString &hostName, quint16 port, bool encrypt) 91 : hostName(hostName), port(port), encrypt(encrypt), 92 channelCount(channelCount), 93 pendingAuthSignal(false), pendingProxyAuthSignal(false) 94 #ifndef QT_NO_NETWORKPROXY 95 , networkProxy(QNetworkProxy::NoProxy) 96 #endif 97 { 98 channels = new QHttpNetworkConnectionChannel[channelCount]; 99 } 100 101 942 102 943 103 QHttpNetworkConnectionPrivate::~QHttpNetworkConnectionPrivate() 944 104 { 945 105 for (int i = 0; i < channelCount; ++i) { 946 channels[i].socket->close(); 947 delete channels[i].socket; 948 } 949 } 950 951 void QHttpNetworkConnectionPrivate::connectSignals(QAbstractSocket *socket) 952 { 953 Q_Q(QHttpNetworkConnection); 954 955 QObject::connect(socket, SIGNAL(bytesWritten(qint64)), 956 q, SLOT(_q_bytesWritten(qint64)), 957 Qt::DirectConnection); 958 QObject::connect(socket, SIGNAL(connected()), 959 q, SLOT(_q_connected()), 960 Qt::DirectConnection); 961 QObject::connect(socket, SIGNAL(readyRead()), 962 q, SLOT(_q_readyRead()), 963 Qt::DirectConnection); 964 QObject::connect(socket, SIGNAL(disconnected()), 965 q, SLOT(_q_disconnected()), 966 Qt::DirectConnection); 967 QObject::connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), 968 q, SLOT(_q_error(QAbstractSocket::SocketError)), 969 Qt::DirectConnection); 970 #ifndef QT_NO_NETWORKPROXY 971 QObject::connect(socket, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*)), 972 q, SLOT(_q_proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*)), 973 Qt::DirectConnection); 974 #endif 975 976 #ifndef QT_NO_OPENSSL 977 QSslSocket *sslSocket = qobject_cast<QSslSocket*>(socket); 978 QObject::connect(sslSocket, SIGNAL(encrypted()), 979 q, SLOT(_q_encrypted()), 980 Qt::DirectConnection); 981 QObject::connect(sslSocket, SIGNAL(sslErrors(const QList<QSslError>&)), 982 q, SLOT(_q_sslErrors(const QList<QSslError>&)), 983 Qt::DirectConnection); 984 #endif 106 if (channels[i].socket) { 107 channels[i].socket->close(); 108 delete channels[i].socket; 109 } 110 } 111 delete []channels; 985 112 } 986 113 987 114 void QHttpNetworkConnectionPrivate::init() 988 115 { 989 for (int i = 0; i < channelCount; ++i) { 990 #ifndef QT_NO_OPENSSL 991 channels[i].socket = new QSslSocket; 992 #else 993 channels[i].socket = new QTcpSocket; 994 #endif 995 connectSignals(channels[i].socket); 116 for (int i = 0; i < channelCount; i++) { 117 channels[i].setConnection(this->q_func()); 118 channels[i].init(); 996 119 } 997 120 } … … 1002 125 if (channels[i].socket == socket) 1003 126 return i; 1004 return -1; 1005 } 1006 1007 bool QHttpNetworkConnectionPrivate::isSocketBusy(QAbstractSocket *socket) const 1008 { 1009 int i = indexOf(socket); 1010 return (channels[i].state & BusyState); 1011 } 1012 1013 bool QHttpNetworkConnectionPrivate::isSocketWriting(QAbstractSocket *socket) const 1014 { 1015 int i = indexOf(socket); 1016 return (i != -1 && (channels[i].state & WritingState)); 1017 } 1018 1019 bool QHttpNetworkConnectionPrivate::isSocketWaiting(QAbstractSocket *socket) const 1020 { 1021 int i = indexOf(socket); 1022 return (i != -1 && (channels[i].state & WaitingState)); 1023 } 1024 1025 bool QHttpNetworkConnectionPrivate::isSocketReading(QAbstractSocket *socket) const 1026 { 1027 int i = indexOf(socket); 1028 return (i != -1 && (channels[i].state & ReadingState)); 1029 } 1030 1031 1032 void QHttpNetworkConnectionPrivate::appendData(QHttpNetworkReply &reply, const QByteArray &fragment, bool compressed) 1033 { 1034 QByteArray *ba = (compressed) ? &reply.d_func()->compressedData : &reply.d_func()->responseData; 1035 ba->append(fragment); 1036 return; 1037 } 1038 1039 qint64 QHttpNetworkConnectionPrivate::bytesAvailable(const QHttpNetworkReply &reply, bool compressed) const 1040 { 1041 const QByteArray *ba = (compressed) ? &reply.d_func()->compressedData : &reply.d_func()->responseData; 1042 return ba->size(); 1043 } 1044 1045 qint64 QHttpNetworkConnectionPrivate::read(QHttpNetworkReply &reply, QByteArray &data, qint64 maxSize, bool compressed) 1046 { 1047 QByteArray *ba = (compressed) ? &reply.d_func()->compressedData : &reply.d_func()->responseData; 1048 if (maxSize == -1 || maxSize >= ba->size()) { 1049 // read the whole data 1050 data = *ba; 1051 ba->clear(); 1052 } else { 1053 // read only the requested length 1054 data = ba->mid(0, maxSize); 1055 ba->remove(0, maxSize); 1056 } 1057 return data.size(); 1058 } 1059 1060 void QHttpNetworkConnectionPrivate::eraseData(QHttpNetworkReply *reply) 1061 { 1062 reply->d_func()->compressedData.clear(); 1063 reply->d_func()->responseData.clear(); 127 128 qFatal("Called with unknown socket object."); 129 return 0; 130 } 131 132 qint64 QHttpNetworkConnectionPrivate::uncompressedBytesAvailable(const QHttpNetworkReply &reply) const 133 { 134 return reply.d_func()->responseData.byteAmount(); 135 } 136 137 qint64 QHttpNetworkConnectionPrivate::uncompressedBytesAvailableNextBlock(const QHttpNetworkReply &reply) const 138 { 139 return reply.d_func()->responseData.sizeNextBlock(); 1064 140 } 1065 141 … … 1072 148 QByteArray value; 1073 149 // check if Content-Length is provided 1074 QIODevice *data = request.data(); 1075 if (data && request.contentLength() == -1) { 1076 if (!data->isSequential()) 1077 request.setContentLength(data->size()); 1078 else 1079 bufferData(messagePair); // ### or do chunked upload 150 QNonContiguousByteDevice* uploadByteDevice = request.uploadByteDevice(); 151 if (uploadByteDevice) { 152 if (request.contentLength() != -1 && uploadByteDevice->size() != -1) { 153 // both values known, take the smaller one. 154 request.setContentLength(qMin(uploadByteDevice->size(), request.contentLength())); 155 } else if (request.contentLength() == -1 && uploadByteDevice->size() != -1) { 156 // content length not supplied by user, but the upload device knows it 157 request.setContentLength(uploadByteDevice->size()); 158 } else if (request.contentLength() != -1 && uploadByteDevice->size() == -1) { 159 // everything OK, the user supplied us the contentLength 160 } else if (request.contentLength() == -1 && uploadByteDevice->size() == -1) { 161 qFatal("QHttpNetworkConnectionPrivate: Neither content-length nor upload device size were given"); 162 } 1080 163 } 1081 164 // set the Connection/Proxy-Connection: Keep-Alive headers … … 1093 176 } 1094 177 #endif 1095 // set the gzip header 178 179 // If the request had a accept-encoding set, we better not mess 180 // with it. If it was not set, we announce that we understand gzip 181 // and remember this fact in request.d->autoDecompress so that 182 // we can later decompress the HTTP reply if it has such an 183 // encoding. 1096 184 value = request.headerField("accept-encoding"); 1097 185 if (value.isEmpty()) { … … 1104 192 #endif 1105 193 } 194 195 // some websites mandate an accept-language header and fail 196 // if it is not sent. This is a problem with the website and 197 // not with us, but we work around this by setting 198 // one always. 199 value = request.headerField("accept-language"); 200 if (value.isEmpty()) { 201 QString systemLocale = QLocale::system().name().replace(QChar::fromAscii('_'),QChar::fromAscii('-')); 202 QString acceptLanguage; 203 if (systemLocale == QLatin1String("C")) 204 acceptLanguage = QString::fromAscii("en,*"); 205 else if (systemLocale.startsWith(QLatin1String("en-"))) 206 acceptLanguage = QString::fromAscii("%1,*").arg(systemLocale); 207 else 208 acceptLanguage = QString::fromAscii("%1,en,*").arg(systemLocale); 209 request.setHeaderField("Accept-Language", acceptLanguage.toAscii()); 210 } 211 1106 212 // set the User Agent 1107 213 value = request.headerField("user-agent"); … … 1125 231 } 1126 232 1127 bool QHttpNetworkConnectionPrivate::ensureConnection(QAbstractSocket *socket) 1128 { 1129 // make sure that this socket is in a connected state, if not initiate 1130 // connection to the host. 1131 if (socket->state() != QAbstractSocket::ConnectedState) { 1132 // connect to the host if not already connected. 1133 int index = indexOf(socket); 1134 channels[index].state = ConnectingState; 1135 channels[index].pendingEncrypt = encrypt; 1136 1137 // This workaround is needed since we use QAuthenticator for NTLM authentication. The "phase == Done" 1138 // is the usual criteria for emitting authentication signals. The "phase" is set to "Done" when the 1139 // last header for Authorization is generated by the QAuthenticator. Basic & Digest logic does not 1140 // check the "phase" for generating the Authorization header. NTLM authentication is a two stage 1141 // process & needs the "phase". To make sure the QAuthenticator uses the current username/password 1142 // the phase is reset to Start. 1143 QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(channels[index].authenticator); 1144 if (priv && priv->phase == QAuthenticatorPrivate::Done) 1145 priv->phase = QAuthenticatorPrivate::Start; 1146 priv = QAuthenticatorPrivate::getPrivate(channels[index].proxyAuthenticator); 1147 if (priv && priv->phase == QAuthenticatorPrivate::Done) 1148 priv->phase = QAuthenticatorPrivate::Start; 1149 1150 QString connectHost = hostName; 1151 qint16 connectPort = port; 1152 1153 #ifndef QT_NO_NETWORKPROXY 1154 // HTTPS always use transparent proxy. 1155 if (networkProxy.type() != QNetworkProxy::NoProxy && !encrypt) { 1156 connectHost = networkProxy.hostName(); 1157 connectPort = networkProxy.port(); 1158 } 1159 #endif 1160 if (encrypt) { 1161 #ifndef QT_NO_OPENSSL 1162 QSslSocket *sslSocket = qobject_cast<QSslSocket*>(socket); 1163 sslSocket->connectToHostEncrypted(connectHost, connectPort); 1164 if (channels[index].ignoreSSLErrors) 1165 sslSocket->ignoreSslErrors(); 1166 #else 1167 emitReplyError(socket, channels[index].reply, QNetworkReply::ProtocolUnknownError); 1168 #endif 1169 } else { 1170 socket->connectToHost(connectHost, connectPort); 1171 } 1172 return false; 1173 } 1174 return true; 1175 } 1176 1177 1178 bool QHttpNetworkConnectionPrivate::sendRequest(QAbstractSocket *socket) 1179 { 1180 Q_Q(QHttpNetworkConnection); 1181 1182 int i = indexOf(socket); 1183 switch (channels[i].state) { 1184 case IdleState: { // write the header 1185 if (!ensureConnection(socket)) { 1186 // wait for the connection (and encryption) to be done 1187 // sendRequest will be called again from either 1188 // _q_connected or _q_encrypted 1189 return false; 1190 } 1191 channels[i].written = 0; // excluding the header 1192 channels[i].bytesTotal = 0; 1193 if (channels[i].reply) { 1194 channels[i].reply->d_func()->clear(); 1195 channels[i].reply->d_func()->connection = q; 1196 channels[i].reply->d_func()->autoDecompress = channels[i].request.d->autoDecompress; 1197 } 1198 channels[i].state = WritingState; 1199 channels[i].pendingEncrypt = false; 1200 // if the url contains authentication parameters, use the new ones 1201 // both channels will use the new authentication parameters 1202 if (!channels[i].request.url().userInfo().isEmpty()) { 1203 QUrl url = channels[i].request.url(); 1204 QAuthenticator &auth = channels[i].authenticator; 1205 if (url.userName() != auth.user() 1206 || (!url.password().isEmpty() && url.password() != auth.password())) { 1207 auth.setUser(url.userName()); 1208 auth.setPassword(url.password()); 1209 copyCredentials(i, &auth, false); 1210 } 1211 // clear the userinfo, since we use the same request for resending 1212 // userinfo in url can conflict with the one in the authenticator 1213 url.setUserInfo(QString()); 1214 channels[i].request.setUrl(url); 1215 } 1216 createAuthorization(socket, channels[i].request); 1217 #ifndef QT_NO_NETWORKPROXY 1218 QByteArray header = QHttpNetworkRequestPrivate::header(channels[i].request, 1219 (networkProxy.type() != QNetworkProxy::NoProxy)); 1220 #else 1221 QByteArray header = QHttpNetworkRequestPrivate::header(channels[i].request, 1222 false); 1223 #endif 1224 socket->write(header); 1225 QIODevice *data = channels[i].request.d->data; 1226 QHttpNetworkReply *reply = channels[i].reply; 1227 if (reply && reply->d_func()->requestDataBuffer.size()) 1228 data = &channels[i].reply->d_func()->requestDataBuffer; 1229 if (data && (data->isOpen() || data->open(QIODevice::ReadOnly))) { 1230 if (data->isSequential()) { 1231 channels[i].bytesTotal = -1; 1232 QObject::connect(data, SIGNAL(readyRead()), q, SLOT(_q_dataReadyReadNoBuffer())); 1233 QObject::connect(data, SIGNAL(readChannelFinished()), q, SLOT(_q_dataReadyReadNoBuffer())); 1234 } else { 1235 channels[i].bytesTotal = data->size(); 1236 } 1237 } else { 1238 channels[i].state = WaitingState; 1239 break; 1240 } 1241 // write the initial chunk together with the headers 1242 // fall through 1243 } 1244 case WritingState: { // write the data 1245 QIODevice *data = channels[i].request.d->data; 1246 if (channels[i].reply->d_func()->requestDataBuffer.size()) 1247 data = &channels[i].reply->d_func()->requestDataBuffer; 1248 if (!data || channels[i].bytesTotal == channels[i].written) { 1249 channels[i].state = WaitingState; // now wait for response 1250 break; 1251 } 1252 1253 QByteArray chunk; 1254 chunk.resize(ChunkSize); 1255 qint64 readSize = data->read(chunk.data(), ChunkSize); 1256 if (readSize == -1) { 1257 // source has reached EOF 1258 channels[i].state = WaitingState; // now wait for response 1259 } else if (readSize > 0) { 1260 // source gave us something useful 1261 channels[i].written += socket->write(chunk.data(), readSize); 1262 if (channels[i].reply) 1263 emit channels[i].reply->dataSendProgress(channels[i].written, channels[i].bytesTotal); 1264 } 1265 break; 1266 } 1267 case WaitingState: 1268 case ReadingState: 1269 case Wait4AuthState: 1270 // ignore _q_bytesWritten in these states 1271 // fall through 1272 default: 1273 break; 1274 } 1275 return true; 1276 } 1277 1278 bool QHttpNetworkConnectionPrivate::emitSignals(QHttpNetworkReply *reply) 1279 { 1280 // for 401 & 407 don't emit the data signals. Content along with these 1281 // responses are send only if the authentication fails. 1282 return (reply && reply->d_func()->statusCode != 401 && reply->d_func()->statusCode != 407); 1283 } 1284 1285 bool QHttpNetworkConnectionPrivate::expectContent(QHttpNetworkReply *reply) 1286 { 1287 // check whether we can expect content after the headers (rfc 2616, sec4.4) 1288 if (!reply) 1289 return false; 1290 if ((reply->d_func()->statusCode >= 100 && reply->d_func()->statusCode < 200) 1291 || reply->d_func()->statusCode == 204 || reply->d_func()->statusCode == 304) 1292 return false; 1293 if (reply->d_func()->request.operation() == QHttpNetworkRequest::Head) 1294 return !emitSignals(reply); 1295 if (reply->d_func()->contentLength() == 0) 1296 return false; 1297 return true; 1298 } 233 234 1299 235 1300 236 void QHttpNetworkConnectionPrivate::emitReplyError(QAbstractSocket *socket, … … 1309 245 int i = indexOf(socket); 1310 246 // remove the corrupt data if any 1311 eraseData(channels[i].reply);1312 c loseChannel(i);247 reply->d_func()->eraseData(); 248 channels[i].close(); 1313 249 // send the next request 1314 QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection);1315 }1316 }1317 1318 #ifndef QT_NO_COMPRESS1319 bool QHttpNetworkConnectionPrivate::expand(QAbstractSocket *socket, QHttpNetworkReply *reply, bool dataComplete)1320 {1321 Q_ASSERT(socket);1322 Q_ASSERT(reply);1323 1324 qint64 total = bytesAvailable(*reply, true);1325 if (total >= CHUNK || dataComplete) {1326 int i = indexOf(socket);1327 // uncompress the data1328 QByteArray content, inflated;1329 read(*reply, content, -1, true);1330 int ret = Z_OK;1331 if (content.size())1332 ret = reply->d_func()->gunzipBodyPartially(content, inflated);1333 int retCheck = (dataComplete) ? Z_STREAM_END : Z_OK;1334 if (ret >= retCheck) {1335 if (inflated.size()) {1336 reply->d_func()->totalProgress += inflated.size();1337 appendData(*reply, inflated, false);1338 if (emitSignals(reply)) {1339 emit reply->readyRead();1340 // make sure that the reply is valid1341 if (channels[i].reply != reply)1342 return true;1343 emit reply->dataReadProgress(reply->d_func()->totalProgress, 0);1344 // make sure that the reply is valid1345 if (channels[i].reply != reply)1346 return true;1347 1348 }1349 }1350 } else {1351 emitReplyError(socket, reply, QNetworkReply::ProtocolFailure);1352 return false;1353 }1354 }1355 return true;1356 }1357 #endif1358 1359 void QHttpNetworkConnectionPrivate::receiveReply(QAbstractSocket *socket, QHttpNetworkReply *reply)1360 {1361 Q_ASSERT(socket);1362 1363 Q_Q(QHttpNetworkConnection);1364 qint64 bytes = 0;1365 QAbstractSocket::SocketState state = socket->state();1366 int i = indexOf(socket);1367 1368 // connection might be closed to signal the end of data1369 if (state == QAbstractSocket::UnconnectedState) {1370 if (!socket->bytesAvailable()) {1371 if (reply && reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingDataState) {1372 reply->d_func()->state = QHttpNetworkReplyPrivate::AllDoneState;1373 channels[i].state = IdleState;1374 allDone(socket, reply);1375 } else {1376 // try to reconnect/resend before sending an error.1377 if (channels[i].reconnectAttempts-- > 0) {1378 resendCurrentRequest(socket);1379 } else {1380 reply->d_func()->errorString = errorDetail(QNetworkReply::RemoteHostClosedError, socket);1381 emit reply->finishedWithError(QNetworkReply::RemoteHostClosedError, reply->d_func()->errorString);1382 QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection);1383 }1384 }1385 }1386 }1387 1388 // read loop for the response1389 while (socket->bytesAvailable()) {1390 QHttpNetworkReplyPrivate::ReplyState state = reply ? reply->d_func()->state : QHttpNetworkReplyPrivate::AllDoneState;1391 switch (state) {1392 case QHttpNetworkReplyPrivate::NothingDoneState:1393 case QHttpNetworkReplyPrivate::ReadingStatusState:1394 bytes += reply->d_func()->readStatus(socket);1395 channels[i].lastStatus = reply->d_func()->statusCode;1396 break;1397 case QHttpNetworkReplyPrivate::ReadingHeaderState:1398 bytes += reply->d_func()->readHeader(socket);1399 if (reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingDataState) {1400 if (reply->d_func()->isGzipped() && reply->d_func()->autoDecompress) {1401 // remove the Content-Length from header1402 reply->d_func()->removeAutoDecompressHeader();1403 } else {1404 reply->d_func()->autoDecompress = false;1405 }1406 if (reply && reply->d_func()->statusCode == 100) {1407 reply->d_func()->state = QHttpNetworkReplyPrivate::ReadingStatusState;1408 break; // ignore1409 }1410 if (emitSignals(reply))1411 emit reply->headerChanged();1412 if (!expectContent(reply)) {1413 reply->d_func()->state = QHttpNetworkReplyPrivate::AllDoneState;1414 channels[i].state = IdleState;1415 allDone(socket, reply);1416 return;1417 }1418 }1419 break;1420 case QHttpNetworkReplyPrivate::ReadingDataState: {1421 QBuffer fragment;1422 fragment.open(QIODevice::WriteOnly);1423 bytes = reply->d_func()->readBody(socket, &fragment);1424 if (bytes) {1425 appendData(*reply, fragment.data(), reply->d_func()->autoDecompress);1426 if (!reply->d_func()->autoDecompress) {1427 reply->d_func()->totalProgress += fragment.size();1428 if (emitSignals(reply)) {1429 emit reply->readyRead();1430 // make sure that the reply is valid1431 if (channels[i].reply != reply)1432 return;1433 emit reply->dataReadProgress(reply->d_func()->totalProgress, reply->d_func()->bodyLength);1434 // make sure that the reply is valid1435 if (channels[i].reply != reply)1436 return;1437 }1438 }1439 #ifndef QT_NO_COMPRESS1440 else if (!expand(socket, reply, false)) { // expand a chunk if possible1441 return; // ### expand failed1442 }1443 #endif1444 }1445 if (reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingDataState)1446 break;1447 // everything done, fall through1448 }1449 case QHttpNetworkReplyPrivate::AllDoneState:1450 channels[i].state = IdleState;1451 allDone(socket, reply);1452 break;1453 default:1454 break;1455 }1456 }1457 }1458 1459 void QHttpNetworkConnectionPrivate::allDone(QAbstractSocket *socket, QHttpNetworkReply *reply)1460 {1461 #ifndef QT_NO_COMPRESS1462 // expand the whole data.1463 if (expectContent(reply) && reply->d_func()->autoDecompress && !reply->d_func()->streamEnd)1464 expand(socket, reply, true); // ### if expand returns false, its an error1465 #endif1466 // while handling 401 & 407, we might reset the status code, so save this.1467 bool emitFinished = emitSignals(reply);1468 handleStatus(socket, reply);1469 // ### at this point there should be no more data on the socket1470 // close if server requested1471 int i = indexOf(socket);1472 if (reply->d_func()->connectionCloseEnabled())1473 closeChannel(i);1474 // queue the finished signal, this is required since we might send new requests from1475 // slot connected to it. The socket will not fire readyRead signal, if we are already1476 // in the slot connected to readyRead1477 if (emitFinished)1478 QMetaObject::invokeMethod(reply, "finished", Qt::QueuedConnection);1479 // reset the reconnection attempts after we receive a complete reply.1480 // in case of failures, each channel will attempt two reconnects before emitting error.1481 channels[i].reconnectAttempts = 2;1482 }1483 1484 void QHttpNetworkConnectionPrivate::handleStatus(QAbstractSocket *socket, QHttpNetworkReply *reply)1485 {1486 Q_ASSERT(socket);1487 Q_ASSERT(reply);1488 1489 Q_Q(QHttpNetworkConnection);1490 1491 int statusCode = reply->statusCode();1492 bool resend = false;1493 1494 switch (statusCode) {1495 case 401:1496 case 407:1497 handleAuthenticateChallenge(socket, reply, (statusCode == 407), resend);1498 if (resend) {1499 eraseData(reply);1500 sendRequest(socket);1501 }1502 break;1503 default:1504 250 QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection); 1505 251 } … … 1528 274 1529 275 276 // handles the authentication for one channel and eventually re-starts the other channels 1530 277 bool QHttpNetworkConnectionPrivate::handleAuthenticateChallenge(QAbstractSocket *socket, QHttpNetworkReply *reply, 1531 278 bool isProxy, bool &resend) … … 1567 314 if ((isProxy && pendingProxyAuthSignal) ||(!isProxy && pendingAuthSignal)) { 1568 315 // drop the request 1569 eraseData(channels[i].reply);1570 c loseChannel(i);316 reply->d_func()->eraseData(); 317 channels[i].close(); 1571 318 channels[i].lastStatus = 0; 1572 channels[i].state = Wait4AuthState;319 channels[i].state = QHttpNetworkConnectionChannel::Wait4AuthState; 1573 320 return false; 1574 321 } 1575 322 // cannot use this socket until the slot returns 1576 channels[i].state = WaitingState;323 channels[i].state = QHttpNetworkConnectionChannel::WaitingState; 1577 324 socket->blockSignals(true); 1578 325 if (!isProxy) { … … 1589 336 socket->blockSignals(false); 1590 337 // socket free to use 1591 channels[i].state = IdleState;338 channels[i].state = QHttpNetworkConnectionChannel::IdleState; 1592 339 if (priv->phase != QAuthenticatorPrivate::Done) { 1593 340 // send any pending requests 1594 341 copyCredentials(i, auth, isProxy); 1595 QMetaObject::invokeMethod(q, "_q_restart PendingRequest", Qt::QueuedConnection);342 QMetaObject::invokeMethod(q, "_q_restartAuthPendingRequests", Qt::QueuedConnection); 1596 343 } 1597 344 } … … 1601 348 emit channels[i].reply->headerChanged(); 1602 349 emit channels[i].reply->readyRead(); 1603 emit channels[i].reply->finished();1604 350 QNetworkReply::NetworkError errorCode = 1605 351 isProxy … … 1613 359 // remove pending request on the other channels 1614 360 for (int j = 0; j < channelCount; ++j) { 1615 if (j != i && channels[j].state == Wait4AuthState)1616 channels[j].state = IdleState;361 if (j != i && channels[j].state == QHttpNetworkConnectionChannel::Wait4AuthState) 362 channels[j].state = QHttpNetworkConnectionChannel::IdleState; 1617 363 } 1618 364 return true; … … 1630 376 1631 377 int i = indexOf(socket); 378 1632 379 if (channels[i].authMehtod != QAuthenticatorPrivate::None) { 1633 380 if (!(channels[i].authMehtod == QAuthenticatorPrivate::Ntlm && channels[i].lastStatus != 401)) { … … 1635 382 if (priv && priv->method != QAuthenticatorPrivate::None) { 1636 383 QByteArray response = priv->calculateResponse(request.d->methodName(), request.d->uri(false)); 1637 request.setHeaderField(" authorization", response);384 request.setHeaderField("Authorization", response); 1638 385 } 1639 386 } … … 1644 391 if (priv && priv->method != QAuthenticatorPrivate::None) { 1645 392 QByteArray response = priv->calculateResponse(request.d->methodName(), request.d->uri(false)); 1646 request.setHeaderField(" proxy-authorization", response);393 request.setHeaderField("Proxy-Authorization", response); 1647 394 } 1648 395 } … … 1673 420 } 1674 421 1675 void QHttpNetworkConnectionPrivate::unqueueRequest(QAbstractSocket *socket) 422 void QHttpNetworkConnectionPrivate::requeueRequest(const HttpMessagePair &pair) 423 { 424 Q_Q(QHttpNetworkConnection); 425 426 QHttpNetworkRequest request = pair.first; 427 switch (request.priority()) { 428 case QHttpNetworkRequest::HighPriority: 429 highPriorityQueue.prepend(pair); 430 break; 431 case QHttpNetworkRequest::NormalPriority: 432 case QHttpNetworkRequest::LowPriority: 433 lowPriorityQueue.prepend(pair); 434 break; 435 } 436 QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection); 437 } 438 439 void QHttpNetworkConnectionPrivate::dequeueAndSendRequest(QAbstractSocket *socket) 1676 440 { 1677 441 Q_ASSERT(socket); … … 1680 444 1681 445 if (!highPriorityQueue.isEmpty()) { 1682 for (int j = highPriorityQueue.count() - 1; j >= 0; --j) { 1683 HttpMessagePair &messagePair = highPriorityQueue[j]; 1684 if (!messagePair.second->d_func()->requestIsPrepared) 1685 prepareRequest(messagePair); 1686 if (!messagePair.second->d_func()->requestIsBuffering) { 1687 channels[i].request = messagePair.first; 1688 channels[i].reply = messagePair.second; 1689 sendRequest(socket); 1690 highPriorityQueue.removeAt(j); 1691 return; 1692 } 1693 } 446 // remove from queue before sendRequest! else we might pipeline the same request again 447 HttpMessagePair messagePair = highPriorityQueue.takeLast(); 448 if (!messagePair.second->d_func()->requestIsPrepared) 449 prepareRequest(messagePair); 450 channels[i].request = messagePair.first; 451 channels[i].reply = messagePair.second; 452 channels[i].sendRequest(); 453 return; 1694 454 } 1695 455 1696 456 if (!lowPriorityQueue.isEmpty()) { 1697 for (int j = lowPriorityQueue.count() - 1; j >= 0; --j) { 1698 HttpMessagePair &messagePair = lowPriorityQueue[j]; 1699 if (!messagePair.second->d_func()->requestIsPrepared) 1700 prepareRequest(messagePair); 1701 if (!messagePair.second->d_func()->requestIsBuffering) { 1702 channels[i].request = messagePair.first; 1703 channels[i].reply = messagePair.second; 1704 sendRequest(socket); 1705 lowPriorityQueue.removeAt(j); 1706 return; 1707 } 1708 } 1709 } 1710 } 1711 1712 void QHttpNetworkConnectionPrivate::closeChannel(int channel) 1713 { 1714 QAbstractSocket *socket = channels[channel].socket; 1715 socket->blockSignals(true); 1716 socket->close(); 1717 socket->blockSignals(false); 1718 channels[channel].state = IdleState; 1719 } 1720 1721 void QHttpNetworkConnectionPrivate::resendCurrentRequest(QAbstractSocket *socket) 1722 { 1723 Q_Q(QHttpNetworkConnection); 1724 Q_ASSERT(socket); 457 // remove from queue before sendRequest! else we might pipeline the same request again 458 HttpMessagePair messagePair = lowPriorityQueue.takeLast(); 459 if (!messagePair.second->d_func()->requestIsPrepared) 460 prepareRequest(messagePair); 461 channels[i].request = messagePair.first; 462 channels[i].reply = messagePair.second; 463 channels[i].sendRequest(); 464 return; 465 } 466 } 467 468 // this is called from _q_startNextRequest and when a request has been sent down a socket from the channel 469 void QHttpNetworkConnectionPrivate::fillPipeline(QAbstractSocket *socket) 470 { 471 // return fast if there is nothing to pipeline 472 if (highPriorityQueue.isEmpty() && lowPriorityQueue.isEmpty()) 473 return; 474 1725 475 int i = indexOf(socket); 1726 closeChannel(i); 1727 channels[i].resendCurrent = true; 1728 QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection); 1729 } 476 477 bool highPriorityQueueProcessingDone = false; 478 bool lowPriorityQueueProcessingDone = false; 479 480 while (!highPriorityQueueProcessingDone && !lowPriorityQueueProcessingDone) { 481 // this loop runs once per request we intend to pipeline in. 482 483 if (channels[i].pipeliningSupported != QHttpNetworkConnectionChannel::PipeliningProbablySupported) 484 return; 485 486 // the current request that is in must already support pipelining 487 if (!channels[i].request.isPipeliningAllowed()) 488 return; 489 490 // the current request must be a idempotent (right now we only check GET) 491 if (channels[i].request.operation() != QHttpNetworkRequest::Get) 492 return; 493 494 // check if socket is connected 495 if (socket->state() != QAbstractSocket::ConnectedState) 496 return; 497 498 // check for resendCurrent 499 if (channels[i].resendCurrent) 500 return; 501 502 // we do not like authentication stuff 503 // ### make sure to be OK with this in later releases 504 if (!channels[i].authenticator.isNull() || !channels[i].authenticator.user().isEmpty()) 505 return; 506 if (!channels[i].proxyAuthenticator.isNull() || !channels[i].proxyAuthenticator.user().isEmpty()) 507 return; 508 509 // check for pipeline length 510 if (channels[i].alreadyPipelinedRequests.length() >= defaultPipelineLength) 511 return; 512 513 // must be in ReadingState or WaitingState 514 if (! (channels[i].state == QHttpNetworkConnectionChannel::WaitingState 515 || channels[i].state == QHttpNetworkConnectionChannel::ReadingState)) 516 return; 517 518 highPriorityQueueProcessingDone = fillPipeline(highPriorityQueue, channels[i]); 519 // not finished with highPriorityQueue? then loop again 520 if (!highPriorityQueueProcessingDone) 521 continue; 522 // highPriorityQueue was processed, now deal with the lowPriorityQueue 523 lowPriorityQueueProcessingDone = fillPipeline(lowPriorityQueue, channels[i]); 524 } 525 } 526 527 // returns true when the processing of a queue has been done 528 bool QHttpNetworkConnectionPrivate::fillPipeline(QList<HttpMessagePair> &queue, QHttpNetworkConnectionChannel &channel) 529 { 530 if (queue.isEmpty()) 531 return true; 532 533 for (int i = queue.count() - 1; i >= 0; --i) { 534 HttpMessagePair messagePair = queue.at(i); 535 const QHttpNetworkRequest &request = messagePair.first; 536 537 // we currently do not support pipelining if HTTP authentication is used 538 if (!request.url().userInfo().isEmpty()) 539 continue; 540 541 // take only GET requests 542 if (request.operation() != QHttpNetworkRequest::Get) 543 continue; 544 545 if (!request.isPipeliningAllowed()) 546 continue; 547 548 // remove it from the queue 549 queue.takeAt(i); 550 // we modify the queue we iterate over here, but since we return from the function 551 // afterwards this is fine. 552 553 // actually send it 554 if (!messagePair.second->d_func()->requestIsPrepared) 555 prepareRequest(messagePair); 556 channel.pipelineInto(messagePair); 557 558 // return false because we processed something and need to process again 559 return false; 560 } 561 562 // return true, the queue has been processed and not changed 563 return true; 564 } 565 1730 566 1731 567 QString QHttpNetworkConnectionPrivate::errorDetail(QNetworkReply::NetworkError errorCode, QAbstractSocket* socket) … … 1771 607 } 1772 608 609 // this is called from the destructor of QHttpNetworkReply. It is called when 610 // the reply was finished correctly or when it was aborted. 1773 611 void QHttpNetworkConnectionPrivate::removeReply(QHttpNetworkReply *reply) 1774 612 { 1775 613 Q_Q(QHttpNetworkConnection); 1776 614 1777 // remove the from active list.615 // check if the reply is currently being processed or it is pipelined in 1778 616 for (int i = 0; i < channelCount; ++i) { 617 // is the reply associated the currently processing of this channel? 1779 618 if (channels[i].reply == reply) { 1780 619 channels[i].reply = 0; 1781 closeChannel(i); 620 621 if (!reply->isFinished() && !channels[i].alreadyPipelinedRequests.isEmpty()) { 622 // the reply had to be prematurely removed, e.g. it was not finished 623 // therefore we have to requeue the already pipelined requests. 624 channels[i].requeueCurrentlyPipelinedRequests(); 625 } 626 627 // if HTTP mandates we should close 628 // or the reply is not finished yet, e.g. it was aborted 629 // we have to close that connection 630 if (reply->d_func()->isConnectionCloseEnabled() || !reply->isFinished()) 631 channels[i].close(); 632 1782 633 QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection); 1783 634 return; 635 } 636 637 // is the reply inside the pipeline of this channel already? 638 for (int j = 0; j < channels[i].alreadyPipelinedRequests.length(); j++) { 639 if (channels[i].alreadyPipelinedRequests.at(j).second == reply) { 640 // Remove that HttpMessagePair 641 channels[i].alreadyPipelinedRequests.removeAt(j); 642 643 channels[i].requeueCurrentlyPipelinedRequests(); 644 645 // Since some requests had already been pipelined, but we removed 646 // one and re-queued the others 647 // we must force a connection close after the request that is 648 // currently in processing has been finished. 649 if (channels[i].reply) 650 channels[i].reply->d_func()->forceConnectionCloseEnabled = true; 651 652 QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection); 653 return; 654 } 1784 655 } 1785 656 } … … 1809 680 1810 681 1811 //private slots1812 void QHttpNetworkConnectionPrivate::_q_readyRead()1813 {1814 Q_Q(QHttpNetworkConnection);1815 QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(q->sender());1816 if (!socket)1817 return; // ### error1818 if (isSocketWaiting(socket) || isSocketReading(socket)) {1819 int i = indexOf(socket);1820 channels[i].state = ReadingState;1821 if (channels[i].reply)1822 receiveReply(socket, channels[i].reply);1823 }1824 // ### error1825 }1826 1827 void QHttpNetworkConnectionPrivate::_q_bytesWritten(qint64 bytes)1828 {1829 Q_UNUSED(bytes);1830 Q_Q(QHttpNetworkConnection);1831 QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(q->sender());1832 if (!socket)1833 return; // ### error1834 if (isSocketWriting(socket))1835 sendRequest(socket);1836 // otherwise we do nothing1837 }1838 1839 void QHttpNetworkConnectionPrivate::_q_disconnected()1840 {1841 Q_Q(QHttpNetworkConnection);1842 QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(q->sender());1843 if (!socket)1844 return; // ### error1845 // read the available data before closing1846 int i = indexOf(socket);1847 if (isSocketWaiting(socket) || isSocketReading(socket)) {1848 channels[i].state = ReadingState;1849 if (channels[i].reply)1850 receiveReply(socket, channels[i].reply);1851 }1852 channels[i].state = IdleState;1853 }1854 682 1855 683 void QHttpNetworkConnectionPrivate::_q_startNextRequest() 1856 684 { 1857 // send the current request again 1858 if (channels[0].resendCurrent || channels[1].resendCurrent) { 1859 int i = channels[0].resendCurrent ? 0:1; 1860 QAbstractSocket *socket = channels[i].socket; 1861 channels[i].resendCurrent = false; 1862 channels[i].state = IdleState; 1863 if (channels[i].reply) 1864 sendRequest(socket); 685 //resend the necessary ones. 686 for (int i = 0; i < channelCount; ++i) { 687 if (channels[i].resendCurrent) { 688 channels[i].resendCurrent = false; 689 channels[i].state = QHttpNetworkConnectionChannel::IdleState; 690 if (channels[i].reply) 691 channels[i].sendRequest(); 692 } 693 } 694 QAbstractSocket *socket = 0; 695 for (int i = 0; i < channelCount; ++i) { 696 QAbstractSocket *chSocket = channels[i].socket; 697 // send the request using the idle socket 698 if (!channels[i].isSocketBusy()) { 699 socket = chSocket; 700 break; 701 } 702 } 703 704 // this socket is free, 705 if (socket) 706 dequeueAndSendRequest(socket); 707 708 // try to push more into all sockets 709 // ### FIXME we should move this to the beginning of the function 710 // as soon as QtWebkit is properly using the pipelining 711 // (e.g. not for XMLHttpRequest or the first page load) 712 // ### FIXME we should also divide the requests more even 713 // on the connected sockets 714 //tryToFillPipeline(socket); 715 // return fast if there is nothing to pipeline 716 if (highPriorityQueue.isEmpty() && lowPriorityQueue.isEmpty()) 1865 717 return; 1866 } 1867 // send the request using the idle socket 1868 QAbstractSocket *socket = channels[0].socket; 1869 if (isSocketBusy(socket)) { 1870 socket = (isSocketBusy(channels[1].socket) ? 0 :channels[1].socket); 1871 } 1872 1873 if (!socket) { 1874 return; // this will be called after finishing current request. 1875 } 1876 unqueueRequest(socket); 1877 } 1878 1879 void QHttpNetworkConnectionPrivate::_q_restartPendingRequest() 718 for (int j = 0; j < channelCount; j++) 719 fillPipeline(channels[j].socket); 720 } 721 722 void QHttpNetworkConnectionPrivate::_q_restartAuthPendingRequests() 1880 723 { 1881 724 // send the request using the idle socket 1882 725 for (int i = 0 ; i < channelCount; ++i) { 1883 QAbstractSocket *socket = channels[i].socket; 1884 if (channels[i].state == Wait4AuthState) { 1885 channels[i].state = IdleState; 726 if (channels[i].state == QHttpNetworkConnectionChannel::Wait4AuthState) { 727 channels[i].state = QHttpNetworkConnectionChannel::IdleState; 1886 728 if (channels[i].reply) 1887 sendRequest(socket); 1888 } 1889 } 1890 } 1891 1892 void QHttpNetworkConnectionPrivate::_q_connected() 1893 { 1894 Q_Q(QHttpNetworkConnection); 1895 QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(q->sender()); 1896 if (!socket) 1897 return; // ### error 1898 int i = indexOf(socket); 1899 // ### FIXME: if the server closes the connection unexpectedly, we shouldn't send the same broken request again! 1900 //channels[i].reconnectAttempts = 2; 1901 if (!channels[i].pendingEncrypt) { 1902 channels[i].state = IdleState; 1903 if (channels[i].reply) 1904 sendRequest(socket); 1905 else 1906 closeChannel(i); 1907 } 1908 } 1909 1910 1911 void QHttpNetworkConnectionPrivate::_q_error(QAbstractSocket::SocketError socketError) 1912 { 1913 Q_Q(QHttpNetworkConnection); 1914 QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(q->sender()); 1915 if (!socket) 1916 return; 1917 bool send2Reply = false; 1918 int i = indexOf(socket); 1919 QNetworkReply::NetworkError errorCode = QNetworkReply::UnknownNetworkError; 1920 1921 switch (socketError) { 1922 case QAbstractSocket::HostNotFoundError: 1923 errorCode = QNetworkReply::HostNotFoundError; 1924 break; 1925 case QAbstractSocket::ConnectionRefusedError: 1926 errorCode = QNetworkReply::ConnectionRefusedError; 1927 break; 1928 case QAbstractSocket::RemoteHostClosedError: 1929 // try to reconnect/resend before sending an error. 1930 // while "Reading" the _q_disconnected() will handle this. 1931 if (channels[i].state != IdleState && channels[i].state != ReadingState) { 1932 if (channels[i].reconnectAttempts-- > 0) { 1933 resendCurrentRequest(socket); 1934 return; 1935 } else { 1936 send2Reply = true; 1937 errorCode = QNetworkReply::RemoteHostClosedError; 1938 } 1939 } else { 1940 return; 1941 } 1942 break; 1943 case QAbstractSocket::SocketTimeoutError: 1944 // try to reconnect/resend before sending an error. 1945 if (channels[i].state == WritingState && (channels[i].reconnectAttempts-- > 0)) { 1946 resendCurrentRequest(socket); 1947 return; 1948 } 1949 send2Reply = true; 1950 errorCode = QNetworkReply::TimeoutError; 1951 break; 1952 case QAbstractSocket::ProxyAuthenticationRequiredError: 1953 errorCode = QNetworkReply::ProxyAuthenticationRequiredError; 1954 break; 1955 case QAbstractSocket::SslHandshakeFailedError: 1956 errorCode = QNetworkReply::SslHandshakeFailedError; 1957 break; 1958 default: 1959 // all other errors are treated as NetworkError 1960 errorCode = QNetworkReply::UnknownNetworkError; 1961 break; 1962 } 1963 QPointer<QObject> that = q; 1964 QString errorString = errorDetail(errorCode, socket); 1965 if (send2Reply) { 1966 if (channels[i].reply) { 1967 channels[i].reply->d_func()->errorString = errorString; 1968 // this error matters only to this reply 1969 emit channels[i].reply->finishedWithError(errorCode, errorString); 1970 } 1971 // send the next request 1972 QMetaObject::invokeMethod(that, "_q_startNextRequest", Qt::QueuedConnection); 1973 } else { 1974 // the failure affects all requests. 1975 emit q->error(errorCode, errorString); 1976 } 1977 if (that) //signals make enter the event loop 1978 closeChannel(i); 1979 } 1980 1981 #ifndef QT_NO_NETWORKPROXY 1982 void QHttpNetworkConnectionPrivate::_q_proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator* auth) 1983 { 1984 Q_Q(QHttpNetworkConnection); 1985 emit q->proxyAuthenticationRequired(proxy, auth, q); 1986 } 1987 #endif 1988 1989 void QHttpNetworkConnectionPrivate::_q_dataReadyReadNoBuffer() 1990 { 1991 Q_Q(QHttpNetworkConnection); 1992 // data emitted either readyRead() 1993 // find out which channel it is for 1994 QIODevice *sender = qobject_cast<QIODevice *>(q->sender()); 1995 1996 // won't match anything if the qobject_cast above failed 1997 for (int i = 0; i < channelCount; ++i) { 1998 if (sender == channels[i].request.data()) { 1999 sendRequest(channels[i].socket); 2000 break; 2001 } 2002 } 2003 } 2004 2005 void QHttpNetworkConnectionPrivate::_q_dataReadyReadBuffer() 2006 { 2007 Q_Q(QHttpNetworkConnection); 2008 QIODevice *sender = qobject_cast<QIODevice *>(q->sender()); 2009 HttpMessagePair *thePair = 0; 2010 for (int i = 0; !thePair && i < lowPriorityQueue.size(); ++i) 2011 if (lowPriorityQueue.at(i).first.data() == sender) 2012 thePair = &lowPriorityQueue[i]; 2013 2014 for (int i = 0; !thePair && i < highPriorityQueue.size(); ++i) 2015 if (highPriorityQueue.at(i).first.data() == sender) 2016 thePair = &highPriorityQueue[i]; 2017 2018 if (thePair) { 2019 bufferData(*thePair); 2020 2021 // are we finished buffering? 2022 if (!thePair->second->d_func()->requestIsBuffering) 2023 _q_startNextRequest(); 2024 } 2025 } 2026 2027 void QHttpNetworkConnectionPrivate::bufferData(HttpMessagePair &messagePair) 2028 { 2029 Q_Q(QHttpNetworkConnection); 2030 QHttpNetworkRequest &request = messagePair.first; 2031 QHttpNetworkReply *reply = messagePair.second; 2032 Q_ASSERT(request.data()); 2033 if (!reply->d_func()->requestIsBuffering) { // first time 2034 QObject::connect(request.data(), SIGNAL(readyRead()), q, SLOT(_q_dataReadyReadBuffer())); 2035 QObject::connect(request.data(), SIGNAL(readChannelFinished()), q, SLOT(_q_dataReadyReadBuffer())); 2036 reply->d_func()->requestIsBuffering = true; 2037 reply->d_func()->requestDataBuffer.open(QIODevice::ReadWrite); 2038 } 2039 2040 // always try to read at least one byte 2041 // ### FIXME! use a QRingBuffer 2042 qint64 bytesToRead = qMax<qint64>(1, request.data()->bytesAvailable()); 2043 QByteArray newData; 2044 newData.resize(bytesToRead); 2045 qint64 bytesActuallyRead = request.data()->read(newData.data(), bytesToRead); 2046 2047 if (bytesActuallyRead > 0) { 2048 // we read something 2049 newData.chop(bytesToRead - bytesActuallyRead); 2050 reply->d_func()->requestDataBuffer.write(newData); 2051 } else if (bytesActuallyRead == -1) { // last time 2052 QObject::disconnect(request.data(), SIGNAL(readyRead()), q, SLOT(_q_dataReadyReadBuffer())); 2053 QObject::disconnect(request.data(), SIGNAL(readChannelFinished()), q, SLOT(_q_dataReadyReadBuffer())); 2054 2055 request.setContentLength(reply->d_func()->requestDataBuffer.size()); 2056 reply->d_func()->requestDataBuffer.seek(0); 2057 reply->d_func()->requestIsBuffering = false; 2058 } 2059 } 2060 2061 // QHttpNetworkConnection 729 channels[i].sendRequest(); 730 } 731 } 732 } 733 2062 734 2063 735 QHttpNetworkConnection::QHttpNetworkConnection(const QString &hostName, quint16 port, bool encrypt, QObject *parent) 2064 736 : QObject(*(new QHttpNetworkConnectionPrivate(hostName, port, encrypt)), parent) 737 { 738 Q_D(QHttpNetworkConnection); 739 d->init(); 740 } 741 742 QHttpNetworkConnection::QHttpNetworkConnection(quint16 connectionCount, const QString &hostName, quint16 port, bool encrypt, QObject *parent) 743 : QObject(*(new QHttpNetworkConnectionPrivate(connectionCount, hostName, port, encrypt)), parent) 2065 744 { 2066 745 Q_D(QHttpNetworkConnection); … … 2151 830 #endif 2152 831 2153 // QHttpNetworkRequest2154 2155 QHttpNetworkRequest::QHttpNetworkRequest(const QUrl &url, Operation operation, Priority priority)2156 : d(new QHttpNetworkRequestPrivate(operation, priority, url))2157 {2158 }2159 2160 QHttpNetworkRequest::QHttpNetworkRequest(const QHttpNetworkRequest &other)2161 : QHttpNetworkHeader(other), d(other.d)2162 {2163 }2164 2165 QHttpNetworkRequest::~QHttpNetworkRequest()2166 {2167 }2168 2169 QUrl QHttpNetworkRequest::url() const2170 {2171 return d->url;2172 }2173 void QHttpNetworkRequest::setUrl(const QUrl &url)2174 {2175 d->url = url;2176 }2177 2178 qint64 QHttpNetworkRequest::contentLength() const2179 {2180 return d->contentLength();2181 }2182 2183 void QHttpNetworkRequest::setContentLength(qint64 length)2184 {2185 d->setContentLength(length);2186 }2187 2188 QList<QPair<QByteArray, QByteArray> > QHttpNetworkRequest::header() const2189 {2190 return d->fields;2191 }2192 2193 QByteArray QHttpNetworkRequest::headerField(const QByteArray &name, const QByteArray &defaultValue) const2194 {2195 return d->headerField(name, defaultValue);2196 }2197 2198 void QHttpNetworkRequest::setHeaderField(const QByteArray &name, const QByteArray &data)2199 {2200 d->setHeaderField(name, data);2201 }2202 2203 QHttpNetworkRequest &QHttpNetworkRequest::operator=(const QHttpNetworkRequest &other)2204 {2205 d = other.d;2206 return *this;2207 }2208 2209 bool QHttpNetworkRequest::operator==(const QHttpNetworkRequest &other) const2210 {2211 return d->operator==(*other.d);2212 }2213 2214 QHttpNetworkRequest::Operation QHttpNetworkRequest::operation() const2215 {2216 return d->operation;2217 }2218 2219 void QHttpNetworkRequest::setOperation(Operation operation)2220 {2221 d->operation = operation;2222 }2223 2224 QHttpNetworkRequest::Priority QHttpNetworkRequest::priority() const2225 {2226 return d->priority;2227 }2228 2229 void QHttpNetworkRequest::setPriority(Priority priority)2230 {2231 d->priority = priority;2232 }2233 2234 QIODevice *QHttpNetworkRequest::data() const2235 {2236 return d->data;2237 }2238 2239 void QHttpNetworkRequest::setData(QIODevice *data)2240 {2241 d->data = data;2242 }2243 2244 int QHttpNetworkRequest::majorVersion() const2245 {2246 return 1;2247 }2248 2249 int QHttpNetworkRequest::minorVersion() const2250 {2251 return 1;2252 }2253 2254 // QHttpNetworkReply2255 2256 QHttpNetworkReply::QHttpNetworkReply(const QUrl &url, QObject *parent)2257 : QObject(*new QHttpNetworkReplyPrivate(url), parent)2258 {2259 }2260 2261 QHttpNetworkReply::~QHttpNetworkReply()2262 {2263 Q_D(QHttpNetworkReply);2264 if (d->connection) {2265 d->connection->d_func()->removeReply(this);2266 }2267 }2268 2269 QUrl QHttpNetworkReply::url() const2270 {2271 return d_func()->url;2272 }2273 void QHttpNetworkReply::setUrl(const QUrl &url)2274 {2275 Q_D(QHttpNetworkReply);2276 d->url = url;2277 }2278 2279 qint64 QHttpNetworkReply::contentLength() const2280 {2281 return d_func()->contentLength();2282 }2283 2284 void QHttpNetworkReply::setContentLength(qint64 length)2285 {2286 Q_D(QHttpNetworkReply);2287 d->setContentLength(length);2288 }2289 2290 QList<QPair<QByteArray, QByteArray> > QHttpNetworkReply::header() const2291 {2292 return d_func()->fields;2293 }2294 2295 QByteArray QHttpNetworkReply::headerField(const QByteArray &name, const QByteArray &defaultValue) const2296 {2297 return d_func()->headerField(name, defaultValue);2298 }2299 2300 void QHttpNetworkReply::setHeaderField(const QByteArray &name, const QByteArray &data)2301 {2302 Q_D(QHttpNetworkReply);2303 d->setHeaderField(name, data);2304 }2305 2306 void QHttpNetworkReply::parseHeader(const QByteArray &header)2307 {2308 Q_D(QHttpNetworkReply);2309 d->parseHeader(header);2310 }2311 2312 QHttpNetworkRequest QHttpNetworkReply::request() const2313 {2314 return d_func()->request;2315 }2316 2317 void QHttpNetworkReply::setRequest(const QHttpNetworkRequest &request)2318 {2319 Q_D(QHttpNetworkReply);2320 d->request = request;2321 }2322 2323 int QHttpNetworkReply::statusCode() const2324 {2325 return d_func()->statusCode;2326 }2327 2328 void QHttpNetworkReply::setStatusCode(int code)2329 {2330 Q_D(QHttpNetworkReply);2331 d->statusCode = code;2332 }2333 2334 QString QHttpNetworkReply::errorString() const2335 {2336 return d_func()->errorString;2337 }2338 2339 QString QHttpNetworkReply::reasonPhrase() const2340 {2341 return d_func()->reasonPhrase;2342 }2343 2344 void QHttpNetworkReply::setErrorString(const QString &error)2345 {2346 Q_D(QHttpNetworkReply);2347 d->errorString = error;2348 }2349 2350 int QHttpNetworkReply::majorVersion() const2351 {2352 return d_func()->majorVersion;2353 }2354 2355 int QHttpNetworkReply::minorVersion() const2356 {2357 return d_func()->minorVersion;2358 }2359 2360 qint64 QHttpNetworkReply::bytesAvailable() const2361 {2362 Q_D(const QHttpNetworkReply);2363 if (d->connection)2364 return d->connection->d_func()->bytesAvailable(*this);2365 else2366 return -1;2367 }2368 2369 QByteArray QHttpNetworkReply::read(qint64 maxSize)2370 {2371 Q_D(QHttpNetworkReply);2372 QByteArray data;2373 if (d->connection)2374 d->connection->d_func()->read(*this, data, maxSize, false);2375 return data;2376 }2377 2378 bool QHttpNetworkReply::isFinished() const2379 {2380 return d_func()->state == QHttpNetworkReplyPrivate::AllDoneState;2381 }2382 832 2383 833 // SSL support below 2384 834 #ifndef QT_NO_OPENSSL 2385 void QHttpNetworkConnectionPrivate::_q_encrypted()2386 {2387 Q_Q(QHttpNetworkConnection);2388 QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(q->sender());2389 if (!socket)2390 return; // ### error2391 channels[indexOf(socket)].state = IdleState;2392 sendRequest(socket);2393 }2394 2395 void QHttpNetworkConnectionPrivate::_q_sslErrors(const QList<QSslError> &errors)2396 {2397 Q_Q(QHttpNetworkConnection);2398 QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(q->sender());2399 if (!socket)2400 return;2401 //QNetworkReply::NetworkError errorCode = QNetworkReply::ProtocolFailure;2402 emit q->sslErrors(errors);2403 }2404 2405 835 QSslConfiguration QHttpNetworkConnectionPrivate::sslConfiguration(const QHttpNetworkReply &reply) const 2406 836 { 837 if (!encrypt) 838 return QSslConfiguration(); 839 2407 840 for (int i = 0; i < channelCount; ++i) 2408 841 if (channels[i].reply == &reply) … … 2414 847 { 2415 848 Q_D(QHttpNetworkConnection); 849 if (!d->encrypt) 850 return; 851 2416 852 // set the config on all channels 2417 853 for (int i = 0; i < d->channelCount; ++i) … … 2422 858 { 2423 859 Q_D(QHttpNetworkConnection); 860 if (!d->encrypt) 861 return; 862 2424 863 if (channel == -1) { // ignore for all channels 2425 864 for (int i = 0; i < d->channelCount; ++i) { 2426 865 static_cast<QSslSocket *>(d->channels[i].socket)->ignoreSslErrors(); 2427 d->channels[i].ignore SSLErrors = true;866 d->channels[i].ignoreAllSslErrors = true; 2428 867 } 2429 868 2430 869 } else { 2431 870 static_cast<QSslSocket *>(d->channels[channel].socket)->ignoreSslErrors(); 2432 d->channels[channel].ignoreSSLErrors = true; 2433 } 2434 } 2435 2436 QSslConfiguration QHttpNetworkReply::sslConfiguration() const 2437 { 2438 Q_D(const QHttpNetworkReply); 2439 if (d->connection) 2440 return d->connection->d_func()->sslConfiguration(*this); 2441 return QSslConfiguration(); 2442 } 2443 2444 void QHttpNetworkReply::setSslConfiguration(const QSslConfiguration &config) 2445 { 2446 Q_D(QHttpNetworkReply); 2447 if (d->connection) 2448 d->connection->setSslConfiguration(config); 2449 } 2450 2451 void QHttpNetworkReply::ignoreSslErrors() 2452 { 2453 Q_D(QHttpNetworkReply); 2454 if (d->connection) 2455 d->connection->ignoreSslErrors(); 2456 } 871 d->channels[channel].ignoreAllSslErrors = true; 872 } 873 } 874 875 void QHttpNetworkConnection::ignoreSslErrors(const QList<QSslError> &errors, int channel) 876 { 877 Q_D(QHttpNetworkConnection); 878 if (!d->encrypt) 879 return; 880 881 if (channel == -1) { // ignore for all channels 882 for (int i = 0; i < d->channelCount; ++i) { 883 static_cast<QSslSocket *>(d->channels[i].socket)->ignoreSslErrors(errors); 884 d->channels[i].ignoreSslErrorsList = errors; 885 } 886 887 } else { 888 static_cast<QSslSocket *>(d->channels[channel].socket)->ignoreSslErrors(errors); 889 d->channels[channel].ignoreSslErrorsList = errors; 890 } 891 } 892 2457 893 #endif //QT_NO_OPENSSL 2458 894 895 #ifndef QT_NO_NETWORKPROXY 896 // only called from QHttpNetworkConnectionChannel::_q_proxyAuthenticationRequired, not 897 // from QHttpNetworkConnectionChannel::handleAuthenticationChallenge 898 // e.g. it is for SOCKS proxies which require authentication. 899 void QHttpNetworkConnectionPrivate::emitProxyAuthenticationRequired(const QHttpNetworkConnectionChannel *chan, const QNetworkProxy &proxy, QAuthenticator* auth) 900 { 901 Q_Q(QHttpNetworkConnection); 902 emit q->proxyAuthenticationRequired(proxy, auth, q); 903 int i = indexOf(chan->socket); 904 copyCredentials(i, auth, true); 905 } 906 #endif 907 2459 908 2460 909 QT_END_NAMESPACE -
trunk/src/network/access/qhttpnetworkconnection_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 56 56 #include <QtNetwork/qnetworkreply.h> 57 57 #include <QtNetwork/qabstractsocket.h> 58 59 #include <private/qobject_p.h> 60 #include <qauthenticator.h> 61 #include <qnetworkproxy.h> 62 #include <qbuffer.h> 63 64 #include <private/qhttpnetworkheader_p.h> 65 #include <private/qhttpnetworkrequest_p.h> 66 #include <private/qhttpnetworkreply_p.h> 67 68 #include <private/qhttpnetworkconnectionchannel_p.h> 58 69 59 70 #ifndef QT_NO_HTTP … … 70 81 class QHttpNetworkRequest; 71 82 class QHttpNetworkReply; 83 class QByteArray; 72 84 73 85 class QHttpNetworkConnectionPrivate; … … 78 90 79 91 QHttpNetworkConnection(const QString &hostName, quint16 port = 80, bool encrypt = false, QObject *parent = 0); 92 QHttpNetworkConnection(quint16 channelCount, const QString &hostName, quint16 port = 80, bool encrypt = false, QObject *parent = 0); 80 93 ~QHttpNetworkConnection(); 81 94 … … 107 120 void setSslConfiguration(const QSslConfiguration &config); 108 121 void ignoreSslErrors(int channel = -1); 122 void ignoreSslErrors(const QList<QSslError> &errors, int channel = -1); 109 123 110 124 Q_SIGNALS: … … 126 140 Q_DISABLE_COPY(QHttpNetworkConnection) 127 141 friend class QHttpNetworkReply; 128 129 Q_PRIVATE_SLOT(d_func(), void _q_bytesWritten(qint64)) 130 Q_PRIVATE_SLOT(d_func(), void _q_readyRead()) 131 Q_PRIVATE_SLOT(d_func(), void _q_disconnected()) 142 friend class QHttpNetworkConnectionChannel; 143 132 144 Q_PRIVATE_SLOT(d_func(), void _q_startNextRequest()) 133 Q_PRIVATE_SLOT(d_func(), void _q_restartPendingRequest()) 134 Q_PRIVATE_SLOT(d_func(), void _q_connected()) 135 Q_PRIVATE_SLOT(d_func(), void _q_error(QAbstractSocket::SocketError)) 145 Q_PRIVATE_SLOT(d_func(), void _q_restartAuthPendingRequests()) 146 }; 147 148 149 // private classes 150 typedef QPair<QHttpNetworkRequest, QHttpNetworkReply*> HttpMessagePair; 151 152 153 class QHttpNetworkConnectionPrivate : public QObjectPrivate 154 { 155 Q_DECLARE_PUBLIC(QHttpNetworkConnection) 156 public: 157 static const int defaultChannelCount; 158 static const int defaultPipelineLength; 159 160 QHttpNetworkConnectionPrivate(const QString &hostName, quint16 port, bool encrypt); 161 QHttpNetworkConnectionPrivate(quint16 channelCount, const QString &hostName, quint16 port, bool encrypt); 162 ~QHttpNetworkConnectionPrivate(); 163 void init(); 164 165 enum { ChunkSize = 4096 }; 166 167 int indexOf(QAbstractSocket *socket) const; 168 169 QHttpNetworkReply *queueRequest(const QHttpNetworkRequest &request); 170 void requeueRequest(const HttpMessagePair &pair); // e.g. after pipeline broke 171 void dequeueAndSendRequest(QAbstractSocket *socket); 172 void prepareRequest(HttpMessagePair &request); 173 174 void fillPipeline(QAbstractSocket *socket); 175 bool fillPipeline(QList<HttpMessagePair> &queue, QHttpNetworkConnectionChannel &channel); 176 177 void copyCredentials(int fromChannel, QAuthenticator *auth, bool isProxy); 178 179 // private slots 180 void _q_startNextRequest(); // send the next request from the queue 181 void _q_restartAuthPendingRequests(); // send the currently blocked request 182 183 void createAuthorization(QAbstractSocket *socket, QHttpNetworkRequest &request); 184 185 QString errorDetail(QNetworkReply::NetworkError errorCode, QAbstractSocket *socket); 186 187 #ifndef QT_NO_COMPRESS 188 bool expand(QAbstractSocket *socket, QHttpNetworkReply *reply, bool dataComplete); 189 #endif 190 void removeReply(QHttpNetworkReply *reply); 191 192 QString hostName; 193 quint16 port; 194 bool encrypt; 195 196 const int channelCount; 197 QHttpNetworkConnectionChannel *channels; // parallel connections to the server 198 199 bool pendingAuthSignal; // there is an incomplete authentication signal 200 bool pendingProxyAuthSignal; // there is an incomplete proxy authentication signal 201 202 qint64 uncompressedBytesAvailable(const QHttpNetworkReply &reply) const; 203 qint64 uncompressedBytesAvailableNextBlock(const QHttpNetworkReply &reply) const; 204 205 206 void emitReplyError(QAbstractSocket *socket, QHttpNetworkReply *reply, QNetworkReply::NetworkError errorCode); 207 bool handleAuthenticateChallenge(QAbstractSocket *socket, QHttpNetworkReply *reply, bool isProxy, bool &resend); 208 209 210 #ifndef QT_NO_OPENSSL 211 QSslConfiguration sslConfiguration(const QHttpNetworkReply &reply) const; 212 #endif 213 136 214 #ifndef QT_NO_NETWORKPROXY 137 Q _PRIVATE_SLOT(d_func(), void _q_proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*))138 #endif 139 Q_PRIVATE_SLOT(d_func(), void _q_dataReadyReadBuffer()) 140 Q_PRIVATE_SLOT(d_func(), void _q_dataReadyReadNoBuffer()) 141 142 #ifndef QT_NO_OPENSSL 143 Q _PRIVATE_SLOT(d_func(), void _q_encrypted())144 Q_PRIVATE_SLOT(d_func(), void _q_sslErrors(const QList<QSslError>&)) 145 #endif 215 QNetworkProxy networkProxy; 216 void emitProxyAuthenticationRequired(const QHttpNetworkConnectionChannel *chan, const QNetworkProxy &proxy, QAuthenticator* auth); 217 #endif 218 219 //The request queues 220 QList<HttpMessagePair> highPriorityQueue; 221 QList<HttpMessagePair> lowPriorityQueue; 222 223 friend class QHttpNetworkConnectionChannel; 146 224 }; 147 225 148 class Q_AUTOTEST_EXPORT QHttpNetworkHeader 149 { 150 public: 151 virtual ~QHttpNetworkHeader() {}; 152 virtual QUrl url() const = 0; 153 virtual void setUrl(const QUrl &url) = 0; 154 155 virtual int majorVersion() const = 0; 156 virtual int minorVersion() const = 0; 157 158 virtual qint64 contentLength() const = 0; 159 virtual void setContentLength(qint64 length) = 0; 160 161 virtual QList<QPair<QByteArray, QByteArray> > header() const = 0; 162 virtual QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const = 0; 163 virtual void setHeaderField(const QByteArray &name, const QByteArray &data) = 0; 164 }; 165 166 class QHttpNetworkRequestPrivate; 167 class Q_AUTOTEST_EXPORT QHttpNetworkRequest: public QHttpNetworkHeader 168 { 169 public: 170 enum Operation { 171 Options, 172 Get, 173 Head, 174 Post, 175 Put, 176 Delete, 177 Trace, 178 Connect 179 }; 180 181 enum Priority { 182 HighPriority, 183 NormalPriority, 184 LowPriority 185 }; 186 187 QHttpNetworkRequest(const QUrl &url = QUrl(), Operation operation = Get, Priority priority = NormalPriority); 188 QHttpNetworkRequest(const QHttpNetworkRequest &other); 189 virtual ~QHttpNetworkRequest(); 190 QHttpNetworkRequest &operator=(const QHttpNetworkRequest &other); 191 bool operator==(const QHttpNetworkRequest &other) const; 192 193 QUrl url() const; 194 void setUrl(const QUrl &url); 195 196 int majorVersion() const; 197 int minorVersion() const; 198 199 qint64 contentLength() const; 200 void setContentLength(qint64 length); 201 202 QList<QPair<QByteArray, QByteArray> > header() const; 203 QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const; 204 void setHeaderField(const QByteArray &name, const QByteArray &data); 205 206 Operation operation() const; 207 void setOperation(Operation operation); 208 209 Priority priority() const; 210 void setPriority(Priority priority); 211 212 QIODevice *data() const; 213 void setData(QIODevice *data); 214 215 private: 216 QSharedDataPointer<QHttpNetworkRequestPrivate> d; 217 friend class QHttpNetworkRequestPrivate; 218 friend class QHttpNetworkConnectionPrivate; 219 }; 220 221 class QHttpNetworkReplyPrivate; 222 class Q_AUTOTEST_EXPORT QHttpNetworkReply : public QObject, public QHttpNetworkHeader 223 { 224 Q_OBJECT 225 public: 226 227 explicit QHttpNetworkReply(const QUrl &url = QUrl(), QObject *parent = 0); 228 virtual ~QHttpNetworkReply(); 229 230 QUrl url() const; 231 void setUrl(const QUrl &url); 232 233 int majorVersion() const; 234 int minorVersion() const; 235 236 qint64 contentLength() const; 237 void setContentLength(qint64 length); 238 239 QList<QPair<QByteArray, QByteArray> > header() const; 240 QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const; 241 void setHeaderField(const QByteArray &name, const QByteArray &data); 242 void parseHeader(const QByteArray &header); // mainly for testing 243 244 QHttpNetworkRequest request() const; 245 void setRequest(const QHttpNetworkRequest &request); 246 247 int statusCode() const; 248 void setStatusCode(int code); 249 250 QString errorString() const; 251 void setErrorString(const QString &error); 252 253 QString reasonPhrase() const; 254 255 qint64 bytesAvailable() const; 256 QByteArray read(qint64 maxSize = -1); 257 258 bool isFinished() const; 259 260 #ifndef QT_NO_OPENSSL 261 QSslConfiguration sslConfiguration() const; 262 void setSslConfiguration(const QSslConfiguration &config); 263 void ignoreSslErrors(); 264 265 Q_SIGNALS: 266 void sslErrors(const QList<QSslError> &errors); 267 #endif 268 269 Q_SIGNALS: 270 void readyRead(); 271 void finished(); 272 void finishedWithError(QNetworkReply::NetworkError errorCode, const QString &detail = QString()); 273 void headerChanged(); 274 void dataReadProgress(int done, int total); 275 void dataSendProgress(int done, int total); 276 277 private: 278 Q_DECLARE_PRIVATE(QHttpNetworkReply) 279 friend class QHttpNetworkConnection; 280 friend class QHttpNetworkConnectionPrivate; 281 }; 226 282 227 283 228 QT_END_NAMESPACE 284 229 285 Q_DECLARE_METATYPE(QHttpNetworkRequest)286 //Q_DECLARE_METATYPE(QHttpNetworkReply)287 288 230 #endif // QT_NO_HTTP 289 231 -
trunk/src/network/access/qnetworkaccessbackend.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 51 51 #include "qabstractnetworkcache.h" 52 52 53 #include "private/qnoncontiguousbytedevice_p.h" 54 53 55 QT_BEGIN_NAMESPACE 54 56 … … 91 93 if (mode == QNetworkRequest::AlwaysCache 92 94 && (op == QNetworkAccessManager::GetOperation 93 || op == QNetworkAccessManager::HeadOperation)) 94 return new QNetworkAccessCacheBackend; 95 || op == QNetworkAccessManager::HeadOperation)) { 96 QNetworkAccessBackend *backend = new QNetworkAccessCacheBackend; 97 backend->manager = this; 98 return backend; 99 } 95 100 96 101 if (!factoryDataShutdown) { … … 110 115 } 111 116 117 QNonContiguousByteDevice* QNetworkAccessBackend::createUploadByteDevice() 118 { 119 QNonContiguousByteDevice* device = 0; 120 121 if (reply->outgoingDataBuffer) 122 device = QNonContiguousByteDeviceFactory::create(reply->outgoingDataBuffer); 123 else 124 device = QNonContiguousByteDeviceFactory::create(reply->outgoingData); 125 126 bool bufferDisallowed = 127 reply->request.attribute(QNetworkRequest::DoNotBufferUploadDataAttribute, 128 QVariant(false)) == QVariant(true); 129 if (bufferDisallowed) 130 device->disableReset(); 131 132 // make sure we delete this later 133 device->setParent(this); 134 135 connect(device, SIGNAL(readProgress(qint64,qint64)), this, SLOT(emitReplyUploadProgress(qint64,qint64))); 136 137 return device; 138 } 139 140 // need to have this function since the reply is a private member variable 141 // and the special backends need to access this. 142 void QNetworkAccessBackend::emitReplyUploadProgress(qint64 bytesSent, qint64 bytesTotal) 143 { 144 if (reply->isFinished()) 145 return; 146 reply->emitUploadProgress(bytesSent, bytesTotal); 147 } 148 112 149 QNetworkAccessBackend::QNetworkAccessBackend() 150 : manager(0) 151 , reply(0) 113 152 { 114 153 } … … 118 157 } 119 158 120 void QNetworkAccessBackend::upstreamReadyRead()121 {122 // do nothing123 }124 125 159 void QNetworkAccessBackend::downstreamReadyWrite() 126 160 { … … 135 169 void QNetworkAccessBackend::ignoreSslErrors() 136 170 { 171 // do nothing 172 } 173 174 void QNetworkAccessBackend::ignoreSslErrors(const QList<QSslError> &errors) 175 { 176 Q_UNUSED(errors); 137 177 // do nothing 138 178 } … … 172 212 QAbstractNetworkCache *QNetworkAccessBackend::networkCache() const 173 213 { 174 return reply->networkCache; // should be the same as manager->networkCache 214 if (!manager) 215 return 0; 216 return manager->networkCache; 175 217 } 176 218 … … 185 227 } 186 228 187 qint64 QNetworkAccessBackend::upstreamBytesAvailable() const188 {189 return reply->writeBuffer.size();190 }191 192 void QNetworkAccessBackend::upstreamBytesConsumed(qint64 count)193 {194 // remove count bytes from the write buffer195 reply->consume(count);196 }197 198 QByteArray QNetworkAccessBackend::readUpstream()199 {200 // ### this is expensive. Consider making QRingBuffer::peekAll keep the buffer it returns201 return reply->writeBuffer.peek(upstreamBytesAvailable());202 }203 204 229 qint64 QNetworkAccessBackend::nextDownstreamBlockSize() const 205 230 { … … 207 232 } 208 233 209 qint64 QNetworkAccessBackend::downstreamBytesToConsume() const 210 { 211 return reply->writeBuffer.size(); 212 } 213 214 void QNetworkAccessBackend::writeDownstreamData(const QByteArray &data) 215 { 216 reply->feed(data); 234 void QNetworkAccessBackend::writeDownstreamData(QByteDataBuffer &list) 235 { 236 reply->appendDownstreamData(list); 217 237 } 218 238 219 239 void QNetworkAccessBackend::writeDownstreamData(QIODevice *data) 220 240 { 221 reply-> feed(data);241 reply->appendDownstreamData(data); 222 242 } 223 243 -
trunk/src/network/access/qnetworkaccessbackend_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 71 71 class QAbstractNetworkCache; 72 72 class QNetworkCacheMetaData; 73 class QNetworkAccessBackendUploadIODevice; 74 class QNonContiguousByteDevice; 73 75 74 76 // Should support direct file upload from disk or download to disk. … … 87 89 // 88 90 // - Upstream: 89 // Upstream is data that is being written into this connection, 90 // from the user. Upstream operates in a "pull" mechanism: the 91 // connection will be notified that there is more data available 92 // by a call to "upstreamReadyRead". The number of bytes 93 // available is given by upstreamBytesAvailable(). A call to 94 // readUpstream() always yields the entire upstream buffer. When 95 // the connection has processed a certain amount of bytes from 96 // that buffer, it should call upstreamBytesConsumed(). 91 // The upstream uses a QNonContiguousByteDevice provided 92 // by the backend. This device emits the usual readyRead() 93 // signal when the backend has data available for the connection 94 // to write. The different backends can listen on this signal 95 // and then pull upload data from the QNonContiguousByteDevice and 96 // deal with it. 97 // 97 98 // 98 99 // - Downstream: … … 112 113 virtual void open() = 0; 113 114 virtual void closeDownstreamChannel() = 0; 114 virtual void closeUpstreamChannel() = 0;115 115 virtual bool waitForDownstreamReadyRead(int msecs) = 0; 116 virtual bool waitForUpstreamBytesWritten(int msecs) = 0;117 116 118 117 // slot-like: 119 virtual void upstreamReadyRead();120 118 virtual void downstreamReadyWrite(); 121 119 virtual void copyFinished(QIODevice *); 122 120 virtual void ignoreSslErrors(); 121 virtual void ignoreSslErrors(const QList<QSslError> &errors); 123 122 124 123 virtual void fetchSslConfiguration(QSslConfiguration &configuration) const; … … 156 155 void setAttribute(QNetworkRequest::Attribute code, const QVariant &value); 157 156 157 // return true if the QNonContiguousByteDevice of the upload 158 // data needs to support reset(). Currently needed for HTTP. 159 // This will possibly enable buffering of the upload data. 160 virtual bool needsResetableUploadData() { return false; } 161 158 162 protected: 159 // these functions control the upstream mechanism 160 // that is, data coming into the backend and out via the connection 161 qint64 upstreamBytesAvailable() const; 162 void upstreamBytesConsumed(qint64 count); 163 QByteArray readUpstream(); 163 // Create the device used for reading the upload data 164 QNonContiguousByteDevice* createUploadByteDevice(); 165 164 166 165 167 // these functions control the downstream mechanism 166 168 // that is, data that has come via the connection and is going out the backend 167 169 qint64 nextDownstreamBlockSize() const; 168 qint64 downstreamBytesToConsume() const; 169 void writeDownstreamData(const QByteArray &data); 170 void writeDownstreamData(QByteDataBuffer &list); 171 172 public slots: 173 // for task 251801, needs to be a slot to be called asynchronously 170 174 void writeDownstreamData(QIODevice *data); 171 175 … … 180 184 void redirectionRequested(const QUrl &destination); 181 185 void sslErrors(const QList<QSslError> &errors); 186 void emitReplyUploadProgress(qint64 bytesSent, qint64 bytesTotal); 182 187 183 188 private: 184 189 friend class QNetworkAccessManager; 185 190 friend class QNetworkAccessManagerPrivate; 191 friend class QNetworkAccessBackendUploadIODevice; 186 192 QNetworkAccessManagerPrivate *manager; 187 193 QNetworkReplyImplPrivate *reply; -
trunk/src/network/access/qnetworkaccesscache.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** -
trunk/src/network/access/qnetworkaccesscache_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 65 65 class QUrl; 66 66 67 // this class is not about caching files but about 68 // caching objects used by QNetworkAccessManager, e.g. existing TCP connections 69 // or credentials. 67 70 class QNetworkAccessCache: public QObject 68 71 { -
trunk/src/network/access/qnetworkaccesscachebackend.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 53 53 QNetworkAccessCacheBackend::QNetworkAccessCacheBackend() 54 54 : QNetworkAccessBackend() 55 , device(0) 55 56 { 56 57 } … … 86 87 setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, attributes.value(QNetworkRequest::HttpReasonPhraseAttribute)); 87 88 setAttribute(QNetworkRequest::SourceIsFromCacheAttribute, true); 89 90 // set the raw headers 91 QNetworkCacheMetaData::RawHeaderList rawHeaders = item.rawHeaders(); 92 QNetworkCacheMetaData::RawHeaderList::ConstIterator it = rawHeaders.constBegin(), 93 end = rawHeaders.constEnd(); 94 for ( ; it != end; ++it) 95 setRawHeader(it->first, it->second); 96 97 // handle a possible redirect 98 QVariant redirectionTarget = attributes.value(QNetworkRequest::RedirectionTargetAttribute); 99 if (redirectionTarget.isValid()) { 100 setAttribute(QNetworkRequest::RedirectionTargetAttribute, redirectionTarget); 101 redirectionRequested(redirectionTarget.toUrl()); 102 } 88 103 89 104 // signal we're open -
trunk/src/network/access/qnetworkaccesscachebackend_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** -
trunk/src/network/access/qnetworkaccessdatabackend.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 118 118 emit metaDataChanged(); 119 119 120 writeDownstreamData(payload); 120 QByteDataBuffer list; 121 list.append(payload); 122 payload.clear(); // important because of implicit sharing! 123 writeDownstreamData(list); 124 121 125 finished(); 122 126 return; -
trunk/src/network/access/qnetworkaccessdatabackend_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** -
trunk/src/network/access/qnetworkaccessdebugpipebackend.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 42 42 #include "qnetworkaccessdebugpipebackend_p.h" 43 43 #include "QtCore/qdatastream.h" 44 #include <QCoreApplication> 45 #include "private/qnoncontiguousbytedevice_p.h" 44 46 45 47 QT_BEGIN_NAMESPACE … … 50 52 ReadBufferSize = 16384, 51 53 WriteBufferSize = ReadBufferSize 52 };53 54 struct QNetworkAccessDebugPipeBackend::DataPacket55 {56 QList<QPair<QByteArray, QByteArray> > headers;57 QByteArray data;58 54 }; 59 55 … … 80 76 81 77 QNetworkAccessDebugPipeBackend::QNetworkAccessDebugPipeBackend() 82 : incomingPacketSize(0), bareProtocol(false) 78 : bareProtocol(false), hasUploadFinished(false), hasDownloadFinished(false), 79 hasEverythingFinished(false), bytesDownloaded(0), bytesUploaded(0) 83 80 { 84 81 } … … 86 83 QNetworkAccessDebugPipeBackend::~QNetworkAccessDebugPipeBackend() 87 84 { 85 // this is signals disconnect, not network! 88 86 socket.disconnect(this); // we're not interested in the signals at this point 89 87 } … … 93 91 socket.connectToHost(url().host(), url().port(12345)); 94 92 socket.setReadBufferSize(ReadBufferSize); 93 94 // socket ready read -> we can push from socket to downstream 95 95 connect(&socket, SIGNAL(readyRead()), SLOT(socketReadyRead())); 96 connect(&socket, SIGNAL(bytesWritten(qint64)), SLOT(socketBytesWritten(qint64)));97 96 connect(&socket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(socketError())); 98 97 connect(&socket, SIGNAL(disconnected()), SLOT(socketDisconnected())); 98 connect(&socket, SIGNAL(connected()), SLOT(socketConnected())); 99 // socket bytes written -> we can push more from upstream to socket 100 connect(&socket, SIGNAL(bytesWritten(qint64)), SLOT(socketBytesWritten(qint64))); 99 101 100 102 bareProtocol = url().queryItemValue(QLatin1String("bare")) == QLatin1String("1"); 101 103 102 if (!bareProtocol) { 103 // "Handshake": 104 // send outgoing metadata and the URL being requested 105 DataPacket packet; 106 //packet.metaData = request().metaData(); 107 packet.data = url().toEncoded(); 108 send(packet); 109 } 104 if (operation() == QNetworkAccessManager::PutOperation) { 105 uploadByteDevice = createUploadByteDevice(); 106 QObject::connect(uploadByteDevice, SIGNAL(readyRead()), this, SLOT(uploadReadyReadSlot())); 107 QMetaObject::invokeMethod(this, "uploadReadyReadSlot", Qt::QueuedConnection); 108 } 109 } 110 111 void QNetworkAccessDebugPipeBackend::socketReadyRead() 112 { 113 pushFromSocketToDownstream(); 114 } 115 116 void QNetworkAccessDebugPipeBackend::downstreamReadyWrite() 117 { 118 pushFromSocketToDownstream(); 119 } 120 121 void QNetworkAccessDebugPipeBackend::socketBytesWritten(qint64) 122 { 123 pushFromUpstreamToSocket(); 124 } 125 126 void QNetworkAccessDebugPipeBackend::uploadReadyReadSlot() 127 { 128 pushFromUpstreamToSocket(); 129 } 130 131 void QNetworkAccessDebugPipeBackend::pushFromSocketToDownstream() 132 { 133 QByteArray buffer; 134 135 if (socket.state() == QAbstractSocket::ConnectingState) { 136 return; 137 } 138 139 forever { 140 if (hasDownloadFinished) 141 return; 142 143 buffer.resize(ReadBufferSize); 144 qint64 haveRead = socket.read(buffer.data(), ReadBufferSize); 145 146 if (haveRead == -1) { 147 hasDownloadFinished = true; 148 // this ensures a good last downloadProgress is emitted 149 setHeader(QNetworkRequest::ContentLengthHeader, QVariant()); 150 possiblyFinish(); 151 break; 152 } else if (haveRead == 0) { 153 break; 154 } else { 155 // have read something 156 buffer.resize(haveRead); 157 bytesDownloaded += haveRead; 158 159 QByteDataBuffer list; 160 list.append(buffer); 161 buffer.clear(); // important because of implicit sharing! 162 writeDownstreamData(list); 163 } 164 } 165 } 166 167 void QNetworkAccessDebugPipeBackend::pushFromUpstreamToSocket() 168 { 169 // FIXME 170 if (operation() == QNetworkAccessManager::PutOperation) { 171 if (hasUploadFinished) 172 return; 173 174 forever { 175 if (socket.bytesToWrite() >= WriteBufferSize) 176 return; 177 178 qint64 haveRead; 179 const char *readPointer = uploadByteDevice->readPointer(WriteBufferSize, haveRead); 180 if (haveRead == -1) { 181 // EOF 182 hasUploadFinished = true; 183 emitReplyUploadProgress(bytesUploaded, bytesUploaded); 184 possiblyFinish(); 185 break; 186 } else if (haveRead == 0 || readPointer == 0) { 187 // nothing to read right now, we will be called again later 188 break; 189 } else { 190 qint64 haveWritten; 191 haveWritten = socket.write(readPointer, haveRead); 192 193 if (haveWritten < 0) { 194 // write error! 195 QString msg = QCoreApplication::translate("QNetworkAccessDebugPipeBackend", "Write error writing to %1: %2") 196 .arg(url().toString(), socket.errorString()); 197 error(QNetworkReply::ProtocolFailure, msg); 198 finished(); 199 return; 200 } else { 201 uploadByteDevice->advanceReadPointer(haveWritten); 202 bytesUploaded += haveWritten; 203 emitReplyUploadProgress(bytesUploaded, -1); 204 } 205 206 //QCoreApplication::processEvents(); 207 208 } 209 } 210 } 211 } 212 213 void QNetworkAccessDebugPipeBackend::possiblyFinish() 214 { 215 if (hasEverythingFinished) 216 return; 217 hasEverythingFinished = true; 218 219 if ((operation() == QNetworkAccessManager::GetOperation) && hasDownloadFinished) { 220 socket.close(); 221 finished(); 222 } else if ((operation() == QNetworkAccessManager::PutOperation) && hasUploadFinished) { 223 socket.close(); 224 finished(); 225 } 226 227 110 228 } 111 229 112 230 void QNetworkAccessDebugPipeBackend::closeDownstreamChannel() 113 231 { 114 if (operation() == QNetworkAccessManager::GetOperation) 115 socket.disconnectFromHost(); 116 } 117 118 void QNetworkAccessDebugPipeBackend::closeUpstreamChannel() 119 { 120 if (operation() == QNetworkAccessManager::PutOperation) 121 socket.disconnectFromHost(); 122 else if (operation() == QNetworkAccessManager::PostOperation) { 123 send(DataPacket()); 124 } 125 } 126 127 bool QNetworkAccessDebugPipeBackend::waitForDownstreamReadyRead(int ms) 128 { 129 readyReadEmitted = false; 130 if (socket.bytesAvailable()) { 131 socketReadyRead(); 132 if (readyReadEmitted) 133 return true; 134 } 135 socket.waitForReadyRead(ms); 136 return readyReadEmitted; 137 } 138 139 bool QNetworkAccessDebugPipeBackend::waitForUpstreamBytesWritten(int ms) 140 { 141 bytesWrittenEmitted = false; 142 upstreamReadyRead(); 143 if (bytesWrittenEmitted) 144 return true; 145 146 socket.waitForBytesWritten(ms); 147 return bytesWrittenEmitted; 148 } 149 150 void QNetworkAccessDebugPipeBackend::upstreamReadyRead() 151 { 152 int maxWrite = WriteBufferSize - socket.bytesToWrite(); 153 if (maxWrite <= 0) 154 return; // can't write yet, wait for the socket to write 155 156 if (bareProtocol) { 157 QByteArray data = readUpstream(); 158 if (data.isEmpty()) 159 return; 160 161 socket.write(data); 162 upstreamBytesConsumed(data.size()); 163 bytesWrittenEmitted = true; 164 return; 165 } 166 167 DataPacket packet; 168 packet.data = readUpstream(); 169 if (packet.data.isEmpty()) 170 return; // we'll be called again when there's data 171 if (packet.data.size() > maxWrite) 172 packet.data.truncate(maxWrite); 173 174 if (!send(packet)) { 175 QString msg = QObject::tr("Write error writing to %1: %2") 176 .arg(url().toString(), socket.errorString()); 177 error(QNetworkReply::ProtocolFailure, msg); 178 179 finished(); 180 return; 181 } 182 upstreamBytesConsumed(packet.data.size()); 183 bytesWrittenEmitted = true; 184 } 185 186 void QNetworkAccessDebugPipeBackend::downstreamReadyWrite() 187 { 188 socketReadyRead(); 189 } 190 191 void QNetworkAccessDebugPipeBackend::socketReadyRead() 192 { 193 if (bareProtocol) { 194 qint64 bytesToRead = socket.bytesAvailable(); 195 if (bytesToRead) { 196 QByteArray buffer; 197 buffer.resize(bytesToRead); 198 qint64 bytesRead = socket.read(buffer.data(), bytesToRead); 199 if (bytesRead < bytesToRead) 200 buffer.truncate(bytesRead); 201 writeDownstreamData(buffer); 202 readyReadEmitted = true; 203 } 204 return; 205 } 206 207 while (canReceive() && 208 (socket.state() == QAbstractSocket::UnconnectedState || nextDownstreamBlockSize())) { 209 DataPacket packet; 210 if (receive(packet)) { 211 if (!packet.headers.isEmpty()) { 212 QList<QPair<QByteArray, QByteArray> >::ConstIterator 213 it = packet.headers.constBegin(), 214 end = packet.headers.constEnd(); 215 for ( ; it != end; ++it) 216 setRawHeader(it->first, it->second); 217 metaDataChanged(); 218 } 219 220 if (!packet.data.isEmpty()) { 221 writeDownstreamData(packet.data); 222 readyReadEmitted = true; 223 } 224 225 if (packet.headers.isEmpty() && packet.data.isEmpty()) { 226 // it's an eof 227 socket.close(); 228 readyReadEmitted = true; 229 } 230 } else { 231 // got an error 232 QString msg = QObject::tr("Read error reading from %1: %2") 233 .arg(url().toString(), socket.errorString()); 234 error(QNetworkReply::ProtocolFailure, msg); 235 236 finished(); 237 return; 238 } 239 } 240 } 241 242 void QNetworkAccessDebugPipeBackend::socketBytesWritten(qint64) 243 { 244 upstreamReadyRead(); 245 } 232 qWarning("QNetworkAccessDebugPipeBackend::closeDownstreamChannel() %d",operation());; 233 //if (operation() == QNetworkAccessManager::GetOperation) 234 // socket.disconnectFromHost(); 235 } 236 246 237 247 238 void QNetworkAccessDebugPipeBackend::socketError() 248 239 { 240 qWarning("QNetworkAccessDebugPipeBackend::socketError() %d",socket.error()); 249 241 QNetworkReply::NetworkError code; 250 242 switch (socket.error()) { … … 270 262 void QNetworkAccessDebugPipeBackend::socketDisconnected() 271 263 { 272 socketReadyRead(); 273 if (incomingPacketSize == 0 && socket.bytesToWrite() == 0) { 264 pushFromSocketToDownstream(); 265 266 if (socket.bytesToWrite() == 0) { 274 267 // normal close 275 finished();276 268 } else { 277 269 // abnormal close … … 279 271 .arg(url().toString()); 280 272 error(QNetworkReply::RemoteHostClosedError, msg); 281 282 273 finished(); 283 274 } 284 275 } 285 276 286 bool QNetworkAccessDebugPipeBackend::send(const DataPacket &packet) 287 { 288 QByteArray ba; 289 { 290 QDataStream stream(&ba, QIODevice::WriteOnly); 291 stream.setVersion(QDataStream::Qt_4_4); 292 293 stream << packet.headers << packet.data; 294 } 295 296 qint32 outgoingPacketSize = ba.size(); 297 qint64 written = socket.write((const char*)&outgoingPacketSize, sizeof outgoingPacketSize); 298 written += socket.write(ba); 299 return quint64(written) == (outgoingPacketSize + sizeof outgoingPacketSize); 300 } 301 302 bool QNetworkAccessDebugPipeBackend::receive(DataPacket &packet) 303 { 304 if (!canReceive()) 305 return false; 306 307 // canReceive() does the setting up for us 308 Q_ASSERT(socket.bytesAvailable() >= incomingPacketSize); 309 QByteArray incomingPacket = socket.read(incomingPacketSize); 310 QDataStream stream(&incomingPacket, QIODevice::ReadOnly); 311 stream.setVersion(QDataStream::Qt_4_4); 312 stream >> packet.headers >> packet.data; 313 314 // reset for next packet: 315 incomingPacketSize = 0; 316 socket.setReadBufferSize(ReadBufferSize); 317 return true; 318 } 319 320 bool QNetworkAccessDebugPipeBackend::canReceive() 321 { 322 if (incomingPacketSize == 0) { 323 // read the packet size 324 if (quint64(socket.bytesAvailable()) >= sizeof incomingPacketSize) 325 socket.read((char*)&incomingPacketSize, sizeof incomingPacketSize); 326 else 327 return false; 328 } 329 330 if (incomingPacketSize == 0) { 331 QString msg = QObject::tr("Protocol error: packet of size 0 received"); 332 error(QNetworkReply::ProtocolFailure, msg); 333 finished(); 334 335 socket.blockSignals(true); 336 socket.abort(); 337 socket.blockSignals(false); 338 return false; 339 } 340 341 return socket.bytesAvailable() >= incomingPacketSize; 277 void QNetworkAccessDebugPipeBackend::socketConnected() 278 { 279 } 280 281 bool QNetworkAccessDebugPipeBackend::waitForDownstreamReadyRead(int ms) 282 { 283 Q_UNUSED(ms); 284 qCritical("QNetworkAccess: Debug pipe backend does not support waitForReadyRead()"); 285 return false; 342 286 } 343 287 -
trunk/src/network/access/qnetworkaccessdebugpipebackend_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 67 67 Q_OBJECT 68 68 public: 69 struct DataPacket;70 69 QNetworkAccessDebugPipeBackend(); 71 70 virtual ~QNetworkAccessDebugPipeBackend(); … … 73 72 virtual void open(); 74 73 virtual void closeDownstreamChannel(); 75 virtual void closeUpstreamChannel();76 74 virtual bool waitForDownstreamReadyRead(int msecs); 77 virtual bool waitForUpstreamBytesWritten(int msecs);78 75 79 virtual void upstreamReadyRead();80 76 virtual void downstreamReadyWrite(); 81 77 78 protected: 79 void pushFromSocketToDownstream(); 80 void pushFromUpstreamToSocket(); 81 void possiblyFinish(); 82 QNonContiguousByteDevice *uploadByteDevice; 83 82 84 private slots: 85 void uploadReadyReadSlot(); 83 86 void socketReadyRead(); 84 87 void socketBytesWritten(qint64 bytes); 85 88 void socketError(); 86 89 void socketDisconnected(); 90 void socketConnected(); 87 91 88 92 private: 89 93 QTcpSocket socket; 90 qint32 incomingPacketSize;91 bool readyReadEmitted;92 bool bytesWrittenEmitted;93 94 bool bareProtocol; 95 bool hasUploadFinished; 96 bool hasDownloadFinished; 97 bool hasEverythingFinished; 94 98 95 bool send(const DataPacket &packet); 96 bool canReceive(); 97 bool receive(DataPacket &packet); 99 qint64 bytesDownloaded; 100 qint64 bytesUploaded; 98 101 }; 99 102 -
trunk/src/network/access/qnetworkaccessfilebackend.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 44 44 #include "qurlinfo.h" 45 45 #include "qdir.h" 46 #include "private/qnoncontiguousbytedevice_p.h" 46 47 47 48 #include <QtCore/QCoreApplication> … … 78 79 79 80 QNetworkAccessFileBackend::QNetworkAccessFileBackend() 80 : totalBytes(0)81 : uploadByteDevice(0), totalBytes(0), hasUploadFinished(false) 81 82 { 82 83 } … … 109 110 if (fileName.isEmpty()) { 110 111 if (url.scheme() == QLatin1String("qrc")) 111 fileName = QLatin1 String(":") + url.path();112 fileName = QLatin1Char(':') + url.path(); 112 113 else 113 114 fileName = url.toString(QUrl::RemoveAuthority | QUrl::RemoveFragment | QUrl::RemoveQuery); … … 127 128 case QNetworkAccessManager::PutOperation: 128 129 mode = QIODevice::WriteOnly | QIODevice::Truncate; 130 uploadByteDevice = createUploadByteDevice(); 131 QObject::connect(uploadByteDevice, SIGNAL(readyRead()), this, SLOT(uploadReadyReadSlot())); 132 QMetaObject::invokeMethod(this, "uploadReadyReadSlot", Qt::QueuedConnection); 129 133 break; 130 134 default: … … 153 157 } 154 158 159 void QNetworkAccessFileBackend::uploadReadyReadSlot() 160 { 161 if (hasUploadFinished) 162 return; 163 164 forever { 165 qint64 haveRead; 166 const char *readPointer = uploadByteDevice->readPointer(-1, haveRead); 167 if (haveRead == -1) { 168 // EOF 169 hasUploadFinished = true; 170 file.flush(); 171 file.close(); 172 finished(); 173 break; 174 } else if (haveRead == 0 || readPointer == 0) { 175 // nothing to read right now, we will be called again later 176 break; 177 } else { 178 qint64 haveWritten; 179 haveWritten = file.write(readPointer, haveRead); 180 181 if (haveWritten < 0) { 182 // write error! 183 QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Write error writing to %1: %2") 184 .arg(url().toString(), file.errorString()); 185 error(QNetworkReply::ProtocolFailure, msg); 186 187 finished(); 188 return; 189 } else { 190 uploadByteDevice->advanceReadPointer(haveWritten); 191 } 192 193 194 file.flush(); 195 } 196 } 197 } 198 155 199 void QNetworkAccessFileBackend::closeDownstreamChannel() 156 200 { 157 201 if (operation() == QNetworkAccessManager::GetOperation) { 158 202 file.close(); 159 //downstreamChannelClosed();160 }161 }162 163 void QNetworkAccessFileBackend::closeUpstreamChannel()164 {165 if (operation() == QNetworkAccessManager::PutOperation) {166 file.close();167 finished();168 203 } 169 204 } … … 173 208 Q_ASSERT(operation() == QNetworkAccessManager::GetOperation); 174 209 return readMoreFromFile(); 175 }176 177 bool QNetworkAccessFileBackend::waitForUpstreamBytesWritten(int)178 {179 Q_ASSERT_X(false, "QNetworkAccessFileBackend::waitForUpstreamBytesWritten",180 "This function should never have been called, since there is never anything "181 "left to be written!");182 return false;183 }184 185 void QNetworkAccessFileBackend::upstreamReadyRead()186 {187 Q_ASSERT_X(operation() == QNetworkAccessManager::PutOperation, "QNetworkAccessFileBackend",188 "We're being told to upload data but operation isn't PUT!");189 190 // there's more data to be written to the file191 while (upstreamBytesAvailable()) {192 // write everything and let QFile handle it193 int written = file.write(readUpstream());194 195 if (written < 0) {196 // write error!197 QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Write error writing to %1: %2")198 .arg(url().toString(), file.errorString());199 error(QNetworkReply::ProtocolFailure, msg);200 201 finished();202 return;203 }204 205 // successful write206 file.flush();207 upstreamBytesConsumed(written);208 }209 210 } 210 211 … … 263 264 data.resize(actuallyRead); 264 265 totalBytes += actuallyRead; 265 writeDownstreamData(data); 266 267 QByteDataBuffer list; 268 list.append(data); 269 data.clear(); // important because of implicit sharing! 270 writeDownstreamData(list); 266 271 } 267 272 return true; -
trunk/src/network/access/qnetworkaccessfilebackend_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 63 63 class QNetworkAccessFileBackend: public QNetworkAccessBackend 64 64 { 65 Q_OBJECT 65 66 public: 66 67 QNetworkAccessFileBackend(); … … 69 70 virtual void open(); 70 71 virtual void closeDownstreamChannel(); 71 virtual void closeUpstreamChannel();72 72 virtual bool waitForDownstreamReadyRead(int msecs); 73 virtual bool waitForUpstreamBytesWritten(int msecs);74 73 75 virtual void upstreamReadyRead();76 74 virtual void downstreamReadyWrite(); 77 75 76 public slots: 77 void uploadReadyReadSlot(); 78 protected: 79 QNonContiguousByteDevice *uploadByteDevice; 78 80 private: 79 81 QFile file; 80 82 qint64 totalBytes; 83 bool hasUploadFinished; 81 84 82 85 bool loadFileInfo(); -
trunk/src/network/access/qnetworkaccessftpbackend.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 43 43 #include "qnetworkaccessmanager_p.h" 44 44 #include "QtNetwork/qauthenticator.h" 45 #include "private/qnoncontiguousbytedevice_p.h" 45 46 46 47 #ifndef QT_NO_FTP … … 82 83 } 83 84 84 class QNetworkAccessFtpIODevice: public QIODevice 85 { 86 //Q_OBJECT 87 public: 88 QNetworkAccessFtpBackend *backend; 89 bool eof; 90 91 inline QNetworkAccessFtpIODevice(QNetworkAccessFtpBackend *parent) 92 : QIODevice(parent), backend(parent), eof(false) 93 { open(ReadOnly); } 94 95 bool isSequential() const { return true; } 96 bool atEnd() const { return backend->upstreamBytesAvailable() == 0; } 97 98 qint64 bytesAvailable() const { return backend->upstreamBytesAvailable(); } 99 qint64 bytesToWrite() const { return backend->downstreamBytesToConsume(); } 100 protected: 101 qint64 readData(char *data, qint64 maxlen) 102 { 103 const QByteArray toSend = backend->readUpstream(); 104 maxlen = qMin<qint64>(maxlen, toSend.size()); 105 if (!maxlen) 106 return eof ? -1 : 0; 107 108 backend->upstreamBytesConsumed(maxlen); 109 memcpy(data, toSend.constData(), maxlen); 110 return maxlen; 111 } 112 113 qint64 writeData(const char *, qint64) 114 { return -1; } 115 116 friend class QNetworkAccessFtpBackend; 117 }; 118 119 class QNetworkAccessFtpFtp: public QFtp, public QNetworkAccessCache::CacheableObject 85 class QNetworkAccessCachedFtpConnection: public QFtp, public QNetworkAccessCache::CacheableObject 120 86 { 121 87 // Q_OBJECT 122 88 public: 123 QNetworkAccess FtpFtp()89 QNetworkAccessCachedFtpConnection() 124 90 { 125 91 setExpires(true); … … 183 149 state = LoggingIn; 184 150 185 QNetworkAccessCache* cache = QNetworkAccessManagerPrivate::getCache(this);151 QNetworkAccessCache* objectCache = QNetworkAccessManagerPrivate::getObjectCache(this); 186 152 QByteArray cacheKey = makeCacheKey(url); 187 if (! cache->requestEntry(cacheKey, this,153 if (!objectCache->requestEntry(cacheKey, this, 188 154 SLOT(ftpConnectionReady(QNetworkAccessCache::CacheableObject*)))) { 189 ftp = new QNetworkAccess FtpFtp;155 ftp = new QNetworkAccessCachedFtpConnection; 190 156 #ifndef QT_NO_NETWORKPROXY 191 157 if (proxy.type() == QNetworkProxy::FtpCachingProxy) … … 195 161 ftp->login(url.userName(), url.password()); 196 162 197 cache->addEntry(cacheKey, ftp);163 objectCache->addEntry(cacheKey, ftp); 198 164 ftpConnectionReady(ftp); 199 165 } 200 166 201 uploadDevice = new QNetworkAccessFtpIODevice(this); 167 // Put operation 168 if (operation() == QNetworkAccessManager::PutOperation) { 169 uploadDevice = QNonContiguousByteDeviceFactory::wrap(createUploadByteDevice()); 170 uploadDevice->setParent(this); 171 } 202 172 } 203 173 … … 213 183 } 214 184 215 void QNetworkAccessFtpBackend::closeUpstreamChannel()216 {217 if (operation() == QNetworkAccessManager::PutOperation) {218 Q_ASSERT(uploadDevice);219 uploadDevice->eof = true;220 if (!upstreamBytesAvailable())221 emit uploadDevice->readyRead();222 }223 }224 225 185 bool QNetworkAccessFtpBackend::waitForDownstreamReadyRead(int ms) 226 186 { … … 240 200 } 241 201 242 bool QNetworkAccessFtpBackend::waitForUpstreamBytesWritten(int ms)243 {244 Q_UNUSED(ms);245 qCritical("QNetworkAccess: FTP backend does not support waitForBytesWritten()");246 return false;247 }248 249 void QNetworkAccessFtpBackend::upstreamReadyRead()250 {251 // uh... how does QFtp operate?252 }253 254 202 void QNetworkAccessFtpBackend::downstreamReadyWrite() 255 203 { … … 260 208 void QNetworkAccessFtpBackend::ftpConnectionReady(QNetworkAccessCache::CacheableObject *o) 261 209 { 262 ftp = static_cast<QNetworkAccess FtpFtp*>(o);210 ftp = static_cast<QNetworkAccessCachedFtpConnection *>(o); 263 211 connect(ftp, SIGNAL(done(bool)), SLOT(ftpDone())); 264 212 connect(ftp, SIGNAL(rawCommandReply(int,QString)), SLOT(ftpRawCommandReply(int,QString))); … … 280 228 281 229 QByteArray key = makeCacheKey(url()); 282 QNetworkAccessManagerPrivate::get Cache(this)->releaseEntry(key);230 QNetworkAccessManagerPrivate::getObjectCache(this)->releaseEntry(key); 283 231 284 232 ftp = 0; … … 331 279 // we're not connected, so remove the cache entry: 332 280 QByteArray key = makeCacheKey(url()); 333 QNetworkAccessManagerPrivate::get Cache(this)->removeEntry(key);281 QNetworkAccessManagerPrivate::getObjectCache(this)->removeEntry(key); 334 282 335 283 disconnect(ftp, 0, this, 0); … … 408 356 void QNetworkAccessFtpBackend::ftpReadyRead() 409 357 { 410 writeDownstreamData(ftp->readAll()); 358 QByteArray data = ftp->readAll(); 359 QByteDataBuffer list; 360 list.append(data); 361 data.clear(); // important because of implicit sharing! 362 writeDownstreamData(list); 411 363 } 412 364 -
trunk/src/network/access/qnetworkaccessftpbackend_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 67 67 68 68 class QNetworkAccessFtpIODevice; 69 class QNetworkAccess FtpFtp;69 class QNetworkAccessCachedFtpConnection; 70 70 71 71 class QNetworkAccessFtpBackend: public QNetworkAccessBackend … … 88 88 virtual void open(); 89 89 virtual void closeDownstreamChannel(); 90 virtual void closeUpstreamChannel();91 90 virtual bool waitForDownstreamReadyRead(int msecs); 92 virtual bool waitForUpstreamBytesWritten(int msecs);93 91 94 virtual void upstreamReadyRead();95 92 virtual void downstreamReadyWrite(); 96 93 … … 105 102 private: 106 103 friend class QNetworkAccessFtpIODevice; 107 QPointer<QNetworkAccess FtpFtp> ftp;108 Q NetworkAccessFtpIODevice *uploadDevice;104 QPointer<QNetworkAccessCachedFtpConnection> ftp; 105 QIODevice *uploadDevice; 109 106 qint64 totalBytes; 110 107 int helpId, sizeId, mdtmId; -
trunk/src/network/access/qnetworkaccesshttpbackend.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 213 213 case QNetworkAccessManager::HeadOperation: 214 214 case QNetworkAccessManager::PutOperation: 215 case QNetworkAccessManager::DeleteOperation: 215 216 break; 216 217 … … 243 244 case 404: // Not Found 244 245 code = QNetworkReply::ContentNotFoundError; 246 break; 247 248 case 405: // Method Not Allowed 249 code = QNetworkReply::ContentOperationNotPermittedError; 245 250 break; 246 251 … … 266 271 } 267 272 268 class QNetworkAccess HttpBackendCache: public QHttpNetworkConnection,273 class QNetworkAccessCachedHttpConnection: public QHttpNetworkConnection, 269 274 public QNetworkAccessCache::CacheableObject 270 275 { 271 276 // Q_OBJECT 272 277 public: 273 QNetworkAccess HttpBackendCache(const QString &hostName, quint16 port, bool encrypt)278 QNetworkAccessCachedHttpConnection(const QString &hostName, quint16 port, bool encrypt) 274 279 : QHttpNetworkConnection(hostName, port, encrypt) 275 280 { … … 287 292 }; 288 293 289 class QNetworkAccessHttpBackendIODevice: public QIODevice290 {291 // Q_OBJECT292 public:293 bool eof;294 QNetworkAccessHttpBackendIODevice(QNetworkAccessHttpBackend *parent)295 : QIODevice(parent), eof(false)296 {297 setOpenMode(ReadOnly);298 }299 bool isSequential() const { return true; }300 qint64 bytesAvailable() const301 { return static_cast<QNetworkAccessHttpBackend *>(parent())->upstreamBytesAvailable(); }302 303 protected:304 virtual qint64 readData(char *buffer, qint64 maxlen)305 {306 qint64 ret = static_cast<QNetworkAccessHttpBackend *>(parent())->deviceReadData(buffer, maxlen);307 if (!ret && eof)308 return -1;309 return ret;310 }311 312 virtual qint64 writeData(const char *, qint64)313 {314 return -1; // cannot write315 }316 317 friend class QNetworkAccessHttpBackend;318 };319 320 294 QNetworkAccessHttpBackend::QNetworkAccessHttpBackend() 321 295 : QNetworkAccessBackend(), httpReply(0), http(0), uploadDevice(0) 322 296 #ifndef QT_NO_OPENSSL 323 , pendingSslConfiguration(0), pendingIgnore SslErrors(false)297 , pendingSslConfiguration(0), pendingIgnoreAllSslErrors(false) 324 298 #endif 325 299 { … … 338 312 { 339 313 if (http) { 314 // This is abut disconnecting signals, not about disconnecting TCP connections 340 315 disconnect(http, 0, this, 0); 341 QNetworkAccessCache *cache = QNetworkAccessManagerPrivate::getCache(this); 316 317 // Get the object cache that stores our QHttpNetworkConnection objects 318 QNetworkAccessCache *cache = QNetworkAccessManagerPrivate::getObjectCache(this); 342 319 cache->releaseEntry(cacheKey); 343 320 } 344 321 322 // This is abut disconnecting signals, not about disconnecting TCP connections 345 323 if (httpReply) 346 324 disconnect(httpReply, 0, this, 0); … … 508 486 invalidateCache(); 509 487 httpRequest.setOperation(QHttpNetworkRequest::Post); 510 uploadDevice = new QNetworkAccessHttpBackendIODevice(this);488 httpRequest.setUploadByteDevice(createUploadByteDevice()); 511 489 break; 512 490 … … 514 492 invalidateCache(); 515 493 httpRequest.setOperation(QHttpNetworkRequest::Put); 516 uploadDevice = new QNetworkAccessHttpBackendIODevice(this); 494 httpRequest.setUploadByteDevice(createUploadByteDevice()); 495 break; 496 497 case QNetworkAccessManager::DeleteOperation: 498 invalidateCache(); 499 httpRequest.setOperation(QHttpNetworkRequest::Delete); 517 500 break; 518 501 … … 521 504 } 522 505 523 httpRequest.setData(uploadDevice);524 506 httpRequest.setUrl(url()); 525 507 … … 529 511 530 512 if (loadedFromCache) { 531 QNetworkAccessBackend::finished(); 513 // commented this out since it will be called later anyway 514 // by copyFinished() 515 //QNetworkAccessBackend::finished(); 532 516 return; // no need to send the request! :) 533 517 } 518 519 if (request().attribute(QNetworkRequest::HttpPipeliningAllowedAttribute).toBool() == true) 520 httpRequest.setPipeliningAllowed(true); 534 521 535 522 httpReply = http->sendRequest(httpRequest); … … 538 525 if (pendingSslConfiguration) 539 526 httpReply->setSslConfiguration(*pendingSslConfiguration); 540 if (pendingIgnore SslErrors)527 if (pendingIgnoreAllSslErrors) 541 528 httpReply->ignoreSslErrors(); 529 httpReply->ignoreSslErrors(pendingIgnoreSslErrorsList); 542 530 #endif 543 531 … … 603 591 // check if we have an open connection to this host 604 592 cacheKey = makeCacheKey(this, theProxy); 605 QNetworkAccessCache *cache = QNetworkAccessManagerPrivate::getCache(this); 606 if ((http = static_cast<QNetworkAccessHttpBackendCache *>(cache->requestEntryNow(cacheKey))) == 0) { 593 QNetworkAccessCache *cache = QNetworkAccessManagerPrivate::getObjectCache(this); 594 // the http object is actually a QHttpNetworkConnection 595 http = static_cast<QNetworkAccessCachedHttpConnection *>(cache->requestEntryNow(cacheKey)); 596 if (http == 0) { 607 597 // no entry in cache; create an object 608 http = new QNetworkAccessHttpBackendCache(url.host(), url.port(), encrypt); 598 // the http object is actually a QHttpNetworkConnection 599 http = new QNetworkAccessCachedHttpConnection(url.host(), url.port(), encrypt); 609 600 610 601 #ifndef QT_NO_NETWORKPROXY … … 613 604 #endif 614 605 606 // cache the QHttpNetworkConnection corresponding to this cache key 615 607 cache->addEntry(cacheKey, http); 616 608 } … … 623 615 { 624 616 // this indicates that the user closed the stream while the reply isn't finished yet 625 }626 627 void QNetworkAccessHttpBackend::closeUpstreamChannel()628 {629 // this indicates that the user finished uploading the data for POST630 Q_ASSERT(uploadDevice);631 uploadDevice->eof = true;632 emit uploadDevice->readChannelFinished();633 617 } 634 618 … … 652 636 } 653 637 654 bool QNetworkAccessHttpBackend::waitForUpstreamBytesWritten(int msecs)655 {656 657 // ### FIXME: not implemented in QHttpNetworkAccess658 Q_UNUSED(msecs);659 qCritical("QNetworkAccess: HTTP backend does not support waitForBytesWritten()");660 return false;661 }662 663 void QNetworkAccessHttpBackend::upstreamReadyRead()664 {665 // There is more data available from the user to be uploaded666 // QHttpNetworkAccess implements the upload rate control:667 // we simply tell QHttpNetworkAccess that there is more data available668 // it'll pull from us when it can (through uploadDevice)669 670 Q_ASSERT(uploadDevice);671 emit uploadDevice->readyRead();672 }673 674 qint64 QNetworkAccessHttpBackend::deviceReadData(char *buffer, qint64 maxlen)675 {676 QByteArray toBeUploaded = readUpstream();677 if (toBeUploaded.isEmpty())678 return 0; // nothing to be uploaded679 680 maxlen = qMin<qint64>(maxlen, toBeUploaded.length());681 682 memcpy(buffer, toBeUploaded.constData(), maxlen);683 upstreamBytesConsumed(maxlen);684 return maxlen;685 }686 638 687 639 void QNetworkAccessHttpBackend::downstreamReadyWrite() … … 702 654 return; 703 655 704 // We implement the download rate control 705 // Don't read from QHttpNetworkAccess more than QNetworkAccessBackend wants 706 // One of the two functions above will be called when we can read again 707 708 qint64 bytesToRead = qBound<qint64>(0, httpReply->bytesAvailable(), nextDownstreamBlockSize()); 709 if (!bytesToRead) 710 return; 711 712 QByteArray data = httpReply->read(bytesToRead); 713 writeDownstreamData(data); 656 // We read possibly more than nextDownstreamBlockSize(), but 657 // this is not a critical thing since it is already in the 658 // memory anyway 659 660 QByteDataBuffer list; 661 662 while (httpReply->bytesAvailable() != 0 && nextDownstreamBlockSize() != 0 && nextDownstreamBlockSize() > list.byteAmount()) { 663 QByteArray data = httpReply->readAny(); 664 list.append(data); 665 } 666 667 if (!list.isEmpty()) 668 writeDownstreamData(list); 714 669 } 715 670 … … 733 688 // once we call finished(), we won't have access to httpReply anymore 734 689 QSslConfiguration sslConfig = httpReply->sslConfiguration(); 735 if (pendingSslConfiguration) 690 if (pendingSslConfiguration) { 736 691 *pendingSslConfiguration = sslConfig; 737 else if (!sslConfig.isNull()) 738 pendingSslConfiguration = new QSslConfiguration(sslConfig); 692 } else if (!sslConfig.isNull()) { 693 QT_TRY { 694 pendingSslConfiguration = new QSslConfiguration(sslConfig); 695 } QT_CATCH(...) { 696 qWarning("QNetworkAccess: could not allocate a QSslConfiguration object for a SSL connection."); 697 } 698 } 739 699 #endif 740 700 … … 762 722 void QNetworkAccessHttpBackend::replyHeaderChanged() 763 723 { 724 setAttribute(QNetworkRequest::HttpPipeliningWasUsedAttribute, httpReply->isPipeliningUsed()); 725 764 726 // reconstruct the HTTP header 765 727 QList<QPair<QByteArray, QByteArray> > headerMap = httpReply->header(); … … 771 733 QByteArray value = rawHeader(it->first); 772 734 if (!value.isEmpty()) { 773 if ( it->first.toLower() == "set-cookie")735 if (qstricmp(it->first.constData(), "set-cookie") == 0) 774 736 value += "\n"; 775 737 else … … 905 867 checkForRedirect(status); 906 868 907 writeDownstreamData(contents); 869 emit metaDataChanged(); 870 871 // invoke this asynchronously, else Arora/QtDemoBrowser don't like cached downloads 872 // see task 250221 / 251801 873 qRegisterMetaType<QIODevice*>("QIODevice*"); 874 QMetaObject::invokeMethod(this, "writeDownstreamData", Qt::QueuedConnection, Q_ARG(QIODevice*, contents)); 875 876 908 877 #if defined(QNETWORKACCESSHTTPBACKEND_DEBUG) 909 878 qDebug() << "Successfully sent cache:" << url() << contents->size() << "bytes"; … … 926 895 httpReply->ignoreSslErrors(); 927 896 else 928 pendingIgnoreSslErrors = true; 897 pendingIgnoreAllSslErrors = true; 898 } 899 900 void QNetworkAccessHttpBackend::ignoreSslErrors(const QList<QSslError> &errors) 901 { 902 if (httpReply) { 903 httpReply->ignoreSslErrors(errors); 904 } else { 905 // the pending list is set if QNetworkReply::ignoreSslErrors(const QList<QSslError> &errors) 906 // is called before QNetworkAccessManager::get() (or post(), etc.) 907 pendingIgnoreSslErrorsList = errors; 908 } 929 909 } 930 910 … … 972 952 continue; 973 953 954 // for 4.6.0, we were planning to not store the date header in the 955 // cached resource; through that we planned to reduce the number 956 // of writes to disk when using a QNetworkDiskCache (i.e. don't 957 // write to disk when only the date changes). 958 // However, without the date we cannot calculate the age of the page 959 // anymore. Consider a proper fix of that problem for 4.6.1. 960 //if (header == "date") 961 //continue; 962 974 963 // Don't store Warning 1xx headers 975 964 if (header == "warning") { … … 1037 1026 metaData.setLastModified(QNetworkHeadersPrivate::fromHttpDate(it->second)); 1038 1027 1039 bool canDiskCache = true; // Everything defaults to being cacheable on disk 1040 1041 // 14.32 1042 // HTTP/1.1 caches SHOULD treat "Pragma: no-cache" as if the client 1043 // had sent "Cache-Control: no-cache". 1044 it = cacheHeaders.findRawHeader("pragma"); 1045 if (it != cacheHeaders.rawHeaders.constEnd() 1046 && it->second == "no-cache") 1028 bool canDiskCache; 1029 // only cache GET replies by default, all other replies (POST, PUT, DELETE) 1030 // are not cacheable by default (according to RFC 2616 section 9) 1031 if (httpReply->request().operation() == QHttpNetworkRequest::Get) { 1032 1033 canDiskCache = true; 1034 // 14.32 1035 // HTTP/1.1 caches SHOULD treat "Pragma: no-cache" as if the client 1036 // had sent "Cache-Control: no-cache". 1037 it = cacheHeaders.findRawHeader("pragma"); 1038 if (it != cacheHeaders.rawHeaders.constEnd() 1039 && it->second == "no-cache") 1040 canDiskCache = false; 1041 1042 // HTTP/1.1. Check the Cache-Control header 1043 if (cacheControl.contains("no-cache")) 1044 canDiskCache = false; 1045 else if (cacheControl.contains("no-store")) 1046 canDiskCache = false; 1047 1048 // responses to POST might be cacheable 1049 } else if (httpReply->request().operation() == QHttpNetworkRequest::Post) { 1050 1047 1051 canDiskCache = false; 1048 1049 // HTTP/1.1. Check the Cache-Control header 1050 if (cacheControl.contains("no-cache")) 1052 // some pages contain "expires:" and "cache-control: no-cache" field, 1053 // so we only might cache POST requests if we get "cache-control: max-age ..." 1054 if (cacheControl.contains("max-age")) 1055 canDiskCache = true; 1056 1057 // responses to PUT and DELETE are not cacheable 1058 } else { 1051 1059 canDiskCache = false; 1052 else if (cacheControl.contains("no-store")) 1053 canDiskCache = false; 1060 } 1054 1061 1055 1062 metaData.setSaveToDisk(canDiskCache); -
trunk/src/network/access/qnetworkaccesshttpbackend_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 67 67 QT_BEGIN_NAMESPACE 68 68 69 class QNetworkAccess HttpBackendCache;69 class QNetworkAccessCachedHttpConnection; 70 70 71 71 class QNetworkAccessHttpBackendIODevice; … … 80 80 virtual void open(); 81 81 virtual void closeDownstreamChannel(); 82 virtual void closeUpstreamChannel();83 82 virtual bool waitForDownstreamReadyRead(int msecs); 84 virtual bool waitForUpstreamBytesWritten(int msecs);85 83 86 virtual void upstreamReadyRead();87 84 virtual void downstreamReadyWrite(); 88 85 virtual void copyFinished(QIODevice *); 89 86 #ifndef QT_NO_OPENSSL 90 87 virtual void ignoreSslErrors(); 88 virtual void ignoreSslErrors(const QList<QSslError> &errors); 91 89 92 90 virtual void fetchSslConfiguration(QSslConfiguration &configuration) const; … … 96 94 97 95 qint64 deviceReadData(char *buffer, qint64 maxlen); 96 97 // we return true since HTTP needs to send PUT/POST data again after having authenticated 98 bool needsResetableUploadData() { return true; } 98 99 99 100 private slots: … … 107 108 private: 108 109 QHttpNetworkReply *httpReply; 109 QPointer<QNetworkAccess HttpBackendCache> http;110 QPointer<QNetworkAccessCachedHttpConnection> http; 110 111 QByteArray cacheKey; 111 QNetworkAccessHttpBackendIODevice *uploadDevice; 112 QNetworkAccessBackendUploadIODevice *uploadDevice; 113 112 114 #ifndef QT_NO_OPENSSL 113 115 QSslConfiguration *pendingSslConfiguration; 114 bool pendingIgnoreSslErrors; 116 bool pendingIgnoreAllSslErrors; 117 QList<QSslError> pendingIgnoreSslErrorsList; 115 118 #endif 116 119 … … 123 126 void readFromHttp(); 124 127 void checkForRedirect(const int statusCode); 125 126 friend class QNetworkAccessHttpBackendIODevice;127 128 }; 128 129 -
trunk/src/network/access/qnetworkaccessmanager.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 53 53 #include "qnetworkaccessdatabackend_p.h" 54 54 #include "qnetworkaccessdebugpipebackend_p.h" 55 #include "qfilenetworkreply_p.h" 55 56 56 57 #include "QtCore/qbuffer.h" … … 96 97 \class QNetworkAccessManager 97 98 \brief The QNetworkAccessManager class allows the application to 98 postnetwork requests and receive replies99 send network requests and receive replies 99 100 \since 4.4 100 101 102 \ingroup network 101 103 \inmodule QtNetwork 102 104 \reentrant … … 113 115 QNetworkReply object. The returned object is used to obtain any data 114 116 returned in response to the corresponding request. 115 the reply to is where most of the signals as well116 as the downloaded data are posted.117 117 118 118 A simple download off the network could be accomplished with: … … 123 123 as well as meta-data (headers, etc.). 124 124 125 \note The slot is responsible for deleting the object at that point. 125 \note After the request has finished, it is the responsibility of the user 126 to delete the QNetworkReply object at an appropriate time. Do not directly 127 delete it inside the slot connected to finished(). You can use the 128 deleteLater() function. 126 129 127 130 A more involved example, assuming the manager is already existent, … … 148 151 \value PostOperation send the contents of an HTML form for 149 152 processing via HTTP POST (created with post()) 153 154 \value DeleteOperation delete contents operation (created with 155 deleteResource()) 150 156 151 157 \omitvalue UnknownOperation … … 200 206 See QNetworkReply::finished() for information on the status that 201 207 the object will be in. 208 209 \note Do not delete the \a reply object in the slot connected to this 210 signal. Use deleteLater(). 202 211 203 212 \sa QNetworkReply::finished(), QNetworkReply::error() … … 300 309 case QNetworkProxy::FtpCachingProxy: 301 310 key.setScheme(QLatin1String("proxy-ftp")); 311 break; 302 312 303 313 case QNetworkProxy::DefaultProxy: … … 478 488 delete d->networkCache; 479 489 d->networkCache = cache; 480 d->networkCache->setParent(this); 490 if (d->networkCache) 491 d->networkCache->setParent(this); 481 492 } 482 493 } … … 538 549 539 550 /*! 540 This function is used to post a request to obtain the network541 headers for \a request. It takes its name after the HTTP request542 associated (HEAD). It returns a new QNetworkReply object which 543 will contain such headers.551 Posts a request to obtain the network headers for \a request 552 and returns a new QNetworkReply object which will contain such headers 553 554 The function is named after the HTTP request associated (HEAD). 544 555 */ 545 556 QNetworkReply *QNetworkAccessManager::head(const QNetworkRequest &request) … … 549 560 550 561 /*! 551 This function is used to post a request to obtain the contents of 552 the target \a request. It will cause the contents to be 553 downloaded, along with the headers associated with it. It returns 554 a new QNetworkReply object opened for reading which emits its 555 QIODevice::readyRead() signal whenever new data arrives. 556 557 \sa post(), put() 562 Posts a request to obtain the contents of the target \a request 563 and returns a new QNetworkReply object opened for reading which emits the 564 \l{QIODevice::readyRead()}{readyRead()} signal whenever new data 565 arrives. 566 567 The contents as well as associated headers will be downloaded. 568 569 \sa post(), put(), deleteResource() 558 570 */ 559 571 QNetworkReply *QNetworkAccessManager::get(const QNetworkRequest &request) … … 563 575 564 576 /*! 565 This function is used to send an HTTP POST request to the 566 destination specified by \a request. The contents of the \a data 577 Sends an HTTP POST request to the destination specified by \a request 578 and returns a new QNetworkReply object opened for reading that will 579 contain the reply sent by the server. The contents of the \a data 567 580 device will be uploaded to the server. 581 582 \a data must be open for reading and must remain valid until the 583 finished() signal is emitted for this reply. 584 585 \note Sending a POST request on protocols other than HTTP and 586 HTTPS is undefined and will probably fail. 587 588 \sa get(), put(), deleteResource() 589 */ 590 QNetworkReply *QNetworkAccessManager::post(const QNetworkRequest &request, QIODevice *data) 591 { 592 return d_func()->postProcess(createRequest(QNetworkAccessManager::PostOperation, request, data)); 593 } 594 595 /*! 596 \overload 597 598 Sends the contents of the \a data byte array to the destination 599 specified by \a request. 600 */ 601 QNetworkReply *QNetworkAccessManager::post(const QNetworkRequest &request, const QByteArray &data) 602 { 603 QBuffer *buffer = new QBuffer; 604 buffer->setData(data); 605 buffer->open(QIODevice::ReadOnly); 606 607 QNetworkReply *reply = post(request, buffer); 608 buffer->setParent(reply); 609 return reply; 610 } 611 612 /*! 613 Uploads the contents of \a data to the destination \a request and 614 returnes a new QNetworkReply object that will be open for reply. 568 615 569 616 \a data must be opened for reading when this function is called … … 571 618 this reply. 572 619 573 The returned QNetworkReply object will be open for reading and 574 will contain the reply sent by the server to the POST request. 575 576 Note: sending a POST request on protocols other than HTTP and 577 HTTPS is undefined and will probably fail. 578 579 \sa get(), put() 580 */ 581 QNetworkReply *QNetworkAccessManager::post(const QNetworkRequest &request, QIODevice *data) 582 { 583 return d_func()->postProcess(createRequest(QNetworkAccessManager::PostOperation, request, data)); 620 Whether anything will be available for reading from the returned 621 object is protocol dependent. For HTTP, the server may send a 622 small HTML page indicating the upload was successful (or not). 623 Other protocols will probably have content in their replies. 624 625 \note For HTTP, this request will send a PUT request, which most servers 626 do not allow. Form upload mechanisms, including that of uploading 627 files through HTML forms, use the POST mechanism. 628 629 \sa get(), post() 630 */ 631 QNetworkReply *QNetworkAccessManager::put(const QNetworkRequest &request, QIODevice *data) 632 { 633 return d_func()->postProcess(createRequest(QNetworkAccessManager::PutOperation, request, data)); 584 634 } 585 635 586 636 /*! 587 637 \overload 588 This function sends the contents of the \a data byte array to the589 destinationspecified by \a request.590 */ 591 QNetworkReply *QNetworkAccessManager::p ost(const QNetworkRequest &request, const QByteArray &data)638 Sends the contents of the \a data byte array to the destination 639 specified by \a request. 640 */ 641 QNetworkReply *QNetworkAccessManager::put(const QNetworkRequest &request, const QByteArray &data) 592 642 { 593 643 QBuffer *buffer = new QBuffer; … … 595 645 buffer->open(QIODevice::ReadOnly); 596 646 597 QNetworkReply *reply = post(request, buffer);598 buffer->setParent(reply);599 return reply;600 }601 602 /*!603 This function is used to upload the contents of \a data to the604 destination \a request.605 606 \a data must be opened for reading when this function is called607 and must remain valid until the finished() signal is emitted for608 this reply.609 610 The returned QNetworkReply object will be open for reply, but611 whether anything will be available for reading is protocol612 dependent. For HTTP, the server may send a small HTML page613 indicating the upload was successful (or not). Other protocols614 will probably have content in their replies.615 616 For HTTP, this request will send a PUT request, which most servers617 do not allow. Form upload mechanisms, including that of uploading618 files through HTML forms, use the POST mechanism.619 620 \sa get(), post()621 */622 QNetworkReply *QNetworkAccessManager::put(const QNetworkRequest &request, QIODevice *data)623 {624 return d_func()->postProcess(createRequest(QNetworkAccessManager::PutOperation, request, data));625 }626 627 /*!628 \overload629 This function sends the contents of the \a data byte array to the630 destination specified by \a request.631 */632 QNetworkReply *QNetworkAccessManager::put(const QNetworkRequest &request, const QByteArray &data)633 {634 QBuffer *buffer = new QBuffer;635 buffer->setData(data);636 buffer->open(QIODevice::ReadOnly);637 638 647 QNetworkReply *reply = put(request, buffer); 639 648 buffer->setParent(reply); 640 649 return reply; 650 } 651 652 /*! 653 \since 4.6 654 655 Sends a request to delete the resource identified by the URL of \a request. 656 657 \note This feature is currently available for HTTP only, performing an 658 HTTP DELETE request. 659 660 \sa get(), post(), put() 661 */ 662 QNetworkReply *QNetworkAccessManager::deleteResource(const QNetworkRequest &request) 663 { 664 return d_func()->postProcess(createRequest(QNetworkAccessManager::DeleteOperation, request)); 641 665 } 642 666 … … 659 683 { 660 684 Q_D(QNetworkAccessManager); 685 686 // fast path for GET on file:// URLs 687 // Also if the scheme is empty we consider it a file. 688 // The QNetworkAccessFileBackend will right now only be used 689 // for PUT or qrc:// 690 if (op == QNetworkAccessManager::GetOperation 691 && (req.url().scheme() == QLatin1String("file") 692 || req.url().scheme().isEmpty())) { 693 return new QFileNetworkReply(this, req); 694 } 695 661 696 QNetworkRequest request = req; 662 697 if (!request.header(QNetworkRequest::ContentLengthHeader).isValid() && … … 686 721 } 687 722 688 // third step: setup the reply 723 // third step: find a backend 724 priv->backend = d->findBackend(op, request); 725 726 // fourth step: setup the reply 689 727 priv->setup(op, request, outgoingData); 690 if (request.attribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork).toInt() !=691 QNetworkRequest::AlwaysNetwork)692 priv->setNetworkCache(d->networkCache);693 728 #ifndef QT_NO_NETWORKPROXY 694 729 QList<QNetworkProxy> proxyList = d->queryProxy(QNetworkProxyQuery(request.url())); 695 730 priv->proxyList = proxyList; 696 731 #endif 697 698 // fourth step: find a backend699 priv->backend = d->findBackend(op, request);700 732 if (priv->backend) { 701 733 priv->backend->setParent(reply); … … 748 780 // keep the ugly hack in here 749 781 QNetworkAccessManagerPrivate *that = const_cast<QNetworkAccessManagerPrivate *>(this); 782 that->cookieJar = new QNetworkCookieJar(that->q_func()); 750 783 that->cookieJarCreated = true; 751 that->cookieJar = new QNetworkCookieJar(that->q_func());752 784 } 753 785 } … … 784 816 { 785 817 Q_Q(QNetworkAccessManager); 786 818 // ### FIXME Tracking of successful authentications 819 // This code is a bit broken right now for SOCKS authentication 820 // first request: proxyAuthenticationRequired gets emitted, credentials gets saved 821 // second request: (proxy != backend->reply->lastProxyAuthentication) does not evaluate to true, 822 // proxyAuthenticationRequired gets emitted again 823 // possible solution: some tracking inside the authenticator 824 // or a new function proxyAuthenticationSucceeded(true|false) 787 825 if (proxy != backend->reply->lastProxyAuthentication) { 788 826 QNetworkAuthenticationCredential *cred = fetchCachedCredentials(proxy); … … 819 857 QNetworkAuthenticationCache *auth = new QNetworkAuthenticationCache; 820 858 auth->insert(QString(), authenticator->user(), authenticator->password()); 821 cache.addEntry(cacheKey, auth); // replace the existing one, if there's any859 objectCache.addEntry(cacheKey, auth); // replace the existing one, if there's any 822 860 823 861 if (realm.isEmpty()) { … … 853 891 if (cacheKey.isEmpty()) 854 892 return 0; 855 if (! cache.hasEntry(cacheKey))893 if (!objectCache.hasEntry(cacheKey)) 856 894 return 0; 857 895 858 896 QNetworkAuthenticationCache *auth = 859 static_cast<QNetworkAuthenticationCache *>( cache.requestEntryNow(cacheKey));897 static_cast<QNetworkAuthenticationCache *>(objectCache.requestEntryNow(cacheKey)); 860 898 QNetworkAuthenticationCredential *cred = auth->findClosestMatch(QString()); 861 cache.releaseEntry(cacheKey);899 objectCache.releaseEntry(cacheKey); 862 900 863 901 // proxy cache credentials always have exactly one item … … 900 938 do { 901 939 QByteArray cacheKey = authenticationKey(copy, realm); 902 if ( cache.hasEntry(cacheKey)) {940 if (objectCache.hasEntry(cacheKey)) { 903 941 QNetworkAuthenticationCache *auth = 904 static_cast<QNetworkAuthenticationCache *>( cache.requestEntryNow(cacheKey));942 static_cast<QNetworkAuthenticationCache *>(objectCache.requestEntryNow(cacheKey)); 905 943 auth->insert(domain, authenticator->user(), authenticator->password()); 906 cache.releaseEntry(cacheKey);944 objectCache.releaseEntry(cacheKey); 907 945 } else { 908 946 QNetworkAuthenticationCache *auth = new QNetworkAuthenticationCache; 909 947 auth->insert(domain, authenticator->user(), authenticator->password()); 910 cache.addEntry(cacheKey, auth);948 objectCache.addEntry(cacheKey, auth); 911 949 } 912 950 … … 942 980 943 981 QByteArray cacheKey = authenticationKey(url, realm); 944 if (! cache.hasEntry(cacheKey))982 if (!objectCache.hasEntry(cacheKey)) 945 983 return 0; 946 984 947 985 QNetworkAuthenticationCache *auth = 948 static_cast<QNetworkAuthenticationCache *>( cache.requestEntryNow(cacheKey));986 static_cast<QNetworkAuthenticationCache *>(objectCache.requestEntryNow(cacheKey)); 949 987 QNetworkAuthenticationCredential *cred = auth->findClosestMatch(url.path()); 950 cache.releaseEntry(cacheKey);988 objectCache.releaseEntry(cacheKey); 951 989 return cred; 952 990 } … … 954 992 void QNetworkAccessManagerPrivate::clearCache(QNetworkAccessManager *manager) 955 993 { 956 manager->d_func()->cache.clear(); 994 manager->d_func()->objectCache.clear(); 995 } 996 997 QNetworkAccessManagerPrivate::~QNetworkAccessManagerPrivate() 998 { 957 999 } 958 1000 -
trunk/src/network/access/qnetworkaccessmanager.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 75 75 PutOperation, 76 76 PostOperation, 77 DeleteOperation, 77 78 78 79 UnknownOperation = 0 … … 101 102 QNetworkReply *put(const QNetworkRequest &request, QIODevice *data); 102 103 QNetworkReply *put(const QNetworkRequest &request, const QByteArray &data); 104 QNetworkReply *deleteResource(const QNetworkRequest &request); 103 105 104 106 Q_SIGNALS: -
trunk/src/network/access/qnetworkaccessmanager_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 77 77 cookieJarCreated(false) 78 78 { } 79 ~QNetworkAccessManagerPrivate(); 79 80 80 81 void _q_replyFinished(); … … 99 100 QNetworkAccessBackend *findBackend(QNetworkAccessManager::Operation op, const QNetworkRequest &request); 100 101 102 // this is the cache for storing downloaded files 101 103 QAbstractNetworkCache *networkCache; 104 102 105 QNetworkCookieJar *cookieJar; 103 106 104 QNetworkAccessCache cache; 107 105 108 #ifndef QT_NO_NETWORKPROXY 106 109 QNetworkProxy proxy; … … 110 113 bool cookieJarCreated; 111 114 112 static inline QNetworkAccessCache *getCache(QNetworkAccessBackend *backend) 113 { return &backend->manager->cache; } 115 116 // this cache can be used by individual backends to cache e.g. their TCP connections to a server 117 // and use the connections for multiple requests. 118 QNetworkAccessCache objectCache; 119 static inline QNetworkAccessCache *getObjectCache(QNetworkAccessBackend *backend) 120 { return &backend->manager->objectCache; } 114 121 Q_AUTOTEST_EXPORT static void clearCache(QNetworkAccessManager *manager); 115 122 -
trunk/src/network/access/qnetworkcookie.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 505 505 if (!d->domain.isEmpty()) { 506 506 result += "; domain="; 507 result += QUrl::toAce(d->domain); 507 QString domainNoDot = d->domain; 508 if (domainNoDot.startsWith(QLatin1Char('.'))) { 509 result += '.'; 510 domainNoDot = domainNoDot.mid(1); 511 } 512 result += QUrl::toAce(domainNoDot); 508 513 } 509 514 if (!d->path.isEmpty()) { … … 914 919 QList<QNetworkCookie> QNetworkCookie::parseCookies(const QByteArray &cookieString) 915 920 { 921 // cookieString can be a number of set-cookie header strings joined together 922 // by \n, parse each line separately. 923 QList<QNetworkCookie> cookies; 924 QList<QByteArray> list = cookieString.split('\n'); 925 for (int a = 0; a < list.size(); a++) 926 cookies += QNetworkCookiePrivate::parseSetCookieHeaderLine(list.at(a)); 927 return cookies; 928 } 929 930 QList<QNetworkCookie> QNetworkCookiePrivate::parseSetCookieHeaderLine(const QByteArray &cookieString) 931 { 916 932 // According to http://wp.netscape.com/newsref/std/cookie_spec.html,< 917 933 // the Set-Cookie response header is of the format: … … 931 947 QNetworkCookie cookie; 932 948 933 // When there are multiple SetCookie headers they are join with a new line934 // \n will always be the start of a new cookie935 int endOfSetCookie = cookieString.indexOf('\n', position);936 if (endOfSetCookie == -1)937 endOfSetCookie = length;938 939 949 // The first part is always the "NAME=VALUE" part 940 950 QPair<QByteArray,QByteArray> field = nextField(cookieString, position); … … 947 957 position = nextNonWhitespace(cookieString, position); 948 958 bool endOfCookie = false; 949 while (!endOfCookie && position < endOfSetCookie)959 while (!endOfCookie && position < length) { 950 960 switch (cookieString.at(position++)) { 951 961 case ',': … … 970 980 QDateTime dt = parseDateString(dateString.toLower()); 971 981 if (!dt.isValid()) { 972 cookie = QNetworkCookie(); 973 endOfCookie = true; 974 continue; 982 return result; 975 983 } 976 984 cookie.setExpirationDate(dt); … … 989 997 int secs = field.second.toInt(&ok); 990 998 if (!ok) 991 // invalid cookie string 992 return QList<QNetworkCookie>(); 999 return result; 993 1000 cookie.setExpirationDate(now.addSecs(secs)); 994 1001 } else if (field.first == "path") { … … 1004 1011 if (field.second != "1") { 1005 1012 // oops, we don't know how to handle this cookie 1006 cookie = QNetworkCookie(); 1007 endOfCookie = true; 1008 continue; 1013 return result; 1009 1014 } 1010 1015 } else { … … 1014 1019 1015 1020 position = nextNonWhitespace(cookieString, position); 1016 if (position > endOfSetCookie)1017 endOfCookie = true;1018 1021 } 1022 } 1019 1023 1020 1024 if (!cookie.name().isEmpty()) … … 1028 1032 QDebug operator<<(QDebug s, const QNetworkCookie &cookie) 1029 1033 { 1030 s.nospace() << "QNetworkCookie(" << cookie.toRawForm(QNetworkCookie::Full) << ")";1034 s.nospace() << "QNetworkCookie(" << cookie.toRawForm(QNetworkCookie::Full) << ')'; 1031 1035 return s.space(); 1032 1036 } 1033 1037 #endif 1034 1038 1035 1036 1037 class QNetworkCookieJarPrivate: public QObjectPrivate1038 {1039 public:1040 QList<QNetworkCookie> allCookies;1041 1042 Q_DECLARE_PUBLIC(QNetworkCookieJar)1043 };1044 1045 /*!1046 \class QNetworkCookieJar1047 \brief The QNetworkCookieJar class implements a simple jar of QNetworkCookie objects1048 \since 4.41049 1050 Cookies are small bits of information that stateless protocols1051 like HTTP use to maintain some persistent information across1052 requests.1053 1054 A cookie is set by a remote server when it replies to a request1055 and it expects the same cookie to be sent back when further1056 requests are sent.1057 1058 The cookie jar is the object that holds all cookies set in1059 previous requests. Web browsers save their cookie jars to disk in1060 order to conserve permanent cookies across invocations of the1061 application.1062 1063 QNetworkCookieJar does not implement permanent storage: it only1064 keeps the cookies in memory. Once the QNetworkCookieJar object is1065 deleted, all cookies it held will be discarded as well. If you1066 want to save the cookies, you should derive from this class and1067 implement the saving to disk to your own storage format.1068 1069 This class implements only the basic security recommended by the1070 cookie specifications and does not implement any cookie acceptance1071 policy (it accepts all cookies set by any requests). In order to1072 override those rules, you should reimplement the1073 cookiesForUrl() and setCookiesFromUrl() virtual1074 functions. They are called by QNetworkReply and1075 QNetworkAccessManager when they detect new cookies and when they1076 require cookies.1077 1078 \sa QNetworkCookie, QNetworkAccessManager, QNetworkReply,1079 QNetworkRequest, QNetworkAccessManager::setCookieJar()1080 */1081 1082 /*!1083 Creates a QNetworkCookieJar object and sets the parent object to1084 be \a parent.1085 1086 The cookie jar is initialized to empty.1087 */1088 QNetworkCookieJar::QNetworkCookieJar(QObject *parent)1089 : QObject(*new QNetworkCookieJarPrivate, parent)1090 {1091 }1092 1093 /*!1094 Destroys this cookie jar object and discards all cookies stored in1095 it. Cookies are not saved to disk in the QNetworkCookieJar default1096 implementation.1097 1098 If you need to save the cookies to disk, you have to derive from1099 QNetworkCookieJar and save the cookies to disk yourself.1100 */1101 QNetworkCookieJar::~QNetworkCookieJar()1102 {1103 }1104 1105 /*!1106 Returns all cookies stored in this cookie jar. This function is1107 suitable for derived classes to save cookies to disk, as well as1108 to implement cookie expiration and other policies.1109 1110 \sa setAllCookies(), cookiesForUrl()1111 */1112 QList<QNetworkCookie> QNetworkCookieJar::allCookies() const1113 {1114 return d_func()->allCookies;1115 }1116 1117 /*!1118 Sets the internal list of cookies held by this cookie jar to be \a1119 cookieList. This function is suitable for derived classes to1120 implement loading cookies from permanent storage, or their own1121 cookie acceptance policies by reimplementing1122 setCookiesFromUrl().1123 1124 \sa allCookies(), setCookiesFromUrl()1125 */1126 void QNetworkCookieJar::setAllCookies(const QList<QNetworkCookie> &cookieList)1127 {1128 Q_D(QNetworkCookieJar);1129 d->allCookies = cookieList;1130 }1131 1132 static inline bool isParentPath(QString path, QString reference)1133 {1134 if (!path.endsWith(QLatin1Char('/')))1135 path += QLatin1Char('/');1136 if (!reference.endsWith(QLatin1Char('/')))1137 reference += QLatin1Char('/');1138 return path.startsWith(reference);1139 }1140 1141 static inline bool isParentDomain(QString domain, QString reference)1142 {1143 if (!reference.startsWith(QLatin1Char('.')))1144 return domain == reference;1145 1146 return domain.endsWith(reference) || domain == reference.mid(1);1147 }1148 1149 /*!1150 Adds the cookies in the list \a cookieList to this cookie1151 jar. Default values for path and domain are taken from the \a1152 url object.1153 1154 Returns true if one or more cookes are set for url otherwise false.1155 1156 If a cookie already exists in the cookie jar, it will be1157 overridden by those in \a cookieList.1158 1159 The default QNetworkCookieJar class implements only a very basic1160 security policy (it makes sure that the cookies' domain and path1161 match the reply's). To enhance the security policy with your own1162 algorithms, override setCookiesFromUrl().1163 1164 Also, QNetworkCookieJar does not have a maximum cookie jar1165 size. Reimplement this function to discard older cookies to create1166 room for new ones.1167 1168 \sa cookiesForUrl(), QNetworkAccessManager::setCookieJar()1169 */1170 bool QNetworkCookieJar::setCookiesFromUrl(const QList<QNetworkCookie> &cookieList,1171 const QUrl &url)1172 {1173 Q_D(QNetworkCookieJar);1174 QString defaultDomain = url.host();1175 QString pathAndFileName = url.path();1176 QString defaultPath = pathAndFileName.left(pathAndFileName.lastIndexOf(QLatin1Char('/'))+1);1177 if (defaultPath.isEmpty())1178 defaultPath = QLatin1Char('/');1179 1180 int added = 0;1181 QDateTime now = QDateTime::currentDateTime();1182 foreach (QNetworkCookie cookie, cookieList) {1183 bool isDeletion = !cookie.isSessionCookie() &&1184 cookie.expirationDate() < now;1185 1186 // validate the cookie & set the defaults if unset1187 // (RFC 2965: "The request-URI MUST path-match the Path attribute of the cookie.")1188 if (cookie.path().isEmpty())1189 cookie.setPath(defaultPath);1190 else if (!isParentPath(pathAndFileName, cookie.path()))1191 continue; // not accepted1192 1193 if (cookie.domain().isEmpty()) {1194 cookie.setDomain(defaultDomain);1195 } else {1196 QString domain = cookie.domain();1197 if (!(isParentDomain(domain, defaultDomain)1198 || isParentDomain(defaultDomain, domain))) {1199 continue; // not accepted1200 }1201 }1202 1203 QList<QNetworkCookie>::Iterator it = d->allCookies.begin(),1204 end = d->allCookies.end();1205 for ( ; it != end; ++it)1206 // does this cookie already exist?1207 if (cookie.name() == it->name() &&1208 cookie.domain() == it->domain() &&1209 cookie.path() == it->path()) {1210 // found a match1211 d->allCookies.erase(it);1212 break;1213 }1214 1215 // did not find a match1216 if (!isDeletion) {1217 d->allCookies += cookie;1218 ++added;1219 }1220 }1221 return (added > 0);1222 }1223 1224 /*!1225 Returns the cookies to be added to when a request is sent to1226 \a url. This function is called by the default1227 QNetworkAccessManager::createRequest(), which adds the1228 cookies returned by this function to the request being sent.1229 1230 If more than one cookie with the same name is found, but with1231 differing paths, the one with longer path is returned before the1232 one with shorter path. In other words, this function returns1233 cookies sorted by path length.1234 1235 The default QNetworkCookieJar class implements only a very basic1236 security policy (it makes sure that the cookies' domain and path1237 match the reply's). To enhance the security policy with your own1238 algorithms, override cookiesForUrl().1239 1240 \sa setCookiesFromUrl(), QNetworkAccessManager::setCookieJar()1241 */1242 QList<QNetworkCookie> QNetworkCookieJar::cookiesForUrl(const QUrl &url) const1243 {1244 // \b Warning! This is only a dumb implementation!1245 // It does NOT follow all of the recommendations from1246 // http://wp.netscape.com/newsref/std/cookie_spec.html1247 // It does not implement a very good cross-domain verification yet.1248 1249 Q_D(const QNetworkCookieJar);1250 QDateTime now = QDateTime::currentDateTime();1251 QList<QNetworkCookie> result;1252 1253 // scan our cookies for something that matches1254 QList<QNetworkCookie>::ConstIterator it = d->allCookies.constBegin(),1255 end = d->allCookies.constEnd();1256 for ( ; it != end; ++it) {1257 if (!isParentDomain(url.host(), it->domain()))1258 continue;1259 if (!isParentPath(url.path(), it->path()))1260 continue;1261 if (!(*it).isSessionCookie() && (*it).expirationDate() < now)1262 continue;1263 1264 // insert this cookie into result, sorted by path1265 QList<QNetworkCookie>::Iterator insertIt = result.begin();1266 while (insertIt != result.end()) {1267 if (insertIt->path().length() < it->path().length()) {1268 // insert here1269 insertIt = result.insert(insertIt, *it);1270 break;1271 } else {1272 ++insertIt;1273 }1274 }1275 1276 // this is the shortest path yet, just append1277 if (insertIt == result.end())1278 result += *it;1279 }1280 1281 return result;1282 }1283 1284 1039 QT_END_NAMESPACE -
trunk/src/network/access/qnetworkcookie.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 107 107 Q_DECLARE_TYPEINFO(QNetworkCookie, Q_MOVABLE_TYPE); 108 108 109 class QNetworkCookieJarPrivate;110 class Q_NETWORK_EXPORT QNetworkCookieJar: public QObject111 {112 Q_OBJECT113 public:114 QNetworkCookieJar(QObject *parent = 0);115 virtual ~QNetworkCookieJar();116 117 virtual QList<QNetworkCookie> cookiesForUrl(const QUrl &url) const;118 virtual bool setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url);119 120 protected:121 QList<QNetworkCookie> allCookies() const;122 void setAllCookies(const QList<QNetworkCookie> &cookieList);123 124 private:125 Q_DECLARE_PRIVATE(QNetworkCookieJar)126 Q_DISABLE_COPY(QNetworkCookieJar)127 };128 129 109 #ifndef QT_NO_DEBUG_STREAM 130 110 class QDebug; … … 134 114 QT_END_NAMESPACE 135 115 116 // ### Qt5 remove this include 117 #include "qnetworkcookiejar.h" 118 136 119 Q_DECLARE_METATYPE(QNetworkCookie) 137 120 Q_DECLARE_METATYPE(QList<QNetworkCookie>) -
trunk/src/network/access/qnetworkcookie_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 62 62 public: 63 63 inline QNetworkCookiePrivate() : secure(false), httpOnly(false) { } 64 static QList<QNetworkCookie> parseSetCookieHeaderLine(const QByteArray &cookieString); 64 65 65 66 QDateTime expirationDate; -
trunk/src/network/access/qnetworkdiskcache.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 41 41 42 42 //#define QNETWORKDISKCACHE_DEBUG 43 44 #ifndef QT_NO_NETWORKDISKCACHE 43 45 44 46 #include "qnetworkdiskcache.h" 45 47 #include "qnetworkdiskcache_p.h" 48 #include "QtCore/qscopedpointer.h" 46 49 47 50 #include <qfile.h> … … 80 83 81 84 Note you have to set the cache directory before it will work. 85 86 A network disk cache can be enabled by: 87 88 \snippet doc/src/snippets/code/src_network_access_qnetworkdiskcache.cpp 0 89 90 When sending requests, to control the preference of when to use the cache 91 and when to use the network, consider the following: 92 93 \snippet doc/src/snippets/code/src_network_access_qnetworkdiskcache.cpp 1 94 95 To check whether the response came from the cache or from the network, the 96 following can be applied: 97 98 \snippet doc/src/snippets/code/src_network_access_qnetworkdiskcache.cpp 2 82 99 */ 83 100 … … 181 198 } 182 199 } 183 184 QCacheItem *cacheItem = new QCacheItem; 200 QScopedPointer<QCacheItem> cacheItem(new QCacheItem); 185 201 cacheItem->metaData = metaData; 186 202 … … 191 207 } else { 192 208 QString templateName = d->tmpCacheFileName(); 193 cacheItem->file = new QTemporaryFile(templateName, &cacheItem->data); 194 cacheItem->file->open(); 209 QT_TRY { 210 cacheItem->file = new QTemporaryFile(templateName, &cacheItem->data); 211 } QT_CATCH(...) { 212 cacheItem->file = 0; 213 } 214 if (!cacheItem->file || !cacheItem->file->open()) { 215 qWarning() << "QNetworkDiskCache::prepare() unable to open temporary file"; 216 cacheItem.reset(); 217 return 0; 218 } 195 219 cacheItem->writeHeader(cacheItem->file); 196 220 device = cacheItem->file; 197 221 } 198 d->inserting[device] = cacheItem ;222 d->inserting[device] = cacheItem.take(); 199 223 return device; 200 224 } … … 230 254 if (QFile::exists(fileName)) { 231 255 if (!QFile::remove(fileName)) { 232 qWarning() << "QNetworkDiskCache: could 't remove the cache file " << fileName;256 qWarning() << "QNetworkDiskCache: couldn't remove the cache file " << fileName; 233 257 return; 234 258 } … … 355 379 #endif 356 380 Q_D(QNetworkDiskCache); 357 Q Buffer *buffer = 0;381 QScopedPointer<QBuffer> buffer; 358 382 if (!url.isValid()) 359 return buffer;383 return 0; 360 384 if (d->lastItem.metaData.url() == url && d->lastItem.data.isOpen()) { 361 buffer = new QBuffer;385 buffer.reset(new QBuffer); 362 386 buffer->setData(d->lastItem.data.data()); 363 387 } else { 364 QFile *file = new QFile(d->cacheFileName(url)); 365 if (!file->open(QFile::ReadOnly | QIODevice::Unbuffered)) { 366 delete file; 388 QScopedPointer<QFile> file(new QFile(d->cacheFileName(url))); 389 if (!file->open(QFile::ReadOnly | QIODevice::Unbuffered)) 367 390 return 0; 368 } 369 if (!d->lastItem.read(file , true)) {391 392 if (!d->lastItem.read(file.data(), true)) { 370 393 file->close(); 371 394 remove(url); 372 delete file;373 395 return 0; 374 396 } 375 397 if (d->lastItem.data.isOpen()) { 376 398 // compressed 377 buffer = new QBuffer;399 buffer.reset(new QBuffer); 378 400 buffer->setData(d->lastItem.data.data()); 379 delete file;380 401 } else { 381 buffer = new QBuffer;402 buffer.reset(new QBuffer); 382 403 // ### verify that QFile uses the fd size and not the file name 383 404 qint64 size = file->size() - file->pos(); … … 387 408 #endif 388 409 if (p) { 389 file->setParent(buffer);390 410 buffer->setData((const char *)p, size); 411 file.take()->setParent(buffer.data()); 391 412 } else { 392 413 buffer->setData(file->readAll()); 393 delete file;394 414 } 395 415 } 396 416 } 397 417 buffer->open(QBuffer::ReadOnly); 398 return buffer ;418 return buffer.take(); 399 419 } 400 420 … … 463 483 Returns the current size of the cache. 464 484 465 When the current size of the cache is greater th en the maximumCacheSize()485 When the current size of the cache is greater than the maximumCacheSize() 466 486 older cache files are removed until the total size is less then 90% of 467 487 maximumCacheSize() starting with the oldest ones first using the file … … 491 511 QDirIterator it(cacheDirectory(), filters, QDirIterator::Subdirectories); 492 512 493 QM ap<QDateTime, QString> cacheItems;513 QMultiMap<QDateTime, QString> cacheItems; 494 514 qint64 totalSize = 0; 495 515 while (it.hasNext()) { … … 498 518 QString fileName = info.fileName(); 499 519 if (fileName.endsWith(CACHE_POSTFIX) && fileName.startsWith(CACHE_PREFIX)) { 500 cacheItems [info.created()] = path;520 cacheItems.insert(info.created(), path); 501 521 totalSize += info.size(); 502 522 } … … 505 525 int removedFiles = 0; 506 526 qint64 goal = (maximumCacheSize() * 9) / 10; 507 QM ap<QDateTime, QString>::const_iterator i = cacheItems.constBegin();527 QMultiMap<QDateTime, QString>::const_iterator i = cacheItems.constBegin(); 508 528 while (i != cacheItems.constEnd()) { 509 529 if (totalSize < goal) … … 666 686 667 687 QT_END_NAMESPACE 688 689 #endif // QT_NO_NETWORKDISKCACHE -
trunk/src/network/access/qnetworkdiskcache.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 50 50 51 51 QT_MODULE(Network) 52 53 #ifndef QT_NO_NETWORKDISKCACHE 52 54 53 55 class QNetworkDiskCachePrivate; … … 87 89 }; 88 90 91 #endif // QT_NO_NETWORKDISKCACHE 92 89 93 QT_END_NAMESPACE 90 94 … … 92 96 93 97 #endif // QNETWORKDISKCACHE_H 94 -
trunk/src/network/access/qnetworkdiskcache_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** -
trunk/src/network/access/qnetworkreply.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 60 60 \since 4.4 61 61 \brief The QNetworkReply class contains the data and headers for a request 62 postedwith QNetworkAccessManager62 sent with QNetworkAccessManager 63 63 64 64 \reentrant 65 \ingroup network 65 66 \inmodule QtNetwork 66 67 … … 88 89 content. 89 90 91 \note Do not delete the object in the slot connected to the 92 error() or finished() signal. Use deleteLater(). 93 90 94 \sa QNetworkRequest, QNetworkAccessManager 91 95 */ … … 152 156 were not accepted (if any) 153 157 158 \value ContentReSendError the request needed to be sent 159 again, but this failed for example because the upload data 160 could not be read a second time. 161 154 162 \value ProtocolUnknownError the Network Access API cannot 155 163 honor the request because the protocol is not known … … 164 172 was detected 165 173 166 \value UnknownContentError an unkno nwn error related to174 \value UnknownContentError an unknown error related to 167 175 the remote content was detected 168 176 … … 229 237 parameter is this object. 230 238 239 \note Do not delete the object in the slot connected to this 240 signal. Use deleteLater(). 241 231 242 \sa QNetworkAccessManager::finished() 232 243 */ … … 242 253 detected. Call errorString() to obtain a textual representation of 243 254 the error condition. 255 256 \note Do not delete the object in the slot connected to this 257 signal. Use deleteLater(). 244 258 245 259 \sa error(), errorString() … … 436 450 { 437 451 return d_func()->errorCode; 452 } 453 454 /*! 455 \since 4.6 456 457 Returns true when the reply has finished or was aborted. 458 459 \sa isRunning() 460 */ 461 bool QNetworkReply::isFinished() const 462 { 463 return d_func()->isFinished(); 464 } 465 466 /*! 467 \since 4.6 468 469 Returns true when the request is still processing and the 470 reply has not finished or was aborted yet. 471 472 \sa isFinished() 473 */ 474 bool QNetworkReply::isRunning() const 475 { 476 return !isFinished(); 438 477 } 439 478 … … 556 595 } 557 596 } 597 598 /*! 599 \overload 600 \since 4.6 601 602 If this function is called, the SSL errors given in \a errors 603 will be ignored. 604 605 Note that you can set the expected certificate in the SSL error: 606 If, for instance, you want to issue a request to a server that uses 607 a self-signed certificate, consider the following snippet: 608 609 \snippet doc/src/snippets/code/src_network_access_qnetworkreply.cpp 0 610 611 Multiple calls to this function will replace the list of errors that 612 were passed in previous calls. 613 You can clear the list of errors you want to ignore by calling this 614 function with an empty list. 615 616 \sa sslConfiguration(), sslErrors(), QSslSocket::ignoreSslErrors() 617 */ 618 void QNetworkReply::ignoreSslErrors(const QList<QSslError> &errors) 619 { 620 // do this cryptic trick, because we could not add a virtual method to this class later on 621 // since that breaks binary compatibility 622 int id = metaObject()->indexOfMethod("ignoreSslErrorsImplementation(QList<QSslError>)"); 623 if (id != -1) { 624 QList<QSslError> copy(errors); 625 void *arr[] = { 0, © }; 626 qt_metacall(QMetaObject::InvokeMetaMethod, id, arr); 627 } 628 } 558 629 #endif 559 630 … … 570 641 found. 571 642 572 \sa sslConfiguration(), sslErrors() 643 \sa sslConfiguration(), sslErrors(), QSslSocket::ignoreSslErrors() 573 644 */ 574 645 void QNetworkReply::ignoreSslErrors() -
trunk/src/network/access/qnetworkreply.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 93 93 ContentNotFoundError, 94 94 AuthenticationRequiredError, 95 ContentReSendError, 95 96 UnknownContentError = 299, 96 97 … … 116 117 QNetworkRequest request() const; 117 118 NetworkError error() const; 119 bool isFinished() const; 120 bool isRunning() const; 118 121 QUrl url() const; 119 122 … … 132 135 QSslConfiguration sslConfiguration() const; 133 136 void setSslConfiguration(const QSslConfiguration &configuration); 137 void ignoreSslErrors(const QList<QSslError> &errors); 134 138 #endif 135 139 -
trunk/src/network/access/qnetworkreply_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 76 76 { reply->d_func()->manager = manager; } 77 77 78 virtual bool isFinished() const { return false; } 79 78 80 Q_DECLARE_PUBLIC(QNetworkReply) 79 81 }; -
trunk/src/network/access/qnetworkreplyimpl.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 47 47 #include "QtCore/qdatetime.h" 48 48 #include "QtNetwork/qsslconfiguration.h" 49 #include "qnetworkaccesshttpbackend_p.h" 49 50 50 51 #include <QtCore/QCoreApplication> … … 53 54 54 55 inline QNetworkReplyImplPrivate::QNetworkReplyImplPrivate() 55 : copyDevice(0), networkCache(0), 56 : backend(0), outgoingData(0), outgoingDataBuffer(0), 57 copyDevice(0), 56 58 cacheEnabled(false), cacheSaveDevice(0), 59 notificationHandlingPaused(false), 57 60 bytesDownloaded(0), lastBytesDownloaded(-1), bytesUploaded(-1), 61 httpStatusCode(0), 58 62 state(Idle) 59 63 { … … 62 66 void QNetworkReplyImplPrivate::_q_startOperation() 63 67 { 64 // This function is called exactly once 68 // ensure this function is only being called once 69 if (state == Working) { 70 qDebug("QNetworkReplyImpl::_q_startOperation was called more than once"); 71 return; 72 } 65 73 state = Working; 74 66 75 if (!backend) { 67 76 error(QNetworkReplyImpl::ProtocolUnknownError, … … 75 84 if (operation == QNetworkAccessManager::GetOperation) 76 85 pendingNotifications.append(NotifyDownstreamReadyWrite); 77 if (outgoingData) {78 _q_sourceReadyRead();79 #if 0 // ### FIXME80 if (outgoingData->atEndOfStream() && writeBuffer.isEmpty())81 // empty upload82 emit q->uploadProgress(0, 0);83 #endif84 }85 86 86 87 handleNotifications(); … … 88 89 } 89 90 90 void QNetworkReplyImplPrivate::_q_sourceReadyRead()91 {92 // read data from the outgoingData QIODevice into our internal buffer93 enum { DesiredBufferSize = 32 * 1024 };94 95 if (writeBuffer.size() >= DesiredBufferSize)96 return; // don't grow the buffer too much97 98 // read as many bytes are available or up until we fill up the buffer99 // but always read at least one byte100 qint64 bytesToRead = qBound<qint64>(1, outgoingData->bytesAvailable(),101 DesiredBufferSize - writeBuffer.size());102 char *ptr = writeBuffer.reserve(bytesToRead);103 qint64 bytesActuallyRead = outgoingData->read(ptr, bytesToRead);104 if (bytesActuallyRead == -1) {105 // EOF106 writeBuffer.chop(bytesToRead);107 backendNotify(NotifyCloseUpstreamChannel);108 return;109 }110 111 if (bytesActuallyRead < bytesToRead)112 writeBuffer.chop(bytesToRead - bytesActuallyRead);113 114 // if we did read anything, let the backend know and handle it115 if (bytesActuallyRead)116 backendNotify(NotifyUpstreamReadyRead);117 118 // check for EOF again119 if (!outgoingData->isSequential() && outgoingData->atEnd())120 backendNotify(NotifyCloseUpstreamChannel);121 }122 123 void QNetworkReplyImplPrivate::_q_sourceReadChannelFinished()124 {125 _q_sourceReadyRead();126 }127 128 91 void QNetworkReplyImplPrivate::_q_copyReadyRead() 129 92 { 130 93 Q_Q(QNetworkReplyImpl); 131 if (!copyDevice && !q->isOpen()) 132 return; 133 134 qint64 bytesToRead = nextDownstreamBlockSize(); 135 if (bytesToRead == 0) 136 // we'll be called again, eventually 137 return; 138 139 bytesToRead = qBound<qint64>(1, bytesToRead, copyDevice->bytesAvailable()); 140 char *ptr = readBuffer.reserve(bytesToRead); 141 qint64 bytesActuallyRead = copyDevice->read(ptr, bytesToRead); 142 if (bytesActuallyRead == -1) { 143 readBuffer.chop(bytesToRead); 144 backendNotify(NotifyCopyFinished); 145 return; 146 } 147 148 if (bytesActuallyRead != bytesToRead) 149 readBuffer.chop(bytesToRead - bytesActuallyRead); 150 151 if (!copyDevice->isSequential() && copyDevice->atEnd()) 152 backendNotify(NotifyCopyFinished); 153 154 bytesDownloaded += bytesActuallyRead; 94 if (state != Working) 95 return; 96 if (!copyDevice || !q->isOpen()) 97 return; 98 99 forever { 100 qint64 bytesToRead = nextDownstreamBlockSize(); 101 if (bytesToRead == 0) 102 // we'll be called again, eventually 103 break; 104 105 bytesToRead = qBound<qint64>(1, bytesToRead, copyDevice->bytesAvailable()); 106 QByteArray byteData; 107 byteData.resize(bytesToRead); 108 qint64 bytesActuallyRead = copyDevice->read(byteData.data(), byteData.size()); 109 if (bytesActuallyRead == -1) { 110 byteData.clear(); 111 backendNotify(NotifyCopyFinished); 112 break; 113 } 114 115 byteData.resize(bytesActuallyRead); 116 readBuffer.append(byteData); 117 118 if (!copyDevice->isSequential() && copyDevice->atEnd()) { 119 backendNotify(NotifyCopyFinished); 120 bytesDownloaded += bytesActuallyRead; 121 break; 122 } 123 124 bytesDownloaded += bytesActuallyRead; 125 } 126 127 if (bytesDownloaded == lastBytesDownloaded) { 128 // we didn't read anything 129 return; 130 } 131 155 132 lastBytesDownloaded = bytesDownloaded; 156 133 QVariant totalSize = cookedHeaders.value(QNetworkRequest::ContentLengthHeader); 134 pauseNotificationHandling(); 157 135 emit q->downloadProgress(bytesDownloaded, 158 136 totalSize.isNull() ? Q_INT64_C(-1) : totalSize.toLongLong()); 159 137 emit q->readyRead(); 138 resumeNotificationHandling(); 160 139 } 161 140 … … 164 143 _q_copyReadyRead(); 165 144 } 145 146 void QNetworkReplyImplPrivate::_q_bufferOutgoingDataFinished() 147 { 148 Q_Q(QNetworkReplyImpl); 149 150 // make sure this is only called once, ever. 151 //_q_bufferOutgoingData may call it or the readChannelFinished emission 152 if (state != Buffering) 153 return; 154 155 // disconnect signals 156 QObject::disconnect(outgoingData, SIGNAL(readyRead()), q, SLOT(_q_bufferOutgoingData())); 157 QObject::disconnect(outgoingData, SIGNAL(readChannelFinished()), q, SLOT(_q_bufferOutgoingDataFinished())); 158 159 // finally, start the request 160 QMetaObject::invokeMethod(q, "_q_startOperation", Qt::QueuedConnection); 161 } 162 163 void QNetworkReplyImplPrivate::_q_bufferOutgoingData() 164 { 165 Q_Q(QNetworkReplyImpl); 166 167 if (!outgoingDataBuffer) { 168 // first call, create our buffer 169 outgoingDataBuffer = new QRingBuffer(); 170 171 QObject::connect(outgoingData, SIGNAL(readyRead()), q, SLOT(_q_bufferOutgoingData())); 172 QObject::connect(outgoingData, SIGNAL(readChannelFinished()), q, SLOT(_q_bufferOutgoingDataFinished())); 173 } 174 175 qint64 bytesBuffered = 0; 176 qint64 bytesToBuffer = 0; 177 178 // read data into our buffer 179 forever { 180 bytesToBuffer = outgoingData->bytesAvailable(); 181 // unknown? just try 2 kB, this also ensures we always try to read the EOF 182 if (bytesToBuffer <= 0) 183 bytesToBuffer = 2*1024; 184 185 char *dst = outgoingDataBuffer->reserve(bytesToBuffer); 186 bytesBuffered = outgoingData->read(dst, bytesToBuffer); 187 188 if (bytesBuffered == -1) { 189 // EOF has been reached. 190 outgoingDataBuffer->chop(bytesToBuffer); 191 192 _q_bufferOutgoingDataFinished(); 193 break; 194 } else if (bytesBuffered == 0) { 195 // nothing read right now, just wait until we get called again 196 outgoingDataBuffer->chop(bytesToBuffer); 197 198 break; 199 } else { 200 // don't break, try to read() again 201 outgoingDataBuffer->chop(bytesToBuffer - bytesBuffered); 202 } 203 } 204 } 205 166 206 167 207 void QNetworkReplyImplPrivate::setup(QNetworkAccessManager::Operation op, const QNetworkRequest &req, … … 175 215 operation = op; 176 216 177 if (outgoingData) { 178 q->connect(outgoingData, SIGNAL(readyRead()), SLOT(_q_sourceReadyRead())); 179 q->connect(outgoingData, SIGNAL(readChannelFinished()), SLOT(_q_sourceReadChannelFinished())); 217 if (outgoingData && backend) { 218 // there is data to be uploaded, e.g. HTTP POST. 219 220 if (!backend->needsResetableUploadData() || !outgoingData->isSequential()) { 221 // backend does not need upload buffering or 222 // fixed size non-sequential 223 // just start the operation 224 QMetaObject::invokeMethod(q, "_q_startOperation", Qt::QueuedConnection); 225 } else { 226 bool bufferingDisallowed = 227 req.attribute(QNetworkRequest::DoNotBufferUploadDataAttribute, 228 false).toBool(); 229 230 if (bufferingDisallowed) { 231 // if a valid content-length header for the request was supplied, we can disable buffering 232 // if not, we will buffer anyway 233 if (req.header(QNetworkRequest::ContentLengthHeader).isValid()) { 234 QMetaObject::invokeMethod(q, "_q_startOperation", Qt::QueuedConnection); 235 } else { 236 state = Buffering; 237 QMetaObject::invokeMethod(q, "_q_bufferOutgoingData", Qt::QueuedConnection); 238 } 239 } else { 240 // _q_startOperation will be called when the buffering has finished. 241 state = Buffering; 242 QMetaObject::invokeMethod(q, "_q_bufferOutgoingData", Qt::QueuedConnection); 243 } 244 } 245 } else { 246 // No outgoing data (e.g. HTTP GET request) 247 // or no backend 248 // if no backend, _q_startOperation will handle the error of this 249 QMetaObject::invokeMethod(q, "_q_startOperation", Qt::QueuedConnection); 180 250 } 181 251 182 252 q->QIODevice::open(QIODevice::ReadOnly); 183 QMetaObject::invokeMethod(q, "_q_startOperation", Qt::QueuedConnection);184 }185 186 void QNetworkReplyImplPrivate::setNetworkCache(QAbstractNetworkCache *nc)187 {188 networkCache = nc;189 253 } 190 254 … … 201 265 void QNetworkReplyImplPrivate::handleNotifications() 202 266 { 267 if (notificationHandlingPaused) 268 return; 269 203 270 NotificationQueue current = pendingNotifications; 204 271 pendingNotifications.clear(); … … 207 274 return; 208 275 209 while ( !current.isEmpty()) {276 while (state == Working && !current.isEmpty()) { 210 277 InternalNotifications notification = current.dequeue(); 211 278 switch (notification) { … … 217 284 break; 218 285 219 case NotifyUpstreamReadyRead:220 backend->upstreamReadyRead();221 break;222 223 286 case NotifyCloseDownstreamChannel: 224 287 backend->closeDownstreamChannel(); 225 break;226 227 case NotifyCloseUpstreamChannel:228 backend->closeUpstreamChannel();229 288 break; 230 289 … … 239 298 } 240 299 300 // Do not handle the notifications while we are emitting downloadProgress 301 // or readyRead 302 void QNetworkReplyImplPrivate::pauseNotificationHandling() 303 { 304 notificationHandlingPaused = true; 305 } 306 307 // Resume notification handling 308 void QNetworkReplyImplPrivate::resumeNotificationHandling() 309 { 310 Q_Q(QNetworkReplyImpl); 311 notificationHandlingPaused = false; 312 if (pendingNotifications.size() >= 1) 313 QCoreApplication::postEvent(q, new QEvent(QEvent::NetworkReplyUpdated)); 314 } 315 316 QAbstractNetworkCache *QNetworkReplyImplPrivate::networkCache() const 317 { 318 if (!backend) 319 return 0; 320 return backend->networkCache(); 321 } 322 241 323 void QNetworkReplyImplPrivate::createCache() 242 324 { 243 325 // check if we can save and if we're allowed to 244 if (!networkCache || !request.attribute(QNetworkRequest::CacheSaveControlAttribute, true).toBool()) 326 if (!networkCache() 327 || !request.attribute(QNetworkRequest::CacheSaveControlAttribute, true).toBool() 328 || request.attribute(QNetworkRequest::CacheLoadControlAttribute, 329 QNetworkRequest::PreferNetwork).toInt() 330 == QNetworkRequest::AlwaysNetwork) 245 331 return; 246 332 cacheEnabled = true; … … 249 335 bool QNetworkReplyImplPrivate::isCachingEnabled() const 250 336 { 251 return (cacheEnabled && networkCache != 0);337 return (cacheEnabled && networkCache() != 0); 252 338 } 253 339 … … 273 359 "backend %s probably needs to be fixed", 274 360 backend->metaObject()->className()); 275 networkCache ->remove(url);361 networkCache()->remove(url); 276 362 cacheSaveDevice = 0; 277 363 cacheEnabled = false; … … 282 368 { 283 369 if (cacheEnabled && errorCode != QNetworkReplyImpl::NoError) { 284 networkCache ->remove(url);370 networkCache()->remove(url); 285 371 } else if (cacheEnabled && cacheSaveDevice) { 286 networkCache ->insert(cacheSaveDevice);372 networkCache()->insert(cacheSaveDevice); 287 373 } 288 374 cacheSaveDevice = 0; … … 290 376 } 291 377 292 void QNetworkReplyImplPrivate::consume(qint64 count) 293 { 294 Q_Q(QNetworkReplyImpl); 295 if (count <= 0) { 296 qWarning("QNetworkConnection: backend signalled that it consumed %ld bytes", long(count)); 297 return; 298 } 299 300 if (outgoingData) 301 // schedule another read from the source 302 QMetaObject::invokeMethod(q_func(), "_q_sourceReadyRead", Qt::QueuedConnection); 303 304 writeBuffer.skip(count); 305 if (bytesUploaded == -1) 306 bytesUploaded = count; 307 else 308 bytesUploaded += count; 309 310 QVariant totalSize = request.header(QNetworkRequest::ContentLengthHeader); 311 emit q->uploadProgress(bytesUploaded, 312 totalSize.isNull() ? Q_INT64_C(-1) : totalSize.toLongLong()); 313 } 378 void QNetworkReplyImplPrivate::emitUploadProgress(qint64 bytesSent, qint64 bytesTotal) 379 { 380 Q_Q(QNetworkReplyImpl); 381 bytesUploaded = bytesSent; 382 pauseNotificationHandling(); 383 emit q->uploadProgress(bytesSent, bytesTotal); 384 resumeNotificationHandling(); 385 } 386 314 387 315 388 qint64 QNetworkReplyImplPrivate::nextDownstreamBlockSize() const … … 319 392 return DesiredBufferSize; 320 393 321 return qMax<qint64>(0, readBufferMaxSize - readBuffer.size()); 322 } 323 324 void QNetworkReplyImplPrivate::feed(const QByteArray &data) 394 return qMax<qint64>(0, readBufferMaxSize - readBuffer.byteAmount()); 395 } 396 397 // we received downstream data and send this to the cache 398 // and to our readBuffer (which in turn gets read by the user of QNetworkReply) 399 void QNetworkReplyImplPrivate::appendDownstreamData(QByteDataBuffer &data) 325 400 { 326 401 Q_Q(QNetworkReplyImpl); 327 402 if (!q->isOpen()) 328 403 return; 329 330 char *ptr = readBuffer.reserve(data.size());331 memcpy(ptr, data.constData(), data.size());332 404 333 405 if (cacheEnabled && !cacheSaveDevice) { … … 336 408 metaData.setUrl(url); 337 409 metaData = backend->fetchCacheMetaData(metaData); 338 cacheSaveDevice = networkCache->prepare(metaData); 410 411 // save the redirect request also in the cache 412 QVariant redirectionTarget = q->attribute(QNetworkRequest::RedirectionTargetAttribute); 413 if (redirectionTarget.isValid()) { 414 QNetworkCacheMetaData::AttributesMap attributes = metaData.attributes(); 415 attributes.insert(QNetworkRequest::RedirectionTargetAttribute, redirectionTarget); 416 metaData.setAttributes(attributes); 417 } 418 419 cacheSaveDevice = networkCache()->prepare(metaData); 420 339 421 if (!cacheSaveDevice || (cacheSaveDevice && !cacheSaveDevice->isOpen())) { 340 422 if (cacheSaveDevice && !cacheSaveDevice->isOpen()) 341 423 qCritical("QNetworkReplyImpl: network cache returned a device that is not open -- " 342 424 "class %s probably needs to be fixed", 343 networkCache ->metaObject()->className());344 345 networkCache ->remove(url);425 networkCache()->metaObject()->className()); 426 427 networkCache()->remove(url); 346 428 cacheSaveDevice = 0; 347 429 cacheEnabled = false; … … 349 431 } 350 432 351 if (cacheSaveDevice) 352 cacheSaveDevice->write(data); 353 354 bytesDownloaded += data.size(); 433 qint64 bytesWritten = 0; 434 for (int i = 0; i < data.bufferCount(); i++) { 435 QByteArray item = data[i]; 436 437 if (cacheSaveDevice) 438 cacheSaveDevice->write(item.constData(), item.size()); 439 readBuffer.append(item); 440 441 bytesWritten += item.size(); 442 } 443 data.clear(); 444 445 bytesDownloaded += bytesWritten; 355 446 lastBytesDownloaded = bytesDownloaded; 356 447 … … 358 449 359 450 QVariant totalSize = cookedHeaders.value(QNetworkRequest::ContentLengthHeader); 451 pauseNotificationHandling(); 360 452 emit q->downloadProgress(bytesDownloaded, 361 453 totalSize.isNull() ? Q_INT64_C(-1) : totalSize.toLongLong()); 454 // important: At the point of this readyRead(), the data parameter list must be empty, 455 // else implicit sharing will trigger memcpy when the user is reading data! 362 456 emit q->readyRead(); 363 457 364 458 // hopefully we haven't been deleted here 365 459 if (!qq.isNull()) { 460 resumeNotificationHandling(); 366 461 // do we still have room in the buffer? 367 462 if (nextDownstreamBlockSize() > 0) … … 370 465 } 371 466 372 void QNetworkReplyImplPrivate::feed(QIODevice *data) 373 { 374 Q_Q(QNetworkReplyImpl); 375 Q_ASSERT(q->isOpen()); 467 // this is used when it was fetched from the cache, right? 468 void QNetworkReplyImplPrivate::appendDownstreamData(QIODevice *data) 469 { 470 Q_Q(QNetworkReplyImpl); 471 if (!q->isOpen()) 472 return; 376 473 377 474 // read until EOF from data … … 393 490 { 394 491 Q_Q(QNetworkReplyImpl); 395 Q_ASSERT_X(state != Finished, "QNetworkReplyImpl",396 "Backend called finished/finishedWithError more than once");492 if (state == Finished || state == Aborted) 493 return; 397 494 398 495 state = Finished; 399 496 pendingNotifications.clear(); 400 497 498 pauseNotificationHandling(); 401 499 QVariant totalSize = cookedHeaders.value(QNetworkRequest::ContentLengthHeader); 402 if ( bytesDownloaded != lastBytesDownloaded || totalSize.isNull())500 if (totalSize.isNull() || totalSize == -1) { 403 501 emit q->downloadProgress(bytesDownloaded, bytesDownloaded); 404 if (bytesUploaded == -1 && outgoingData) 502 } 503 504 if (bytesUploaded == -1 && (outgoingData || outgoingDataBuffer)) 405 505 emit q->uploadProgress(0, 0); 506 resumeNotificationHandling(); 406 507 407 508 completeCacheSave(); … … 410 511 // which would delete the backend too... 411 512 // maybe we should protect the backend 513 pauseNotificationHandling(); 412 514 emit q->readChannelFinished(); 413 515 emit q->finished(); 516 resumeNotificationHandling(); 414 517 } 415 518 … … 456 559 } 457 560 561 bool QNetworkReplyImplPrivate::isFinished() const 562 { 563 return (state == Finished || state == Aborted); 564 } 565 458 566 QNetworkReplyImpl::QNetworkReplyImpl(QObject *parent) 459 567 : QNetworkReply(*new QNetworkReplyImplPrivate, parent) … … 465 573 Q_D(QNetworkReplyImpl); 466 574 if (d->isCachingEnabled()) 467 d->networkCache->remove(url()); 575 d->networkCache()->remove(url()); 576 if (d->outgoingDataBuffer) 577 delete d->outgoingDataBuffer; 468 578 } 469 579 … … 471 581 { 472 582 Q_D(QNetworkReplyImpl); 473 if (d->state == QNetworkReplyImplPrivate:: Aborted)583 if (d->state == QNetworkReplyImplPrivate::Finished || d->state == QNetworkReplyImplPrivate::Aborted) 474 584 return; 475 585 476 586 // stop both upload and download 477 if (d->backend) {478 d->backend->deleteLater();479 d->backend = 0;480 }481 587 if (d->outgoingData) 482 588 disconnect(d->outgoingData, 0, this, 0); … … 492 598 } 493 599 d->state = QNetworkReplyImplPrivate::Aborted; 600 601 // finished may access the backend 602 if (d->backend) { 603 d->backend->deleteLater(); 604 d->backend = 0; 605 } 494 606 } 495 607 … … 521 633 qint64 QNetworkReplyImpl::bytesAvailable() const 522 634 { 523 return QNetworkReply::bytesAvailable() + d_func()->readBuffer. size();635 return QNetworkReply::bytesAvailable() + d_func()->readBuffer.byteAmount(); 524 636 } 525 637 … … 528 640 Q_D(QNetworkReplyImpl); 529 641 if (size > d->readBufferMaxSize && 530 size == d->readBuffer.size())642 size > d->readBuffer.byteAmount()) 531 643 d->backendNotify(QNetworkReplyImplPrivate::NotifyDownstreamReadyWrite); 532 644 … … 558 670 } 559 671 672 void QNetworkReplyImpl::ignoreSslErrorsImplementation(const QList<QSslError> &errors) 673 { 674 Q_D(QNetworkReplyImpl); 675 if (d->backend) 676 d->backend->ignoreSslErrors(errors); 677 } 560 678 #endif // QT_NO_OPENSSL 561 679 … … 576 694 } 577 695 578 maxlen = qMin<qint64>(maxlen, d->readBuffer. size());696 maxlen = qMin<qint64>(maxlen, d->readBuffer.byteAmount()); 579 697 return d->readBuffer.read(data, maxlen); 580 698 } -
trunk/src/network/access/qnetworkreplyimpl_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 60 60 #include "QtCore/qmap.h" 61 61 #include "QtCore/qqueue.h" 62 #include "QtCore/qbuffer.h" 62 63 #include "private/qringbuffer_p.h" 64 #include "private/qbytedata_p.h" 63 65 64 66 QT_BEGIN_NAMESPACE … … 88 90 Q_INVOKABLE void setSslConfigurationImplementation(const QSslConfiguration &configuration); 89 91 virtual void ignoreSslErrors(); 92 Q_INVOKABLE virtual void ignoreSslErrorsImplementation(const QList<QSslError> &errors); 90 93 #endif 91 94 92 95 Q_DECLARE_PRIVATE(QNetworkReplyImpl) 93 96 Q_PRIVATE_SLOT(d_func(), void _q_startOperation()) 94 Q_PRIVATE_SLOT(d_func(), void _q_sourceReadyRead())95 Q_PRIVATE_SLOT(d_func(), void _q_sourceReadChannelFinished())96 97 Q_PRIVATE_SLOT(d_func(), void _q_copyReadyRead()) 97 98 Q_PRIVATE_SLOT(d_func(), void _q_copyReadChannelFinished()) 99 Q_PRIVATE_SLOT(d_func(), void _q_bufferOutgoingData()) 100 Q_PRIVATE_SLOT(d_func(), void _q_bufferOutgoingDataFinished()) 98 101 }; 99 102 … … 103 106 enum InternalNotifications { 104 107 NotifyDownstreamReadyWrite, 105 NotifyUpstreamReadyRead,106 108 NotifyCloseDownstreamChannel, 107 NotifyCloseUpstreamChannel,108 109 NotifyCopyFinished 109 110 }; … … 111 112 enum State { 112 113 Idle, 113 Opening,114 Buffering, 114 115 Working, 115 116 Finished, … … 126 127 void _q_copyReadyRead(); 127 128 void _q_copyReadChannelFinished(); 129 void _q_bufferOutgoingData(); 130 void _q_bufferOutgoingDataFinished(); 128 131 129 132 void setup(QNetworkAccessManager::Operation op, const QNetworkRequest &request, 130 133 QIODevice *outgoingData); 131 void setNetworkCache(QAbstractNetworkCache *networkCache); 134 135 void pauseNotificationHandling(); 136 void resumeNotificationHandling(); 132 137 void backendNotify(InternalNotifications notification); 133 138 void handleNotifications(); … … 139 144 bool isCachingEnabled() const; 140 145 void consume(qint64 count); 146 void emitUploadProgress(qint64 bytesSent, qint64 bytesTotal); 141 147 qint64 nextDownstreamBlockSize() const; 142 void feed(const QByteArray&data);143 void feed(QIODevice *data);148 void appendDownstreamData(QByteDataBuffer &data); 149 void appendDownstreamData(QIODevice *data); 144 150 void finished(); 145 151 void error(QNetworkReply::NetworkError code, const QString &errorString); … … 148 154 void sslErrors(const QList<QSslError> &errors); 149 155 156 bool isFinished() const; 157 150 158 QNetworkAccessBackend *backend; 151 159 QIODevice *outgoingData; 160 QRingBuffer *outgoingDataBuffer; 152 161 QIODevice *copyDevice; 153 QAbstractNetworkCache *networkCache ;162 QAbstractNetworkCache *networkCache() const; 154 163 155 164 bool cacheEnabled; … … 157 166 158 167 NotificationQueue pendingNotifications; 168 bool notificationHandlingPaused; 169 159 170 QUrl urlForLastAuthentication; 160 171 #ifndef QT_NO_NETWORKPROXY … … 163 174 #endif 164 175 165 QRingBuffer readBuffer; 166 QRingBuffer writeBuffer; 176 QByteDataBuffer readBuffer; 167 177 qint64 bytesDownloaded; 168 178 qint64 lastBytesDownloaded; -
trunk/src/network/access/qnetworkrequest.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 49 49 #include "QtCore/qdatetime.h" 50 50 51 #include <ctype.h> 52 #ifndef QT_NO_DATESTRING 53 # include <stdio.h> 54 #endif 55 51 56 QT_BEGIN_NAMESPACE 52 57 53 58 /*! 54 59 \class QNetworkRequest 55 \brief The QNetworkRequest class holds one request to be sent with the Network Access API.60 \brief The QNetworkRequest class holds a request to be sent with QNetworkAccessManager. 56 61 \since 4.4 57 62 58 \ingroup io63 \ingroup network 59 64 \inmodule QtNetwork 60 65 … … 154 159 be automatically cached. If true, data may be cached, provided 155 160 it is cacheable (what is cacheable depends on the protocol 156 being used). Note that the default QNetworkAccessManager 157 implementation does not support caching, so it will ignore 158 this attribute. 161 being used). 159 162 160 163 \value SourceIsFromCacheAttribute … … 162 165 Indicates whether the data was obtained from cache 163 166 or not. 167 168 \value DoNotBufferUploadDataAttribute 169 Requests only, type: QVariant::Bool (default: false) 170 Indicates whether the QNetworkAccessManager code is 171 allowed to buffer the upload data, e.g. when doing a HTTP POST. 172 When using this flag with sequential upload data, the ContentLengthHeader 173 header must be set. 174 175 \value HttpPipeliningAllowedAttribute 176 Requests only, type: QVariant::Bool (default: false) 177 Indicates whether the QNetworkAccessManager code is 178 allowed to use HTTP pipelining with this request. 179 180 \value HttpPipeliningWasUsedAttribute 181 Replies only, type: QVariant::Bool 182 Indicates whether the HTTP pipelining was used for receiving 183 this reply. 164 184 165 185 \value User … … 217 237 218 238 #ifndef QT_NO_OPENSSL 239 sslConfiguration = 0; 219 240 if (other.sslConfiguration) 220 241 sslConfiguration = new QSslConfiguration(*other.sslConfiguration); 221 else222 sslConfiguration = 0;223 242 #endif 224 243 } … … 467 486 } 468 487 #endif 488 489 /*! 490 \since 4.6 491 492 Allows setting a reference to the \a object initiating 493 the request. 494 495 For example QtWebKit sets the originating object to the 496 QWebFrame that initiated the request. 497 498 \sa originatingObject() 499 */ 500 void QNetworkRequest::setOriginatingObject(QObject *object) 501 { 502 d->originatingObject = object; 503 } 504 505 /*! 506 \since 4.6 507 508 Returns a reference to the object that initiated this 509 network request; returns 0 if not set or the object has 510 been destroyed. 511 512 \sa setOriginatingObject() 513 */ 514 QObject *QNetworkRequest::originatingObject() const 515 { 516 return d->originatingObject.data(); 517 } 469 518 470 519 static QByteArray headerName(QNetworkRequest::KnownHeaders header) … … 563 612 // headerName is not empty here 564 613 565 QByteArray lower = headerName.toLower(); 566 switch (lower.at(0)) { 614 switch (tolower(headerName.at(0))) { 567 615 case 'c': 568 if ( lower == "content-type")616 if (qstricmp(headerName.constData(), "content-type") == 0) 569 617 return QNetworkRequest::ContentTypeHeader; 570 else if ( lower == "content-length")618 else if (qstricmp(headerName.constData(), "content-length") == 0) 571 619 return QNetworkRequest::ContentLengthHeader; 572 else if ( lower == "cookie")620 else if (qstricmp(headerName.constData(), "cookie") == 0) 573 621 return QNetworkRequest::CookieHeader; 574 622 break; 575 623 576 624 case 'l': 577 if ( lower == "location")625 if (qstricmp(headerName.constData(), "location") == 0) 578 626 return QNetworkRequest::LocationHeader; 579 else if ( lower == "last-modified")627 else if (qstricmp(headerName.constData(), "last-modified") == 0) 580 628 return QNetworkRequest::LastModifiedHeader; 581 629 break; 582 630 583 631 case 's': 584 if ( lower == "set-cookie")632 if (qstricmp(headerName.constData(), "set-cookie") == 0) 585 633 return QNetworkRequest::SetCookieHeader; 586 634 break; … … 654 702 QNetworkHeadersPrivate::findRawHeader(const QByteArray &key) const 655 703 { 656 QByteArray lowerKey = key.toLower();657 704 RawHeadersList::ConstIterator it = rawHeaders.constBegin(); 658 705 RawHeadersList::ConstIterator end = rawHeaders.constEnd(); 659 706 for ( ; it != end; ++it) 660 if ( it->first.toLower() == lowerKey)707 if (qstricmp(it->first.constData(), key.constData()) == 0) 661 708 return it; 662 709 … … 732 779 void QNetworkHeadersPrivate::setRawHeaderInternal(const QByteArray &key, const QByteArray &value) 733 780 { 734 QByteArray lowerKey = key.toLower();735 781 RawHeadersList::Iterator it = rawHeaders.begin(); 736 782 while (it != rawHeaders.end()) { 737 if ( it->first.toLower() == lowerKey)783 if (qstricmp(it->first.constData(), key.constData()) == 0) 738 784 it = rawHeaders.erase(it); 739 785 else … … 762 808 } 763 809 810 // Fast month string to int conversion. This code 811 // assumes that the Month name is correct and that 812 // the string is at least three chars long. 813 static int name_to_month(const char* month_str) 814 { 815 switch (month_str[0]) { 816 case 'J': 817 switch (month_str[1]) { 818 case 'a': 819 return 1; 820 break; 821 case 'u': 822 switch (month_str[2] ) { 823 case 'n': 824 return 6; 825 break; 826 case 'l': 827 return 7; 828 break; 829 } 830 } 831 break; 832 case 'F': 833 return 2; 834 break; 835 case 'M': 836 switch (month_str[2] ) { 837 case 'r': 838 return 3; 839 break; 840 case 'y': 841 return 5; 842 break; 843 } 844 break; 845 case 'A': 846 switch (month_str[1]) { 847 case 'p': 848 return 4; 849 break; 850 case 'u': 851 return 8; 852 break; 853 } 854 break; 855 case 'O': 856 return 10; 857 break; 858 case 'S': 859 return 9; 860 break; 861 case 'N': 862 return 11; 863 break; 864 case 'D': 865 return 12; 866 break; 867 } 868 869 return 0; 870 } 871 764 872 QDateTime QNetworkHeadersPrivate::fromHttpDate(const QByteArray &value) 765 873 { … … 777 885 dt = QDateTime::fromString(QString::fromLatin1(value), Qt::TextDate); 778 886 } else { 779 // eat the weekday, the comma and the space following it 780 QString sansWeekday = QString::fromLatin1(value.constData() + pos + 2); 781 782 QLocale c = QLocale::c(); 783 if (pos == 3) 784 // must be RFC 1123 date 785 dt = c.toDateTime(sansWeekday, QLatin1String("dd MMM yyyy hh:mm:ss 'GMT")); 786 else 887 // Use sscanf over QLocal/QDateTimeParser for speed reasons. See the 888 // QtWebKit performance benchmarks to get an idea. 889 if (pos == 3) { 890 char month_name[4]; 891 int day, year, hour, minute, second; 892 if (sscanf(value.constData(), "%*3s, %d %3s %d %d:%d:%d 'GMT'", &day, month_name, &year, &hour, &minute, &second) == 6) 893 dt = QDateTime(QDate(year, name_to_month(month_name), day), QTime(hour, minute, second)); 894 } else { 895 QLocale c = QLocale::c(); 896 // eat the weekday, the comma and the space following it 897 QString sansWeekday = QString::fromLatin1(value.constData() + pos + 2); 787 898 // must be RFC 850 date 788 899 dt = c.toDateTime(sansWeekday, QLatin1String("dd-MMM-yy hh:mm:ss 'GMT'")); 900 } 789 901 } 790 902 #endif // QT_NO_DATESTRING -
trunk/src/network/access/qnetworkrequest.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 76 76 CacheSaveControlAttribute, 77 77 SourceIsFromCacheAttribute, 78 DoNotBufferUploadDataAttribute, 79 HttpPipeliningAllowedAttribute, 80 HttpPipeliningWasUsedAttribute, 78 81 79 82 User = 1000, … … 118 121 #endif 119 122 123 void setOriginatingObject(QObject *object); 124 QObject *originatingObject() const; 125 120 126 private: 121 127 QSharedDataPointer<QNetworkRequestPrivate> d; -
trunk/src/network/access/qnetworkrequest_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 59 59 #include "QtCore/qhash.h" 60 60 #include "QtCore/qshareddata.h" 61 #include "QtCore/qsharedpointer.h" 61 62 62 63 QT_BEGIN_NAMESPACE … … 74 75 CookedHeadersMap cookedHeaders; 75 76 AttributesMap attributes; 77 QWeakPointer<QObject> originatingObject; 76 78 77 79 RawHeadersList::ConstIterator findRawHeader(const QByteArray &key) const; -
trunk/src/network/kernel/kernel.pri
r160 r561 21 21 kernel/qnetworkinterface.cpp 22 22 23 unix:SOURCES += kernel/qhostinfo_unix.cpp kernel/qnetworkinterface_unix.cpp 23 symbian: SOURCES += kernel/qhostinfo_unix.cpp kernel/qnetworkinterface_symbian.cpp 24 unix:!symbian:SOURCES += kernel/qhostinfo_unix.cpp kernel/qnetworkinterface_unix.cpp 24 25 win32:SOURCES += kernel/qhostinfo_win.cpp kernel/qnetworkinterface_win.cpp 25 26 os2:SOURCES += kernel/qhostinfo_os2.cpp kernel/qnetworkinterface_os2.cpp 26 27 27 mac:LIBS += -framework SystemConfiguration28 mac:LIBS_PRIVATE += -framework SystemConfiguration -framework CoreFoundation 28 29 mac:SOURCES += kernel/qnetworkproxy_mac.cpp 29 30 else:win32:SOURCES += kernel/qnetworkproxy_win.cpp -
trunk/src/network/kernel/qauthenticator.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 47 47 #include <qcryptographichash.h> 48 48 #include <qhttp.h> 49 #include <qiodevice.h> 49 50 #include <qdatastream.h> 50 51 #include <qendian.h> … … 64 65 65 66 \reentrant 66 \ingroup io67 \ingroup network 67 68 \inmodule QtNetwork 68 69 69 70 The QAuthenticator class is usually used in the 70 \l{Q Http::}{authenticationRequired()} and71 \l{Q Http::}{proxyAuthenticationRequired()} signals of QHttpand71 \l{QNetworkAccessManager::}{authenticationRequired()} and 72 \l{QNetworkAccessManager::}{proxyAuthenticationRequired()} signals of QNetworkAccessManager and 72 73 QAbstractSocket. The class provides a way to pass back the required 73 74 authentication information to the socket when accessing services that 74 75 require authentication. 76 77 QAuthenticator supports the following authentication methods: 78 \list 79 \o Basic 80 \o NTLM version 1 81 \o Digest-MD5 82 \endlist 83 84 Note that, in particular, NTLM version 2 is not supported. 75 85 76 86 \sa QSslSocket … … 503 513 if (!opaque.isEmpty()) 504 514 credentials += "opaque=\"" + opaque + "\", "; 505 credentials += "response=\"" + response + "\"";515 credentials += "response=\"" + response + '\"'; 506 516 if (!options.value("algorithm").isEmpty()) 507 517 credentials += ", algorithm=" + options.value("algorithm"); … … 509 519 credentials += ", qop=" + qop + ", "; 510 520 credentials += "nc=" + nonceCountString + ", "; 511 credentials += "cnonce=\"" + cnonce + "\"";521 credentials += "cnonce=\"" + cnonce + '\"'; 512 522 } 513 523 -
trunk/src/network/kernel/qauthenticator.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** -
trunk/src/network/kernel/qauthenticator_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** -
trunk/src/network/kernel/qhostaddress.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 420 420 \class QHostAddress 421 421 \brief The QHostAddress class provides an IP address. 422 \ingroup io422 \ingroup network 423 423 \inmodule QtNetwork 424 424 … … 432 432 using isIPv4Address() or isIPv6Address(), and retrieved with 433 433 toIPv4Address(), toIPv6Address(), or toString(). 434 435 \note Please note that QHostAddress does not do DNS lookups. 436 QHostInfo is needed for that. 434 437 435 438 The class also supports common predefined addresses: \l Null, \l … … 524 527 */ 525 528 QHostAddress::QHostAddress(const QHostAddress &address) 526 : d(new QHostAddressPrivate(*address.d ))529 : d(new QHostAddressPrivate(*address.d.data())) 527 530 { 528 531 } … … 560 563 QHostAddress::~QHostAddress() 561 564 { 562 delete d;563 565 } 564 566 … … 569 571 QHostAddress &QHostAddress::operator=(const QHostAddress &address) 570 572 { 571 *d = *address.d;573 *d.data() = *address.d.data(); 572 574 return *this; 573 575 } … … 1079 1081 QDebug operator<<(QDebug d, const QHostAddress &address) 1080 1082 { 1081 d.maybeSpace() << "QHostAddress(" << address.toString() << ")";1083 d.maybeSpace() << "QHostAddress(" << address.toString() << ')'; 1082 1084 return d.space(); 1083 1085 } -
trunk/src/network/kernel/qhostaddress.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 45 45 #include <QtCore/qpair.h> 46 46 #include <QtCore/qstring.h> 47 #include <QtCore/qscopedpointer.h> 47 48 #include <QtNetwork/qabstractsocket.h> 48 49 … … 131 132 132 133 protected: 133 Q HostAddressPrivate *d;134 QScopedPointer<QHostAddressPrivate> d; 134 135 }; 135 136 -
trunk/src/network/kernel/qhostaddress_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** -
trunk/src/network/kernel/qhostinfo.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 43 43 #include "qhostinfo_p.h" 44 44 45 #include "QtCore/qscopedpointer.h" 45 46 #include <qabstracteventdispatcher.h> 46 47 #include <private/qunicodetables_p.h> … … 60 61 QT_BEGIN_NAMESPACE 61 62 62 Q_GLOBAL_STATIC(QHostInfoAgent, theAgent) 63 void QHostInfoAgent::staticCleanup() 64 { 65 theAgent()->cleanup(); 66 } 63 #ifndef QT_NO_THREAD 64 Q_GLOBAL_STATIC(QHostInfoLookupManager, theHostInfoLookupManager) 65 #endif 67 66 68 67 //#define QHOSTINFO_DEBUG … … 74 73 \reentrant 75 74 \inmodule QtNetwork 76 \ingroup io75 \ingroup network 77 76 78 77 QHostInfo uses the lookup mechanisms provided by the operating … … 142 141 143 142 \snippet doc/src/snippets/code/src_network_kernel_qhostinfo.cpp 4 143 144 \note There is no guarantee on the order the signals will be emitted 145 if you start multiple requests with lookupHost(). 144 146 145 147 \sa abortHostLookup(), addresses(), error(), fromName() … … 159 161 qRegisterMetaType<QHostInfo>("QHostInfo"); 160 162 161 #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) 162 QWindowsSockInit bust; // makes sure WSAStartup was callled 163 int id = theIdCounter.fetchAndAddRelaxed(1); // generate unique ID 164 165 if (name.isEmpty()) { 166 QHostInfo hostInfo(id); 167 hostInfo.setError(QHostInfo::HostNotFound); 168 hostInfo.setErrorString(QObject::tr("No host name given")); 169 QScopedPointer<QHostInfoResult> result(new QHostInfoResult); 170 QObject::connect(result.data(), SIGNAL(resultsReady(QHostInfo)), 171 receiver, member, Qt::QueuedConnection); 172 result.data()->emitResultsReady(hostInfo); 173 return id; 174 } 175 176 #ifdef QT_NO_THREAD 177 QHostInfo hostInfo = QHostInfoAgent::fromName(name); 178 hostInfo.setLookupId(id); 179 QScopedPointer<QHostInfoResult> result(new QHostInfoResult); 180 QObject::connect(result.data(), SIGNAL(resultsReady(QHostInfo)), 181 receiver, member, Qt::QueuedConnection); 182 result.data()->emitResultsReady(hostInfo); 183 #else 184 QHostInfoRunnable* runnable = new QHostInfoRunnable(name, id); 185 QObject::connect(&runnable->resultEmitter, SIGNAL(resultsReady(QHostInfo)), receiver, member, Qt::QueuedConnection); 186 theHostInfoLookupManager()->scheduleLookup(runnable); 163 187 #endif 164 188 165 // Support for IDNA 166 QString lookup = QString::fromLatin1(QUrl::toAce(name)); 167 168 QHostInfoResult *result = new QHostInfoResult; 169 result->autoDelete = false; 170 QObject::connect(result, SIGNAL(resultsReady(QHostInfo)), 171 receiver, member); 172 int id = result->lookupId = theIdCounter.fetchAndAddRelaxed(1); 173 174 if (lookup.isEmpty()) { 175 QHostInfo info(id); 176 info.setError(QHostInfo::HostNotFound); 177 info.setErrorString(QObject::tr("No host name given")); 178 QMetaObject::invokeMethod(result, "emitResultsReady", Qt::QueuedConnection, 179 Q_ARG(QHostInfo, info)); 180 result->autoDelete = true; 181 return id; 182 } 183 184 QHostInfoAgent *agent = theAgent(); 185 agent->addHostName(lookup, result); 186 187 #if !defined QT_NO_THREAD 188 if (!agent->isRunning()) 189 agent->start(); 189 return id; 190 } 191 192 /*! 193 Aborts the host lookup with the ID \a id, as returned by lookupHost(). 194 195 \sa lookupHost(), lookupId() 196 */ 197 void QHostInfo::abortHostLookup(int id) 198 { 199 #ifndef QT_NO_THREAD 200 theHostInfoLookupManager()->abortLookup(id); 190 201 #else 191 // if (!agent->isRunning()) 192 agent->run(); 193 // else 194 // agent->wakeOne(); 202 // we cannot abort if it was non threaded.. the result signal has already been posted 203 Q_UNUSED(id); 195 204 #endif 196 return id;197 }198 199 /*!200 Aborts the host lookup with the ID \a id, as returned by lookupHost().201 202 \sa lookupHost(), lookupId()203 */204 void QHostInfo::abortHostLookup(int id)205 {206 QHostInfoAgent *agent = theAgent();207 agent->abortLookup(id);208 205 } 209 206 … … 227 224 #endif 228 225 229 if (!name.isEmpty()) 230 return QHostInfoAgent::fromName(QLatin1String(QUrl::toAce(name))); 231 232 QHostInfo retval; 233 retval.d->err = HostNotFound; 234 retval.d->errorStr = QObject::tr("No host name given"); 235 return retval; 236 } 237 238 /*! 239 \internal 240 Pops a query off the queries list, performs a blocking call to 241 QHostInfoAgent::lookupHost(), and emits the resultsReady() 242 signal. This process repeats until the queries list is empty. 243 */ 244 void QHostInfoAgent::run() 245 { 246 #ifndef QT_NO_THREAD 247 // Dont' allow thread termination during event delivery, but allow it 248 // during the actual blocking host lookup stage. 249 setTerminationEnabled(false); 250 forever 251 #endif 252 { 253 QHostInfoQuery *query; 254 { 255 #ifndef QT_NO_THREAD 256 // the queries list is shared between threads. lock all 257 // access to it. 258 QMutexLocker locker(&mutex); 259 if (!quit && queries.isEmpty()) 260 cond.wait(&mutex); 261 if (quit) { 262 // Reset the quit variable in case QCoreApplication is 263 // destroyed and recreated. 264 quit = false; 265 break; 266 } 267 if (queries.isEmpty()) 268 continue; 269 #else 270 if (queries.isEmpty()) 271 return; 272 #endif 273 query = queries.takeFirst(); 274 pendingQueryId = query->object->lookupId; 275 } 276 277 #if defined(QHOSTINFO_DEBUG) 278 qDebug("QHostInfoAgent::run(%p): looking up \"%s\"", this, 279 query->hostName.toLatin1().constData()); 280 #endif 281 282 #ifndef QT_NO_THREAD 283 // Start query - allow termination at this point, but not outside. We 284 // don't want to all termination during event delivery, but we don't 285 // want the lookup to prevent the app from quitting (the agent 286 // destructor terminates the thread). 287 setTerminationEnabled(true); 288 #endif 289 QHostInfo info = fromName(query->hostName); 290 #ifndef QT_NO_THREAD 291 setTerminationEnabled(false); 292 #endif 293 294 int id = query->object->lookupId; 295 info.setLookupId(id); 296 if (pendingQueryId == id) 297 query->object->emitResultsReady(info); 298 delete query; 299 } 226 return QHostInfoAgent::fromName(name); 300 227 } 301 228 … … 328 255 */ 329 256 QHostInfo::QHostInfo(const QHostInfo &other) 330 : d(new QHostInfoPrivate(*other.d ))257 : d(new QHostInfoPrivate(*other.d.data())) 331 258 { 332 259 } … … 338 265 QHostInfo &QHostInfo::operator=(const QHostInfo &other) 339 266 { 340 *d = *other.d;267 *d.data() = *other.d.data(); 341 268 return *this; 342 269 } … … 347 274 QHostInfo::~QHostInfo() 348 275 { 349 delete d;350 276 } 351 277 … … 477 403 */ 478 404 405 #ifndef QT_NO_THREAD 406 QHostInfoRunnable::QHostInfoRunnable(QString hn, int i) : toBeLookedUp(hn), id(i) 407 { 408 setAutoDelete(true); 409 } 410 411 // the QHostInfoLookupManager will at some point call this via a QThreadPool 412 void QHostInfoRunnable::run() 413 { 414 QHostInfoLookupManager *manager = theHostInfoLookupManager(); 415 // check aborted 416 if (manager->wasAborted(id)) { 417 manager->lookupFinished(this); 418 return; 419 } 420 421 // check cache 422 // FIXME 423 424 // if not in cache: OS lookup 425 QHostInfo hostInfo = QHostInfoAgent::fromName(toBeLookedUp); 426 427 // save to cache 428 // FIXME 429 430 // check aborted again 431 if (manager->wasAborted(id)) { 432 manager->lookupFinished(this); 433 return; 434 } 435 436 // signal emission 437 hostInfo.setLookupId(id); 438 resultEmitter.emitResultsReady(hostInfo); 439 440 manager->lookupFinished(this); 441 442 // thread goes back to QThreadPool 443 } 444 445 QHostInfoLookupManager::QHostInfoLookupManager() : mutex(QMutex::Recursive), wasDeleted(false) 446 { 447 moveToThread(QCoreApplicationPrivate::mainThread()); 448 threadPool.setMaxThreadCount(5); // do 5 DNS lookups in parallel 449 } 450 451 QHostInfoLookupManager::~QHostInfoLookupManager() 452 { 453 wasDeleted = true; 454 } 455 456 void QHostInfoLookupManager::work() 457 { 458 if (wasDeleted) 459 return; 460 461 // goals of this function: 462 // - launch new lookups via the thread pool 463 // - make sure only one lookup per host/IP is in progress 464 465 QMutexLocker locker(&mutex); 466 467 if (!finishedLookups.isEmpty()) { 468 // remove ID from aborted if it is in there 469 for (int i = 0; i < finishedLookups.length(); i++) { 470 abortedLookups.removeAll(finishedLookups.at(i)->id); 471 } 472 473 finishedLookups.clear(); 474 } 475 476 if (!postponedLookups.isEmpty()) { 477 // try to start the postponed ones 478 479 QMutableListIterator<QHostInfoRunnable*> iterator(postponedLookups); 480 while (iterator.hasNext()) { 481 QHostInfoRunnable* postponed = iterator.next(); 482 483 // check if none of the postponed hostnames is currently running 484 bool alreadyRunning = false; 485 for (int i = 0; i < currentLookups.length(); i++) { 486 if (currentLookups.at(i)->toBeLookedUp == postponed->toBeLookedUp) { 487 alreadyRunning = true; 488 break; 489 } 490 } 491 if (!alreadyRunning) { 492 iterator.remove(); 493 scheduledLookups.prepend(postponed); // prepend! we want to finish it ASAP 494 } 495 } 496 } 497 498 if (!scheduledLookups.isEmpty()) { 499 // try to start the new ones 500 QMutableListIterator<QHostInfoRunnable*> iterator(scheduledLookups); 501 while (iterator.hasNext()) { 502 QHostInfoRunnable *scheduled = iterator.next(); 503 504 // check if a lookup for this host is already running, then postpone 505 for (int i = 0; i < currentLookups.size(); i++) { 506 if (currentLookups.at(i)->toBeLookedUp == scheduled->toBeLookedUp) { 507 iterator.remove(); 508 postponedLookups.append(scheduled); 509 scheduled = 0; 510 break; 511 } 512 } 513 514 if (scheduled && threadPool.tryStart(scheduled)) { 515 // runnable now running in new thread, track this in currentLookups 516 iterator.remove(); 517 currentLookups.append(scheduled); 518 } else if (scheduled) { 519 // wanted to start, but could not because thread pool is busy 520 break; 521 } else { 522 // was postponed, continue iterating 523 continue; 524 } 525 }; 526 } 527 } 528 529 // called by QHostInfo 530 void QHostInfoLookupManager::scheduleLookup(QHostInfoRunnable *r) 531 { 532 if (wasDeleted) 533 return; 534 535 QMutexLocker locker(&this->mutex); 536 scheduledLookups.enqueue(r); 537 work(); 538 } 539 540 // called by QHostInfo 541 void QHostInfoLookupManager::abortLookup(int id) 542 { 543 if (wasDeleted) 544 return; 545 546 QMutexLocker locker(&this->mutex); 547 if (!abortedLookups.contains(id)) 548 abortedLookups.append(id); 549 } 550 551 // called from QHostInfoRunnable 552 bool QHostInfoLookupManager::wasAborted(int id) 553 { 554 if (wasDeleted) 555 return true; 556 557 QMutexLocker locker(&this->mutex); 558 return abortedLookups.contains(id); 559 } 560 561 // called from QHostInfoRunnable 562 void QHostInfoLookupManager::lookupFinished(QHostInfoRunnable *r) 563 { 564 if (wasDeleted) 565 return; 566 567 QMutexLocker locker(&this->mutex); 568 currentLookups.removeOne(r); 569 finishedLookups.append(r); 570 work(); 571 } 572 573 #endif // QT_NO_THREAD 574 479 575 QT_END_NAMESPACE -
trunk/src/network/kernel/qhostinfo.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 44 44 45 45 #include <QtCore/qlist.h> 46 #include <QtCore/qscopedpointer.h> 46 47 #include <QtNetwork/qhostaddress.h> 47 48 … … 92 93 93 94 private: 94 Q HostInfoPrivate *d;95 QScopedPointer<QHostInfoPrivate> d; 95 96 }; 96 97 -
trunk/src/network/kernel/qhostinfo_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 48 48 // 49 49 // This file is not part of the Qt API. It exists for the convenience 50 // of the Q Libraryclass. This header file may change from50 // of the QHostInfo class. This header file may change from 51 51 // version to version without notice, or even be removed. 52 52 // … … 62 62 #include "QtCore/qpointer.h" 63 63 64 #if !definedQT_NO_THREAD64 #ifndef QT_NO_THREAD 65 65 #include "QtCore/qthread.h" 66 # define QHostInfoAgentBase QThread 67 #else 68 # define QHostInfoAgentBase QObject 66 #include "QtCore/qthreadpool.h" 67 #include "QtCore/qmutex.h" 68 #include "QtCore/qrunnable.h" 69 #include "QtCore/qlist.h" 70 #include "QtCore/qqueue.h" 69 71 #endif 70 72 71 73 QT_BEGIN_NAMESPACE 72 73 static const int QHOSTINFO_THREAD_WAIT = 250; // ms74 74 75 75 class QHostInfoResult : public QObject … … 80 80 { 81 81 emit resultsReady(info); 82 if (autoDelete)83 delete this;84 82 } 85 83 86 84 Q_SIGNALS: 87 void resultsReady(const QHostInfo &info); 88 89 public: 90 int lookupId; 91 bool autoDelete; 85 void resultsReady(const QHostInfo info); 92 86 }; 93 87 94 struct QHostInfoQuery 95 { 96 inline QHostInfoQuery() : object(0) {} 97 inline ~QHostInfoQuery() { delete object; } 98 inline QHostInfoQuery(const QString &name, QHostInfoResult *result) 99 : hostName(name), object(result) {} 100 101 QString hostName; 102 QHostInfoResult *object; 103 }; 104 105 class QHostInfoAgent : public QHostInfoAgentBase 88 // needs to be QObject because fromName calls tr() 89 class QHostInfoAgent : public QObject 106 90 { 107 91 Q_OBJECT 108 92 public: 109 inline QHostInfoAgent()110 {111 // There is a chance that there will be two instances of112 // QHostInfoAgent if two threads try to get Q_GLOBAL_STATIC113 // object at the same time. The second object will be deleted114 // immediately before anyone uses it, but we need to be115 // careful about what we do in the constructor.116 static QBasicAtomicInt done = Q_BASIC_ATOMIC_INITIALIZER(0);117 if (done.testAndSetRelaxed(0, 1))118 qAddPostRoutine(staticCleanup);119 moveToThread(QCoreApplicationPrivate::mainThread());120 quit = false;121 pendingQueryId = -1;122 }123 inline ~QHostInfoAgent()124 { cleanup(); }125 126 void run();127 93 static QHostInfo fromName(const QString &hostName); 128 129 inline void addHostName(const QString &name, QHostInfoResult *result)130 {131 QMutexLocker locker(&mutex);132 queries << new QHostInfoQuery(name, result);133 cond.wakeOne();134 }135 136 inline void abortLookup(int id)137 {138 QMutexLocker locker(&mutex);139 for (int i = 0; i < queries.size(); ++i) {140 QHostInfoResult *result = queries.at(i)->object;141 if (result->lookupId == id) {142 result->disconnect();143 delete queries.takeAt(i);144 return;145 }146 }147 if (pendingQueryId == id)148 pendingQueryId = -1;149 }150 151 static void staticCleanup();152 153 public Q_SLOTS:154 inline void cleanup()155 {156 {157 QMutexLocker locker(&mutex);158 qDeleteAll(queries);159 queries.clear();160 quit = true;161 cond.wakeOne();162 }163 #ifndef QT_NO_THREAD164 if (!wait(QHOSTINFO_THREAD_WAIT))165 terminate();166 wait();167 #endif168 }169 170 private:171 QList<QHostInfoQuery *> queries;172 QMutex mutex;173 QWaitCondition cond;174 volatile bool quit;175 int pendingQueryId;176 94 }; 177 95 … … 181 99 inline QHostInfoPrivate() 182 100 : err(QHostInfo::NoError), 183 errorStr(QLatin1String(QT_TRANSLATE_NOOP("QHostInfo", "Unknown error"))) 101 errorStr(QLatin1String(QT_TRANSLATE_NOOP("QHostInfo", "Unknown error"))), 102 lookupId(0) 184 103 { 185 104 } … … 192 111 }; 193 112 113 #ifndef QT_NO_THREAD 114 // the following classes are used for the (normal) case: We use multiple threads to lookup DNS 115 116 class QHostInfoRunnable : public QRunnable 117 { 118 public: 119 QHostInfoRunnable (QString hn, int i); 120 void run(); 121 122 QString toBeLookedUp; 123 int id; 124 QHostInfoResult resultEmitter; 125 }; 126 127 class QHostInfoLookupManager : public QObject 128 { 129 Q_OBJECT 130 public: 131 QHostInfoLookupManager(); 132 ~QHostInfoLookupManager(); 133 134 void work(); 135 136 // called from QHostInfo 137 void scheduleLookup(QHostInfoRunnable *r); 138 void abortLookup(int id); 139 140 // called from QHostInfoRunnable 141 void lookupFinished(QHostInfoRunnable *r); 142 bool wasAborted(int id); 143 144 protected: 145 QList<QHostInfoRunnable*> currentLookups; // in progress 146 QList<QHostInfoRunnable*> postponedLookups; // postponed because in progress for same host 147 QQueue<QHostInfoRunnable*> scheduledLookups; // not yet started 148 QList<QHostInfoRunnable*> finishedLookups; // recently finished 149 QList<int> abortedLookups; // ids of aborted lookups 150 151 QThreadPool threadPool; 152 153 QMutex mutex; 154 155 bool wasDeleted; 156 }; 157 #endif 158 194 159 QT_END_NAMESPACE 195 160 -
trunk/src/network/kernel/qhostinfo_unix.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 41 41 42 42 //#define QHOSTINFO_DEBUG 43 44 static const int RESOLVER_TIMEOUT = 2000;45 43 46 44 #include "qplatformdefs.h" … … 53 51 #include <qfile.h> 54 52 #include <private/qmutexpool_p.h> 55 56 extern "C" { 53 #include <private/qnet_unix_p.h> 54 57 55 #include <sys/types.h> 58 56 #include <netdb.h> 59 57 #include <arpa/inet.h> 60 #include <resolv.h> 61 } 58 #if defined(Q_OS_VXWORKS) 59 # include <hostLib.h> 60 #else 61 # include <resolv.h> 62 #endif 62 63 63 64 #if defined (QT_NO_GETADDRINFO) … … 122 123 { 123 124 QHostInfo results; 124 results.setHostName(hostName);125 125 126 126 #if defined(QHOSTINFO_DEBUG) … … 149 149 // Reverse lookup 150 150 // Reverse lookups using getnameinfo are broken on darwin, use gethostbyaddr instead. 151 #if !defined (QT_NO_GETADDRINFO) && !defined (Q_OS_DARWIN) 151 #if !defined (QT_NO_GETADDRINFO) && !defined (Q_OS_DARWIN) && !defined (Q_OS_SYMBIAN) 152 152 sockaddr_in sa4; 153 153 #ifndef QT_NO_IPV6 … … 174 174 175 175 char hbuf[NI_MAXHOST]; 176 if (!sa || getnameinfo(sa, saSize, hbuf, sizeof(hbuf), 0, 0, 0) != 0) { 177 results.setError(QHostInfo::HostNotFound); 178 results.setErrorString(tr("Host not found")); 179 return results; 180 } 181 results.setHostName(QString::fromLatin1(hbuf)); 176 if (sa && getnameinfo(sa, saSize, hbuf, sizeof(hbuf), 0, 0, 0) == 0) 177 results.setHostName(QString::fromLatin1(hbuf)); 182 178 #else 183 in_addr_t inetaddr = inet_addr(hostName.toLatin1().constData());179 in_addr_t inetaddr = qt_safe_inet_addr(hostName.toLatin1().constData()); 184 180 struct hostent *ent = gethostbyaddr((const char *)&inetaddr, sizeof(inetaddr), AF_INET); 185 if (!ent) { 186 results.setError(QHostInfo::HostNotFound); 187 results.setErrorString(tr("Host not found")); 188 return results; 189 } 190 results.setHostName(QString::fromLatin1(ent->h_name)); 191 #endif 181 if (ent) 182 results.setHostName(QString::fromLatin1(ent->h_name)); 183 #endif 184 185 if (results.hostName().isEmpty()) 186 results.setHostName(address.toString()); 187 results.setAddresses(QList<QHostAddress>() << address); 188 return results; 189 } 190 191 // IDN support 192 QByteArray aceHostname = QUrl::toAce(hostName); 193 results.setHostName(hostName); 194 if (aceHostname.isEmpty()) { 195 results.setError(QHostInfo::HostNotFound); 196 results.setErrorString(hostName.isEmpty() ? QObject::tr("No host name given") : QObject::tr("Invalid hostname")); 197 return results; 192 198 } 193 199 … … 203 209 #endif 204 210 205 int result = getaddrinfo( hostName.toLatin1().constData(), 0, &hints, &res);211 int result = getaddrinfo(aceHostname.constData(), 0, &hints, &res); 206 212 # ifdef Q_ADDRCONFIG 207 213 if (result == EAI_BADFLAGS) { 208 214 // if the lookup failed with AI_ADDRCONFIG set, try again without it 209 215 hints.ai_flags = 0; 210 result = getaddrinfo( hostName.toLatin1().constData(), 0, &hints, &res);216 result = getaddrinfo(aceHostname.constData(), 0, &hints, &res); 211 217 } 212 218 # endif … … 262 268 // must be provided. 263 269 QMutexLocker locker(::getHostByNameMutex()); 264 hostent *result = gethostbyname( hostName.toLatin1().constData());270 hostent *result = gethostbyname(aceHostname.constData()); 265 271 if (result) { 266 272 if (result->h_addrtype == AF_INET) { … … 277 283 results.setErrorString(tr("Unknown address type")); 278 284 } 285 #if !defined(Q_OS_VXWORKS) 279 286 } else if (h_errno == HOST_NOT_FOUND || h_errno == NO_DATA 280 287 || h_errno == NO_ADDRESS) { 281 288 results.setError(QHostInfo::HostNotFound); 282 289 results.setErrorString(tr("Host not found")); 290 #endif 283 291 } else { 284 292 results.setError(QHostInfo::UnknownError); … … 317 325 QString QHostInfo::localDomainName() 318 326 { 327 #if !defined(Q_OS_VXWORKS) 319 328 resolveLibrary(); 320 329 if (local_res_ninit) { 321 330 // using thread-safe version 322 331 res_state_ptr state = res_state_ptr(qMalloc(sizeof(*state))); 332 Q_CHECK_PTR(state); 323 333 memset(state, 0, sizeof(*state)); 324 334 local_res_ninit(state); … … 346 356 return domainName; 347 357 } 348 358 #endif 349 359 // nothing worked, try doing it by ourselves: 350 360 QFile resolvconf; -
trunk/src/network/kernel/qhostinfo_win.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 53 53 #include <qtimer.h> 54 54 #include <qmutex.h> 55 #include <qurl.h> 55 56 #include <private/qmutexpool_p.h> 56 57 … … 71 72 sockaddr *ai_addr; 72 73 qt_addrinfo *ai_next; 73 };74 75 // sockaddr_in6 size changed between old and new SDK76 // Only the new version is the correct one, so always77 // use this structure.78 struct qt_in6_addr {79 uchar qt_s6_addr[16];80 };81 82 struct qt_sockaddr_in6 {83 short sin6_family; /* AF_INET6 */84 u_short sin6_port; /* Transport level port number */85 u_long sin6_flowinfo; /* IPv6 flow information */86 struct qt_in6_addr sin6_addr; /* IPv6 address */87 u_long sin6_scope_id; /* set of interfaces for a scope */88 74 }; 89 75 … … 120 106 QMutex qPrivCEMutex; 121 107 #endif 122 /* 123 Performs a blocking call to gethostbyname or getaddrinfo, stores 124 the results in a QHostInfo structure and emits the 125 resultsReady() signal. 126 */ 108 127 109 QHostInfo QHostInfoAgent::fromName(const QString &hostName) 128 110 { … … 145 127 146 128 QHostInfo results; 147 results.setHostName(hostName);148 129 149 130 #if defined(QHOSTINFO_DEBUG) … … 176 157 177 158 char hbuf[NI_MAXHOST]; 178 if (local_getnameinfo(sa, saSize, hbuf, sizeof(hbuf), 0, 0, 0) != 0) { 179 results.setError(QHostInfo::HostNotFound); 180 results.setErrorString(tr("Host not found")); 181 return results; 182 } 183 results.setHostName(QString::fromLatin1(hbuf)); 159 if (local_getnameinfo(sa, saSize, hbuf, sizeof(hbuf), 0, 0, 0) == 0) 160 results.setHostName(QString::fromLatin1(hbuf)); 184 161 } else { 185 162 unsigned long addr = inet_addr(hostName.toLatin1().constData()); 186 163 struct hostent *ent = gethostbyaddr((const char*)&addr, sizeof(addr), AF_INET); 187 if (!ent) { 188 results.setError(QHostInfo::HostNotFound); 189 results.setErrorString(tr("Host not found")); 190 return results; 191 } 192 results.setHostName(QString::fromLatin1(ent->h_name)); 193 } 164 if (ent) 165 results.setHostName(QString::fromLatin1(ent->h_name)); 166 } 167 168 if (results.hostName().isEmpty()) 169 results.setHostName(address.toString()); 170 results.setAddresses(QList<QHostAddress>() << address); 171 return results; 172 } 173 174 // IDN support 175 QByteArray aceHostname = QUrl::toAce(hostName); 176 results.setHostName(hostName); 177 if (aceHostname.isEmpty()) { 178 results.setError(QHostInfo::HostNotFound); 179 results.setErrorString(hostName.isEmpty() ? tr("No host name given") : tr("Invalid hostname")); 180 return results; 194 181 } 195 182 … … 199 186 // results. 200 187 qt_addrinfo *res; 201 int err = local_getaddrinfo( hostName.toLatin1().constData(), 0, 0, &res);188 int err = local_getaddrinfo(aceHostname.constData(), 0, 0, &res); 202 189 if (err == 0) { 203 190 QList<QHostAddress> addresses; … … 234 221 } else { 235 222 // Fall back to gethostbyname, which only supports IPv4. 236 hostent *ent = gethostbyname( hostName.toLatin1().constData());223 hostent *ent = gethostbyname(aceHostname.constData()); 237 224 if (ent) { 238 225 char **p; -
trunk/src/network/kernel/qnetworkinterface.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 129 129 if (i) 130 130 result += QLatin1Char(':'); 131 131 132 132 char buf[3]; 133 133 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && defined(_MSC_VER) && _MSC_VER >= 1400 … … 149 149 \since 4.2 150 150 \reentrant 151 \ingroup io151 \ingroup network 152 152 153 153 Each network interface can contain zero or more IP addresses, which … … 171 171 */ 172 172 QNetworkAddressEntry::QNetworkAddressEntry(const QNetworkAddressEntry &other) 173 : d(new QNetworkAddressEntryPrivate(*other.d ))173 : d(new QNetworkAddressEntryPrivate(*other.d.data())) 174 174 { 175 175 } … … 180 180 QNetworkAddressEntry &QNetworkAddressEntry::operator=(const QNetworkAddressEntry &other) 181 181 { 182 *d = *other.d;182 *d.data() = *other.d.data(); 183 183 return *this; 184 184 } … … 189 189 QNetworkAddressEntry::~QNetworkAddressEntry() 190 190 { 191 delete d;192 191 } 193 192 … … 334 333 \since 4.2 335 334 \reentrant 336 \ingroup io335 \ingroup network 337 336 338 337 QNetworkInterface represents one network interface attached to the … … 398 397 399 398 /*! 400 Creates a copy of the theQNetworkInterface object contained in \a399 Creates a copy of the QNetworkInterface object contained in \a 401 400 other. 402 401 */ … … 595 594 if (!entry.broadcast().isNull()) 596 595 debug.nospace() << ", broadcast = " << entry.broadcast(); 597 debug.nospace() << ")";596 debug.nospace() << ')'; 598 597 return debug.space(); 599 598 } … … 605 604 << ", flags = "; 606 605 flagsDebug(debug, networkInterface.flags()); 606 #if defined(Q_CC_RVCT) 607 // RVCT gets confused with << networkInterface.addressEntries(), reason unknown. 608 debug.nospace() << ")\n"; 609 #else 607 610 debug.nospace() << ", entries = " << networkInterface.addressEntries() 608 611 << ")\n"; 612 #endif 609 613 return debug.space(); 610 614 } -
trunk/src/network/kernel/qnetworkinterface.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 44 44 45 45 #include <QtCore/qshareddata.h> 46 #include <QtCore/qscopedpointer.h> 46 47 #include <QtNetwork/qhostaddress.h> 47 48 … … 80 81 81 82 private: 82 Q NetworkAddressEntryPrivate *d;83 QScopedPointer<QNetworkAddressEntryPrivate> d; 83 84 }; 84 85 -
trunk/src/network/kernel/qnetworkinterface_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** -
trunk/src/network/kernel/qnetworkinterface_unix.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 44 44 #include "qnetworkinterface_p.h" 45 45 #include "qalgorithms.h" 46 #include "private/qnet_unix_p.h" 46 47 47 48 #ifndef QT_NO_NETWORKINTERFACE … … 124 125 125 126 // get the interface list 126 if ( ::ioctl(socket, SIOCGIFCONF, &interfaceList) >= 0) {127 if (qt_safe_ioctl(socket, SIOCGIFCONF, &interfaceList) >= 0) { 127 128 if (int(interfaceList.ifc_len + sizeof(ifreq) + 64) < storageBuffer.size()) { 128 129 // if the buffer was big enough, break … … 199 200 // Get the canonical name 200 201 QByteArray oldName = req.ifr_name; 201 if ( ::ioctl(socket, SIOCGIFNAME, &req) >= 0) {202 if (qt_safe_ioctl(socket, SIOCGIFNAME, &req) >= 0) { 202 203 iface->name = QString::fromLatin1(req.ifr_name); 203 204 … … 212 213 213 214 // Get interface flags 214 if ( ::ioctl(socket, SIOCGIFFLAGS, &req) >= 0) {215 if (qt_safe_ioctl(socket, SIOCGIFFLAGS, &req) >= 0) { 215 216 iface->flags = convertFlags(req.ifr_flags); 216 217 } … … 218 219 #ifdef SIOCGIFHWADDR 219 220 // Get the HW address 220 if ( ::ioctl(socket, SIOCGIFHWADDR, &req) >= 0) {221 if (qt_safe_ioctl(socket, SIOCGIFHWADDR, &req) >= 0) { 221 222 uchar *addr = (uchar *)&req.ifr_addr; 222 223 iface->hardwareAddress = iface->makeHwAddress(6, addr); … … 233 234 234 235 int socket; 235 if ((socket = ::socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) == -1)236 if ((socket = qt_safe_socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) == -1) 236 237 return interfaces; // error 237 238 … … 248 249 QNetworkAddressEntry entry; 249 250 if (iface->flags & QNetworkInterface::CanBroadcast) { 250 if ( ::ioctl(socket, SIOCGIFBRDADDR, &req) >= 0) {251 if (qt_safe_ioctl(socket, SIOCGIFBRDADDR, &req) >= 0) { 251 252 sockaddr *sa = &req.ifr_addr; 252 253 if (sa->sa_family == AF_INET) … … 256 257 257 258 // Get the interface netmask 258 if ( ::ioctl(socket, SIOCGIFNETMASK, &req) >= 0) {259 if (qt_safe_ioctl(socket, SIOCGIFNETMASK, &req) >= 0) { 259 260 sockaddr *sa = &req.ifr_addr; 260 261 entry.setNetmask(addressFromSockaddr(sa)); … … 262 263 263 264 // Get the address of the interface 264 if ( ::ioctl(socket, SIOCGIFADDR, &req) >= 0) {265 if (qt_safe_ioctl(socket, SIOCGIFADDR, &req) >= 0) { 265 266 sockaddr *sa = &req.ifr_addr; 266 267 entry.setIp(addressFromSockaddr(sa)); … … 393 394 394 395 int socket; 395 if ((socket = ::socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) == -1)396 if ((socket = qt_safe_socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) == -1) 396 397 return interfaces; // error 397 398 -
trunk/src/network/kernel/qnetworkinterface_win.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 67 67 done = true; 68 68 69 HINSTANCE iphlpapiHnd; 70 QT_WA({ 71 iphlpapiHnd = LoadLibraryW(L"iphlpapi"); 72 }, { 73 iphlpapiHnd = LoadLibraryA("iphlpapi"); 74 }); 69 HINSTANCE iphlpapiHnd = LoadLibrary(L"iphlpapi"); 75 70 if (iphlpapiHnd == NULL) 76 return; // failed to load, probably Windows 9571 return; 77 72 78 73 #if defined(Q_OS_WINCE) 79 ptrGetAdaptersInfo = (PtrGetAdaptersInfo)GetProcAddress W(iphlpapiHnd, L"GetAdaptersInfo");80 ptrGetAdaptersAddresses = (PtrGetAdaptersAddresses)GetProcAddress W(iphlpapiHnd, L"GetAdaptersAddresses");81 ptrGetNetworkParams = (PtrGetNetworkParams)GetProcAddress W(iphlpapiHnd, L"GetNetworkParams");74 ptrGetAdaptersInfo = (PtrGetAdaptersInfo)GetProcAddress(iphlpapiHnd, L"GetAdaptersInfo"); 75 ptrGetAdaptersAddresses = (PtrGetAdaptersAddresses)GetProcAddress(iphlpapiHnd, L"GetAdaptersAddresses"); 76 ptrGetNetworkParams = (PtrGetNetworkParams)GetProcAddress(iphlpapiHnd, L"GetNetworkParams"); 82 77 #else 83 78 ptrGetAdaptersInfo = (PtrGetAdaptersInfo)GetProcAddress(iphlpapiHnd, "GetAdaptersInfo"); … … 116 111 // need more memory 117 112 pAdapter = (IP_ADAPTER_INFO *)qMalloc(bufSize); 113 if (!pAdapter) 114 return ipv4netmasks; 118 115 // try again 119 116 if (ptrGetAdaptersInfo(pAdapter, &bufSize) != ERROR_SUCCESS) { … … 157 154 // need more memory 158 155 pAdapter = (IP_ADAPTER_ADDRESSES *)qMalloc(bufSize); 159 156 if (!pAdapter) 157 return interfaces; 160 158 // try again 161 159 if (ptrGetAdaptersAddresses(AF_UNSPEC, flags, NULL, pAdapter, &bufSize) != ERROR_SUCCESS) { … … 237 235 // need more memory 238 236 pAdapter = (IP_ADAPTER_INFO *)qMalloc(bufSize); 239 237 if (!pAdapter) 238 return interfaces; 240 239 // try again 241 240 if (ptrGetAdaptersInfo(pAdapter, &bufSize) != ERROR_SUCCESS) { … … 307 306 if (ptrGetNetworkParams(pinfo, &bufSize) == ERROR_BUFFER_OVERFLOW) { 308 307 pinfo = (FIXED_INFO *)qMalloc(bufSize); 309 308 if (!pinfo) 309 return QString(); 310 310 // try again 311 311 if (ptrGetNetworkParams(pinfo, &bufSize) != ERROR_SUCCESS) { -
trunk/src/network/kernel/qnetworkinterface_win_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 55 55 56 56 #include <winsock2.h> 57 #include < windows.h>57 #include <qt_windows.h> 58 58 #include <time.h> 59 59 -
trunk/src/network/kernel/qnetworkproxy.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 49 49 50 50 \reentrant 51 \ingroup io51 \ingroup network 52 52 \inmodule QtNetwork 53 53 … … 55 55 proxy support to the Qt network classes. The currently supported 56 56 classes are QAbstractSocket, QTcpSocket, QUdpSocket, QTcpServer, 57 Q Http and QFtp. The proxy support is designed to be as transparent58 as possible. This means that existing network-enabled applications59 that you have written should automatically support network proxy60 using the following code.57 QNetworkAccessManager and QFtp. The proxy support is designed to 58 be as transparent as possible. This means that existing 59 network-enabled applications that you have written should 60 automatically support network proxy using the following code. 61 61 62 62 \snippet doc/src/snippets/code/src_network_kernel_qnetworkproxy.cpp 0 … … 87 87 The supported authentication methods are no authentication and 88 88 username/password authentication. Both IPv4 and IPv6 are 89 supported, but domain name resolution via the SOCKS server is not 90 supported; i.e. all domain names are resolved locally. There are 91 several things to remember when using SOCKS5 with QUdpSocket and 92 QTcpServer: 89 supported. Domain names are resolved through the SOCKS5 server if 90 the QNetworkProxy::HostNameLookupCapability is enabled, otherwise 91 they are resolved locally and the IP address is sent to the 92 server. There are several things to remember when using SOCKS5 93 with QUdpSocket and QTcpServer: 93 94 94 95 With QUdpSocket, a call to \l {QUdpSocket::bind()}{bind()} may fail … … 160 161 \o Caching-only HTTP 161 162 \o Implemented using normal HTTP commands, it is useful only 162 in the context of HTTP requests (see QHttp, 163 QNetworkAccessManager) 163 in the context of HTTP requests (see QNetworkAccessManager) 164 164 \o CachingCapability, HostNameLookupCapability 165 165 … … 221 221 #ifndef QT_NO_NETWORKPROXY 222 222 223 #include "private/qnetworkproxy_p.h" 223 224 #include "private/qsocks5socketengine_p.h" 224 225 #include "private/qhttpsocketengine_p.h" … … 324 325 } 325 326 326 Q_GLOBAL_STATIC(QGlobalNetworkProxy, globalNetworkProxy) ;327 Q_GLOBAL_STATIC(QGlobalNetworkProxy, globalNetworkProxy) 327 328 328 329 namespace { … … 366 367 }; 367 368 368 Q_ASSERT(int(type) >= 0 && int(type) <= int(QNetworkProxy::FtpCachingProxy)); 369 if (int(type) < 0 || int(type) > int(QNetworkProxy::FtpCachingProxy)) 370 type = QNetworkProxy::DefaultProxy; 369 371 return QNetworkProxy::Capabilities(defaults[int(type)]); 370 372 } … … 379 381 quint16 port; 380 382 QNetworkProxy::ProxyType type; 383 bool capabilitiesSet; 381 384 382 385 inline QNetworkProxyPrivate(QNetworkProxy::ProxyType t = QNetworkProxy::DefaultProxy, … … 388 391 capabilities(defaultCapabilitiesForType(t)), 389 392 port(p), 390 type(t) 393 type(t), 394 capabilitiesSet(false) 391 395 { } 392 396 … … 491 495 492 496 Note that changing the type of a proxy does not change 493 the set of capabilities this QNetworkProxy object holds. 497 the set of capabilities this QNetworkProxy object holds if any 498 capabilities have been set with setCapabilities(). 494 499 495 500 \sa type(), setCapabilities() … … 498 503 { 499 504 d->type = type; 505 if (!d->capabilitiesSet) 506 d->capabilities = defaultCapabilitiesForType(type); 500 507 } 501 508 … … 520 527 { 521 528 d->capabilities = capabilities; 529 d->capabilitiesSet = true; 522 530 } 523 531 … … 1112 1120 \since 4.5 1113 1121 1114 \ingroup io1122 \ingroup network 1115 1123 \inmodule QtNetwork 1116 1124 … … 1148 1156 QNetworkProxyFactory::~QNetworkProxyFactory() 1149 1157 { 1158 } 1159 1160 1161 /*! 1162 Enables the use of the platform-specific proxy settings, and only those. 1163 See systemProxyForQuery() for more information. 1164 1165 Internally, this method (when called with \a enable set to true) 1166 sets an application-wide proxy factory. For this reason, this method 1167 is mutually exclusive with setApplicationProxyFactory: calling 1168 setApplicationProxyFactory overrides the use of the system-wide proxy, 1169 and calling setUseSystemConfiguration overrides any 1170 application proxy or proxy factory that was previously set. 1171 1172 \since 4.6 1173 */ 1174 void QNetworkProxyFactory::setUseSystemConfiguration(bool enable) 1175 { 1176 if (enable) { 1177 setApplicationProxyFactory(new QSystemConfigurationProxyFactory); 1178 } else { 1179 setApplicationProxyFactory(0); 1180 } 1150 1181 } 1151 1182 … … 1251 1282 } 1252 1283 1284 QT_END_NAMESPACE 1285 1253 1286 #endif // QT_NO_NETWORKPROXY 1254 1255 QT_END_NAMESPACE -
trunk/src/network/kernel/qnetworkproxy.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 172 172 virtual QList<QNetworkProxy> queryProxy(const QNetworkProxyQuery &query = QNetworkProxyQuery()) = 0; 173 173 174 static void setUseSystemConfiguration(bool enable); 174 175 static void setApplicationProxyFactory(QNetworkProxyFactory *factory); 175 176 static QList<QNetworkProxy> proxyForQuery(const QNetworkProxyQuery &query); -
trunk/src/network/kernel/qnetworkproxy_generic.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** -
trunk/src/network/kernel/qnetworkproxy_mac.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 171 171 QString url = QCFString::toQString(pacUrl); 172 172 173 // ### Use PAC somehow 174 qDebug("Mac system proxy: found PAC script at \"%s\"", qPrintable(url)); 173 // ### TODO: Use PAC somehow 175 174 } 176 175 } -
trunk/src/network/kernel/qnetworkproxy_win.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 43 43 44 44 #ifndef QT_NO_NETWORKPROXY 45 46 #if defined(UNICODE)47 45 48 46 #include <qmutex.h> … … 52 50 53 51 #include <string.h> 54 #include < windows.h>52 #include <qt_windows.h> 55 53 #include <wininet.h> 56 54 … … 270 268 return; 271 269 initialized = true; 272 if (QSysInfo::windowsVersion() & QSysInfo::WV_DOS_based)273 return; // no point, this library is only available on 2k, XP and up274 270 275 271 #ifdef Q_OS_WINCE … … 278 274 #else 279 275 // load the winhttp.dll library 280 HINSTANCE winhttpHnd = LoadLibrary W(L"winhttp");276 HINSTANCE winhttpHnd = LoadLibrary(L"winhttp"); 281 277 if (!winhttpHnd) 282 278 return; // failed to load … … 296 292 } 297 293 if (ieProxyConfig.lpszProxy) { 298 proxyServerList << QString::fromWCharArray(ieProxyConfig.lpszProxy); 294 // http://msdn.microsoft.com/en-us/library/aa384250%28VS.85%29.aspx speaks only about a "proxy URL", 295 // not multiple URLs. However we tested this and it can return multiple URLs. So we use splitSpaceSemicolon 296 // on it. 297 proxyServerList = splitSpaceSemicolon(QString::fromWCharArray(ieProxyConfig.lpszProxy)); 299 298 GlobalFree(ieProxyConfig.lpszProxy); 300 299 } … … 368 367 WINHTTP_PROXY_INFO proxyInfo; 369 368 370 // try to get the proxy config for the URL , if we have a URL369 // try to get the proxy config for the URL 371 370 QUrl url = query.url(); 371 // url could be empty, e.g. from QNetworkProxy::applicationProxy(), that's fine, 372 // we'll still ask for the proxy. 373 // But for a file url, we know we don't need one. 374 if (url.scheme() == QLatin1String("file") || url.scheme() == QLatin1String("qrc")) 375 return sp->defaultResult; 372 376 if (query.queryType() != QNetworkProxyQuery::UrlRequest) { 373 377 // change the scheme to https, maybe it'll work … … 399 403 return sp->defaultResult; 400 404 401 returnparseServerList(query, sp->proxyServerList);402 } 403 404 #else // !UNICODE 405 406 QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkProxyQuery &) 407 { 408 return QList<QNetworkProxy>() << QNetworkProxy::NoProxy; 409 } 405 QList<QNetworkProxy> result = parseServerList(query, sp->proxyServerList); 406 // In some cases, this was empty. See SF task 00062670 407 if (result.isEmpty()) 408 return sp->defaultResult; 409 410 return result; 411 } 412 413 QT_END_NAMESPACE 410 414 411 415 #endif 412 413 QT_END_NAMESPACE414 415 #endif -
trunk/src/network/kernel/qurlinfo.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 86 86 87 87 \ingroup io 88 \ingroup misc88 \ingroup network 89 89 90 90 The information about a URL that can be retrieved includes name(), … … 216 216 /*! 217 217 Sets the name of the URL to \a name. The name is the full text, 218 for example, "http:// doc.trolltech.com/qurlinfo.html".218 for example, "http://qt.nokia.com/doc/qurlinfo.html". 219 219 220 220 If you call this function for an invalid URL info, this function … … 727 727 } 728 728 729 QT_END_NAMESPACE 730 729 731 #endif // QT_NO_URLINFO 730 731 QT_END_NAMESPACE -
trunk/src/network/kernel/qurlinfo.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** -
trunk/src/network/network.pro
r160 r561 7 7 QPRO_PWD = $$PWD 8 8 DEFINES += QT_BUILD_NETWORK_LIB QT_NO_USING_NAMESPACE 9 #DEFINES += QLOCALSERVER_DEBUG QLOCALSOCKET_DEBUG 10 #DEFINES += QNETWORKDISKCACHE_DEBUG 11 #DEFINES += QSSLSOCKET_DEBUG 12 #DEFINES += QHOSTINFO_DEBUG 13 #DEFINES += QABSTRACTSOCKET_DEBUG QNATIVESOCKETENGINE_DEBUG 14 #DEFINES += QTCPSOCKETENGINE_DEBUG QTCPSOCKET_DEBUG QTCPSERVER_DEBUG QSSLSOCKET_DEBUG 15 #DEFINES += QUDPSOCKET_DEBUG QUDPSERVER_DEBUG 9 16 QT = core 10 17 win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x64000000 … … 19 26 20 27 QMAKE_LIBS += $$QMAKE_LIBS_NETWORK 28 29 30 symbian { 31 TARGET.UID3=0x2001B2DE 32 LIBS += -lesock -linsock 33 } -
trunk/src/network/socket/qabstractsocket.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 49 49 50 50 \reentrant 51 \ingroup io51 \ingroup network 52 52 \inmodule QtNetwork 53 53 … … 100 100 write buffer size. You can monitor its size by listening to this 101 101 signal. 102 102 103 103 The readyRead() signal is emitted every time a new chunk of data 104 104 has arrived. bytesAvailable() then returns the number of bytes … … 161 161 is available before attempting to read it using operator>>(). 162 162 163 \sa QFtp, Q Http, QTcpServer163 \sa QFtp, QNetworkAccessManager, QTcpServer 164 164 */ 165 165 … … 200 200 201 201 QAbstractSocket::SocketError is not a registered metatype, so for queued 202 connections, you will have to register it with Q_REGISTER_METATYPE. 203 204 \sa error(), errorString() 202 connections, you will have to register it with Q_DECLARE_METATYPE() and 203 qRegisterMetaType(). 204 205 \sa error(), errorString(), {Creating Custom Qt Types} 205 206 */ 206 207 … … 212 213 213 214 QAbstractSocket::SocketState is not a registered metatype, so for queued 214 connections, you will have to register it with Q_REGISTER_METATYPE. 215 216 \sa state() 215 connections, you will have to register it with Q_REGISTER_METATYPE() and 216 qRegisterMetaType(). 217 218 \sa state(), {Creating Custom Qt Types} 217 219 */ 218 220 … … 331 333 */ 332 334 335 /*! 336 \enum QAbstractSocket::SocketOption 337 \since 4.6 338 339 This enum represents the options that can be set on a socket. 340 If desired, they can be set after having received the connected() signal from 341 the socket or after having received a new socket from a QTcpServer. 342 343 \value LowDelayOption Try to optimize the socket for low latency. For a QTcpSocket 344 this would set the TCP_NODELAY option and disable Nagle's algorithm. Set this to 1 345 to enable. 346 \value KeepAliveOption Set this to 1 to enable the SO_KEEPALIVE socket option 347 348 \sa QAbstractSocket::setSocketOption(), QAbstractSocket::socketOption() 349 */ 350 333 351 #include "qabstractsocket.h" 334 352 #include "qabstractsocket_p.h" … … 436 454 socketEngine(0), 437 455 cachedSocketDescriptor(-1), 456 #ifdef Q_OS_LINUX 457 addToBytesAvailable(0), 458 #endif 438 459 readBufferMaxSize(0), 439 460 readBuffer(QABSTRACTSOCKET_BUFFERSIZE), … … 442 463 blockingTimeout(30000), 443 464 connectTimer(0), 465 disconnectTimer(0), 444 466 connectTimeElapsed(0), 445 467 hostLookupId(-1), 468 socketType(QAbstractSocket::UnknownSocketType), 446 469 state(QAbstractSocket::UnconnectedState), 447 470 socketError(QAbstractSocket::UnknownSocketError) … … 476 499 cachedSocketDescriptor = -1; 477 500 } 478 if (connectTimer) {501 if (connectTimer) 479 502 connectTimer->stop(); 480 } 503 if (disconnectTimer) 504 disconnectTimer->stop(); 481 505 } 482 506 … … 648 672 if (socketEngine) { 649 673 #if defined (Q_OS_WIN) 650 651 674 if (!writeBuffer.isEmpty()) 675 socketEngine->setWriteNotificationEnabled(true); 652 676 #else 653 if (writeBuffer.isEmpty())654 677 if (writeBuffer.isEmpty() && socketEngine->bytesToWrite() == 0) 678 socketEngine->setWriteNotificationEnabled(false); 655 679 #endif 656 680 } … … 689 713 { 690 714 Q_Q(QAbstractSocket); 691 if (!socketEngine || !socketEngine->isValid() || writeBuffer.isEmpty()) { 715 if (!socketEngine || !socketEngine->isValid() || (writeBuffer.isEmpty() 716 && socketEngine->bytesToWrite() == 0)) { 692 717 #if defined (QABSTRACTSOCKET_DEBUG) 693 718 qDebug("QAbstractSocketPrivate::flush() nothing to do: valid ? %s, writeBuffer.isEmpty() ? %s", 694 719 socketEngine->isValid() ? "yes" : "no", writeBuffer.isEmpty() ? "yes" : "no"); 695 720 #endif 721 722 // this covers the case when the buffer was empty, but we had to wait for the socket engine to finish 723 if (state == QAbstractSocket::ClosingState) 724 q->disconnectFromHost(); 725 696 726 return false; 697 727 } … … 730 760 } 731 761 732 if (writeBuffer.isEmpty() && socketEngine && socketEngine->isWriteNotificationEnabled()) 762 if (writeBuffer.isEmpty() && socketEngine && socketEngine->isWriteNotificationEnabled() 763 && !socketEngine->bytesToWrite()) 733 764 socketEngine->setWriteNotificationEnabled(false); 734 765 if (state == QAbstractSocket::ClosingState) … … 851 882 s += addresses.at(i).toString(); 852 883 } 853 s += "}";884 s += '}'; 854 885 qDebug("QAbstractSocketPrivate::_q_startConnecting(hostInfo == %s)", s.toLatin1().constData()); 855 886 #endif … … 1052 1083 if (socketEngine) 1053 1084 socketEngine->setWriteNotificationEnabled(false); 1085 1054 1086 connectTimer->stop(); 1055 1087 … … 1062 1094 } else { 1063 1095 _q_connectToNextAddress(); 1096 } 1097 } 1098 1099 void QAbstractSocketPrivate::_q_forceDisconnect() 1100 { 1101 Q_Q(QAbstractSocket); 1102 if (socketEngine && socketEngine->isValid() && state == QAbstractSocket::ClosingState) { 1103 socketEngine->close(); 1104 q->disconnectFromHost(); 1064 1105 } 1065 1106 } … … 1128 1169 /*! \internal 1129 1170 1130 Sets up the theinternal state after the connection has succeeded.1171 Sets up the internal state after the connection has succeeded. 1131 1172 */ 1132 1173 void QAbstractSocketPrivate::fetchConnectionParameters() … … 1232 1273 \a hostName may be an IP address in string form (e.g., 1233 1274 "43.195.83.32"), or it may be a host name (e.g., 1234 " qtsoftware.com"). QAbstractSocket will do a lookup only if1275 "example.com"). QAbstractSocket will do a lookup only if 1235 1276 required. \a port is in native byte order. 1236 1277 … … 1264 1305 #endif 1265 1306 1266 if (d->state == ConnectedState || d->state == ConnectingState) { 1267 qWarning("QAbstractSocket::connectToHost() called when already connecting/connected to \"%s\"", qPrintable(hostName)); 1307 if (d->state == ConnectedState || d->state == ConnectingState 1308 || d->state == ClosingState || d->state == HostLookupState) { 1309 qWarning("QAbstractSocket::connectToHost() called when already looking up or connecting/connected to \"%s\"", qPrintable(hostName)); 1268 1310 return; 1269 1311 } … … 1547 1589 } 1548 1590 1591 /*! 1592 \since 4.6 1593 Sets the given \a option to the value described by \a value. 1594 1595 \sa socketOption() 1596 */ 1597 void QAbstractSocket::setSocketOption(QAbstractSocket::SocketOption option, const QVariant &value) 1598 { 1599 #ifndef QT_NO_OPENSSL 1600 if (QSslSocket *sslSocket = qobject_cast<QSslSocket*>(this)) { 1601 sslSocket->setSocketOption(option, value); 1602 return; 1603 } 1604 #endif 1605 1606 if (!d_func()->socketEngine) 1607 return; 1608 1609 switch (option) { 1610 case LowDelayOption: 1611 d_func()->socketEngine->setOption(QAbstractSocketEngine::LowDelayOption, value.toInt()); 1612 break; 1613 1614 case KeepAliveOption: 1615 d_func()->socketEngine->setOption(QAbstractSocketEngine::KeepAliveOption, value.toInt()); 1616 break; 1617 } 1618 } 1619 1620 /*! 1621 \since 4.6 1622 Returns the value of the \a option option. 1623 1624 \sa setSocketOption() 1625 */ 1626 QVariant QAbstractSocket::socketOption(QAbstractSocket::SocketOption option) 1627 { 1628 #ifndef QT_NO_OPENSSL 1629 if (QSslSocket *sslSocket = qobject_cast<QSslSocket*>(this)) { 1630 return sslSocket->socketOption(option); 1631 } 1632 #endif 1633 1634 if (!d_func()->socketEngine) 1635 return QVariant(); 1636 1637 int ret = -1; 1638 switch (option) { 1639 case LowDelayOption: 1640 ret = d_func()->socketEngine->option(QAbstractSocketEngine::LowDelayOption); 1641 break; 1642 1643 case KeepAliveOption: 1644 ret = d_func()->socketEngine->option(QAbstractSocketEngine::KeepAliveOption); 1645 break; 1646 } 1647 if (ret == -1) 1648 return QVariant(); 1649 else 1650 return QVariant(ret); 1651 } 1652 1653 1549 1654 /* 1550 1655 Returns the difference between msecs and elapsed. If msecs is -1, … … 1657 1762 1658 1763 /*! 1659 This function blocks until data is available for reading and the1764 This function blocks until new data is available for reading and the 1660 1765 \l{QIODevice::}{readyRead()} signal has been emitted. The function 1661 1766 will timeout after \a msecs milliseconds; the default timeout is … … 1663 1768 1664 1769 The function returns true if the readyRead() signal is emitted and 1665 there is data available for reading; otherwise it returns false1770 there is new data available for reading; otherwise it returns false 1666 1771 (if an error occurred or the operation timed out). 1667 1772 … … 1865 1970 1866 1971 /*! 1867 Aborts the current connection and resets the socket. Unlike 1868 disconnectFromHost(), this function immediately closes the socket, discarding1869 any pending data in thewrite buffer.1972 Aborts the current connection and resets the socket. Unlike disconnectFromHost(), 1973 this function immediately closes the socket, discarding any pending data in the 1974 write buffer. 1870 1975 1871 1976 \sa disconnectFromHost(), close() … … 2164 2269 2165 2270 /*! 2166 Disconnects the socket's connection with the host. 2271 Closes the I/O device for the socket, disconnects the socket's connection with the 2272 host, closes the socket, and resets the name, address, port number and underlying 2273 socket descriptor. 2274 2275 See QIODevice::close() for a description of the actions that occur when an I/O 2276 device is closed. 2167 2277 2168 2278 \sa abort() … … 2256 2366 2257 2367 // Wait for pending data to be written. 2258 if (d->socketEngine && d->socketEngine->isValid() && d->writeBuffer.size() > 0) { 2368 if (d->socketEngine && d->socketEngine->isValid() && (d->writeBuffer.size() > 0 2369 || d->socketEngine->bytesToWrite() > 0)) { 2370 // hack: when we are waiting for the socket engine to write bytes (only 2371 // possible when using Socks5 or HTTP socket engine), then close 2372 // anyway after 2 seconds. This is to prevent a timeout on Mac, where we 2373 // sometimes just did not get the write notifier from the underlying 2374 // CFSocket and no progress was made. 2375 if (d->writeBuffer.size() == 0 && d->socketEngine->bytesToWrite() > 0) { 2376 if (!d->disconnectTimer) { 2377 d->disconnectTimer = new QTimer(this); 2378 connect(d->disconnectTimer, SIGNAL(timeout()), this, 2379 SLOT(_q_forceDisconnect()), Qt::DirectConnection); 2380 } 2381 if (!d->disconnectTimer->isActive()) 2382 d->disconnectTimer->start(2000); 2383 } 2259 2384 d->socketEngine->setWriteNotificationEnabled(true); 2260 2385 … … 2457 2582 2458 2583 #ifdef QT3_SUPPORT 2459 /*! \enum QAbstractSocket::Error 2584 /*! 2585 \enum QAbstractSocket::Error 2460 2586 \compat 2461 2587 … … 2589 2715 break; 2590 2716 default: 2591 debug << "QAbstractSocket::SocketError(" << int(error) << ")";2717 debug << "QAbstractSocket::SocketError(" << int(error) << ')'; 2592 2718 break; 2593 2719 } … … 2620 2746 break; 2621 2747 default: 2622 debug << "QAbstractSocket::SocketState(" << int(state) << ")";2748 debug << "QAbstractSocket::SocketState(" << int(state) << ')'; 2623 2749 break; 2624 2750 } -
trunk/src/network/socket/qabstractsocket.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 117 117 #endif 118 118 }; 119 enum SocketOption { 120 LowDelayOption, // TCP_NODELAY 121 KeepAliveOption // SO_KEEPALIVE 122 }; 119 123 120 124 QAbstractSocket(SocketType socketType, QObject *parent); … … 149 153 bool setSocketDescriptor(int socketDescriptor, SocketState state = ConnectedState, 150 154 OpenMode openMode = ReadWrite); 155 156 // ### Qt 5: Make virtual? 157 void setSocketOption(QAbstractSocket::SocketOption option, const QVariant &value); 158 QVariant socketOption(QAbstractSocket::SocketOption option); 151 159 152 160 SocketType socketType() const; … … 209 217 Q_PRIVATE_SLOT(d_func(), void _q_abortConnectionAttempt()) 210 218 Q_PRIVATE_SLOT(d_func(), void _q_testConnection()) 219 Q_PRIVATE_SLOT(d_func(), void _q_forceDisconnect()) 211 220 212 221 #ifdef QT3_SUPPORT -
trunk/src/network/socket/qabstractsocket_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 48 48 // 49 49 // This file is not part of the Qt API. It exists for the convenience 50 // of the Q Libraryclass. This header file may change from50 // of the QAbstractSocket class. This header file may change from 51 51 // version to version without notice, or even be removed. 52 52 // … … 94 94 void _q_testConnection(); 95 95 void _q_abortConnectionAttempt(); 96 void _q_forceDisconnect(); 96 97 97 98 bool readSocketNotifierCalled; … … 149 150 150 151 QTimer *connectTimer; 152 QTimer *disconnectTimer; 151 153 int connectTimeElapsed; 152 154 -
trunk/src/network/socket/qabstractsocketengine.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** -
trunk/src/network/socket/qabstractsocketengine_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 93 93 AddressReusable, 94 94 BindExclusively, 95 ReceiveOutOfBandData 95 ReceiveOutOfBandData, 96 LowDelayOption, 97 KeepAliveOption 96 98 }; 97 99 … … 124 126 virtual qint64 pendingDatagramSize() const = 0; 125 127 #endif 128 129 virtual qint64 bytesToWrite() const = 0; 126 130 127 131 virtual int option(SocketOption option) const = 0; -
trunk/src/network/socket/qhttpsocketengine.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 277 277 #endif // QT_NO_UDPSOCKET 278 278 279 int QHttpSocketEngine::option(SocketOption) const 280 { 279 qint64 QHttpSocketEngine::bytesToWrite() const 280 { 281 Q_D(const QHttpSocketEngine); 282 if (d->socket) { 283 return d->socket->bytesToWrite(); 284 } else { 285 return 0; 286 } 287 } 288 289 int QHttpSocketEngine::option(SocketOption option) const 290 { 291 Q_D(const QHttpSocketEngine); 292 if (d->socket) { 293 // convert the enum and call the real socket 294 if (option == QAbstractSocketEngine::LowDelayOption) 295 return d->socket->socketOption(QAbstractSocket::LowDelayOption).toInt(); 296 if (option == QAbstractSocketEngine::KeepAliveOption) 297 return d->socket->socketOption(QAbstractSocket::KeepAliveOption).toInt(); 298 } 281 299 return -1; 282 300 } 283 301 284 bool QHttpSocketEngine::setOption(SocketOption, int) 285 { 302 bool QHttpSocketEngine::setOption(SocketOption option, int value) 303 { 304 Q_D(QHttpSocketEngine); 305 if (d->socket) { 306 // convert the enum and call the real socket 307 if (option == QAbstractSocketEngine::LowDelayOption) 308 d->socket->setSocketOption(QAbstractSocket::LowDelayOption, value); 309 if (option == QAbstractSocketEngine::KeepAliveOption) 310 d->socket->setSocketOption(QAbstractSocket::KeepAliveOption, value); 311 return true; 312 } 286 313 return false; 287 314 } … … 455 482 data += " HTTP/1.1\r\n"; 456 483 data += "Proxy-Connection: keep-alive\r\n" 484 "User-Agent: Mozilla/5.0\r\n" 457 485 "Host: " + peerAddress + "\r\n"; 458 486 QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(d->authenticator); … … 735 763 , writeNotificationPending(false) 736 764 , connectionNotificationPending(false) 765 , pendingResponseData(0) 737 766 { 738 767 socket = 0; … … 769 798 } 770 799 800 QT_END_NAMESPACE 801 771 802 #endif 772 773 QT_END_NAMESPACE -
trunk/src/network/socket/qhttpsocketengine_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 110 110 qint64 pendingDatagramSize() const; 111 111 #endif // QT_NO_UDPSOCKET 112 113 qint64 bytesToWrite() const; 112 114 113 115 int option(SocketOption option) const; -
trunk/src/network/socket/qlocalserver.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 78 78 to use it without one. In that case, you must use waitForNewConnection(), 79 79 which blocks until either a connection is available or a timeout expires. 80 81 Note that this feature is not supported on Windows 9x.82 80 83 81 \sa QLocalSocket, QTcpServer … … 277 275 return 0; 278 276 QLocalSocket *nextSocket = d->pendingConnections.dequeue(); 277 #ifdef Q_OS_SYMBIAN 278 if(!d->socketNotifier) 279 return nextSocket; 280 #endif 281 #ifndef QT_LOCALSOCKET_TCP 282 if (d->pendingConnections.size() <= d->maxPendingConnections) 279 283 #ifndef Q_OS_WIN 280 d->socketNotifier->setEnabled(d->pendingConnections.size() 281 <= d->maxPendingConnections); 284 d->socketNotifier->setEnabled(true); 285 #else 286 d->connectionEventNotifier->setEnabled(true); 287 #endif 282 288 #endif 283 289 return nextSocket; -
trunk/src/network/socket/qlocalserver.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 87 87 private: 88 88 Q_DISABLE_COPY(QLocalServer) 89 #if defined(QT_LOCALSOCKET_TCP)90 89 Q_PRIVATE_SLOT(d_func(), void _q_onNewConnection()) 91 #elif defined(Q_OS_WIN)92 Q_PRIVATE_SLOT(d_func(), void _q_openSocket(HANDLE handle))93 Q_PRIVATE_SLOT(d_func(), void _q_stoppedListening())94 Q_PRIVATE_SLOT(d_func(), void _q_setError(QAbstractSocket::SocketError error, const QString &errorString))95 #else96 Q_PRIVATE_SLOT(d_func(), void _q_socketActivated())97 #endif98 90 }; 99 91 -
trunk/src/network/socket/qlocalserver_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 64 64 #elif defined(Q_OS_WIN) 65 65 # include <qt_windows.h> 66 # include < qthread.h>66 # include <private/qwineventnotifier_p.h> 67 67 #else 68 68 # include <private/qnativesocketengine_p.h> … … 72 72 QT_BEGIN_NAMESPACE 73 73 74 #if defined(Q_OS_WIN) && !defined(QT_LOCALSOCKET_TCP)75 76 /*!77 \internal78 QLocalServerThread exists because Windows does not have a79 way to provide notifications when there is a new connections to80 the server.81 */82 class QLocalServerThread : public QThread83 {84 Q_OBJECT85 86 Q_SIGNALS:87 void connected(HANDLE newSocket);88 void error(QAbstractSocket::SocketError error, const QString &errorString);89 90 public:91 QLocalServerThread(QObject *parent = 0);92 ~QLocalServerThread();93 void closeServer();94 95 public:96 QString setName(const QString &name);97 void run();98 void stop();99 bool makeHandle();100 101 HANDLE gotConnectionEvent;102 QQueue<HANDLE> pendingHandles;103 int maxPendingConnections;104 private:105 HANDLE stopEvent;106 QString fullServerName;107 };108 109 #endif110 111 74 class QLocalServerPrivate : public QObjectPrivate 112 75 { … … 115 78 public: 116 79 QLocalServerPrivate() : 117 #if defined(Q_OS_WIN) && !defined(QT_LOCALSOCKET_TCP) 118 inWaitingFunction(false), 119 #elif !defined(QT_LOCALSOCKET_TCP) 80 #if !defined(QT_LOCALSOCKET_TCP) && !defined(Q_OS_WIN) 120 81 listenSocket(-1), socketNotifier(0), 121 82 #endif … … 129 90 void closeServer(); 130 91 void waitForNewConnection(int msec, bool *timedOut); 92 void _q_onNewConnection(); 131 93 132 94 #if defined(QT_LOCALSOCKET_TCP) 133 void _q_onNewConnection();134 95 135 96 QTcpServer tcpServer; 136 97 QMap<quintptr, QTcpSocket*> socketMap; 137 98 #elif defined(Q_OS_WIN) 138 void _q_openSocket(HANDLE socket); 139 void _q_stoppedListening(); 140 void _q_setError(QAbstractSocket::SocketError error, const QString &errorString); 99 struct Listener { 100 HANDLE handle; 101 OVERLAPPED overlapped; 102 }; 141 103 142 QLocalServerThread waitForConnection; 143 bool inWaitingFunction; 104 void setError(const QString &function); 105 bool addListener(); 106 107 QList<Listener> listeners; 108 HANDLE eventHandle; 109 QWinEventNotifier *connectionEventNotifier; 144 110 #else 145 111 void setError(const QString &function); 146 void _q_socketActivated();147 112 148 113 int listenSocket; -
trunk/src/network/socket/qlocalserver_tcp.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 93 93 if (pendingConnections.isEmpty()) 94 94 tcpServer.waitForNewConnection(msec, timedOut); 95 else 95 else if (timedOut) 96 96 *timedOut = false; 97 97 } -
trunk/src/network/socket/qlocalserver_unix.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 44 44 #include "qlocalsocket.h" 45 45 #include "qlocalsocket_p.h" 46 #include "qnet_unix_p.h" 46 47 47 48 #ifndef QT_NO_LOCALSERVER … … 53 54 #include <qdir.h> 54 55 #include <qdatetime.h> 56 57 #ifdef Q_OS_VXWORKS 58 # include <selectLib.h> 59 #endif 55 60 56 61 QT_BEGIN_NAMESPACE … … 89 94 90 95 // create the unix socket 91 listenSocket = q Socket(PF_UNIX, SOCK_STREAM, 0);96 listenSocket = qt_safe_socket(PF_UNIX, SOCK_STREAM, 0); 92 97 if (-1 == listenSocket) { 93 98 setError(QLatin1String("QLocalServer::listen")); … … 107 112 fullServerName.toLatin1().size() + 1); 108 113 114 #ifdef Q_OS_SYMBIAN 115 // In SYMBIAN OS it can currently happen that accept is called twice, 116 // once from waitForNewConnection and once via QSocketNotfier activity 117 // 118 // As an workaround, we set the socket to non blocking so possible 119 // subsequent call to accept will not block in any case 120 // 121 // This change can be removed once more generic fix to select thread 122 // syncronization problem is implemented. 123 int flags = fcntl(listenSocket, F_GETFL, 0); 124 if (-1 == flags 125 || -1 == (fcntl(listenSocket, F_SETFL, flags | O_NONBLOCK))) { 126 setError(QLatin1String("QLocalServer::listen")); 127 closeServer(); 128 return false; 129 } 130 #endif 131 109 132 // bind 110 if(-1 == qBind(listenSocket, (sockaddr *)&addr, sizeof(sockaddr_un))) {133 if(-1 == QT_SOCKET_BIND(listenSocket, (sockaddr *)&addr, sizeof(sockaddr_un))) { 111 134 setError(QLatin1String("QLocalServer::listen")); 112 135 // if address is in use already, just close the socket, but do not delete the file … … 121 144 122 145 // listen for connections 123 if (-1 == q Listen(listenSocket, 50)) {146 if (-1 == qt_safe_listen(listenSocket, 50)) { 124 147 setError(QLatin1String("QLocalServer::listen")); 125 148 closeServer(); … … 133 156 QSocketNotifier::Read, q); 134 157 q->connect(socketNotifier, SIGNAL(activated(int)), 135 q, SLOT(_q_ socketActivated()));158 q, SLOT(_q_onNewConnection())); 136 159 socketNotifier->setEnabled(maxPendingConnections > 0); 137 160 return true; … … 149 172 listenSocket = -1; 150 173 151 if (socketNotifier) 174 if (socketNotifier) { 175 socketNotifier->setEnabled(false); // Otherwise, closed socket is checked before deleter runs 152 176 socketNotifier->deleteLater(); 153 socketNotifier = 0; 177 socketNotifier = 0; 178 } 154 179 155 180 if (!fullServerName.isEmpty()) … … 163 188 Accept the new socket. 164 189 */ 165 void QLocalServerPrivate::_q_ socketActivated()190 void QLocalServerPrivate::_q_onNewConnection() 166 191 { 167 192 Q_Q(QLocalServer); … … 171 196 ::sockaddr_un addr; 172 197 QT_SOCKLEN_T length = sizeof(sockaddr_un); 173 int connectedSocket = q Accept(listenSocket, (sockaddr *)&addr, &length);198 int connectedSocket = qt_safe_accept(listenSocket, (sockaddr *)&addr, &length); 174 199 if(-1 == connectedSocket) { 175 200 setError(QLatin1String("QLocalSocket::activated")); … … 192 217 timeout.tv_usec = (msec % 1000) * 1000; 193 218 194 // timeout can not be 0 or else select will return an error.195 if (0 == msec)196 timeout.tv_usec = 1000;197 198 219 int result = -1; 199 // on Linux timeout will be updated by select, but _not_ on other systems. 200 QTime timer; 201 timer.start(); 202 while (pendingConnections.isEmpty() && (-1 == msec || timer.elapsed() < msec)) { 203 result = ::select(listenSocket + 1, &readfds, 0, 0, &timeout); 204 if (-1 == result && errno != EINTR) { 205 setError(QLatin1String("QLocalServer::waitForNewConnection")); 206 closeServer(); 207 break; 208 } 209 if (result > 0) 210 _q_socketActivated(); 211 } 220 result = qt_safe_select(listenSocket + 1, &readfds, 0, 0, (msec == -1) ? 0 : &timeout); 221 if (-1 == result) { 222 setError(QLatin1String("QLocalServer::waitForNewConnection")); 223 closeServer(); 224 } 225 if (result > 0) 226 _q_onNewConnection(); 212 227 if (timedOut) 213 228 *timedOut = (result == 0); -
trunk/src/network/socket/qlocalserver_win.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 45 45 46 46 #include <qdebug.h> 47 #include <qdatetime.h>48 #include <qcoreapplication.h>49 #include <QMetaType>50 47 51 48 // The buffer size need to be 0 otherwise data could be … … 54 51 #define BUFSIZE 0 55 52 53 // ###: This should be a property. Should replace the insane 50 on unix as well. 54 #define SYSTEM_MAX_PENDING_SOCKETS 8 55 56 56 QT_BEGIN_NAMESPACE 57 57 58 QLocalServerThread::QLocalServerThread(QObject *parent) : QThread(parent), 59 maxPendingConnections(1) 60 { 61 stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 62 gotConnectionEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 63 } 64 65 QLocalServerThread::~QLocalServerThread() 66 { 67 stop(); 68 closeServer(); 69 CloseHandle(stopEvent); 70 CloseHandle(gotConnectionEvent); 71 } 72 73 void QLocalServerThread::stop() 74 { 75 if (isRunning()) { 76 SetEvent(stopEvent); 77 wait(); 78 ResetEvent(stopEvent); 79 } 80 } 81 82 void QLocalServerThread::closeServer() 83 { 84 while (!pendingHandles.isEmpty()) 85 CloseHandle(pendingHandles.dequeue()); 86 } 87 88 QString QLocalServerThread::setName(const QString &name) 89 { 90 QString pipePath = QLatin1String("\\\\.\\pipe\\"); 91 if (name.startsWith(pipePath)) 92 fullServerName = name; 93 else 94 fullServerName = pipePath + name; 95 for (int i = pendingHandles.count(); i < maxPendingConnections; ++i) 96 if (!makeHandle()) 97 break; 98 return fullServerName; 99 } 100 101 bool QLocalServerThread::makeHandle() 102 { 103 if (pendingHandles.count() >= maxPendingConnections) 104 return false; 105 106 HANDLE handle = INVALID_HANDLE_VALUE; 107 QT_WA({ 108 handle = CreateNamedPipeW( 109 (TCHAR*)fullServerName.utf16(), // pipe name 58 bool QLocalServerPrivate::addListener() 59 { 60 // The object must not change its address once the 61 // contained OVERLAPPED struct is passed to Windows. 62 listeners << Listener(); 63 Listener &listener = listeners.last(); 64 65 listener.handle = CreateNamedPipe( 66 (const wchar_t *)fullServerName.utf16(), // pipe name 110 67 PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, // read/write access 111 68 PIPE_TYPE_MESSAGE | // message type pipe … … 117 74 3000, // client time-out 118 75 NULL); 119 }, { 120 handle = CreateNamedPipeA( 121 fullServerName.toLocal8Bit().constData(), // pipe name 122 PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, // read/write access 123 PIPE_TYPE_MESSAGE | // message type pipe 124 PIPE_READMODE_MESSAGE | // message-read mode 125 PIPE_WAIT, // blocking mode 126 PIPE_UNLIMITED_INSTANCES, // max. instances 127 BUFSIZE, // output buffer size 128 BUFSIZE, // input buffer size 129 3000, // client time-out 130 NULL); 131 }); 132 133 if (INVALID_HANDLE_VALUE == handle) { 76 77 if (listener.handle == INVALID_HANDLE_VALUE) { 78 setError(QLatin1String("QLocalServerPrivate::addListener")); 79 listeners.removeLast(); 134 80 return false; 135 81 } 136 pendingHandles.enqueue(handle); 82 83 memset(&listener.overlapped, 0, sizeof(listener.overlapped)); 84 listener.overlapped.hEvent = eventHandle; 85 if (!ConnectNamedPipe(listener.handle, &listener.overlapped)) { 86 switch (GetLastError()) { 87 case ERROR_IO_PENDING: 88 break; 89 case ERROR_PIPE_CONNECTED: 90 SetEvent(eventHandle); 91 break; 92 default: 93 CloseHandle(listener.handle); 94 setError(QLatin1String("QLocalServerPrivate::addListener")); 95 listeners.removeLast(); 96 return false; 97 } 98 } else { 99 Q_ASSERT_X(false, "QLocalServerPrivate::addListener", "The impossible happened"); 100 SetEvent(eventHandle); 101 } 137 102 return true; 138 103 } 139 104 140 void QLocalServerThread::run() 141 { 142 OVERLAPPED op; 143 HANDLE handleArray[2]; 144 memset(&op, 0, sizeof(op)); 145 handleArray[0] = op.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 146 handleArray[1] = stopEvent; 147 HANDLE handle = INVALID_HANDLE_VALUE; 148 149 forever { 150 if (INVALID_HANDLE_VALUE == handle) { 151 makeHandle(); 152 if (!pendingHandles.isEmpty()) 153 handle = pendingHandles.dequeue(); 154 } 155 if (INVALID_HANDLE_VALUE == handle) { 156 int windowsError = GetLastError(); 157 QString function = QLatin1String("QLocalServer::run"); 158 QString errorString = QLocalServer::tr("%1: Unknown error %2").arg(function).arg(windowsError); 159 emit error(QAbstractSocket::UnknownSocketError, errorString); 160 CloseHandle(handleArray[0]); 161 SetEvent(gotConnectionEvent); 162 return; 163 } 164 165 BOOL isConnected = ConnectNamedPipe(handle, &op) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED); 166 if (!isConnected) { 167 switch (WaitForMultipleObjects(2, handleArray, FALSE, INFINITE)) 168 { 169 case WAIT_OBJECT_0 + 1: 170 CloseHandle(handle); 171 CloseHandle(handleArray[0]); 105 void QLocalServerPrivate::setError(const QString &function) 106 { 107 int windowsError = GetLastError(); 108 errorString = QString::fromLatin1("%1: %2").arg(function).arg(qt_error_string(windowsError)); 109 error = QAbstractSocket::UnknownSocketError; 110 } 111 112 void QLocalServerPrivate::init() 113 { 114 } 115 116 bool QLocalServerPrivate::removeServer(const QString &name) 117 { 118 Q_UNUSED(name); 119 return true; 120 } 121 122 bool QLocalServerPrivate::listen(const QString &name) 123 { 124 Q_Q(QLocalServer); 125 126 QString pipePath = QLatin1String("\\\\.\\pipe\\"); 127 if (name.startsWith(pipePath)) 128 fullServerName = name; 129 else 130 fullServerName = pipePath + name; 131 132 // Use only one event for all listeners of one socket. 133 // The idea is that listener events are rare, so polling all listeners once in a while is 134 // cheap compared to waiting for N additional events in each iteration of the main loop. 135 eventHandle = CreateEvent(NULL, TRUE, FALSE, NULL); 136 connectionEventNotifier = new QWinEventNotifier(eventHandle , q); 137 q->connect(connectionEventNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_onNewConnection())); 138 139 for (int i = 0; i < SYSTEM_MAX_PENDING_SOCKETS; ++i) 140 if (!addListener()) 141 return false; 142 return true; 143 } 144 145 void QLocalServerPrivate::_q_onNewConnection() 146 { 147 Q_Q(QLocalServer); 148 DWORD dummy; 149 150 // Reset first, otherwise we could reset an event which was asserted 151 // immediately after we checked the conn status. 152 ResetEvent(eventHandle); 153 154 // Testing shows that there is indeed absolutely no guarantee which listener gets 155 // a client connection first, so there is no way around polling all of them. 156 for (int i = 0; i < listeners.size(); ) { 157 HANDLE handle = listeners[i].handle; 158 if (GetOverlappedResult(handle, &listeners[i].overlapped, &dummy, FALSE)) { 159 listeners.removeAt(i); 160 161 addListener(); 162 163 if (pendingConnections.size() > maxPendingConnections) 164 connectionEventNotifier->setEnabled(false); 165 166 // Make this the last thing so connected slots can wreak the least havoc 167 q->incomingConnection((quintptr)handle); 168 } else { 169 if (GetLastError() != ERROR_IO_INCOMPLETE) { 170 setError(QLatin1String("QLocalServerPrivate::_q_onNewConnection")); 171 closeServer(); 172 172 return; 173 173 } 174 175 ++i; 174 176 } 175 emit connected(handle); 176 handle = INVALID_HANDLE_VALUE; 177 ResetEvent(handleArray[0]); 178 SetEvent(gotConnectionEvent); 179 } 180 } 181 182 void QLocalServerPrivate::init() 183 { 184 Q_Q(QLocalServer); 185 qRegisterMetaType<HANDLE>("HANDLE"); 186 q->connect(&waitForConnection, SIGNAL(connected(HANDLE)), 187 q, SLOT(_q_openSocket(HANDLE)), Qt::QueuedConnection); 188 q->connect(&waitForConnection, SIGNAL(finished()), 189 q, SLOT(_q_stoppedListening()), Qt::QueuedConnection); 190 q->connect(&waitForConnection, SIGNAL(terminated()), 191 q, SLOT(_q_stoppedListening()), Qt::QueuedConnection); 192 q->connect(&waitForConnection, SIGNAL(error(QAbstractSocket::SocketError, const QString &)), 193 q, SLOT(_q_setError(QAbstractSocket::SocketError, const QString &))); 194 } 195 196 bool QLocalServerPrivate::removeServer(const QString &name) 197 { 198 Q_UNUSED(name); 199 return true; 200 } 201 202 bool QLocalServerPrivate::listen(const QString &name) 203 { 204 fullServerName = waitForConnection.setName(name); 205 serverName = name; 206 waitForConnection.start(); 207 return true; 208 } 209 210 void QLocalServerPrivate::_q_setError(QAbstractSocket::SocketError e, const QString &eString) 211 { 212 error = e; 213 errorString = eString; 214 } 215 216 void QLocalServerPrivate::_q_stoppedListening() 217 { 218 Q_Q(QLocalServer); 219 if (!inWaitingFunction) 220 q->close(); 221 } 222 223 void QLocalServerPrivate::_q_openSocket(HANDLE handle) 224 { 225 Q_Q(QLocalServer); 226 q->incomingConnection((int)handle); 177 } 227 178 } 228 179 229 180 void QLocalServerPrivate::closeServer() 230 181 { 231 waitForConnection.stop(); 232 waitForConnection.closeServer(); 182 connectionEventNotifier->setEnabled(false); // Otherwise, closed handle is checked before deleter runs 183 connectionEventNotifier->deleteLater(); 184 connectionEventNotifier = 0; 185 CloseHandle(eventHandle); 186 for (int i = 0; i < listeners.size(); ++i) 187 CloseHandle(listeners[i].handle); 188 listeners.clear(); 233 189 } 234 190 … … 239 195 return; 240 196 241 DWORD result = WaitForSingleObject(waitForConnection.gotConnectionEvent, 242 (msecs == -1) ? INFINITE : msecs); 197 DWORD result = WaitForSingleObject(eventHandle, (msecs == -1) ? INFINITE : msecs); 243 198 if (result == WAIT_TIMEOUT) { 244 199 if (timedOut) 245 200 *timedOut = true; 246 201 } else { 247 ResetEvent(waitForConnection.gotConnectionEvent); 248 QCoreApplication::instance()->processEvents(); 202 _q_onNewConnection(); 249 203 } 250 204 } -
trunk/src/network/socket/qlocalsocket.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 64 64 which blocks until the operation is complete or the timeout expires. 65 65 66 Note that this feature is not supported on Window 9x. 66 Note that this feature is not supported on versions of Windows earlier than 67 Windows XP. 67 68 68 69 \sa QLocalServer … … 103 104 specified by \a socketState. 104 105 105 Note:It is not possible to initialize two local sockets with the same106 \note It is not possible to initialize two local sockets with the same 106 107 native socket descriptor. 107 108 … … 208 209 returns false. 209 210 210 Note:The socket's state must be ConnectedState before reading211 \note The socket's state must be ConnectedState before reading 211 212 and writing can occur. 212 213 213 \sa state() 214 \sa state(), connectToServer() 214 215 */ 215 216 … … 244 245 245 246 /*! 246 \fn bool QLocalSocket::waitForConnected(int msec )247 248 Waits until the socket is connected, up to \a msec milliseconds. If the247 \fn bool QLocalSocket::waitForConnected(int msecs) 248 249 Waits until the socket is connected, up to \a msecs milliseconds. If the 249 250 connection has been established, this function returns true; otherwise 250 251 it returns false. In the case where it returns false, you can call … … 256 257 \snippet doc/src/snippets/code/src_network_socket_qlocalsocket_unix.cpp 0 257 258 258 If msecs is -1, this function will not time out.259 If \a msecs is -1, this function will not time out. 259 260 260 261 \sa connectToServer(), connected() … … 275 276 \snippet doc/src/snippets/code/src_network_socket_qlocalsocket_unix.cpp 1 276 277 277 If msecs is -1, this function will not time out.278 If \a msecs is -1, this function will not time out. 278 279 279 280 \sa disconnectFromServer(), close() … … 310 311 311 312 QLocalSocket::LocalSocketError is not a registered metatype, so for queued 312 connections, you will have to register it with Q_DECLARE_METATYPE. 313 314 \sa error(), errorString() 313 connections, you will have to register it with Q_DECLARE_METATYPE() and 314 qRegisterMetaType(). 315 316 \sa error(), errorString(), {Creating Custom Qt Types} 315 317 */ 316 318 … … 322 324 323 325 QLocalSocket::SocketState is not a registered metatype, so for queued 324 connections, you will have to register it with Q_DECLARE_METATYPE. 325 326 \sa state() 326 connections, you will have to register it with Q_DECLARE_METATYPE() and 327 qRegisterMetaType(). 328 329 \sa state(), {Creating Custom Qt Types} 327 330 */ 328 331 … … 366 369 Returns the server path that the socket is connected to. 367 370 368 Note: This is platform specific371 \note The return value of this function is platform specific. 369 372 370 373 \sa connectToServer(), serverName() … … 469 472 break; 470 473 default: 471 debug << "QLocalSocket::SocketError(" << int(error) << ")";474 debug << "QLocalSocket::SocketError(" << int(error) << ')'; 472 475 break; 473 476 } … … 491 494 break; 492 495 default: 493 debug << "QLocalSocket::SocketState(" << int(state) << ")";496 debug << "QLocalSocket::SocketState(" << int(state) << ')'; 494 497 break; 495 498 } -
trunk/src/network/socket/qlocalsocket.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 135 135 Q_PRIVATE_SLOT(d_func(), void _q_canWrite()) 136 136 Q_PRIVATE_SLOT(d_func(), void _q_pipeClosed()) 137 Q_PRIVATE_SLOT(d_func(), void _q_emitReadyRead()) 137 138 #else 138 139 Q_PRIVATE_SLOT(d_func(), void _q_stateChanged(QAbstractSocket::SocketState)) -
trunk/src/network/socket/qlocalsocket_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 66 66 # include "private/qwindowspipewriter_p.h" 67 67 # include "private/qringbuffer_p.h" 68 # include <private/qwineventnotifier_p.h> 68 69 #else 69 70 # include "private/qnativesocketengine_p.h" … … 74 75 75 76 QT_BEGIN_NAMESPACE 76 77 #if !defined(Q_OS_WIN) && !defined(QT_LOCALSOCKET_TCP)78 static inline int qSocket(int af, int socketype, int proto)79 {80 int ret;81 while((ret = qt_socket_socket(af, socketype, proto)) == -1 && errno == EINTR){}82 return ret;83 }84 85 static inline int qBind(int fd, const sockaddr *sa, int len)86 {87 int ret;88 while((ret = QT_SOCKET_BIND(fd, (sockaddr*)sa, len)) == -1 && errno == EINTR){}89 return ret;90 }91 92 static inline int qConnect(int fd, const sockaddr *sa, int len)93 {94 int ret;95 while((ret = QT_SOCKET_CONNECT(fd, (sockaddr*)sa, len)) == -1 && errno == EINTR){}96 return ret;97 }98 99 static inline int qListen(int fd, int backlog)100 {101 int ret;102 while((ret = qt_socket_listen(fd, backlog)) == -1 && errno == EINTR){}103 return ret;104 }105 106 static inline int qAccept(int fd, struct sockaddr *addr, QT_SOCKLEN_T *addrlen)107 {108 int ret;109 while((ret = qt_socket_accept(fd, addr, addrlen)) == -1 && errno == EINTR){}110 return ret;111 }112 #endif //#if !defined(Q_OS_WIN) && !defined(QT_LOCALSOCKET_TCP)113 77 114 78 #if !defined(Q_OS_WIN) || defined(QT_LOCALSOCKET_TCP) … … 173 137 void _q_canWrite(); 174 138 void _q_pipeClosed(); 175 qint64 readData(char *data, qint64 maxSize); 176 qint64 bytesAvailable(); 177 bool readFromSocket(); 139 void _q_emitReadyRead(); 140 DWORD bytesAvailable(); 141 void startAsyncRead(); 142 bool completeAsyncRead(); 143 void checkReadyRead(); 178 144 HANDLE handle; 179 145 OVERLAPPED overlapped; … … 181 147 qint64 readBufferMaxSize; 182 148 QRingBuffer readBuffer; 183 QTimer dataNotifier; 149 int actualReadBufferSize; 150 QWinEventNotifier *dataReadNotifier; 184 151 QLocalSocket::LocalSocketError error; 185 bool readyReadEmitted; 152 bool readSequenceStarted; 153 bool pendingReadyRead; 186 154 bool pipeClosed; 155 static const qint64 initialReadBufferSize = 4096; 187 156 #else 188 157 QLocalUnixSocket unixSocket; … … 193 162 void _q_connectToSocket(); 194 163 void _q_abortConnectionAttempt(); 164 void cancelDelayedConnect(); 195 165 QSocketNotifier *delayConnect; 196 166 QTimer *connectTimer; -
trunk/src/network/socket/qlocalsocket_tcp.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** -
trunk/src/network/socket/qlocalsocket_unix.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 42 42 #include "qlocalsocket.h" 43 43 #include "qlocalsocket_p.h" 44 #include "qnet_unix_p.h" 44 45 45 46 #ifndef QT_NO_LOCALSOCKET … … 55 56 #include <qdir.h> 56 57 #include <qdebug.h> 58 59 #ifdef Q_OS_VXWORKS 60 # include <selectLib.h> 61 #endif 57 62 58 63 #define QT_CONNECT_TIMEOUT 30000 … … 233 238 234 239 // create the socket 235 if (-1 == (d->connectingSocket = q Socket(PF_UNIX, SOCK_STREAM, 0))) {240 if (-1 == (d->connectingSocket = qt_safe_socket(PF_UNIX, SOCK_STREAM, 0))) { 236 241 d->errorOccurred(UnsupportedSocketOperationError, 237 242 QLatin1String("QLocalSocket::connectToServer")); 238 243 return; 239 244 } 240 245 #ifndef Q_OS_SYMBIAN 241 246 // set non blocking so we can try to connect and it wont wait 242 247 int flags = fcntl(d->connectingSocket, F_GETFL, 0); … … 247 252 return; 248 253 } 254 #endif 249 255 250 256 // _q_connectToSocket does the actual connecting … … 283 289 ::memcpy(name.sun_path, connectingPathName.toLatin1().data(), 284 290 connectingPathName.toLatin1().size() + 1); 285 if (-1 == q Connect(connectingSocket, (struct sockaddr *)&name, sizeof(name))) {291 if (-1 == qt_safe_connect(connectingSocket, (struct sockaddr *)&name, sizeof(name))) { 286 292 QString function = QLatin1String("QLocalSocket::connectToServer"); 287 293 switch (errno) … … 304 310 // Try again later, all of the sockets listening are full 305 311 if (!delayConnect) { 306 delayConnect = new QSocketNotifier(connectingSocket, QSocketNotifier::Write );312 delayConnect = new QSocketNotifier(connectingSocket, QSocketNotifier::Write, q); 307 313 q->connect(delayConnect, SIGNAL(activated(int)), q, SLOT(_q_connectToSocket())); 308 314 } … … 323 329 324 330 // connected! 325 if (delayConnect) { 326 delayConnect->setEnabled(false); 327 delete delayConnect; 328 delayConnect = 0; 329 } 331 cancelDelayedConnect(); 332 330 333 serverName = connectingName; 331 334 fullServerName = connectingPathName; … … 374 377 } 375 378 379 void QLocalSocketPrivate::cancelDelayedConnect() 380 { 381 if (delayConnect) { 382 delayConnect->setEnabled(false); 383 delete delayConnect; 384 delayConnect = 0; 385 connectTimer->stop(); 386 delete connectTimer; 387 connectTimer = 0; 388 } 389 } 390 376 391 quintptr QLocalSocket::socketDescriptor() const 377 392 { … … 420 435 Q_D(QLocalSocket); 421 436 d->unixSocket.close(); 422 if (d->delayConnect) { 423 d->delayConnect->setEnabled(false); 424 delete d->delayConnect; 425 d->delayConnect = 0; 426 d->connectTimer->stop(); 427 delete d->connectTimer; 428 d->connectTimer = 0; 429 } 437 d->cancelDelayedConnect(); 430 438 if (d->connectingSocket != -1) 431 439 ::close(d->connectingSocket); … … 513 521 return (state() == ConnectedState); 514 522 515 fd_set readfds;516 FD_ZERO(& readfds);517 FD_SET(d->connectingSocket, & readfds);523 fd_set fds; 524 FD_ZERO(&fds); 525 FD_SET(d->connectingSocket, &fds); 518 526 519 527 timeval timeout; … … 531 539 while (state() == ConnectingState 532 540 && (-1 == msec || timer.elapsed() < msec)) { 533 result = ::select(d->connectingSocket + 1, &readfds, 0, 0, &timeout); 541 #ifdef Q_OS_SYMBIAN 542 // On Symbian, ready-to-write is signaled when non-blocking socket 543 // connect is finised. Is ready-to-read really used on other 544 // UNIX paltforms when using non-blocking AF_UNIX socket? 545 result = ::select(d->connectingSocket + 1, 0, &fds, 0, &timeout); 546 #else 547 result = ::select(d->connectingSocket + 1, &fds, 0, 0, &timeout); 548 #endif 534 549 if (-1 == result && errno != EINTR) { 535 550 d->errorOccurred( QLocalSocket::UnknownSocketError, -
trunk/src/network/socket/qlocalsocket_win.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 49 49 QT_BEGIN_NAMESPACE 50 50 51 #define NOTIFYTIMEOUT 10052 53 51 void QLocalSocketPrivate::init() 54 52 { 55 53 Q_Q(QLocalSocket); 56 QObject::connect(&dataNotifier, SIGNAL(timeout()), q, SLOT(_q_notified()));54 memset(&overlapped, 0, sizeof(overlapped)); 57 55 overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 56 dataReadNotifier = new QWinEventNotifier(overlapped.hEvent, q); 57 q->connect(dataReadNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_notified())); 58 58 } 59 59 … … 102 102 pipeWriter(0), 103 103 readBufferMaxSize(0), 104 actualReadBufferSize(0), 104 105 error(QLocalSocket::UnknownSocketError), 105 readyReadEmitted(false), 106 readSequenceStarted(false), 107 pendingReadyRead(false), 106 108 pipeClosed(false), 107 109 state(QLocalSocket::UnconnectedState) … … 138 140 DWORD permissions = (openMode & QIODevice::ReadOnly) ? GENERIC_READ : 0; 139 141 permissions |= (openMode & QIODevice::WriteOnly) ? GENERIC_WRITE : 0; 140 QT_WA({ 141 localSocket = CreateFileW( 142 (TCHAR*)d->fullServerName.utf16(), // pipe name 143 permissions, 144 0, // no sharing 145 NULL, // default security attributes 146 OPEN_EXISTING, // opens existing pipe 147 0, // default attributes 148 NULL); // no template file 149 }, { 150 localSocket = CreateFileA( 151 d->fullServerName.toLocal8Bit().constData(), // pipe name 152 permissions, 153 0, // no sharing 154 NULL, // default security attributes 155 OPEN_EXISTING, // opens existing pipe 156 0, // default attributes 157 NULL); // no template file 158 }); 142 localSocket = CreateFile((const wchar_t *)d->fullServerName.utf16(), // pipe name 143 permissions, 144 0, // no sharing 145 NULL, // default security attributes 146 OPEN_EXISTING, // opens existing pipe 147 FILE_FLAG_OVERLAPPED, 148 NULL); // no template file 149 159 150 if (localSocket != INVALID_HANDLE_VALUE) 160 151 break; … … 166 157 167 158 // All pipe instances are busy, so wait until connected or up to 5 seconds. 168 QT_WA({ 169 if (!WaitNamedPipeW((TCHAR*)d->fullServerName.utf16(), 5000)) 170 break; 171 }, { 172 if (!WaitNamedPipeA(d->fullServerName.toLocal8Bit().constData(), 5000)) 173 break; 174 }); 159 if (!WaitNamedPipe((const wchar_t *)d->fullServerName.utf16(), 5000)) 160 break; 175 161 } 176 162 … … 183 169 // we have a valid handle 184 170 d->serverName = name; 185 if (setSocketDescriptor((quintptr)localSocket ), openMode) {171 if (setSocketDescriptor((quintptr)localSocket, ConnectedState, openMode)) { 186 172 d->handle = localSocket; 187 173 emit connected(); … … 193 179 { 194 180 Q_D(QLocalSocket); 195 if (d->readBuffer.isEmpty()) { 196 if (!d->readFromSocket()) { 197 if (d->pipeClosed) 198 return -1; 199 return 0; 200 } 201 } 202 203 if (!d->dataNotifier.isActive() && d->threadData->eventDispatcher) 204 d->dataNotifier.start(NOTIFYTIMEOUT); 205 206 if (d->readBuffer.isEmpty()) 207 return qint64(0); 208 209 // If readFromSocket() read data, copy it to its destination. 210 if (maxSize == 1) { 181 182 qint64 readSoFar; 183 // If startAsyncRead() read data, copy it to its destination. 184 if (maxSize == 1 && d->actualReadBufferSize > 0) { 211 185 *data = d->readBuffer.getChar(); 212 return 1; 213 } 214 215 qint64 bytesToRead = qMin(qint64(d->readBuffer.size()), maxSize); 216 qint64 readSoFar = 0; 217 while (readSoFar < bytesToRead) { 218 const char *ptr = d->readBuffer.readPointer(); 219 int bytesToReadFromThisBlock = qMin(int(bytesToRead - readSoFar), 220 d->readBuffer.nextDataBlockSize()); 221 memcpy(data + readSoFar, ptr, bytesToReadFromThisBlock); 222 readSoFar += bytesToReadFromThisBlock; 223 d->readBuffer.free(bytesToReadFromThisBlock); 224 } 186 d->actualReadBufferSize--; 187 readSoFar = 1; 188 } else { 189 qint64 bytesToRead = qMin(qint64(d->actualReadBufferSize), maxSize); 190 readSoFar = 0; 191 while (readSoFar < bytesToRead) { 192 const char *ptr = d->readBuffer.readPointer(); 193 int bytesToReadFromThisBlock = qMin(bytesToRead - readSoFar, 194 qint64(d->readBuffer.nextDataBlockSize())); 195 memcpy(data + readSoFar, ptr, bytesToReadFromThisBlock); 196 readSoFar += bytesToReadFromThisBlock; 197 d->readBuffer.free(bytesToReadFromThisBlock); 198 d->actualReadBufferSize -= bytesToReadFromThisBlock; 199 } 200 } 201 202 if (d->pipeClosed) { 203 if (readSoFar == 0) { 204 QTimer::singleShot(0, this, SLOT(_q_pipeClosed())); 205 return -1; // signal EOF 206 } 207 } else { 208 if (!d->readSequenceStarted) 209 d->startAsyncRead(); 210 d->checkReadyRead(); 211 } 212 225 213 return readSoFar; 226 214 } … … 228 216 /*! 229 217 \internal 230 read from the socket218 Schedules or cancels a readyRead() emission depending on actual data availability 231 219 */ 232 qint64 QLocalSocketPrivate::readData(char *data, qint64 maxSize) 233 { 234 DWORD bytesRead = 0; 235 overlapped.Offset = 0; 236 overlapped.OffsetHigh = 0; 237 bool success = ReadFile(handle, data, maxSize, &bytesRead, &overlapped); 238 if (!success && GetLastError() == ERROR_IO_PENDING) 239 if (GetOverlappedResult(handle, &overlapped, &bytesRead, TRUE)) 240 success = true; 241 if (!success) { 242 setErrorString(QLatin1String("QLocalSocket::readData")); 243 return 0; 244 } 245 return bytesRead; 220 void QLocalSocketPrivate::checkReadyRead() 221 { 222 if (actualReadBufferSize > 0) { 223 if (!pendingReadyRead) { 224 Q_Q(QLocalSocket); 225 QTimer::singleShot(0, q, SLOT(_q_emitReadyRead())); 226 pendingReadyRead = true; 227 } 228 } else { 229 pendingReadyRead = false; 230 } 246 231 } 247 232 … … 250 235 Reads data from the socket into the readbuffer 251 236 */ 252 bool QLocalSocketPrivate::readFromSocket() 253 { 254 qint64 bytesToRead = bytesAvailable(); 255 if (bytesToRead == 0) 237 void QLocalSocketPrivate::startAsyncRead() 238 { 239 do { 240 DWORD bytesToRead = bytesAvailable(); 241 if (bytesToRead == 0) { 242 // There are no bytes in the pipe but we need to 243 // start the overlapped read with some buffer size. 244 bytesToRead = initialReadBufferSize; 245 } 246 247 if (readBufferMaxSize && bytesToRead > (readBufferMaxSize - readBuffer.size())) { 248 bytesToRead = readBufferMaxSize - readBuffer.size(); 249 if (bytesToRead == 0) { 250 // Buffer is full. User must read data from the buffer 251 // before we can read more from the pipe. 252 return; 253 } 254 } 255 256 char *ptr = readBuffer.reserve(bytesToRead); 257 258 readSequenceStarted = true; 259 if (ReadFile(handle, ptr, bytesToRead, NULL, &overlapped)) { 260 completeAsyncRead(); 261 } else { 262 switch (GetLastError()) { 263 case ERROR_IO_PENDING: 264 // This is not an error. We're getting notified, when data arrives. 265 return; 266 case ERROR_PIPE_NOT_CONNECTED: 267 { 268 // It may happen, that the other side closes the connection directly 269 // after writing data. Then we must set the appropriate socket state. 270 pipeClosed = true; 271 Q_Q(QLocalSocket); 272 emit q->readChannelFinished(); 273 return; 274 } 275 default: 276 setErrorString(QLatin1String("QLocalSocketPrivate::startAsyncRead")); 277 return; 278 } 279 } 280 } while (!readSequenceStarted); 281 } 282 283 /*! 284 \internal 285 Sets the correct size of the read buffer after a read operation. 286 Returns false, if an error occured or the connection dropped. 287 */ 288 bool QLocalSocketPrivate::completeAsyncRead() 289 { 290 ResetEvent(overlapped.hEvent); 291 readSequenceStarted = false; 292 293 DWORD bytesRead; 294 if (!GetOverlappedResult(handle, &overlapped, &bytesRead, TRUE)) { 295 if (GetLastError() != ERROR_PIPE_NOT_CONNECTED) 296 setErrorString(QLatin1String("QLocalSocketPrivate::completeAsyncRead")); 256 297 return false; 257 258 if (readBufferMaxSize && bytesToRead 259 > (readBufferMaxSize - readBuffer.size())) 260 bytesToRead = readBufferMaxSize - readBuffer.size(); 261 262 char *ptr = readBuffer.reserve(bytesToRead); 263 qint64 readBytes = readData(ptr, bytesToRead); 264 if (readBytes == 0) { 265 readBuffer.chop(bytesToRead); 266 return false; 267 } 268 readyReadEmitted = false; 269 readBuffer.chop(int(bytesToRead - (readBytes < 0 ? qint64(0) : readBytes))); 298 } 299 300 actualReadBufferSize += bytesRead; 301 readBuffer.truncate(actualReadBufferSize); 270 302 return true; 271 303 } … … 276 308 if (!d->pipeWriter) { 277 309 d->pipeWriter = new QWindowsPipeWriter(d->handle, this); 310 connect(d->pipeWriter, SIGNAL(canWrite()), this, SLOT(_q_canWrite())); 311 connect(d->pipeWriter, SIGNAL(bytesWritten(qint64)), this, SIGNAL(bytesWritten(qint64))); 278 312 d->pipeWriter->start(); 279 connect(d->pipeWriter, SIGNAL(canWrite()), this, SLOT(_q_canWrite()));280 313 } 281 314 return d->pipeWriter->write(data, maxSize); … … 290 323 The number of bytes available from the pipe 291 324 */ 292 qint64QLocalSocketPrivate::bytesAvailable()325 DWORD QLocalSocketPrivate::bytesAvailable() 293 326 { 294 327 Q_Q(QLocalSocket); 295 if (q->state() != QLocalSocket::ConnectedState)296 return 0;297 328 DWORD bytes; 298 329 if (PeekNamedPipe(handle, NULL, 0, NULL, &bytes, NULL)) { 299 330 return bytes; 300 331 } else { 301 if ( ERROR_BROKEN_PIPE == GetLastError() &&!pipeClosed) {332 if (!pipeClosed) { 302 333 pipeClosed = true; 334 emit q->readChannelFinished(); 303 335 QTimer::singleShot(0, q, SLOT(_q_pipeClosed())); 304 336 } … … 317 349 Q_D(const QLocalSocket); 318 350 qint64 available = QIODevice::bytesAvailable(); 319 available += (qint64) d-> readBuffer.size();351 available += (qint64) d->actualReadBufferSize; 320 352 return available; 321 353 } … … 332 364 if (state() != ConnectedState) 333 365 return false; 334 return (d->readBuffer.indexOf('\n') != -1 || QIODevice::canReadLine()); 366 return (QIODevice::canReadLine() 367 || d->readBuffer.indexOf('\n', d->actualReadBufferSize) != -1); 335 368 } 336 369 … … 344 377 d->state = ClosingState; 345 378 emit stateChanged(d->state); 346 d->readyReadEmitted = false;347 emit readChannelFinished();379 if (!d->pipeClosed) 380 emit readChannelFinished(); 348 381 d->serverName = QString(); 349 382 d->fullServerName = QString(); … … 353 386 return; 354 387 } 388 d->readSequenceStarted = false; 389 d->pendingReadyRead = false; 355 390 d->pipeClosed = false; 356 391 DisconnectNamedPipe(d->handle); 357 392 CloseHandle(d->handle); 358 393 d->handle = INVALID_HANDLE_VALUE; 394 ResetEvent(d->overlapped.hEvent); 359 395 d->state = UnconnectedState; 360 396 emit stateChanged(d->state); … … 364 400 d->pipeWriter = 0; 365 401 } 366 d->dataNotifier.stop();367 402 } 368 403 … … 398 433 Q_D(QLocalSocket); 399 434 d->readBuffer.clear(); 435 d->actualReadBufferSize = 0; 400 436 QIODevice::open(openMode); 401 437 d->handle = (int*)socketDescriptor; 402 438 d->state = socketState; 403 439 emit stateChanged(d->state); 404 if (d->threadData->eventDispatcher) 405 d->dataNotifier.start(NOTIFYTIMEOUT); 440 if (d->state == ConnectedState && openMode.testFlag(QIODevice::ReadOnly)) { 441 d->startAsyncRead(); 442 d->checkReadyRead(); 443 } 406 444 return true; 407 445 } … … 417 455 { 418 456 Q_Q(QLocalSocket); 419 if (0 != bytesAvailable()) { 420 if (readBufferMaxSize == 0 || readBuffer.size() < readBufferMaxSize) { 421 if (!readFromSocket()) { 422 return; 423 } 424 // wait until buffer is cleared before starting again 425 if (readBufferMaxSize && readBuffer.size() == readBufferMaxSize) { 426 dataNotifier.stop(); 427 } 428 } 429 if (!readyReadEmitted) { 430 readyReadEmitted = true; 431 q->emit readyRead(); 432 } 457 if (!completeAsyncRead()) { 458 pipeClosed = true; 459 emit q->readChannelFinished(); 460 return; 461 } 462 startAsyncRead(); 463 pendingReadyRead = false; 464 emit q->readyRead(); 465 } 466 467 void QLocalSocketPrivate::_q_emitReadyRead() 468 { 469 if (pendingReadyRead) { 470 Q_Q(QLocalSocket); 471 pendingReadyRead = false; 472 emit q->readyRead(); 433 473 } 434 474 } … … 463 503 if (state() == UnconnectedState) 464 504 return false; 505 if (!openMode().testFlag(QIODevice::ReadOnly)) { 506 qWarning("QLocalSocket::waitForDisconnected isn't supported for write only pipes."); 507 return false; 508 } 465 509 QIncrementalSleepTimer timer(msecs); 466 510 forever { 467 d-> _q_notified();468 469 511 d->bytesAvailable(); // to check if PeekNamedPipe fails 512 if (d->pipeClosed) 513 close(); 470 514 if (state() == UnconnectedState) 471 515 return true; … … 487 531 { 488 532 Q_D(QLocalSocket); 489 QIncrementalSleepTimer timer(msecs); 490 forever { 491 d->_q_notified(); 492 if (bytesAvailable() > 0) { 493 if (!d->readyReadEmitted) { 494 d->readyReadEmitted = true; 495 emit readyRead(); 496 } 533 534 if (bytesAvailable() > 0) 535 return true; 536 537 if (d->state != QLocalSocket::ConnectedState) 538 return false; 539 540 Q_ASSERT(d->readSequenceStarted); 541 DWORD result = WaitForSingleObject(d->overlapped.hEvent, msecs == -1 ? INFINITE : msecs); 542 switch (result) { 543 case WAIT_OBJECT_0: 544 d->_q_notified(); 497 545 return true; 498 } 499 500 Sleep(timer.nextSleepTime()); 501 if (timer.hasTimedOut()) 502 break; 503 } 504 546 case WAIT_TIMEOUT: 547 return false; 548 } 549 550 qWarning("QLocalSocket::waitForReadyRead WaitForSingleObject failed with error code %d.", int(GetLastError())); 505 551 return false; 506 552 } … … 512 558 return false; 513 559 514 QIncrementalSleepTimer timer(msecs); 515 forever { 516 if (d->pipeWriter->hadWritten()) 517 return true; 518 519 if (d->pipeWriter->bytesToWrite() == 0) 520 return false; 521 522 // Wait for the pipe writer to acknowledge that it has 523 // written. This will succeed if either the pipe writer has 524 // already written the data, or if it manages to write data 525 // within the given timeout. 526 if (d->pipeWriter->waitForWrite(0)) 527 return true; 528 529 Sleep(timer.nextSleepTime()); 530 if (timer.hasTimedOut()) 531 break; 532 } 533 534 return false; 560 // Wait for the pipe writer to acknowledge that it has 561 // written. This will succeed if either the pipe writer has 562 // already written the data, or if it manages to write data 563 // within the given timeout. 564 return d->pipeWriter->waitForWrite(msecs); 535 565 } 536 566 -
trunk/src/network/socket/qnativesocketengine.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 48 48 49 49 \reentrant 50 \ingroup io50 \ingroup network 51 51 \inmodule QtNetwork 52 52 … … 195 195 switch (errorString) { 196 196 case NonBlockingInitFailedErrorString: 197 socketErrorString = Q Latin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Unable to initialize non-blocking socket"));197 socketErrorString = QNativeSocketEngine::tr("Unable to initialize non-blocking socket"); 198 198 break; 199 199 case BroadcastingInitFailedErrorString: 200 socketErrorString = Q Latin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Unable to initialize broadcast socket"));200 socketErrorString = QNativeSocketEngine::tr("Unable to initialize broadcast socket"); 201 201 break; 202 202 case NoIpV6ErrorString: 203 socketErrorString = Q Latin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Attempt to use IPv6 socket on a platform with no IPv6 support"));203 socketErrorString = QNativeSocketEngine::tr("Attempt to use IPv6 socket on a platform with no IPv6 support"); 204 204 break; 205 205 case RemoteHostClosedErrorString: 206 socketErrorString = Q Latin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "The remote host closed the connection"));206 socketErrorString = QNativeSocketEngine::tr("The remote host closed the connection"); 207 207 break; 208 208 case TimeOutErrorString: 209 socketErrorString = Q Latin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Network operation timed out"));209 socketErrorString = QNativeSocketEngine::tr("Network operation timed out"); 210 210 break; 211 211 case ResourceErrorString: 212 socketErrorString = Q Latin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Out of resources"));212 socketErrorString = QNativeSocketEngine::tr("Out of resources"); 213 213 break; 214 214 case OperationUnsupportedErrorString: 215 socketErrorString = Q Latin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Unsupported socket operation"));215 socketErrorString = QNativeSocketEngine::tr("Unsupported socket operation"); 216 216 break; 217 217 case ProtocolUnsupportedErrorString: 218 socketErrorString = Q Latin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Protocol type not supported"));218 socketErrorString = QNativeSocketEngine::tr("Protocol type not supported"); 219 219 break; 220 220 case InvalidSocketErrorString: 221 socketErrorString = Q Latin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Invalid socket descriptor"));221 socketErrorString = QNativeSocketEngine::tr("Invalid socket descriptor"); 222 222 break; 223 223 case HostUnreachableErrorString: 224 socketErrorString = Q Latin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Host unreachable"));224 socketErrorString = QNativeSocketEngine::tr("Host unreachable"); 225 225 break; 226 226 case NetworkUnreachableErrorString: 227 socketErrorString = Q Latin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Network unreachable"));227 socketErrorString = QNativeSocketEngine::tr("Network unreachable"); 228 228 break; 229 229 case AccessErrorString: 230 socketErrorString = Q Latin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Permission denied"));230 socketErrorString = QNativeSocketEngine::tr("Permission denied"); 231 231 break; 232 232 case ConnectionTimeOutErrorString: 233 socketErrorString = Q Latin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Connection timed out"));233 socketErrorString = QNativeSocketEngine::tr("Connection timed out"); 234 234 break; 235 235 case ConnectionRefusedErrorString: 236 socketErrorString = Q Latin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Connection refused"));236 socketErrorString = QNativeSocketEngine::tr("Connection refused"); 237 237 break; 238 238 case AddressInuseErrorString: 239 socketErrorString = Q Latin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "The bound address is already in use"));239 socketErrorString = QNativeSocketEngine::tr("The bound address is already in use"); 240 240 break; 241 241 case AddressNotAvailableErrorString: 242 socketErrorString = Q Latin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "The address is not available"));242 socketErrorString = QNativeSocketEngine::tr("The address is not available"); 243 243 break; 244 244 case AddressProtectedErrorString: 245 socketErrorString = Q Latin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "The address is protected"));245 socketErrorString = QNativeSocketEngine::tr("The address is protected"); 246 246 break; 247 247 case DatagramTooLargeErrorString: 248 socketErrorString = Q Latin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Datagram was too large to send"));248 socketErrorString = QNativeSocketEngine::tr("Datagram was too large to send"); 249 249 break; 250 250 case SendDatagramErrorString: 251 socketErrorString = Q Latin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Unable to send a message"));251 socketErrorString = QNativeSocketEngine::tr("Unable to send a message"); 252 252 break; 253 253 case ReceiveDatagramErrorString: 254 socketErrorString = Q Latin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Unable to receive a message"));254 socketErrorString = QNativeSocketEngine::tr("Unable to receive a message"); 255 255 break; 256 256 case WriteErrorString: 257 socketErrorString = Q Latin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Unable to write"));257 socketErrorString = QNativeSocketEngine::tr("Unable to write"); 258 258 break; 259 259 case ReadErrorString: 260 socketErrorString = Q Latin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Network error"));260 socketErrorString = QNativeSocketEngine::tr("Network error"); 261 261 break; 262 262 case PortInuseErrorString: 263 socketErrorString = Q Latin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Another socket is already listening on the same port"));263 socketErrorString = QNativeSocketEngine::tr("Another socket is already listening on the same port"); 264 264 break; 265 265 case NotSocketErrorString: 266 socketErrorString = Q Latin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Operation on non-socket"));266 socketErrorString = QNativeSocketEngine::tr("Operation on non-socket"); 267 267 break; 268 268 case InvalidProxyTypeString: 269 socketErrorString = Q Latin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "The proxy type is invalid for this operation"));269 socketErrorString = QNativeSocketEngine::tr("The proxy type is invalid for this operation"); 270 270 break; 271 271 case UnknownSocketErrorString: 272 socketErrorString = Q Latin1String(QT_TRANSLATE_NOOP("QNativeSocketEngine", "Unknown error"));272 socketErrorString = QNativeSocketEngine::tr("Unknown error"); 273 273 break; 274 274 } … … 382 382 } 383 383 384 384 385 // Make sure we receive out-of-band data 386 // On Symbian OS this works only with native IP stack, not with WinSock 385 387 if (socketType == QAbstractSocket::TcpSocket 386 388 && !setOption(ReceiveOutOfBandData, 1)) { … … 388 390 } 389 391 390 // Set the send and receive buffer sizes to a magic size, found 391 // most optimal for our platforms. 392 setReceiveBufferSize(49152); 393 setSendBufferSize(49152); 392 // Before Qt 4.6, we always set the send and receive buffer size to 49152 as 393 // this was found to be an optimal value. However, modern OS 394 // all have some kind of auto tuning for this and we therefore don't set 395 // this explictly anymore. 396 // If it introduces any performance regressions for Qt 4.6.x (x > 0) then 397 // it will be put back in. 398 // 399 // You can use tests/manual/qhttpnetworkconnection to test HTTP download speed 400 // with this. 401 // 402 // pre-4.6: 403 // setReceiveBufferSize(49152); 404 // setSendBufferSize(49152); 394 405 395 406 d->socketType = socketType; … … 744 755 } 745 756 757 758 qint64 QNativeSocketEngine::bytesToWrite() const 759 { 760 return 0; 761 } 762 746 763 /*! 747 764 Reads up to \a maxSize bytes into \a data from the socket. … … 860 877 bool QNativeSocketEngine::waitForWrite(int msecs, bool *timedOut) 861 878 { 862 Q_D( constQNativeSocketEngine);879 Q_D(QNativeSocketEngine); 863 880 Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::waitForWrite(), false); 864 881 Q_CHECK_NOT_STATE(QNativeSocketEngine::waitForWrite(), … … 877 894 d_func()->fetchConnectionParameters(); 878 895 return true; 896 } else { 897 int value = 0; 898 int valueSize = sizeof(value); 899 if (::getsockopt(d->socketDescriptor, SOL_SOCKET, SO_ERROR, (char *) &value, &valueSize) == 0) { 900 if (value == WSAECONNREFUSED) { 901 d->setError(QAbstractSocket::ConnectionRefusedError, QNativeSocketEnginePrivate::ConnectionRefusedErrorString); 902 d->socketState = QAbstractSocket::UnconnectedState; 903 return false; 904 } else if (value == WSAETIMEDOUT) { 905 d->setError(QAbstractSocket::NetworkError, QNativeSocketEnginePrivate::ConnectionTimeOutErrorString); 906 d->socketState = QAbstractSocket::UnconnectedState; 907 return false; 908 } else if (value == WSAEHOSTUNREACH) { 909 d->setError(QAbstractSocket::NetworkError, QNativeSocketEnginePrivate::HostUnreachableErrorString); 910 d->socketState = QAbstractSocket::UnconnectedState; 911 return false; 912 } 913 } 879 914 } 880 915 #endif … … 897 932 int msecs, bool *timedOut) 898 933 { 899 Q_D( constQNativeSocketEngine);934 Q_D(QNativeSocketEngine); 900 935 Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::waitForWrite(), false); 901 936 Q_CHECK_NOT_STATE(QNativeSocketEngine::waitForReadOrWrite(), … … 911 946 d_func()->fetchConnectionParameters(); 912 947 return true; 913 } 914 #endif 948 } else { 949 int value = 0; 950 int valueSize = sizeof(value); 951 if (::getsockopt(d->socketDescriptor, SOL_SOCKET, SO_ERROR, (char *) &value, &valueSize) == 0) { 952 if (value == WSAECONNREFUSED) { 953 d->setError(QAbstractSocket::ConnectionRefusedError, QNativeSocketEnginePrivate::ConnectionRefusedErrorString); 954 d->socketState = QAbstractSocket::UnconnectedState; 955 return false; 956 } else if (value == WSAETIMEDOUT) { 957 d->setError(QAbstractSocket::NetworkError, QNativeSocketEnginePrivate::ConnectionTimeOutErrorString); 958 d->socketState = QAbstractSocket::UnconnectedState; 959 return false; 960 } else if (value == WSAEHOSTUNREACH) { 961 d->setError(QAbstractSocket::NetworkError, QNativeSocketEnginePrivate::HostUnreachableErrorString); 962 d->socketState = QAbstractSocket::UnconnectedState; 963 return false; 964 } 965 } 966 } 967 #endif 915 968 if (ret == 0) { 916 969 if (timedOut) … … 1087 1140 { 1088 1141 if (e->type() == QEvent::SockAct) { 1089 engine->exceptionNotification(); 1142 if (engine->state() == QAbstractSocket::ConnectingState) 1143 engine->connectionNotification(); 1144 else 1145 engine->exceptionNotification(); 1090 1146 return true; 1091 1147 } -
trunk/src/network/socket/qnativesocketengine_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 53 53 // We mean it. 54 54 // 55 56 55 #include "QtNetwork/qhostaddress.h" 57 56 #include "private/qabstractsocketengine_p.h" 58 57 #ifndef Q_OS_WIN 59 #include "qplatformdefs.h" 58 # include "qplatformdefs.h" 59 #else 60 # include <winsock2.h> 61 #endif 62 63 #ifdef Q_OS_SYMBIAN 64 #include <private/qeventdispatcher_symbian_p.h> 65 #include <unistd.h> 60 66 #endif 61 67 62 68 QT_BEGIN_NAMESPACE 63 69 64 #ifndef Q_OS_WIN 65 // Almost always the same. If not, specify in qplatformdefs.h. 66 #if !defined(QT_SOCKOPTLEN_T) 67 # define QT_SOCKOPTLEN_T QT_SOCKLEN_T 68 #endif 69 70 // Tru64 redefines accept -> _accept with _XOPEN_SOURCE_EXTENDED 71 static inline int qt_socket_accept(int s, struct sockaddr *addr, QT_SOCKLEN_T *addrlen) 72 { return ::accept(s, addr, static_cast<QT_SOCKLEN_T *>(addrlen)); } 73 #if defined(accept) 74 # undef accept 75 #endif 76 77 // UnixWare 7 redefines listen -> _listen 78 static inline int qt_socket_listen(int s, int backlog) 79 { return ::listen(s, backlog); } 80 #if defined(listen) 81 # undef listen 82 #endif 83 84 // UnixWare 7 redefines socket -> _socket 85 static inline int qt_socket_socket(int domain, int type, int protocol) 86 { return ::socket(domain, type, protocol); } 87 #if defined(socket) 88 # undef socket 89 #endif 90 91 #endif 70 // Use our own defines and structs which we know are correct 71 # define QT_SS_MAXSIZE 128 72 # define QT_SS_ALIGNSIZE (sizeof(qint64)) 73 # define QT_SS_PAD1SIZE (QT_SS_ALIGNSIZE - sizeof (short)) 74 # define QT_SS_PAD2SIZE (QT_SS_MAXSIZE - (sizeof (short) + QT_SS_PAD1SIZE + QT_SS_ALIGNSIZE)) 75 struct qt_sockaddr_storage { 76 short ss_family; 77 char __ss_pad1[QT_SS_PAD1SIZE]; 78 qint64 __ss_align; 79 char __ss_pad2[QT_SS_PAD2SIZE]; 80 }; 81 82 // sockaddr_in6 size changed between old and new SDK 83 // Only the new version is the correct one, so always 84 // use this structure. 85 struct qt_in6_addr { 86 quint8 qt_s6_addr[16]; 87 }; 88 struct qt_sockaddr_in6 { 89 short sin6_family; /* AF_INET6 */ 90 quint16 sin6_port; /* Transport level port number */ 91 quint32 sin6_flowinfo; /* IPv6 flow information */ 92 struct qt_in6_addr sin6_addr; /* IPv6 address */ 93 quint32 sin6_scope_id; /* set of interfaces for a scope */ 94 }; 95 96 union qt_sockaddr { 97 sockaddr a; 98 sockaddr_in a4; 99 qt_sockaddr_in6 a6; 100 qt_sockaddr_storage storage; 101 }; 92 102 93 103 class QNativeSocketEnginePrivate; … … 125 135 bool hasPendingDatagrams() const; 126 136 qint64 pendingDatagramSize() const; 137 138 qint64 bytesToWrite() const; 127 139 128 140 qint64 receiveBufferSize() const; -
trunk/src/network/socket/qnativesocketengine_unix.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 41 41 42 42 //#define QNATIVESOCKETENGINE_DEBUG 43 44 43 #include "qnativesocketengine_p.h" 44 #include "private/qnet_unix_p.h" 45 45 #include "qiodevice.h" 46 46 #include "qhostaddress.h" … … 63 63 #include <qstring.h> 64 64 #include <ctype.h> 65 #endif 66 67 #ifdef Q_OS_SYMBIAN // ### TODO: Are these headers right? 68 #include <sys/socket.h> 69 #include <netinet/in.h> 70 #else 71 #include <netinet/tcp.h> 65 72 #endif 66 73 … … 101 108 static void qt_ignore_sigpipe() 102 109 { 110 #ifndef Q_NO_POSIX_SIGNALS 103 111 // Set to ignore SIGPIPE once only. 104 112 static QBasicAtomicInt atom = Q_BASIC_ATOMIC_INITIALIZER(0); … … 109 117 ::sigaction(SIGPIPE, &noaction, 0); 110 118 } 119 #else 120 // Posix signals are not supported by the underlying platform 121 // so we don't need to ignore sigpipe signal explicitly 122 #endif 111 123 } 112 124 … … 115 127 \a port and \a addr if they are non-null. 116 128 */ 117 static inline void qt_socket_getPortAndAddress( struct sockaddr *sa, quint16 *port, QHostAddress *addr)129 static inline void qt_socket_getPortAndAddress(const qt_sockaddr *s, quint16 *port, QHostAddress *addr) 118 130 { 119 131 #if !defined(QT_NO_IPV6) 120 if (sa->sa_family == AF_INET6) { 121 struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)sa; 132 if (s->a.sa_family == AF_INET6) { 122 133 Q_IPV6ADDR tmp; 123 memcpy(&tmp, &s a6->sin6_addr.s6_addr, sizeof(tmp));134 memcpy(&tmp, &s->a6.sin6_addr, sizeof(tmp)); 124 135 if (addr) { 125 136 QHostAddress tmpAddress; … … 128 139 #ifndef QT_NO_IPV6IFNAME 129 140 char scopeid[IFNAMSIZ]; 130 if (::if_indextoname(s a6->sin6_scope_id, scopeid) > 0) {141 if (::if_indextoname(s->a6.sin6_scope_id, scopeid)) { 131 142 addr->setScopeId(QLatin1String(scopeid)); 132 143 } else 133 144 #endif 134 addr->setScopeId(QString::number(s a6->sin6_scope_id));145 addr->setScopeId(QString::number(s->a6.sin6_scope_id)); 135 146 } 136 147 if (port) 137 *port = ntohs(s a6->sin6_port);148 *port = ntohs(s->a6.sin6_port); 138 149 return; 139 150 } 140 151 #endif 141 struct sockaddr_in *sa4 = (struct sockaddr_in *)sa;142 152 if (port) 143 *port = ntohs(s a4->sin_port);153 *port = ntohs(s->a4.sin_port); 144 154 if (addr) { 145 155 QHostAddress tmpAddress; 146 tmpAddress.setAddress(ntohl(s a4->sin_addr.s_addr));156 tmpAddress.setAddress(ntohl(s->a4.sin_addr.s_addr)); 147 157 *addr = tmpAddress; 148 158 } … … 164 174 #endif 165 175 int type = (socketType == QAbstractSocket::UdpSocket) ? SOCK_DGRAM : SOCK_STREAM; 166 int socket = qt_socket_socket(protocol, type, 0); 176 #ifdef Q_OS_SYMBIAN 177 int socket = ::socket(protocol, type, 0); 178 #else 179 int socket = qt_safe_socket(protocol, type, 0); 180 #endif 167 181 168 182 if (socket <= 0) { … … 191 205 // Ensure that the socket is closed on exec*(). 192 206 ::fcntl(socket, F_SETFD, FD_CLOEXEC); 207 193 208 socketDescriptor = socket; 194 209 return true; … … 205 220 206 221 int n = -1; 222 int level = SOL_SOCKET; // default 223 207 224 switch (opt) { 208 225 case QNativeSocketEngine::ReceiveBufferSocketOption: … … 224 241 n = SO_OOBINLINE; 225 242 break; 243 case QNativeSocketEngine::LowDelayOption: 244 level = IPPROTO_TCP; 245 n = TCP_NODELAY; 246 break; 247 case QNativeSocketEngine::KeepAliveOption: 248 n = SO_KEEPALIVE; 249 break; 226 250 } 227 251 228 252 int v = -1; 229 253 QT_SOCKOPTLEN_T len = sizeof(v); 230 if ( getsockopt(socketDescriptor, SOL_SOCKET, n, (char *) &v, &len) != -1)254 if (::getsockopt(socketDescriptor, level, n, (char *) &v, &len) != -1) 231 255 return v; 256 232 257 return -1; 233 258 } … … 244 269 245 270 int n = 0; 271 int level = SOL_SOCKET; // default 272 246 273 switch (opt) { 247 274 case QNativeSocketEngine::ReceiveBufferSocketOption: … … 256 283 case QNativeSocketEngine::NonBlockingSocketOption: { 257 284 // Make the socket nonblocking. 285 #if !defined(Q_OS_VXWORKS) 258 286 int flags = ::fcntl(socketDescriptor, F_GETFL, 0); 259 287 if (flags == -1) { … … 269 297 return false; 270 298 } 271 299 #else // Q_OS_VXWORKS 300 int onoff = 1; 301 #ifdef Q_OS_SYMBIAN 302 if (::ioctl(socketDescriptor, FIONBIO, &onoff) < 0) { 303 #else 304 if (qt_safe_ioctl(socketDescriptor, FIONBIO, &onoff) < 0) { 305 #endif 306 #ifdef QNATIVESOCKETENGINE_DEBUG 307 perror("QNativeSocketEnginePrivate::setOption(): ioctl(FIONBIO, 1) failed"); 308 #endif 309 return false; 310 } 311 #endif // Q_OS_VXWORKS 272 312 return true; 273 313 } 274 314 case QNativeSocketEngine::AddressReusable: 275 #if def SO_REUSEPORT315 #if defined(SO_REUSEPORT) && !defined(Q_OS_SYMBIAN) 276 316 n = SO_REUSEPORT; 277 317 #else … … 284 324 n = SO_OOBINLINE; 285 325 break; 286 } 287 288 return ::setsockopt(socketDescriptor, SOL_SOCKET, n, (char *) &v, sizeof(v)) == 0; 326 case QNativeSocketEngine::LowDelayOption: 327 level = IPPROTO_TCP; 328 n = TCP_NODELAY; 329 break; 330 case QNativeSocketEngine::KeepAliveOption: 331 n = SO_KEEPALIVE; 332 break; 333 } 334 335 return ::setsockopt(socketDescriptor, level, n, (char *) &v, sizeof(v)) == 0; 289 336 } 290 337 291 338 bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &addr, quint16 port) 292 339 { 340 #ifdef QNATIVESOCKETENGINE_DEBUG 341 qDebug("QNativeSocketEnginePrivate::nativeConnect() : %d ", socketDescriptor); 342 #endif 343 293 344 struct sockaddr_in sockAddrIPv4; 294 345 struct sockaddr *sockAddrPtr = 0; … … 328 379 // unreachable 329 380 } 330 331 int connectResult = QT_SOCKET_CONNECT(socketDescriptor, sockAddrPtr, sockAddrSize); 381 #ifdef Q_OS_SYMBIAN 382 int connectResult = ::connect(socketDescriptor, sockAddrPtr, sockAddrSize); 383 #else 384 int connectResult = qt_safe_connect(socketDescriptor, sockAddrPtr, sockAddrSize); 385 #endif 332 386 if (connectResult == -1) { 333 387 switch (errno) { … … 433 487 434 488 int bindResult = QT_SOCKET_BIND(socketDescriptor, sockAddrPtr, sockAddrSize); 489 435 490 if (bindResult < 0) { 436 491 switch(errno) { … … 469 524 bool QNativeSocketEnginePrivate::nativeListen(int backlog) 470 525 { 471 if (qt_socket_listen(socketDescriptor, backlog) < 0) { 526 #ifdef Q_OS_SYMBIAN 527 if (::listen(socketDescriptor, backlog) < 0) { 528 #else 529 if (qt_safe_listen(socketDescriptor, backlog) < 0) { 530 #endif 472 531 switch (errno) { 473 532 case EADDRINUSE: … … 496 555 int QNativeSocketEnginePrivate::nativeAccept() 497 556 { 498 int acceptedDescriptor = qt_socket_accept(socketDescriptor, 0, 0); 499 #if defined (QNATIVESOCKETENGINE_DEBUG) 500 qDebug("QNativeSocketEnginePrivate::nativeAccept() == %i", acceptedDescriptor); 501 #endif 502 // Ensure that the socket is closed on exec*() 503 ::fcntl(acceptedDescriptor, F_SETFD, FD_CLOEXEC); 557 #ifdef Q_OS_SYMBIAN 558 int acceptedDescriptor = ::accept(socketDescriptor, 0, 0); 559 #else 560 int acceptedDescriptor = qt_safe_accept(socketDescriptor, 0, 0); 561 #endif 562 //check if we have vaild descriptor at all 563 if(acceptedDescriptor > 0) { 564 // Ensure that the socket is closed on exec*() 565 ::fcntl(acceptedDescriptor, F_SETFD, FD_CLOEXEC); 566 } 567 #ifdef Q_OS_SYMBIAN 568 else { 569 qWarning("QNativeSocketEnginePrivate::nativeAccept() - acceptedDescriptor <= 0"); 570 } 571 #endif 572 504 573 return acceptedDescriptor; 505 574 } … … 507 576 qint64 QNativeSocketEnginePrivate::nativeBytesAvailable() const 508 577 { 509 /* 510 Apparently, there is not consistency among different operating 511 systems on how to use FIONREAD. 512 513 FreeBSD, Linux and Solaris all expect the 3rd argument to 514 ioctl() to be an int, which is normally 32-bit even on 64-bit 515 machines. 516 517 IRIX, on the other hand, expects a size_t, which is 64-bit on 518 64-bit machines. 519 520 So, the solution is to use size_t initialized to zero to make 521 sure all bits are set to zero, preventing underflow with the 522 FreeBSD/Linux/Solaris ioctls. 523 */ 524 size_t nbytes = 0; 578 int nbytes = 0; 525 579 // gives shorter than true amounts on Unix domain sockets. 526 580 qint64 available = 0; 527 if (::ioctl(socketDescriptor, FIONREAD, (char *) &nbytes) >= 0) 528 available = (qint64) *((int *) &nbytes); 581 #ifdef Q_OS_SYMBIAN 582 if (::ioctl(socketDescriptor, FIONREAD, (char *) &nbytes) >= 0) 583 #else 584 if (qt_safe_ioctl(socketDescriptor, FIONREAD, (char *) &nbytes) >= 0) 585 #endif 586 available = (qint64) nbytes; 529 587 530 588 #if defined (QNATIVESOCKETENGINE_DEBUG) … … 537 595 { 538 596 // Create a sockaddr struct and reset its port number. 539 #if !defined(QT_NO_IPV6) 540 struct sockaddr_storage storage; 541 sockaddr_in6 *storagePtrIPv6 = reinterpret_cast<sockaddr_in6 *>(&storage); 542 storagePtrIPv6->sin6_port = 0; 543 #else 544 struct sockaddr storage; 545 #endif 546 sockaddr *storagePtr = reinterpret_cast<sockaddr *>(&storage); 547 storagePtr->sa_family = 0; 548 549 sockaddr_in *storagePtrIPv4 = reinterpret_cast<sockaddr_in *>(&storage); 550 storagePtrIPv4->sin_port = 0; 597 qt_sockaddr storage; 551 598 QT_SOCKLEN_T storageSize = sizeof(storage); 599 memset(&storage, 0, storageSize); 552 600 553 601 // Peek 0 bytes into the next message. The size of the message may … … 556 604 do { 557 605 char c; 558 readBytes = ::recvfrom(socketDescriptor, &c, 1, MSG_PEEK, storagePtr, &storageSize);606 readBytes = ::recvfrom(socketDescriptor, &c, 1, MSG_PEEK, &storage.a, &storageSize); 559 607 } while (readBytes == -1 && errno == EINTR); 560 608 … … 570 618 } 571 619 620 #ifdef Q_OS_SYMBIAN 621 qint64 QNativeSocketEnginePrivate::nativePendingDatagramSize() const 622 { 623 size_t nbytes = 0; 624 ::ioctl(socketDescriptor, E32IONREAD, (char *) &nbytes); 625 return qint64(nbytes-28); 626 } 627 #else 572 628 qint64 QNativeSocketEnginePrivate::nativePendingDatagramSize() const 573 629 { 574 630 QVarLengthArray<char, 8192> udpMessagePeekBuffer(8192); 575 631 ssize_t recvResult = -1; 632 576 633 for (;;) { 577 634 // the data written to udpMessagePeekBuffer is discarded, so … … 579 636 // so. 580 637 recvResult = ::recv(socketDescriptor, udpMessagePeekBuffer.data(), 581 638 udpMessagePeekBuffer.size(), MSG_PEEK); 582 639 if (recvResult == -1 && errno == EINTR) 583 640 continue; … … 595 652 return qint64(recvResult); 596 653 } 597 654 #endif 598 655 qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxSize, 599 656 QHostAddress *address, quint16 *port) 600 657 { 601 #if !defined(QT_NO_IPV6) 602 struct sockaddr_storage aa; 603 #else 604 struct sockaddr_in aa; 605 #endif 658 qt_sockaddr aa; 606 659 memset(&aa, 0, sizeof(aa)); 607 660 QT_SOCKLEN_T sz; … … 612 665 char c; 613 666 recvFromResult = ::recvfrom(socketDescriptor, maxSize ? data : &c, maxSize ? maxSize : 1, 614 0, (struct sockaddr *)&aa, &sz);667 0, &aa.a, &sz); 615 668 } while (recvFromResult == -1 && errno == EINTR); 616 669 … … 618 671 setError(QAbstractSocket::NetworkError, ReceiveDatagramErrorString); 619 672 } else if (port || address) { 620 qt_socket_getPortAndAddress( (struct sockaddr *)&aa, port, address);673 qt_socket_getPortAndAddress(&aa, port, address); 621 674 } 622 675 … … 641 694 struct sockaddr_in6 sockAddrIPv6; 642 695 if (host.protocol() == QAbstractSocket::IPv6Protocol) { 643 644 645 646 647 648 649 650 696 memset(&sockAddrIPv6, 0, sizeof(sockAddrIPv6)); 697 sockAddrIPv6.sin6_family = AF_INET6; 698 sockAddrIPv6.sin6_port = htons(port); 699 700 Q_IPV6ADDR tmp = host.toIPv6Address(); 701 memcpy(&sockAddrIPv6.sin6_addr.s6_addr, &tmp, sizeof(tmp)); 702 sockAddrSize = sizeof(sockAddrIPv6); 703 sockAddrPtr = (struct sockaddr *)&sockAddrIPv6; 651 704 } else 652 705 #endif 653 706 if (host.protocol() == QAbstractSocket::IPv4Protocol) { 654 655 656 657 658 659 707 memset(&sockAddrIPv4, 0, sizeof(sockAddrIPv4)); 708 sockAddrIPv4.sin_family = AF_INET; 709 sockAddrIPv4.sin_port = htons(port); 710 sockAddrIPv4.sin_addr.s_addr = htonl(host.toIPv4Address()); 711 sockAddrSize = sizeof(sockAddrIPv4); 712 sockAddrPtr = (struct sockaddr *)&sockAddrIPv4; 660 713 } 661 714 662 715 // ignore the SIGPIPE signal 663 716 qt_ignore_sigpipe(); 664 665 ssize_t sentBytes; 666 do { 667 sentBytes = ::sendto(socketDescriptor, data, len, 668 0, sockAddrPtr, sockAddrSize); 669 } while (sentBytes == -1 && errno == EINTR); 717 #ifdef Q_OS_SYMBIAN 718 ssize_t sentBytes = ::sendto(socketDescriptor, data, len, 719 0, sockAddrPtr, sockAddrSize); 720 #else 721 ssize_t sentBytes = qt_safe_sendto(socketDescriptor, data, len, 722 0, sockAddrPtr, sockAddrSize); 723 #endif 670 724 671 725 if (sentBytes < 0) { … … 698 752 return false; 699 753 700 #if !defined(QT_NO_IPV6) 701 struct sockaddr_storage sa; 702 #else 703 struct sockaddr_in sa; 704 #endif 705 struct sockaddr *sockAddrPtr = (struct sockaddr *) &sa; 754 qt_sockaddr sa; 706 755 QT_SOCKLEN_T sockAddrSize = sizeof(sa); 707 756 708 757 // Determine local address 709 758 memset(&sa, 0, sizeof(sa)); 710 if (::getsockname(socketDescriptor, sockAddrPtr, &sockAddrSize) == 0) {711 qt_socket_getPortAndAddress( sockAddrPtr, &localPort, &localAddress);759 if (::getsockname(socketDescriptor, &sa.a, &sockAddrSize) == 0) { 760 qt_socket_getPortAndAddress(&sa, &localPort, &localAddress); 712 761 713 762 // Determine protocol family 714 switch (s ockAddrPtr->sa_family) {763 switch (sa.a.sa_family) { 715 764 case AF_INET: 716 765 socketProtocol = QAbstractSocket::IPv4Protocol; … … 732 781 733 782 // Determine the remote address 734 if (!::getpeername(socketDescriptor, sockAddrPtr, &sockAddrSize))735 qt_socket_getPortAndAddress( sockAddrPtr, &peerPort, &peerAddress);783 if (!::getpeername(socketDescriptor, &sa.a, &sockAddrSize)) 784 qt_socket_getPortAndAddress(&sa, &peerPort, &peerAddress); 736 785 737 786 // Determine the socket type (UDP/TCP) … … 769 818 qDebug("QNativeSocketEngine::nativeClose()"); 770 819 #endif 820 821 #ifdef Q_OS_SYMBIAN 771 822 ::close(socketDescriptor); 823 #else 824 qt_safe_close(socketDescriptor); 825 #endif 772 826 } 773 827 … … 783 837 ssize_t writtenBytes; 784 838 do { 785 writtenBytes = ::write(socketDescriptor, data, len); 839 #ifdef Q_OS_SYMBIAN 840 writtenBytes = ::write(socketDescriptor, data, len); 841 #else 842 writtenBytes = qt_safe_write(socketDescriptor, data, len); 843 #endif 844 // writtenBytes = QT_WRITE(socketDescriptor, data, len); ### TODO S60: Should this line be removed or the one above it? 786 845 } while (writtenBytes < 0 && errno == EINTR); 787 846 … … 825 884 ssize_t r = 0; 826 885 do { 886 #ifdef Q_OS_SYMBIAN 827 887 r = ::read(socketDescriptor, data, maxSize); 888 #else 889 r = qt_safe_read(socketDescriptor, data, maxSize); 890 #endif 828 891 } while (r == -1 && errno == EINTR); 829 892 … … 843 906 setError(QAbstractSocket::NetworkError, ReadErrorString); 844 907 break; 908 #ifdef Q_OS_SYMBIAN 909 case EPIPE: 910 #endif 845 911 case ECONNRESET: 912 #if defined(Q_OS_VXWORKS) 913 case ESHUTDOWN: 914 #endif 846 915 r = 0; 847 916 break; … … 870 939 tv.tv_usec = (timeout % 1000) * 1000; 871 940 872 QTime timer; 873 timer.start(); 941 #ifdef Q_OS_SYMBIAN 942 fd_set fdexception; 943 FD_ZERO(&fdexception); 944 FD_SET(socketDescriptor, &fdexception); 945 #endif 874 946 875 947 int retval; 876 do { 877 if (selectForRead) 878 retval = select(socketDescriptor + 1, &fds, 0, 0, timeout < 0 ? 0 : &tv); 879 else 880 retval = select(socketDescriptor + 1, 0, &fds, 0, timeout < 0 ? 0 : &tv); 881 882 if (retval != -1 || errno != EINTR) 883 break; 884 885 if (timeout > 0) { 886 // recalculate the timeout 887 int t = timeout - timer.elapsed(); 888 if (t < 0) { 889 // oops, timeout turned negative? 890 retval = -1; 891 break; 948 if (selectForRead) 949 #ifdef Q_OS_SYMBIAN 950 retval = ::select(socketDescriptor + 1, &fds, 0, &fdexception, timeout < 0 ? 0 : &tv); 951 #else 952 retval = qt_safe_select(socketDescriptor + 1, &fds, 0, 0, timeout < 0 ? 0 : &tv); 953 #endif 954 else 955 #ifdef Q_OS_SYMBIAN 956 retval = ::select(socketDescriptor + 1, 0, &fds, &fdexception, timeout < 0 ? 0 : &tv); 957 #else 958 retval = qt_safe_select(socketDescriptor + 1, 0, &fds, 0, timeout < 0 ? 0 : &tv); 959 #endif 960 961 962 #ifdef Q_OS_SYMBIAN 963 bool selectForExec = false; 964 if(retval != 0) { 965 if(retval < 0) { 966 qWarning("nativeSelect(....) returned < 0 for socket %d", socketDescriptor); 892 967 } 893 894 tv.tv_sec = t / 1000; 895 tv.tv_usec = (t % 1000) * 1000; 896 } 897 } while (true); 968 selectForExec = FD_ISSET(socketDescriptor, &fdexception); 969 } 970 if(selectForExec) { 971 qWarning("nativeSelect (selectForRead %d, retVal %d, errno %d) Unexpected exception for fd %d", 972 selectForRead, retval, errno, socketDescriptor); 973 } 974 #endif 898 975 899 976 return retval; … … 901 978 902 979 int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool checkRead, bool checkWrite, 903 980 bool *selectForRead, bool *selectForWrite) const 904 981 { 905 982 fd_set fdread; … … 913 990 FD_SET(socketDescriptor, &fdwrite); 914 991 992 #ifdef Q_OS_SYMBIAN 993 fd_set fdexception; 994 FD_ZERO(&fdexception); 995 FD_SET(socketDescriptor, &fdexception); 996 #endif 997 915 998 struct timeval tv; 916 999 tv.tv_sec = timeout / 1000; 917 1000 tv.tv_usec = (timeout % 1000) * 1000; 918 1001 1002 int ret; 1003 #ifndef Q_OS_SYMBIAN 1004 ret = qt_safe_select(socketDescriptor + 1, &fdread, &fdwrite, 0, timeout < 0 ? 0 : &tv); 1005 #else 919 1006 QTime timer; 920 1007 timer.start(); 921 1008 922 int ret;923 1009 do { 924 ret = select(socketDescriptor + 1, &fdread, &fdwrite, 0, timeout < 0 ? 0 : &tv); 925 if (ret != -1 || errno != EINTR) 926 break; 1010 ret = ::select(socketDescriptor + 1, &fdread, &fdwrite, &fdexception, timeout < 0 ? 0 : &tv); 1011 bool selectForExec = false; 1012 if(ret != 0) { 1013 if(ret < 0) { 1014 qWarning("nativeSelect(....) returned < 0 for socket %d", socketDescriptor); 1015 } 1016 selectForExec = FD_ISSET(socketDescriptor, &fdexception); 1017 } 1018 if(selectForExec) { 1019 qWarning("nativeSelect (checkRead %d, checkWrite %d, ret %d, errno %d): Unexpected expectfds ready in fd %d", 1020 checkRead, checkWrite, ret, errno, socketDescriptor); 1021 if (checkWrite){ 1022 FD_CLR(socketDescriptor, &fdread); 1023 FD_SET(socketDescriptor, &fdwrite); 1024 } else if (checkRead) 1025 FD_SET(socketDescriptor, &fdread); 1026 1027 1028 if ((ret == -1) && ( errno == ECONNREFUSED || errno == EPIPE )) 1029 ret = 1; 1030 1031 } 1032 1033 if (ret != -1 || errno != EINTR) { 1034 break; 1035 } 927 1036 928 1037 if (timeout > 0) { … … 939 1048 } 940 1049 } while (true); 1050 #endif 1051 941 1052 if (ret <= 0) 942 1053 return ret; 943 944 1054 *selectForRead = FD_ISSET(socketDescriptor, &fdread); 945 1055 *selectForWrite = FD_ISSET(socketDescriptor, &fdwrite); 1056 946 1057 return ret; 947 1058 } -
trunk/src/network/socket/qnativesocketengine_win.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 150 150 #endif 151 151 152 #if !defined (QT_NO_IPV6)153 154 // Use our own defines and structs which we know are correct155 # define QT_SS_MAXSIZE 128156 # define QT_SS_ALIGNSIZE (sizeof(__int64))157 # define QT_SS_PAD1SIZE (QT_SS_ALIGNSIZE - sizeof (short))158 # define QT_SS_PAD2SIZE (QT_SS_MAXSIZE - (sizeof (short) + QT_SS_PAD1SIZE + QT_SS_ALIGNSIZE))159 struct qt_sockaddr_storage {160 short ss_family;161 char __ss_pad1[QT_SS_PAD1SIZE];162 __int64 __ss_align;163 char __ss_pad2[QT_SS_PAD2SIZE];164 };165 166 // sockaddr_in6 size changed between old and new SDK167 // Only the new version is the correct one, so always168 // use this structure.169 struct qt_in6_addr {170 u_char qt_s6_addr[16];171 };172 typedef struct {173 short sin6_family; /* AF_INET6 */174 u_short sin6_port; /* Transport level port number */175 u_long sin6_flowinfo; /* IPv6 flow information */176 struct qt_in6_addr sin6_addr; /* IPv6 address */177 u_long sin6_scope_id; /* set of interfaces for a scope */178 } qt_sockaddr_in6;179 180 #else181 182 typedef void * qt_sockaddr_in6 ;183 184 185 #endif186 187 152 #ifndef AF_INET6 188 153 #define AF_INET6 23 /* Internetwork Version 6 */ … … 202 167 \a port and \a addr if they are non-null. 203 168 */ 204 static inline void qt_socket_getPortAndAddress(SOCKET socketDescriptor, structsockaddr *sa, quint16 *port, QHostAddress *address)169 static inline void qt_socket_getPortAndAddress(SOCKET socketDescriptor, const qt_sockaddr *sa, quint16 *port, QHostAddress *address) 205 170 { 206 171 #if !defined (QT_NO_IPV6) 207 if (sa-> sa_family == AF_INET6) {208 qt_sockaddr_in6 *sa6 = (qt_sockaddr_in6 *)sa;172 if (sa->a.sa_family == AF_INET6) { 173 const qt_sockaddr_in6 *sa6 = &sa->a6; 209 174 Q_IPV6ADDR tmp; 210 175 for (int i = 0; i < 16; ++i) … … 218 183 } else 219 184 #endif 220 if (sa-> sa_family == AF_INET) {221 struct sockaddr_in *sa4 = (struct sockaddr_in *)sa;185 if (sa->a.sa_family == AF_INET) { 186 const sockaddr_in *sa4 = &sa->a4; 222 187 unsigned long addr; 223 188 WSANtohl(socketDescriptor, sa4->sin_addr.s_addr, &addr); … … 398 363 399 364 int n = -1; 365 int level = SOL_SOCKET; // default 366 400 367 switch (opt) { 401 368 case QNativeSocketEngine::ReceiveBufferSocketOption: … … 425 392 n = SO_OOBINLINE; 426 393 break; 394 case QNativeSocketEngine::LowDelayOption: 395 level = IPPROTO_TCP; 396 n = TCP_NODELAY; 397 break; 398 case QNativeSocketEngine::KeepAliveOption: 399 n = SO_KEEPALIVE; 400 break; 427 401 } 428 402 429 403 int v = -1; 430 404 QT_SOCKOPTLEN_T len = sizeof(v); 431 if (getsockopt(socketDescriptor, SOL_SOCKET, n, (char *) &v, &len) != -1)405 if (getsockopt(socketDescriptor, level, n, (char *) &v, &len) != -1) 432 406 return v; 433 407 return -1; … … 445 419 446 420 int n = 0; 421 int level = SOL_SOCKET; // default 422 447 423 switch (opt) { 448 424 case QNativeSocketEngine::ReceiveBufferSocketOption: … … 476 452 n = SO_OOBINLINE; 477 453 break; 478 } 479 480 if (::setsockopt(socketDescriptor, SOL_SOCKET, n, (char*)&v, sizeof(v)) != 0) { 454 case QNativeSocketEngine::LowDelayOption: 455 level = IPPROTO_TCP; 456 n = TCP_NODELAY; 457 break; 458 case QNativeSocketEngine::KeepAliveOption: 459 n = SO_KEEPALIVE; 460 break; 461 } 462 463 if (::setsockopt(socketDescriptor, level, n, (char*)&v, sizeof(v)) != 0) { 481 464 WS_ERROR_DEBUG(WSAGetLastError()); 482 465 return false; … … 499 482 return false; 500 483 501 #if !defined (QT_NO_IPV6) 502 struct qt_sockaddr_storage sa; 503 #else 504 struct sockaddr_in sa; 505 #endif 506 struct sockaddr *pSa = (struct sockaddr *) &sa; 507 508 QT_SOCKLEN_T sz = sizeof(sa); 509 484 qt_sockaddr sa; 485 QT_SOCKLEN_T sockAddrSize = sizeof(sa); 486 487 // Determine local address 510 488 memset(&sa, 0, sizeof(sa)); 511 if (::getsockname(socketDescriptor, pSa, &sz) == 0) {512 qt_socket_getPortAndAddress(socketDescriptor, pSa, &localPort, &localAddress);489 if (::getsockname(socketDescriptor, &sa.a, &sockAddrSize) == 0) { 490 qt_socket_getPortAndAddress(socketDescriptor, &sa, &localPort, &localAddress); 513 491 // Determine protocol family 514 switch ( pSa->sa_family) {492 switch (sa.a.sa_family) { 515 493 case AF_INET: 516 494 socketProtocol = QAbstractSocket::IPv4Protocol; … … 536 514 537 515 memset(&sa, 0, sizeof(sa)); 538 if (::getpeername(socketDescriptor, pSa, &sz) == 0) {539 qt_socket_getPortAndAddress(socketDescriptor, pSa, &peerPort, &peerAddress);516 if (::getpeername(socketDescriptor, &sa.a, &sockAddrSize) == 0) { 517 qt_socket_getPortAndAddress(socketDescriptor, &sa, &peerPort, &peerAddress); 540 518 } else { 541 519 WS_ERROR_DEBUG(WSAGetLastError()); … … 569 547 struct sockaddr_in sockAddrIPv4; 570 548 qt_sockaddr_in6 sockAddrIPv6; 571 struct sockaddr *sockAddrPtr ;572 QT_SOCKLEN_T sockAddrSize ;549 struct sockaddr *sockAddrPtr = 0; 550 QT_SOCKLEN_T sockAddrSize = 0; 573 551 574 552 qt_socket_setPortAndAddress(socketDescriptor, &sockAddrIPv4, &sockAddrIPv6, port, address, &sockAddrPtr, &sockAddrSize); … … 606 584 break; 607 585 } 586 if (value == WSAEHOSTUNREACH) { 587 setError(QAbstractSocket::NetworkError, HostUnreachableErrorString); 588 socketState = QAbstractSocket::UnconnectedState; 589 break; 590 } 608 591 } 609 592 // fall through … … 669 652 struct sockaddr_in sockAddrIPv4; 670 653 qt_sockaddr_in6 sockAddrIPv6; 671 struct sockaddr *sockAddrPtr ;672 QT_SOCKLEN_T sockAddrSize ;654 struct sockaddr *sockAddrPtr = 0; 655 QT_SOCKLEN_T sockAddrSize = 0; 673 656 674 657 qt_socket_setPortAndAddress(socketDescriptor, &sockAddrIPv4, &sockAddrIPv6, port, address, &sockAddrPtr, &sockAddrSize); … … 797 780 #if !defined(Q_OS_WINCE) 798 781 // Create a sockaddr struct and reset its port number. 799 #if !defined(QT_NO_IPV6) 800 qt_sockaddr_in6 storage; 801 qt_sockaddr_in6 *storagePtrIPv6 = reinterpret_cast<qt_sockaddr_in6 *>(&storage); 802 storagePtrIPv6->sin6_port = 0; 803 #else 804 struct sockaddr storage; 805 #endif 806 sockaddr *storagePtr = reinterpret_cast<sockaddr *>(&storage); 807 storagePtr->sa_family = 0; 808 809 sockaddr_in *storagePtrIPv4 = reinterpret_cast<sockaddr_in *>(&storage); 810 storagePtrIPv4->sin_port = 0; 782 qt_sockaddr storage; 811 783 QT_SOCKLEN_T storageSize = sizeof(storage); 812 784 memset(&storage, 0, storageSize); 813 785 814 786 bool result = false; … … 822 794 DWORD available = 0; 823 795 DWORD flags = MSG_PEEK; 824 int ret = ::WSARecvFrom(socketDescriptor, &buf, 1, &available, &flags, storagePtr, &storageSize,0,0);796 int ret = ::WSARecvFrom(socketDescriptor, &buf, 1, &available, &flags, &storage.a, &storageSize,0,0); 825 797 int err = WSAGetLastError(); 826 798 if (ret == SOCKET_ERROR && err != WSAEMSGSIZE) { … … 832 804 flags = 0; 833 805 ::WSARecvFrom(socketDescriptor, &buf, 1, &available, &flags, 834 storagePtr, &storageSize, 0, 0);806 &storage.a, &storageSize, 0, 0); 835 807 } 836 808 } else { … … 924 896 qint64 ret = 0; 925 897 926 #if !defined(QT_NO_IPV6) 927 qt_sockaddr_storage aa; 928 #else 929 struct sockaddr_in aa; 930 #endif 898 qt_sockaddr aa; 931 899 memset(&aa, 0, sizeof(aa)); 932 900 QT_SOCKLEN_T sz; 933 901 sz = sizeof(aa); 902 934 903 WSABUF buf; 935 904 buf.buf = data; … … 946 915 DWORD flags = 0; 947 916 DWORD bytesRead = 0; 948 int wsaRet = ::WSARecvFrom(socketDescriptor, &buf, 1, &bytesRead, &flags, (struct sockaddr *) &aa, &sz,0,0);917 int wsaRet = ::WSARecvFrom(socketDescriptor, &buf, 1, &bytesRead, &flags, &aa.a, &sz,0,0); 949 918 if (wsaRet == SOCKET_ERROR) { 950 919 int err = WSAGetLastError(); 951 920 if (err == WSAEMSGSIZE) { 952 921 // it is ok the buffer was to small if bytesRead is larger than 953 // maxLength (win 9x)then assume bytes read is really maxLenth922 // maxLength then assume bytes read is really maxLenth 954 923 ret = qint64(bytesRead) > maxLength ? maxLength : qint64(bytesRead); 955 924 } else { … … 962 931 } 963 932 964 qt_socket_getPortAndAddress(socketDescriptor, (struct sockaddr *)&aa, port, address);933 qt_socket_getPortAndAddress(socketDescriptor, &aa, port, address); 965 934 966 935 #if defined (QNATIVESOCKETENGINE_DEBUG) … … 981 950 struct sockaddr_in sockAddrIPv4; 982 951 qt_sockaddr_in6 sockAddrIPv6; 983 struct sockaddr *sockAddrPtr ;984 QT_SOCKLEN_T sockAddrSize ;952 struct sockaddr *sockAddrPtr = 0; 953 QT_SOCKLEN_T sockAddrSize = 0; 985 954 986 955 qt_socket_setPortAndAddress(socketDescriptor, &sockAddrIPv4, &sockAddrIPv6, port, address, &sockAddrPtr, &sockAddrSize); 987 956 988 if (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based && len > qint64(qt_socket_getMaxMsgSize(socketDescriptor))) { 989 // WSAEMSGSIZE is not reliable enough (win 9x) so we check max size our self. 990 setError(QAbstractSocket::DatagramTooLargeError, DatagramTooLargeErrorString); 957 WSABUF buf; 958 #if !defined(Q_OS_WINCE) 959 buf.buf = len ? (char*)data : 0; 960 #else 961 char tmp; 962 buf.buf = len ? (char*)data : &tmp; 963 #endif 964 buf.len = len; 965 DWORD flags = 0; 966 DWORD bytesSent = 0; 967 if (::WSASendTo(socketDescriptor, &buf, 1, &bytesSent, flags, sockAddrPtr, sockAddrSize, 0,0) == SOCKET_ERROR) { 968 int err = WSAGetLastError(); 969 WS_ERROR_DEBUG(err); 970 switch (err) { 971 case WSAEMSGSIZE: 972 setError(QAbstractSocket::DatagramTooLargeError, DatagramTooLargeErrorString); 973 break; 974 default: 975 setError(QAbstractSocket::NetworkError, SendDatagramErrorString); 976 break; 977 } 978 ret = -1; 991 979 } else { 992 WSABUF buf; 993 #if !defined(Q_OS_WINCE) 994 buf.buf = len ? (char*)data : 0; 995 #else 996 char tmp; 997 buf.buf = len ? (char*)data : &tmp; 998 #endif 999 buf.len = len; 1000 DWORD flags = 0; 1001 DWORD bytesSent = 0; 1002 if (::WSASendTo(socketDescriptor, &buf, 1, &bytesSent, flags, sockAddrPtr, sockAddrSize, 0,0) == SOCKET_ERROR) { 1003 int err = WSAGetLastError(); 1004 WS_ERROR_DEBUG(err); 1005 switch (err) { 1006 case WSAEMSGSIZE: 1007 setError(QAbstractSocket::DatagramTooLargeError, DatagramTooLargeErrorString); 1008 break; 1009 default: 1010 setError(QAbstractSocket::NetworkError, SendDatagramErrorString); 1011 break; 1012 } 1013 ret = -1; 1014 } else { 1015 ret = qint64(bytesSent); 1016 } 1017 } 980 ret = qint64(bytesSent); 981 } 982 1018 983 #if defined (QNATIVESOCKETENGINE_DEBUG) 1019 984 qDebug("QNativeSocketEnginePrivate::nativeSendDatagram(%p \"%s\", %li, \"%s\", %i) == %li", data, … … 1143 1108 tv.tv_usec = (timeout % 1000) * 1000; 1144 1109 1145 if (selectForRead) 1110 if (selectForRead) { 1146 1111 ret = select(0, &fds, 0, 0, timeout < 0 ? 0 : &tv); 1147 else 1148 ret = select(0, 0, &fds, 0, timeout < 0 ? 0 : &tv); 1112 } else { 1113 // select for write 1114 1115 // Windows needs this to report errors when connecting a socket ... 1116 fd_set fdexception; 1117 FD_ZERO(&fdexception); 1118 FD_SET(socketDescriptor, &fdexception); 1119 1120 ret = select(0, 0, &fds, &fdexception, timeout < 0 ? 0 : &tv); 1121 1122 // ... but if it is actually set, pretend it did not happen 1123 if (ret > 0 && FD_ISSET(socketDescriptor, &fdexception)) 1124 ret--; 1125 } 1149 1126 1150 1127 if (readEnabled) … … 1161 1138 if (readEnabled) 1162 1139 readNotifier->setEnabled(false); 1163 1140 1164 1141 fd_set fdread; 1165 1142 fd_set fdwrite; 1143 fd_set fdexception; 1166 1144 1167 1145 int ret = 0; … … 1173 1151 } 1174 1152 memset(&fdwrite, 0, sizeof(fd_set)); 1153 FD_ZERO(&fdexception); 1175 1154 if (checkWrite) { 1176 1155 fdwrite.fd_count = 1; 1177 1156 fdwrite.fd_array[0] = socketDescriptor; 1157 1158 // Windows needs this to report errors when connecting a socket 1159 FD_SET(socketDescriptor, &fdexception); 1178 1160 } 1179 1161 … … 1183 1165 1184 1166 #if !defined(Q_OS_WINCE) 1185 ret = select(socketDescriptor + 1, &fdread, &fdwrite, 0, timeout < 0 ? 0 : &tv);1167 ret = select(socketDescriptor + 1, &fdread, &fdwrite, &fdexception, timeout < 0 ? 0 : &tv); 1186 1168 #else 1187 ret = select(1, &fdread, &fdwrite, 0, timeout < 0 ? 0 : &tv); 1188 #endif 1169 ret = select(1, &fdread, &fdwrite, &fdexception, timeout < 0 ? 0 : &tv); 1170 #endif 1171 1172 //... but if it is actually set, pretend it did not happen 1173 if (ret > 0 && FD_ISSET(socketDescriptor, &fdexception)) 1174 ret--; 1175 1189 1176 if (readEnabled) 1190 1177 readNotifier->setEnabled(true); -
trunk/src/network/socket/qsocks5socketengine.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 60 60 QT_BEGIN_NAMESPACE 61 61 62 #ifdef Q_OS_SYMBIAN 63 static const int MaxWriteBufferSize = 4*1024; 64 #else 62 65 static const int MaxWriteBufferSize = 128*1024; 66 #endif 63 67 64 68 //#define QSOCKS5SOCKETLAYER_DEBUG … … 154 158 static bool qt_socks5_set_host_address_and_port(const QHostAddress &address, quint16 port, QByteArray *pBuf) 155 159 { 156 QSOCKS5_DEBUG << "setting [" << address << ":" << port << "]";160 QSOCKS5_DEBUG << "setting [" << address << ':' << port << ']'; 157 161 158 162 union { … … 187 191 static bool qt_socks5_set_host_name_and_port(const QString &hostname, quint16 port, QByteArray *pBuf) 188 192 { 189 QSOCKS5_DEBUG << "setting [" << hostname << ":" << port << "]";193 QSOCKS5_DEBUG << "setting [" << hostname << ':' << port << ']'; 190 194 191 195 QByteArray encodedHostName = QUrl::toAce(hostname); … … 266 270 267 271 if (ret) { 268 QSOCKS5_DEBUG << "got [" << address << ":" << port << "]";272 QSOCKS5_DEBUG << "got [" << address << ':' << port << ']'; 269 273 *pAddress = address; 270 274 *pPort = port; … … 1125 1129 { 1126 1130 Q_D(QSocks5SocketEngine); 1127 QSOCKS5_DEBUG << "connectToHost" << address << ":"<< port;1131 QSOCKS5_DEBUG << "connectToHost" << address << ':' << port; 1128 1132 1129 1133 setPeerAddress(address); … … 1232 1236 connectData->readBuffer.clear(); 1233 1237 emitReadNotification(); 1238 data->controlSocket->close(); 1239 // cause a disconnect in the outer socket 1240 emitWriteNotification(); 1234 1241 } else if (socks5State == Uninitialized 1235 1242 || socks5State == AuthenticationMethodsSent … … 1242 1249 q_func()->setError(data->controlSocket->error(), data->controlSocket->errorString()); 1243 1250 emitReadNotification(); 1251 emitWriteNotification(); 1244 1252 } 1245 1253 } … … 1380 1388 return false; 1381 1389 } 1382 QSOCKS5_DEBUG << "udp actual address and port" << d->localAddress << ":"<< d->localPort;1390 QSOCKS5_DEBUG << "udp actual address and port" << d->localAddress << ':' << d->localPort; 1383 1391 return true; 1384 1392 #endif // QT_NO_UDPSOCKET … … 1479 1487 { 1480 1488 Q_D(QSocks5SocketEngine); 1481 QSOCKS5_Q_DEBUG << "read( , maxlen = " << maxlen << ")";1489 QSOCKS5_Q_DEBUG << "read( , maxlen = " << maxlen << ')'; 1482 1490 if (d->mode == QSocks5SocketEnginePrivate::ConnectMode) { 1483 1491 if (d->connectData->readBuffer.size() == 0) { … … 1620 1628 #endif // QT_NO_UDPSOCKET 1621 1629 1630 qint64 QSocks5SocketEngine::bytesToWrite() const 1631 { 1632 Q_D(const QSocks5SocketEngine); 1633 if (d->data && d->data->controlSocket) { 1634 return d->data->controlSocket->bytesToWrite(); 1635 } else { 1636 return 0; 1637 } 1638 } 1639 1622 1640 int QSocks5SocketEngine::option(SocketOption option) const 1623 1641 { 1624 Q_UNUSED(option); 1642 Q_D(const QSocks5SocketEngine); 1643 if (d->data && d->data->controlSocket) { 1644 // convert the enum and call the real socket 1645 if (option == QAbstractSocketEngine::LowDelayOption) 1646 return d->data->controlSocket->socketOption(QAbstractSocket::LowDelayOption).toInt(); 1647 if (option == QAbstractSocketEngine::KeepAliveOption) 1648 return d->data->controlSocket->socketOption(QAbstractSocket::KeepAliveOption).toInt(); 1649 } 1625 1650 return -1; 1626 1651 } … … 1628 1653 bool QSocks5SocketEngine::setOption(SocketOption option, int value) 1629 1654 { 1630 Q_UNUSED(option); 1631 Q_UNUSED(value); 1655 Q_D(QSocks5SocketEngine); 1656 if (d->data && d->data->controlSocket) { 1657 // convert the enum and call the real socket 1658 if (option == QAbstractSocketEngine::LowDelayOption) 1659 d->data->controlSocket->setSocketOption(QAbstractSocket::LowDelayOption, value); 1660 if (option == QAbstractSocketEngine::KeepAliveOption) 1661 d->data->controlSocket->setSocketOption(QAbstractSocket::KeepAliveOption, value); 1662 return true; 1663 } 1632 1664 return false; 1633 1665 } … … 1767 1799 Q_D(QSocks5SocketEngine); 1768 1800 1769 QSOCKS5_Q_DEBUG << "setReadNotificationEnabled(" << enable << ")";1801 QSOCKS5_Q_DEBUG << "setReadNotificationEnabled(" << enable << ')'; 1770 1802 1771 1803 bool emitSignal = false; … … 1831 1863 return 0; 1832 1864 } 1833 QS ocks5SocketEngine *engine = new QSocks5SocketEngine(parent);1865 QScopedPointer<QSocks5SocketEngine> engine(new QSocks5SocketEngine(parent)); 1834 1866 engine->setProxy(proxy); 1835 return engine ;1867 return engine.take(); 1836 1868 } 1837 1869 -
trunk/src/network/socket/qsocks5socketengine_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 100 100 qint64 pendingDatagramSize() const; 101 101 #endif // QT_NO_UDPSOCKET 102 103 qint64 bytesToWrite() const; 102 104 103 105 int option(SocketOption option) const; -
trunk/src/network/socket/qtcpserver.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 47 47 48 48 \reentrant 49 \ingroup io49 \ingroup network 50 50 \inmodule QtNetwork 51 51 … … 355 355 if (d->socketEngine) { 356 356 d->socketEngine->close(); 357 d->socketEngine->deleteLater(); 357 QT_TRY { 358 d->socketEngine->deleteLater(); 359 } QT_CATCH(const std::bad_alloc &) { 360 // in out of memory situations, the socketEngine 361 // will be deleted in ~QTcpServer (it's a child-object of this) 362 } 358 363 d->socketEngine = 0; 359 364 } -
trunk/src/network/socket/qtcpserver.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** -
trunk/src/network/socket/qtcpsocket.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 48 48 49 49 \reentrant 50 \ingroup io50 \ingroup network 51 51 \inmodule QtNetwork 52 52 … … 61 61 \bold{Note:} TCP sockets cannot be opened in QIODevice::Unbuffered mode. 62 62 63 \sa QTcpServer, QUdpSocket, QFtp, Q Http, {Fortune Server Example},64 {Fortune Client Example}, {Threaded Fortune ServerExample},65 {Blocking Fortune Client Example}, {LoopbackExample},66 63 \sa QTcpServer, QUdpSocket, QFtp, QNetworkAccessManager, 64 {Fortune Server Example}, {Fortune Client Example}, 65 {Threaded Fortune Server Example}, {Blocking Fortune Client Example}, 66 {Loopback Example}, {Torrent Example} 67 67 */ 68 68 -
trunk/src/network/socket/qtcpsocket.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 44 44 45 45 #include <QtNetwork/qabstractsocket.h> 46 #include <QtCore/qvariant.h> 46 47 47 48 QT_BEGIN_HEADER -
trunk/src/network/socket/qtcpsocket_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** -
trunk/src/network/socket/qudpsocket.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 47 47 \brief The QUdpSocket class provides a UDP socket. 48 48 49 \ingroup io49 \ingroup network 50 50 \inmodule QtNetwork 51 51 … … 71 71 datagram, and readDatagram() to read it. 72 72 73 \note An incoming datagram should be read when you receive the readyRead() 74 signal, otherwise this signal will not be emitted for the next datagram. 75 73 76 Example: 74 77 … … 92 95 This enum describes the different flags you can pass to modify the 93 96 behavior of QUdpSocket::bind(). 97 98 \note On Symbian OS bind flags behaviour depends on process capabilties. 99 If process has NetworkControl capability, the bind attempt with 100 ReuseAddressHint will always succeed even if the address and port is already 101 bound by another socket with any flags. If process does not have 102 NetworkControl capability, the bind attempt to address and port already 103 bound by another socket will always fail. 94 104 95 105 \value ShareAddress Allow other services to bind to the same address … … 348 358 destination. 349 359 360 \warning In S60 5.0 and earlier versions, the writeDatagram return 361 value is not reliable for large datagrams. 362 350 363 \warning Calling this function on a connected UDP socket may 351 364 result in an error and no packet being sent. If you are using a … … 366 379 367 380 qint64 sent = d->socketEngine->writeDatagram(data, size, address, port); 381 #ifdef Q_OS_SYMBIAN 382 if( QSysInfo::s60Version() <= QSysInfo::SV_S60_5_0 ) { 383 // This is evil hack, but for some reason native RSocket::SendTo returns 0, 384 // for large datagrams (such as 600 bytes). Based on comments from Open C team 385 // this should happen only in platforms <= S60 5.0. 386 // As an workaround, we just set sent = size 387 if( sent == 0 ) 388 sent = size; 389 } 390 #endif 368 391 d->cachedSocketDescriptor = d->socketEngine->socketDescriptor(); 369 392 … … 378 401 } 379 402 380 /*! 403 /*! 381 404 \fn qint64 QUdpSocket::writeDatagram(const QByteArray &datagram, 382 405 const QHostAddress &host, quint16 port) -
trunk/src/network/socket/qudpsocket.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** -
trunk/src/network/socket/socket.pri
r157 r561 29 29 socket/qlocalsocket_unix.cpp \ 30 30 socket/qlocalserver_unix.cpp 31 31 unix:HEADERS += \ 32 socket/qnet_unix_p.h 32 33 33 34 win32:SOURCES += socket/qnativesocketengine_win.cpp \ … … 47 48 DEFINES += QT_LOCALSOCKET_TCP 48 49 } 49 50 -
trunk/src/network/ssl/qssl.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 50 50 \since 4.3 51 51 52 \ingroup io 52 \ingroup network 53 \ingroup ssl 53 54 \inmodule QtNetwork 54 55 */ -
trunk/src/network/ssl/qssl.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** -
trunk/src/network/ssl/qsslcertificate.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 47 47 48 48 \reentrant 49 \ingroup io49 \ingroup network 50 50 \ingroup ssl 51 51 \inmodule QtNetwork … … 72 72 certificate, its subject, and its issuer, by calling one of the 73 73 many accessor functions, including version(), serialNumber(), 74 issuerInfo() and subjectInfo(). You can call notValidBefore() and 75 notValidAfter() to check when the certificate was issued, and when 76 it expires. The publicKey() function returns the certificate 74 issuerInfo() and subjectInfo(). You can call effectiveDate() and 75 expiryDate() to check when the certificate starts being 76 effective and when it expires. 77 The publicKey() function returns the certificate 77 78 subject's public key as a QSslKey. You can call issuerInfo() or 78 79 subjectInfo() to get detailed information about the certificate … … 126 127 QT_BEGIN_NAMESPACE 127 128 129 // forward declaration 130 static QMap<QString, QString> _q_mapFromOnelineName(char *name); 131 128 132 /*! 129 133 Constructs a QSslCertificate by reading \a format encoded data … … 158 162 QSslCertificate::QSslCertificate(const QSslCertificate &other) : d(other.d) 159 163 { 160 d->ref.ref();161 164 } 162 165 … … 166 169 QSslCertificate::~QSslCertificate() 167 170 { 168 if (!d->ref.deref())169 delete d;170 171 } 171 172 … … 176 177 QSslCertificate &QSslCertificate::operator=(const QSslCertificate &other) 177 178 { 178 qAtomicAssign(d, other.d);179 d = other.d; 179 180 return *this; 180 181 } … … 242 243 if (isNull()) 243 244 return; 244 if (d->ref == 1)245 delete d;246 else247 d->ref.deref();248 249 245 d = new QSslCertificatePrivate; 250 246 } … … 255 251 QByteArray QSslCertificate::version() const 256 252 { 253 if (d->versionString.isEmpty() && d->x509) 254 d->versionString = 255 QByteArray::number(qlonglong(q_ASN1_INTEGER_get(d->x509->cert_info->version)) + 1); 256 257 257 return d->versionString; 258 258 } 259 259 260 260 /*! 261 Returns the certificate's serial number string .261 Returns the certificate's serial number string in decimal format. 262 262 */ 263 263 QByteArray QSslCertificate::serialNumber() const 264 264 { 265 if (d->serialNumberString.isEmpty() && d->x509) 266 d->serialNumberString = 267 QByteArray::number(qlonglong(q_ASN1_INTEGER_get(d->x509->cert_info->serialNumber))); 268 265 269 return d->serialNumberString; 266 270 } … … 268 272 /*! 269 273 Returns a cryptographic digest of this certificate. By default, 270 an dMD5 digest will be generated, but you can also specify a274 an MD5 digest will be generated, but you can also specify a 271 275 custom \a algorithm. 272 276 */ … … 301 305 QString QSslCertificate::issuerInfo(SubjectInfo info) const 302 306 { 307 if (d->issuerInfo.isEmpty() && d->x509) 308 d->issuerInfo = 309 _q_mapFromOnelineName(q_X509_NAME_oneline(q_X509_get_issuer_name(d->x509), 0, 0)); 310 303 311 return d->issuerInfo.value(_q_SubjectInfoToString(info)); 304 312 } … … 328 336 QString QSslCertificate::subjectInfo(SubjectInfo info) const 329 337 { 338 if (d->subjectInfo.isEmpty() && d->x509) 339 d->subjectInfo = 340 _q_mapFromOnelineName(q_X509_NAME_oneline(q_X509_get_subject_name(d->x509), 0, 0)); 341 330 342 return d->subjectInfo.value(_q_SubjectInfoToString(info)); 331 343 } … … 363 375 return result; 364 376 365 STACK *altNames = (STACK*)q_X509_get_ext_d2i(d->x509, NID_subject_alt_name, 0, 0);377 STACK_OF(GENERAL_NAME) *altNames = (STACK_OF(GENERAL_NAME)*)q_X509_get_ext_d2i(d->x509, NID_subject_alt_name, 0, 0); 366 378 367 379 if (altNames) { … … 378 390 379 391 const char *altNameStr = reinterpret_cast<const char *>(q_ASN1_STRING_data(genName->d.ia5)); 380 const QString altName = Q Latin1String(QByteArray(altNameStr, len));392 const QString altName = QString::fromLatin1(altNameStr, len); 381 393 if (genName->type == GEN_DNS) 382 394 result.insert(QSsl::DnsEntry, altName); … … 384 396 result.insert(QSsl::EmailEntry, altName); 385 397 } 386 q_sk_ free(altNames);398 q_sk_pop_free((STACK*)altNames, reinterpret_cast<void(*)(void*)>(q_sk_free)); 387 399 } 388 400 … … 611 623 array = array.toBase64(); 612 624 QByteArray tmp; 613 for (int i = 0; i < array.size() - 64; i += 64) {625 for (int i = 0; i <= array.size() - 64; i += 64) { 614 626 tmp += QByteArray::fromRawData(array.data() + i, 64); 615 627 tmp += "\n"; … … 662 674 if (!x509 || !QSslSocket::supportsSsl()) 663 675 return certificate; 664 665 certificate.d->issuerInfo =666 _q_mapFromOnelineName(q_X509_NAME_oneline(q_X509_get_issuer_name(x509), 0, 0));667 certificate.d->subjectInfo =668 _q_mapFromOnelineName(q_X509_NAME_oneline(q_X509_get_subject_name(x509), 0, 0));669 676 670 677 ASN1_TIME *nbef = q_X509_get_notBefore(x509); … … 687 694 688 695 if (ch == '\n') { 689 *offset ++;696 *offset += 1; 690 697 return true; 691 698 } … … 767 774 debug << "QSslCertificate(" 768 775 << certificate.version() 769 << ","<< certificate.serialNumber()770 << ","<< certificate.digest().toBase64()771 << ","<< certificate.issuerInfo(QSslCertificate::Organization)772 << ","<< certificate.subjectInfo(QSslCertificate::Organization)773 << ","<< certificate.alternateSubjectNames()776 << ',' << certificate.serialNumber() 777 << ',' << certificate.digest().toBase64() 778 << ',' << certificate.issuerInfo(QSslCertificate::Organization) 779 << ',' << certificate.subjectInfo(QSslCertificate::Organization) 780 << ',' << certificate.alternateSubjectNames() 774 781 #ifndef QT_NO_TEXTSTREAM 775 << ","<< certificate.effectiveDate()776 << ","<< certificate.expiryDate()782 << ',' << certificate.effectiveDate() 783 << ',' << certificate.expiryDate() 777 784 #endif 778 << ")";785 << ')'; 779 786 return debug; 780 787 } -
trunk/src/network/ssl/qsslcertificate.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 48 48 #include <QtCore/qcryptographichash.h> 49 49 #include <QtCore/qregexp.h> 50 #include <QtCore/qsharedpointer.h> 50 51 #include <QtNetwork/qssl.h> 51 52 … … 119 120 120 121 private: 121 Q SslCertificatePrivate *d;122 QExplicitlySharedDataPointer<QSslCertificatePrivate> d; 122 123 friend class QSslCertificatePrivate; 123 124 friend class QSslSocketBackendPrivate; -
trunk/src/network/ssl/qsslcertificate_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 72 72 { 73 73 QSslSocketPrivate::ensureInitialized(); 74 ref = 1;75 74 } 76 75 -
trunk/src/network/ssl/qsslcipher.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 47 47 48 48 \reentrant 49 \ingroup io49 \ingroup network 50 50 \ingroup ssl 51 51 \inmodule QtNetwork … … 65 65 #ifndef QT_NO_DEBUG_STREAM 66 66 #include <QtCore/qdebug.h> 67 #endif 67 68 68 69 QT_BEGIN_NAMESPACE 69 #endif70 70 71 71 /*! … … 104 104 : d(new QSslCipherPrivate) 105 105 { 106 *d = *other.d;106 *d.data() = *other.d.data(); 107 107 } 108 108 … … 112 112 QSslCipher::~QSslCipher() 113 113 { 114 delete d;115 114 } 116 115 … … 121 120 QSslCipher &QSslCipher::operator=(const QSslCipher &other) 122 121 { 123 *d = *other.d;122 *d.data() = *other.d.data(); 124 123 return *this; 125 124 } … … 232 231 << ", bits=" << cipher.usedBits() 233 232 << ", proto=" << qPrintable(cipher.protocolString()) 234 << ")";233 << ')'; 235 234 return debug; 236 235 } -
trunk/src/network/ssl/qsslcipher.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 45 45 46 46 #include <QtCore/qstring.h> 47 #include <QtCore/qscopedpointer.h> 47 48 #include <QtNetwork/qssl.h> 48 49 … … 79 80 80 81 private: 81 QS slCipherPrivate *d;82 QScopedPointer<QSslCipherPrivate> d; 82 83 friend class QSslSocketBackendPrivate; 83 84 }; -
trunk/src/network/ssl/qsslcipher_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** -
trunk/src/network/ssl/qsslconfiguration.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 67 67 \reentrant 68 68 \inmodule QtNetwork 69 \ingroup io69 \ingroup network 70 70 \ingroup ssl 71 71 -
trunk/src/network/ssl/qsslconfiguration.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 42 42 /**************************************************************************** 43 43 ** 44 ** In addition, as a special exception, Trolltechgives permission to link44 ** In addition, as a special exception, Nokia gives permission to link 45 45 ** the code of its release of Qt with the OpenSSL project's "OpenSSL" library 46 46 ** (or modified versions of the "OpenSSL" library that use the same license -
trunk/src/network/ssl/qsslconfiguration_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 42 42 /**************************************************************************** 43 43 ** 44 ** In addition, as a special exception, Trolltechgives permission to link44 ** In addition, as a special exception, Nokia gives permission to link 45 45 ** the code of its release of Qt with the OpenSSL project's "OpenSSL" library 46 46 ** (or modified versions of the "OpenSSL" library that use the same license -
trunk/src/network/ssl/qsslerror.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 47 47 48 48 \reentrant 49 \ingroup io49 \ingroup network 50 50 \ingroup ssl 51 51 \inmodule QtNetwork … … 92 92 93 93 #include "qsslerror.h" 94 #include "qsslsocket.h" 94 95 #ifndef QT_NO_DEBUG_STREAM 95 96 #include <QtCore/qdebug.h> … … 106 107 107 108 /*! 108 Constructs a QSslError object. The two optional arguments specify the \a 109 Constructs a QSslError object with no error and default certificate. 110 111 */ 112 113 // RVCT compiler in debug build does not like about default values in const- 114 // So as an workaround we define all constructor overloads here explicitly 115 QSslError::QSslError() 116 : d(new QSslErrorPrivate) 117 { 118 d->error = QSslError::NoError; 119 d->certificate = QSslCertificate(); 120 } 121 122 /*! 123 Constructs a QSslError object. The argument specifies the \a 124 error that occurred. 125 126 */ 127 QSslError::QSslError(SslError error) 128 : d(new QSslErrorPrivate) 129 { 130 d->error = error; 131 d->certificate = QSslCertificate(); 132 } 133 134 /*! 135 Constructs a QSslError object. The two arguments specify the \a 109 136 error that occurred, and which \a certificate the error relates to. 110 137 … … 124 151 : d(new QSslErrorPrivate) 125 152 { 126 *d = *other.d;153 *d.data() = *other.d.data(); 127 154 } 128 155 … … 132 159 QSslError::~QSslError() 133 160 { 134 delete d;135 161 } 136 162 … … 142 168 QSslError &QSslError::operator=(const QSslError &other) 143 169 { 144 *d = *other.d;170 *d.data() = *other.d.data(); 145 171 return *this; 146 172 } … … 185 211 switch (d->error) { 186 212 case NoError: 187 errStr = Q Object::tr(QT_TRANSLATE_NOOP(QSslError, "No error"));213 errStr = QSslSocket::tr("No error"); 188 214 break; 189 215 case UnableToGetIssuerCertificate: 190 errStr = Q Object::tr(QT_TRANSLATE_NOOP(QSslError, "The issuer certificate could not be found"));216 errStr = QSslSocket::tr("The issuer certificate could not be found"); 191 217 break; 192 218 case UnableToDecryptCertificateSignature: 193 errStr = Q Object::tr(QT_TRANSLATE_NOOP(QSslError, "The certificate signature could not be decrypted"));219 errStr = QSslSocket::tr("The certificate signature could not be decrypted"); 194 220 break; 195 221 case UnableToDecodeIssuerPublicKey: 196 errStr = Q Object::tr(QT_TRANSLATE_NOOP(QSslError, "The public key in the certificate could not be read"));222 errStr = QSslSocket::tr("The public key in the certificate could not be read"); 197 223 break; 198 224 case CertificateSignatureFailed: 199 errStr = Q Object::tr(QT_TRANSLATE_NOOP(QSslError, "The signature of the certificate is invalid"));225 errStr = QSslSocket::tr("The signature of the certificate is invalid"); 200 226 break; 201 227 case CertificateNotYetValid: 202 errStr = Q Object::tr(QT_TRANSLATE_NOOP(QSslError, "The certificate is not yet valid"));228 errStr = QSslSocket::tr("The certificate is not yet valid"); 203 229 break; 204 230 case CertificateExpired: 205 errStr = Q Object::tr(QT_TRANSLATE_NOOP(QSslError, "The certificate has expired"));231 errStr = QSslSocket::tr("The certificate has expired"); 206 232 break; 207 233 case InvalidNotBeforeField: 208 errStr = Q Object::tr(QT_TRANSLATE_NOOP(QSslError, "The certificate's notBefore field contains an invalid time"));234 errStr = QSslSocket::tr("The certificate's notBefore field contains an invalid time"); 209 235 break; 210 236 case InvalidNotAfterField: 211 errStr = Q Object::tr(QT_TRANSLATE_NOOP(QSslError, "The certificate's notAfter field contains an invalid time"));237 errStr = QSslSocket::tr("The certificate's notAfter field contains an invalid time"); 212 238 break; 213 239 case SelfSignedCertificate: 214 errStr = Q Object::tr(QT_TRANSLATE_NOOP(QSslError, "The certificate is self-signed, and untrusted"));240 errStr = QSslSocket::tr("The certificate is self-signed, and untrusted"); 215 241 break; 216 242 case SelfSignedCertificateInChain: 217 errStr = Q Object::tr(QT_TRANSLATE_NOOP(QSslError, "The root certificate of the certificate chain is self-signed, and untrusted"));243 errStr = QSslSocket::tr("The root certificate of the certificate chain is self-signed, and untrusted"); 218 244 break; 219 245 case UnableToGetLocalIssuerCertificate: 220 errStr = Q Object::tr(QT_TRANSLATE_NOOP(QSslError, "The issuer certificate of a locally looked up certificate could not be found"));246 errStr = QSslSocket::tr("The issuer certificate of a locally looked up certificate could not be found"); 221 247 break; 222 248 case UnableToVerifyFirstCertificate: 223 errStr = Q Object::tr(QT_TRANSLATE_NOOP(QSslError, "No certificates could be verified"));249 errStr = QSslSocket::tr("No certificates could be verified"); 224 250 break; 225 251 case InvalidCaCertificate: 226 errStr = Q Object::tr(QT_TRANSLATE_NOOP(QSslError, "One of the CA certificates is invalid"));252 errStr = QSslSocket::tr("One of the CA certificates is invalid"); 227 253 break; 228 254 case PathLengthExceeded: 229 errStr = Q Object::tr(QT_TRANSLATE_NOOP(QSslError, "The basicConstraints pathlength parameter has been exceeded"));255 errStr = QSslSocket::tr("The basicConstraints path length parameter has been exceeded"); 230 256 break; 231 257 case InvalidPurpose: 232 errStr = Q Object::tr(QT_TRANSLATE_NOOP(QSslError, "The supplied certificate is unsuited for this purpose"));258 errStr = QSslSocket::tr("The supplied certificate is unsuitable for this purpose"); 233 259 break; 234 260 case CertificateUntrusted: 235 errStr = Q Object::tr(QT_TRANSLATE_NOOP(QSslError, "The root CA certificate is not trusted for this purpose"));261 errStr = QSslSocket::tr("The root CA certificate is not trusted for this purpose"); 236 262 break; 237 263 case CertificateRejected: 238 errStr = Q Object::tr(QT_TRANSLATE_NOOP(QSslError, "The root CA certificate is marked to reject the specified purpose"));264 errStr = QSslSocket::tr("The root CA certificate is marked to reject the specified purpose"); 239 265 break; 240 266 case SubjectIssuerMismatch: // hostname mismatch 241 errStr = QObject::tr(QT_TRANSLATE_NOOP(QSslError, 242 "The current candidate issuer certificate was rejected because its" 243 " subject name did not match the issuer name of the current certificate")); 267 errStr = QSslSocket::tr("The current candidate issuer certificate was rejected because its" 268 " subject name did not match the issuer name of the current certificate"); 244 269 break; 245 270 case AuthorityIssuerSerialNumberMismatch: 246 errStr = Q Object::tr(QT_TRANSLATE_NOOP(QSslError,"The current candidate issuer certificate was rejected because"247 248 " authority key identifier of the current certificate"));271 errStr = QSslSocket::tr("The current candidate issuer certificate was rejected because" 272 " its issuer name and serial number was present and did not match the" 273 " authority key identifier of the current certificate"); 249 274 break; 250 275 case NoPeerCertificate: 251 errStr = Q Object::tr(QT_TRANSLATE_NOOP(QSslError, "The peer did not present any certificate"));276 errStr = QSslSocket::tr("The peer did not present any certificate"); 252 277 break; 253 278 case HostNameMismatch: 254 errStr = QObject::tr(QT_TRANSLATE_NOOP(QSslError, 255 "The host name did not match any of the valid hosts" 256 " for this certificate")); 279 errStr = QSslSocket::tr("The host name did not match any of the valid hosts" 280 " for this certificate"); 257 281 break; 258 282 case NoSslSupport: 259 283 break; 260 284 default: 261 errStr = Q Object::tr(QT_TRANSLATE_NOOP(QSslError, "Unknown error"));285 errStr = QSslSocket::tr("Unknown error"); 262 286 break; 263 287 } -
trunk/src/network/ssl/qsslerror.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 87 87 }; 88 88 89 QSslError(SslError error = NoError, const QSslCertificate &certificate = QSslCertificate()); 89 // RVCT compiler in debug build does not like about default values in const- 90 // So as an workaround we define all constructor overloads here explicitly 91 QSslError(); 92 QSslError(SslError error); 93 QSslError(SslError error, const QSslCertificate &certificate); 94 90 95 QSslError(const QSslError &other); 96 91 97 ~QSslError(); 92 98 QSslError &operator=(const QSslError &other); … … 100 106 101 107 private: 102 QS slErrorPrivate *d;108 QScopedPointer<QSslErrorPrivate> d; 103 109 }; 104 110 -
trunk/src/network/ssl/qsslkey.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 47 47 48 48 \reentrant 49 \ingroup io49 \ingroup network 50 50 \ingroup ssl 51 51 \inmodule QtNetwork … … 272 272 QSslKey::QSslKey(const QSslKey &other) : d(other.d) 273 273 { 274 d->ref.ref();275 274 } 276 275 … … 280 279 QSslKey::~QSslKey() 281 280 { 282 if (!d->ref.deref())283 delete d;284 281 } 285 282 … … 292 289 QSslKey &QSslKey::operator=(const QSslKey &other) 293 290 { 294 qAtomicAssign(d, other.d);291 d = other.d; 295 292 return *this; 296 293 } … … 313 310 void QSslKey::clear() 314 311 { 315 if (!d->ref.deref()) { 316 delete d; 317 d = new QSslKeyPrivate; 318 } 312 d = new QSslKeyPrivate; 319 313 } 320 314 … … 461 455 << ", " << (key.algorithm() == QSsl::Rsa ? "RSA" : "DSA") 462 456 << ", " << key.length() 463 << ")";457 << ')'; 464 458 return debug; 465 459 } -
trunk/src/network/ssl/qsslkey.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 46 46 #include <QtCore/qnamespace.h> 47 47 #include <QtCore/qbytearray.h> 48 #include <QtCore/qsharedpointer.h> 48 49 #include <QtNetwork/qssl.h> 49 50 … … 59 60 60 61 class QIODevice; 61 62 62 63 class QSslKeyPrivate; 63 64 class Q_NETWORK_EXPORT QSslKey … … 93 94 94 95 private: 95 Q SslKeyPrivate *d;96 QExplicitlySharedDataPointer<QSslKeyPrivate> d; 96 97 friend class QSslCertificate; 97 98 }; -
trunk/src/network/ssl/qsslkey_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 70 70 { 71 71 clear(); 72 ref = 1;73 72 } 74 73 … … 92 91 93 92 QAtomicInt ref; 93 94 private: 95 Q_DISABLE_COPY(QSslKeyPrivate) 94 96 }; 95 97 -
trunk/src/network/ssl/qsslsocket.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 50 50 51 51 \reentrant 52 \ingroup io52 \ingroup network 53 53 \ingroup ssl 54 54 \inmodule QtNetwork … … 114 114 internal buffer, and you can call write() or putChar() to write 115 115 data back to the peer. QSslSocket will automatically encrypt the 116 written data for you, and emit bytesWritten() once the data has117 been written to the peer.116 written data for you, and emit encryptedBytesWritten() once 117 the data has been written to the peer. 118 118 119 119 As a convenience, QSslSocket supports QTcpSocket's blocking … … 150 150 for use in the OpenSSL Toolkit (\l{http://www.openssl.org/}). 151 151 152 \note Be aware of the difference between the bytesWritten() signal and 153 the encryptedBytesWritten() signal. For a QTcpSocket, bytesWritten() 154 will get emitted as soon as data has been written to the TCP socket. 155 For a QSslSocket, bytesWritten() will get emitted when the data 156 is being encrypted and encryptedBytesWritten() 157 will get emitted as soon as data has been written to the TCP socket. 158 152 159 \sa QSslCertificate, QSslCipher, QSslError 153 160 */ … … 357 364 ignoreSslErrors(), either from inside a slot function connected to 358 365 the sslErrors() signal, or prior to entering encrypted mode. If 359 ignoreSslErrors is not called, the connection is dropped, signal366 ignoreSslErrors() is not called, the connection is dropped, signal 360 367 disconnected() is emitted, and QSslSocket returns to the 361 368 UnconnectedState. … … 398 405 399 406 /*! 407 \since 4.6 408 \overload 409 410 In addition to the original behaviour of connectToHostEncrypted, 411 this overloaded method enables the usage of a different hostname 412 (\a sslPeerName) for the certificate validation instead of 413 the one used for the TCP connection (\a hostName). 414 415 \sa connectToHostEncrypted() 416 */ 417 void QSslSocket::connectToHostEncrypted(const QString &hostName, quint16 port, 418 const QString &sslPeerName, OpenMode mode) 419 { 420 Q_D(QSslSocket); 421 if (d->state == ConnectedState || d->state == ConnectingState) { 422 qWarning("QSslSocket::connectToHostEncrypted() called when already connecting/connected"); 423 return; 424 } 425 426 d->init(); 427 d->autoStartHandshake = true; 428 d->initialized = true; 429 d->verificationPeerName = sslPeerName; 430 431 // Note: When connecting to localhost, some platforms (e.g., HP-UX and some BSDs) 432 // establish the connection immediately (i.e., first attempt). 433 connectToHost(hostName, port, mode); 434 } 435 436 /*! 400 437 Initializes QSslSocket with the native socket descriptor \a 401 438 socketDescriptor. Returns true if \a socketDescriptor is accepted … … 413 450 Q_D(QSslSocket); 414 451 #ifdef QSSLSOCKET_DEBUG 415 qDebug() << "QSslSocket::setSocketDescriptor(" << socketDescriptor << ","416 << state << "," << openMode << ")";452 qDebug() << "QSslSocket::setSocketDescriptor(" << socketDescriptor << ',' 453 << state << ',' << openMode << ')'; 417 454 #endif 418 455 if (!d->plainSocket) … … 432 469 433 470 /*! 471 \since 4.6 472 Sets the given \a option to the value described by \a value. 473 474 \sa socketOption() 475 */ 476 void QSslSocket::setSocketOption(QAbstractSocket::SocketOption option, const QVariant &value) 477 { 478 Q_D(QSslSocket); 479 if (d->plainSocket) 480 d->plainSocket->setSocketOption(option, value); 481 } 482 483 /*! 484 \since 4.6 485 Returns the value of the \a option option. 486 487 \sa setSocketOption() 488 */ 489 QVariant QSslSocket::socketOption(QAbstractSocket::SocketOption option) 490 { 491 Q_D(QSslSocket); 492 if (d->plainSocket) 493 return d->plainSocket->socketOption(option); 494 else 495 return QVariant(); 496 } 497 498 /*! 434 499 Returns the current mode for the socket; either UnencryptedMode, where 435 500 QSslSocket behaves identially to QTcpSocket, or one of SslClientMode or … … 451 516 452 517 An encrypted socket encrypts all data that is written by calling write() 453 or putChar() before the data is written to the network, and de scrypts all518 or putChar() before the data is written to the network, and decrypts all 454 519 incoming data as the data is received from the network, before you call 455 520 read(), readLine() or getChar(). … … 654 719 qDebug() << "QSslSocket::close()"; 655 720 #endif 721 Q_D(QSslSocket); 722 if (d->plainSocket) 723 d->plainSocket->close(); 656 724 QTcpSocket::close(); 725 726 // must be cleared, reading/writing not possible on closed socket: 727 d->readBuffer.clear(); 728 d->writeBuffer.clear(); 729 // for QTcpSocket this is already done because it uses the readBuffer/writeBuffer 730 // if the QIODevice it is based on 731 // ### FIXME QSslSocket should probably do similar instead of having 732 // its own readBuffer/writeBuffer 657 733 } 658 734 … … 1259 1335 1260 1336 /*! 1261 Returns the system default CA certificate database for your 1262 system. This database is normally found in a standard place for 1263 your system. If it is not found there, Qt will provide its own 1264 default CA certificate database. The CA certificate database 1337 This function provides a default CA certificate database 1338 shipped together with Qt. The CA certificate database 1265 1339 returned by this function is used to initialize the database 1266 1340 returned by defaultCaCertificates(). You can replace that database … … 1528 1602 Q_D(QSslSocket); 1529 1603 if (d->mode != UnencryptedMode) { 1530 qWarning("QSslSocket::start ClientEncryption: cannot start handshake on non-plain connection");1604 qWarning("QSslSocket::startServerEncryption: cannot start handshake on non-plain connection"); 1531 1605 return; 1532 1606 } … … 1563 1637 { 1564 1638 Q_D(QSslSocket); 1565 d->ignoreSslErrors = true; 1639 d->ignoreAllSslErrors = true; 1640 } 1641 1642 /*! 1643 \overload 1644 \since 4.6 1645 1646 This method tells QSslSocket to ignore only the errors given in \a 1647 errors. 1648 1649 Note that you can set the expected certificate in the SSL error: 1650 If, for instance, you want to connect to a server that uses 1651 a self-signed certificate, consider the following snippet: 1652 1653 \snippet doc/src/snippets/code/src_network_ssl_qsslsocket.cpp 6 1654 1655 Multiple calls to this function will replace the list of errors that 1656 were passed in previous calls. 1657 You can clear the list of errors you want to ignore by calling this 1658 function with an empty list. 1659 1660 \sa sslErrors() 1661 */ 1662 void QSslSocket::ignoreSslErrors(const QList<QSslError> &errors) 1663 { 1664 Q_D(QSslSocket); 1665 d->ignoreErrorsList = errors; 1566 1666 } 1567 1667 … … 1579 1679 #ifdef QSSLSOCKET_DEBUG 1580 1680 qDebug() << "QSslSocket::connectToHostImplementation(" 1581 << hostName << "," << port << "," << openMode << ")";1681 << hostName << ',' << port << ',' << openMode << ')'; 1582 1682 #endif 1583 1683 if (!d->plainSocket) { … … 1653 1753 } 1654 1754 #ifdef QSSLSOCKET_DEBUG 1655 qDebug() << "QSslSocket::readData(" << (void *)data << ","<< maxlen << ") ==" << readBytes;1755 qDebug() << "QSslSocket::readData(" << (void *)data << ',' << maxlen << ") ==" << readBytes; 1656 1756 #endif 1757 1758 // possibly trigger another transmit() to decrypt more data from the socket 1759 if (d->readBuffer.isEmpty() && d->plainSocket->bytesAvailable()) 1760 QMetaObject::invokeMethod(this, "_q_flushReadBuffer", Qt::QueuedConnection); 1761 1657 1762 return readBytes; 1658 1763 } … … 1665 1770 Q_D(QSslSocket); 1666 1771 #ifdef QSSLSOCKET_DEBUG 1667 qDebug() << "QSslSocket::writeData(" << (void *)data << "," << len << ")";1772 qDebug() << "QSslSocket::writeData(" << (void *)data << ',' << len << ')'; 1668 1773 #endif 1669 1774 if (d->mode == UnencryptedMode && !d->autoStartHandshake) … … 1683 1788 */ 1684 1789 QSslSocketPrivate::QSslSocketPrivate() 1685 : initialized(false), readyReadEmittedPointer(0), plainSocket(0) 1790 : initialized(false) 1791 , mode(QSslSocket::UnencryptedMode) 1792 , autoStartHandshake(false) 1793 , connectionEncrypted(false) 1794 , ignoreAllSslErrors(false) 1795 , readyReadEmittedPointer(0) 1796 , plainSocket(0) 1686 1797 { 1687 1798 QSslConfigurationPrivate::deepCopyDefaultConfiguration(&configuration); … … 1703 1814 autoStartHandshake = false; 1704 1815 connectionEncrypted = false; 1705 ignoreSslErrors = false; 1816 ignoreAllSslErrors = false; 1817 1818 // we don't want to clear the ignoreErrorsList, so 1819 // that it is possible setting it before connecting 1820 // ignoreErrorsList.clear(); 1706 1821 1707 1822 readBuffer.clear(); … … 1970 2085 Q_Q(QSslSocket); 1971 2086 #ifdef QSSLSOCKET_DEBUG 1972 qDebug() << "QSslSocket::_q_stateChangedSlot(" << state << ")";2087 qDebug() << "QSslSocket::_q_stateChangedSlot(" << state << ')'; 1973 2088 #endif 1974 2089 q->setSocketState(state); … … 1983 2098 Q_Q(QSslSocket); 1984 2099 #ifdef QSSLSOCKET_DEBUG 1985 qDebug() << "QSslSocket::_q_errorSlot(" << error << ")";2100 qDebug() << "QSslSocket::_q_errorSlot(" << error << ')'; 1986 2101 qDebug() << "\tstate =" << q->state(); 1987 2102 qDebug() << "\terrorString =" << q->errorString(); … … 2018 2133 Q_Q(QSslSocket); 2019 2134 #ifdef QSSLSOCKET_DEBUG 2020 qDebug() << "QSslSocket::_q_bytesWrittenSlot(" << written << ")";2135 qDebug() << "QSslSocket::_q_bytesWrittenSlot(" << written << ')'; 2021 2136 #endif 2022 2137 … … 2039 2154 } 2040 2155 2156 /*! 2157 \internal 2158 */ 2159 void QSslSocketPrivate::_q_flushReadBuffer() 2160 { 2161 // trigger a read from the plainSocket into SSL 2162 if (mode != QSslSocket::UnencryptedMode) 2163 transmit(); 2164 } 2165 2041 2166 QT_END_NAMESPACE 2042 2167 -
trunk/src/network/ssl/qsslsocket.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 87 87 // Autostarting the SSL client handshake. 88 88 void connectToHostEncrypted(const QString &hostName, quint16 port, OpenMode mode = ReadWrite); 89 void connectToHostEncrypted(const QString &hostName, quint16 port, const QString &sslPeerName, OpenMode mode = ReadWrite); 89 90 bool setSocketDescriptor(int socketDescriptor, SocketState state = ConnectedState, 90 91 OpenMode openMode = ReadWrite); 92 93 // ### Qt 5: Make virtual 94 void setSocketOption(QAbstractSocket::SocketOption option, const QVariant &value); 95 QVariant socketOption(QAbstractSocket::SocketOption option); 91 96 92 97 SslMode mode() const; … … 169 174 170 175 static bool supportsSsl(); 176 void ignoreSslErrors(const QList<QSslError> &errors); 171 177 172 178 public Q_SLOTS: … … 202 208 Q_PRIVATE_SLOT(d_func(), void _q_bytesWrittenSlot(qint64)) 203 209 Q_PRIVATE_SLOT(d_func(), void _q_flushWriteBuffer()) 210 Q_PRIVATE_SLOT(d_func(), void _q_flushReadBuffer()) 204 211 friend class QSslSocketBackendPrivate; 205 212 }; -
trunk/src/network/ssl/qsslsocket_openssl.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 277 277 first = false; 278 278 else 279 cipherString.append( ":");279 cipherString.append(':'); 280 280 cipherString.append(cipher.name().toLatin1()); 281 281 } … … 325 325 // Check if the certificate matches the private key. 326 326 if (!q_SSL_CTX_check_private_key(ctx)) { 327 q->setErrorString(QSslSocket::tr("Private key does not certif icatepublic key, %1").arg(SSL_ERRORSTR()));327 q->setErrorString(QSslSocket::tr("Private key does not certify public key, %1").arg(SSL_ERRORSTR())); 328 328 emit q->error(QAbstractSocket::UnknownSocketError); 329 329 return false; … … 483 483 QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates() 484 484 { 485 #ifdef QQ_OS_UNIX 486 // Check known locations for the system's default bundle. ### On Windows, 487 // we should use CAPI to find the bundle, and not rely on default unix 488 // locations. 489 const char *standardLocations[] = {"/etc/ssl/certs/", 490 #if 0 491 // KDE uses KConfig for its SSL store, 492 // but it also stores the bundle at 493 // this location 494 "$HOME/.kde/share/apps/kssl/ca-bundle.crt", 495 #endif 496 0}; 497 const char **it = standardLocations; 498 QStringList nameFilter; 499 nameFilter << QLatin1String("*.pem") << QLatin1String("*.crt"); 500 while (*it) { 501 if (QDirIterator(QLatin1String(*it), nameFilter).hasNext()) 502 return certificatesFromPath(QLatin1String(*it)); 503 ++it; 504 } 505 #endif 506 507 // Qt provides a default bundle when we cannot detect the system's default 508 // bundle. 485 // Qt provides a default bundle of certificates 509 486 QFile caBundle(QLatin1String(":/trolltech/network/ssl/qt-ca-bundle.crt")); 510 487 if (caBundle.open(QIODevice::ReadOnly | QIODevice::Text)) … … 524 501 // Start connecting. This will place outgoing data in the BIO, so we 525 502 // follow up with calling transmit(). 526 testConnection();503 startHandshake(); 527 504 transmit(); 528 505 } … … 537 514 // Start connecting. This will place outgoing data in the BIO, so we 538 515 // follow up with calling transmit(). 539 testConnection();516 startHandshake(); 540 517 transmit(); 541 518 } … … 625 602 qDebug() << "QSslSocketBackendPrivate::transmit: testing encryption"; 626 603 #endif 627 if ( testConnection()) {604 if (startHandshake()) { 628 605 #ifdef QSSLSOCKET_DEBUG 629 606 qDebug() << "QSslSocketBackendPrivate::transmit: encryption established"; … … 644 621 645 622 // If the request is small and the remote host closes the transmission 646 // after sending, there's a chance that testConnection() will already623 // after sending, there's a chance that startHandshake() will already 647 624 // have triggered a shutdown. 648 625 if (!ssl) … … 744 721 } 745 722 746 bool QSslSocketBackendPrivate:: testConnection()723 bool QSslSocketBackendPrivate::startHandshake() 747 724 { 748 725 Q_Q(QSslSocket); … … 785 762 q->setSocketError(QAbstractSocket::SslHandshakeFailedError); 786 763 #ifdef QSSLSOCKET_DEBUG 787 qDebug() << "QSslSocketBackendPrivate:: testConnection: error!" << q->errorString();764 qDebug() << "QSslSocketBackendPrivate::startHandshake: error!" << q->errorString(); 788 765 #endif 789 766 emit q->error(QAbstractSocket::SslHandshakeFailedError); … … 816 793 // if we're the server, don't check CN 817 794 if (mode == QSslSocket::SslClientMode) { 818 QString peerName = q->peerName();795 QString peerName = (verificationPeerName.isEmpty () ? q->peerName() : verificationPeerName); 819 796 QString commonName = configuration.peerCertificate.subjectInfo(QSslCertificate::CommonName); 820 797 … … 863 840 sslErrors = errors; 864 841 emit q->sslErrors(errors); 865 if (doVerifyPeer && !ignoreSslErrors) { 842 843 bool doEmitSslError; 844 if (!ignoreErrorsList.empty()) { 845 // check whether the errors we got are all in the list of expected errors 846 // (applies only if the method QSslSocket::ignoreSslErrors(const QList<QSslError> &errors) 847 // was called) 848 doEmitSslError = false; 849 for (int a = 0; a < errors.count(); a++) { 850 if (!ignoreErrorsList.contains(errors.at(a))) { 851 doEmitSslError = true; 852 break; 853 } 854 } 855 } else { 856 // if QSslSocket::ignoreSslErrors(const QList<QSslError> &errors) was not called and 857 // we get an SSL error, emit a signal unless we ignored all errors (by calling 858 // QSslSocket::ignoreSslErrors() ) 859 doEmitSslError = !ignoreAllSslErrors; 860 } 861 // check whether we need to emit an SSL handshake error 862 if (doVerifyPeer && doEmitSslError) { 866 863 q->setErrorString(sslErrors.first().errorString()); 867 864 q->setSocketError(QAbstractSocket::SslHandshakeFailedError); … … 912 909 if (!ssl || !ctx) 913 910 return QSslCipher(); 911 #if OPENSSL_VERSION_NUMBER >= 0x10000000L 912 // FIXME This is fairly evil, but needed to keep source level compatibility 913 // with the OpenSSL 0.9.x implementation at maximum -- some other functions 914 // don't take a const SSL_CIPHER* when they should 915 SSL_CIPHER *sessionCipher = const_cast<SSL_CIPHER *>(q_SSL_get_current_cipher(ssl)); 916 #else 914 917 SSL_CIPHER *sessionCipher = q_SSL_get_current_cipher(ssl); 918 #endif 915 919 return sessionCipher ? QSslCipher_from_SSL_CIPHER(sessionCipher) : QSslCipher(); 916 920 } -
trunk/src/network/ssl/qsslsocket_openssl_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 58 58 59 59 #ifdef Q_OS_WIN 60 #include < windows.h>60 #include <qt_windows.h> 61 61 #if defined(OCSP_RESPONSE) 62 62 #undef OCSP_RESPONSE … … 78 78 #include <openssl/x509v3.h> 79 79 #include <openssl/x509_vfy.h> 80 #include <openssl/dsa.h> 81 #include <openssl/rsa.h> 82 83 #if OPENSSL_VERSION_NUMBER >= 0x10000000L 84 typedef _STACK STACK; 85 #endif 80 86 81 87 QT_BEGIN_NAMESPACE … … 103 109 void startServerEncryption(); 104 110 void transmit(); 105 bool testConnection();111 bool startHandshake(); 106 112 void disconnectFromHost(); 107 113 void disconnected(); -
trunk/src/network/ssl/qsslsocket_openssl_symbols.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 95 95 DEFINEFUNC3(void *, ASN1_dup, i2d_of_void *a, a, d2i_of_void *b, b, char *c, c, return 0, return) 96 96 #endif 97 DEFINEFUNC(long, ASN1_INTEGER_get, ASN1_INTEGER *a, a, return 0, return) 97 98 DEFINEFUNC(unsigned char *, ASN1_STRING_data, ASN1_STRING *a, a, return 0, return) 98 99 DEFINEFUNC(int, ASN1_STRING_length, ASN1_STRING *a, a, return 0, return) … … 143 144 DEFINEFUNC(int, RAND_status, void, DUMMYARG, return -1, return) 144 145 DEFINEFUNC(void, RSA_free, RSA *a, a, return, DUMMYARG) 146 DEFINEFUNC(int, sk_num, STACK *a, a, return -1, return) 147 DEFINEFUNC2(void, sk_pop_free, STACK *a, a, void (*b)(void*), b, return, DUMMYARG) 148 #if OPENSSL_VERSION_NUMBER >= 0x10000000L 149 DEFINEFUNC(void, sk_free, _STACK *a, a, return, DUMMYARG) 150 DEFINEFUNC2(void *, sk_value, STACK *a, a, int b, b, return 0, return) 151 #else 145 152 DEFINEFUNC(void, sk_free, STACK *a, a, return, DUMMYARG) 146 DEFINEFUNC(int, sk_num, STACK *a, a, return -1, return)147 153 DEFINEFUNC2(char *, sk_value, STACK *a, a, int b, b, return 0, return) 154 #endif 148 155 DEFINEFUNC(int, SSL_accept, SSL *a, a, return -1, return) 149 156 DEFINEFUNC(int, SSL_clear, SSL *a, a, return -1, return) … … 158 165 DEFINEFUNC4(long, SSL_CTX_ctrl, SSL_CTX *a, a, int b, b, long c, c, void *d, d, return -1, return) 159 166 DEFINEFUNC(void, SSL_CTX_free, SSL_CTX *a, a, return, DUMMYARG) 167 #if OPENSSL_VERSION_NUMBER >= 0x10000000L 168 DEFINEFUNC(SSL_CTX *, SSL_CTX_new, const SSL_METHOD *a, a, return 0, return) 169 #else 160 170 DEFINEFUNC(SSL_CTX *, SSL_CTX_new, SSL_METHOD *a, a, return 0, return) 171 #endif 161 172 DEFINEFUNC2(int, SSL_CTX_set_cipher_list, SSL_CTX *a, a, const char *b, b, return -1, return) 162 173 DEFINEFUNC(int, SSL_CTX_set_default_verify_paths, SSL_CTX *a, a, return -1, return) … … 175 186 DEFINEFUNC(STACK_OF(SSL_CIPHER) *, SSL_get_ciphers, SSL *a, a, return 0, return) 176 187 #endif 188 #if OPENSSL_VERSION_NUMBER >= 0x10000000L 189 DEFINEFUNC(const SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return 0, return) 190 #else 177 191 DEFINEFUNC(SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return 0, return) 192 #endif 178 193 DEFINEFUNC2(int, SSL_get_error, SSL *a, a, int b, b, return -1, return) 179 194 DEFINEFUNC(STACK_OF(X509) *, SSL_get_peer_cert_chain, SSL *a, a, return 0, return) … … 193 208 DEFINEFUNC(void, SSL_set_connect_state, SSL *a, a, return, DUMMYARG) 194 209 DEFINEFUNC(int, SSL_shutdown, SSL *a, a, return -1, return) 210 #if OPENSSL_VERSION_NUMBER >= 0x10000000L 211 DEFINEFUNC(const SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return 0, return) 212 DEFINEFUNC(const SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return 0, return) 213 DEFINEFUNC(const SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return 0, return) 214 DEFINEFUNC(const SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return 0, return) 215 DEFINEFUNC(const SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return 0, return) 216 DEFINEFUNC(const SSL_METHOD *, SSLv3_server_method, DUMMYARG, DUMMYARG, return 0, return) 217 DEFINEFUNC(const SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return 0, return) 218 DEFINEFUNC(const SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return 0, return) 219 #else 195 220 DEFINEFUNC(SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return 0, return) 196 221 DEFINEFUNC(SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return 0, return) … … 201 226 DEFINEFUNC(SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return 0, return) 202 227 DEFINEFUNC(SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return 0, return) 228 #endif 203 229 DEFINEFUNC3(int, SSL_write, SSL *a, a, const void *b, b, int c, c, return -1, return) 204 230 DEFINEFUNC2(int, X509_cmp, X509 *a, a, X509 *b, b, return -1, return) … … 232 258 DEFINEFUNC(void, OPENSSL_add_all_algorithms_conf, void, DUMMYARG, return, DUMMYARG) 233 259 260 #ifdef Q_OS_SYMBIAN 261 #define RESOLVEFUNC(func, ordinal, lib) \ 262 if (!(_q_##func = _q_PTR_##func(lib->resolve(#ordinal)))) \ 263 qWarning("QSslSocket: cannot resolve "#func); 264 #else 234 265 #define RESOLVEFUNC(func) \ 235 266 if (!(_q_##func = _q_PTR_##func(libs.first->resolve(#func))) \ 236 267 && !(_q_##func = _q_PTR_##func(libs.second->resolve(#func)))) \ 237 268 qWarning("QSslSocket: cannot resolve "#func); 269 #endif 238 270 239 271 #if !defined QT_LINKED_OPENSSL … … 336 368 pair.second = libeay32; 337 369 return pair; 338 370 # elif defined(Q_OS_SYMBIAN) 371 QLibrary *libssl = new QLibrary(QLatin1String("libssl")); 372 if (!libssl->load()) { 373 // Cannot find ssleay32.dll 374 delete libssl; 375 return pair; 376 } 377 378 QLibrary *libcrypto = new QLibrary(QLatin1String("libcrypto")); 379 if (!libcrypto->load()) { 380 delete libcrypto; 381 delete libssl; 382 return pair; 383 } 384 385 pair.first = libssl; 386 pair.second = libcrypto; 387 return pair; 339 388 # elif defined(Q_OS_UNIX) 340 389 QLibrary *&libssl = pair.first; … … 365 414 // paths. See the man page for dlopen(3) on your system for more information. 366 415 416 #ifdef Q_OS_OPENBSD 417 libcrypto->setLoadHints(QLibrary::ExportExternalSymbolsHint); 418 #endif 367 419 #ifdef SHLIB_VERSION_NUMBER 368 420 // first attempt: the canonical name is libssl.so.<SHLIB_VERSION_NUMBER> 369 421 libssl->setFileNameAndVersion(QLatin1String("ssl"), QLatin1String(SHLIB_VERSION_NUMBER)); 370 422 libcrypto->setFileNameAndVersion(QLatin1String("crypto"), QLatin1String(SHLIB_VERSION_NUMBER)); 371 if (lib ssl->load() && libcrypto->load()) {423 if (libcrypto->load() && libssl->load()) { 372 424 // libssl.so.<SHLIB_VERSION_NUMBER> and libcrypto.so.<SHLIB_VERSION_NUMBER> found 373 425 return pair; … … 381 433 libssl->setFileNameAndVersion(QLatin1String("ssl"), -1); 382 434 libcrypto->setFileNameAndVersion(QLatin1String("crypto"), -1); 383 if (lib ssl->load() && libcrypto->load()) {435 if (libcrypto->load() && libssl->load()) { 384 436 // libssl.so.0 and libcrypto.so.0 found 385 437 return pair; … … 396 448 libssl->setFileNameAndVersion(ssl, -1); 397 449 libcrypto->setFileNameAndVersion(crypto, -1); 398 if (lib ssl->load() && libcrypto->load()) {450 if (libcrypto->load() && libssl->load()) { 399 451 // libssl.so.0 and libcrypto.so.0 found 400 452 return pair; … … 435 487 return false; 436 488 489 #ifdef Q_OS_SYMBIAN 490 #ifdef SSLEAY_MACROS 491 RESOLVEFUNC(ASN1_dup, 125, libs.second ) 492 #endif 493 RESOLVEFUNC(ASN1_INTEGER_get, 48, libs.second ) 494 RESOLVEFUNC(ASN1_STRING_data, 71, libs.second ) 495 RESOLVEFUNC(ASN1_STRING_length, 76, libs.second ) 496 RESOLVEFUNC(BIO_ctrl, 184, libs.second ) 497 RESOLVEFUNC(BIO_free, 209, libs.second ) 498 RESOLVEFUNC(BIO_new, 222, libs.second ) 499 RESOLVEFUNC(BIO_new_mem_buf, 230, libs.second ) 500 RESOLVEFUNC(BIO_read, 244, libs.second ) 501 RESOLVEFUNC(BIO_s_mem, 251, libs.second ) 502 RESOLVEFUNC(BIO_write, 269, libs.second ) 503 RESOLVEFUNC(BN_num_bits, 387, libs.second ) 504 RESOLVEFUNC(CRYPTO_free, 469, libs.second ) 505 RESOLVEFUNC(CRYPTO_num_locks, 500, libs.second ) 506 RESOLVEFUNC(CRYPTO_set_id_callback, 513, libs.second ) 507 RESOLVEFUNC(CRYPTO_set_locking_callback, 516, libs.second ) 508 RESOLVEFUNC(DSA_free, 594, libs.second ) 509 RESOLVEFUNC(ERR_error_string, 744, libs.second ) 510 RESOLVEFUNC(ERR_get_error, 749, libs.second ) 511 RESOLVEFUNC(EVP_des_ede3_cbc, 919, libs.second ) 512 RESOLVEFUNC(EVP_PKEY_assign, 859, libs.second ) 513 RESOLVEFUNC(EVP_PKEY_free, 867, libs.second ) 514 RESOLVEFUNC(EVP_PKEY_get1_DSA, 869, libs.second ) 515 RESOLVEFUNC(EVP_PKEY_get1_RSA, 870, libs.second ) 516 RESOLVEFUNC(EVP_PKEY_new, 876, libs.second ) 517 RESOLVEFUNC(EVP_PKEY_type, 882, libs.second ) 518 RESOLVEFUNC(OBJ_nid2sn, 1036, libs.second ) 519 RESOLVEFUNC(OBJ_obj2nid, 1037, libs.second ) 520 #ifdef SSLEAY_MACROS // ### verify 521 RESOLVEFUNC(PEM_ASN1_read_bio, 1180, libs.second ) 522 #else 523 RESOLVEFUNC(PEM_read_bio_DSAPrivateKey, 1219, libs.second ) 524 RESOLVEFUNC(PEM_read_bio_RSAPrivateKey, 1228, libs.second ) 525 RESOLVEFUNC(PEM_write_bio_DSAPrivateKey, 1260, libs.second ) 526 RESOLVEFUNC(PEM_write_bio_RSAPrivateKey, 1271, libs.second ) 527 #endif 528 RESOLVEFUNC(PEM_read_bio_DSA_PUBKEY, 1220, libs.second ) 529 RESOLVEFUNC(PEM_read_bio_RSA_PUBKEY, 1230, libs.second ) 530 RESOLVEFUNC(PEM_write_bio_DSA_PUBKEY, 1261, libs.second ) 531 RESOLVEFUNC(PEM_write_bio_RSA_PUBKEY, 1273, libs.second ) 532 RESOLVEFUNC(RAND_seed, 1426, libs.second ) 533 RESOLVEFUNC(RAND_status, 1429, libs.second ) 534 RESOLVEFUNC(RSA_free, 1450, libs.second ) 535 RESOLVEFUNC(sk_free, 2571, libs.second ) 536 RESOLVEFUNC(sk_num, 2576, libs.second ) 537 RESOLVEFUNC(sk_pop_free, 2578, libs.second ) 538 RESOLVEFUNC(sk_value, 2585, libs.second ) 539 RESOLVEFUNC(SSL_CIPHER_description, 11, libs.first ) 540 RESOLVEFUNC(SSL_CTX_check_private_key, 21, libs.first ) 541 RESOLVEFUNC(SSL_CTX_ctrl, 22, libs.first ) 542 RESOLVEFUNC(SSL_CTX_free, 24, libs.first ) 543 RESOLVEFUNC(SSL_CTX_new, 35, libs.first ) 544 RESOLVEFUNC(SSL_CTX_set_cipher_list, 40, libs.first ) 545 RESOLVEFUNC(SSL_CTX_set_default_verify_paths, 44, libs.first ) 546 RESOLVEFUNC(SSL_CTX_set_verify, 56, libs.first ) 547 RESOLVEFUNC(SSL_CTX_set_verify_depth, 57, libs.first ) 548 RESOLVEFUNC(SSL_CTX_use_certificate, 64, libs.first ) 549 RESOLVEFUNC(SSL_CTX_use_certificate_file, 67, libs.first ) 550 RESOLVEFUNC(SSL_CTX_use_PrivateKey, 58, libs.first ) 551 RESOLVEFUNC(SSL_CTX_use_RSAPrivateKey, 61, libs.first ) 552 RESOLVEFUNC(SSL_CTX_use_PrivateKey_file, 60, libs.first ) 553 RESOLVEFUNC(SSL_accept, 82, libs.first ) 554 RESOLVEFUNC(SSL_clear, 92, libs.first ) 555 RESOLVEFUNC(SSL_connect, 93, libs.first ) 556 RESOLVEFUNC(SSL_free, 99, libs.first ) 557 RESOLVEFUNC(SSL_get_ciphers, 104, libs.first ) 558 RESOLVEFUNC(SSL_get_current_cipher, 106, libs.first ) 559 RESOLVEFUNC(SSL_get_error, 110, libs.first ) 560 RESOLVEFUNC(SSL_get_peer_cert_chain, 117, libs.first ) 561 RESOLVEFUNC(SSL_get_peer_certificate, 118, libs.first ) 562 RESOLVEFUNC(SSL_get_verify_result, 132, libs.first ) 563 RESOLVEFUNC(SSL_library_init, 137, libs.first ) 564 RESOLVEFUNC(SSL_load_error_strings, 139, libs.first ) 565 RESOLVEFUNC(SSL_new, 140, libs.first ) 566 RESOLVEFUNC(SSL_read, 143, libs.first ) 567 RESOLVEFUNC(SSL_set_accept_state, 148, libs.first ) 568 RESOLVEFUNC(SSL_set_bio, 149, libs.first ) 569 RESOLVEFUNC(SSL_set_connect_state, 152, libs.first ) 570 RESOLVEFUNC(SSL_shutdown, 173, libs.first ) 571 RESOLVEFUNC(SSL_write, 188, libs.first ) 572 RESOLVEFUNC(SSLv2_client_method, 192, libs.first ) 573 RESOLVEFUNC(SSLv3_client_method, 195, libs.first ) 574 RESOLVEFUNC(SSLv23_client_method, 189, libs.first ) 575 RESOLVEFUNC(TLSv1_client_method, 198, libs.first ) 576 RESOLVEFUNC(SSLv2_server_method, 194, libs.first ) 577 RESOLVEFUNC(SSLv3_server_method, 197, libs.first ) 578 RESOLVEFUNC(SSLv23_server_method, 191, libs.first ) 579 RESOLVEFUNC(TLSv1_server_method, 200, libs.first ) 580 RESOLVEFUNC(X509_NAME_oneline, 1830, libs.second ) 581 RESOLVEFUNC(X509_PUBKEY_get, 1844, libs.second ) 582 RESOLVEFUNC(X509_STORE_free, 1939, libs.second ) 583 RESOLVEFUNC(X509_STORE_new, 1942, libs.second ) 584 RESOLVEFUNC(X509_STORE_add_cert, 1936, libs.second ) 585 RESOLVEFUNC(X509_STORE_CTX_free, 1907, libs.second ) 586 RESOLVEFUNC(X509_STORE_CTX_init, 1919, libs.second ) 587 RESOLVEFUNC(X509_STORE_CTX_new, 1920, libs.second ) 588 RESOLVEFUNC(X509_STORE_CTX_set_purpose, 1931, libs.second ) 589 RESOLVEFUNC(X509_cmp, 1992, libs.second ) 590 #ifndef SSLEAY_MACROS 591 RESOLVEFUNC(X509_dup, 1997, libs.second ) 592 #endif 593 RESOLVEFUNC(X509_EXTENSION_get_object, 1785, libs.second ) 594 RESOLVEFUNC(X509_free, 2001, libs.second ) 595 RESOLVEFUNC(X509_get_ext, 2012, libs.second ) 596 RESOLVEFUNC(X509_get_ext_count, 2016, libs.second ) 597 RESOLVEFUNC(X509_get_ext_d2i, 2017, libs.second ) 598 RESOLVEFUNC(X509_get_issuer_name, 2018, libs.second ) 599 RESOLVEFUNC(X509_get_subject_name, 2022, libs.second ) 600 RESOLVEFUNC(X509_verify_cert, 2069, libs.second ) 601 RESOLVEFUNC(d2i_X509, 2309, libs.second ) 602 RESOLVEFUNC(i2d_X509, 2489, libs.second ) 603 #ifdef SSLEAY_MACROS 604 RESOLVEFUNC(i2d_DSAPrivateKey, 2395, libs.second ) 605 RESOLVEFUNC(i2d_RSAPrivateKey, 2476, libs.second ) 606 RESOLVEFUNC(d2i_DSAPrivateKey, 2220, libs.second ) 607 RESOLVEFUNC(d2i_RSAPrivateKey, 2296, libs.second ) 608 #endif 609 RESOLVEFUNC(OPENSSL_add_all_algorithms_noconf, 1153, libs.second ) 610 RESOLVEFUNC(OPENSSL_add_all_algorithms_conf, 1152, libs.second ) 611 #else // Q_OS_SYMBIAN 437 612 #ifdef SSLEAY_MACROS 438 613 RESOLVEFUNC(ASN1_dup) 439 614 #endif 615 RESOLVEFUNC(ASN1_INTEGER_get) 440 616 RESOLVEFUNC(ASN1_STRING_data) 441 617 RESOLVEFUNC(ASN1_STRING_length) … … 481 657 RESOLVEFUNC(sk_free) 482 658 RESOLVEFUNC(sk_num) 659 RESOLVEFUNC(sk_pop_free) 483 660 RESOLVEFUNC(sk_value) 484 661 RESOLVEFUNC(SSL_CIPHER_description) … … 554 731 RESOLVEFUNC(OPENSSL_add_all_algorithms_noconf) 555 732 RESOLVEFUNC(OPENSSL_add_all_algorithms_conf) 733 #endif // Q_OS_SYMBIAN 556 734 symbolsResolved = true; 557 735 delete libs.first; -
trunk/src/network/ssl/qsslsocket_openssl_symbols_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 202 202 203 203 bool q_resolveOpenSslSymbols(); 204 long q_ASN1_INTEGER_get(ASN1_INTEGER *a); 204 205 unsigned char * q_ASN1_STRING_data(ASN1_STRING *a); 205 206 int q_ASN1_STRING_length(ASN1_STRING *a); … … 255 256 int q_RAND_status(); 256 257 void q_RSA_free(RSA *a); 258 int q_sk_num(STACK *a); 259 void q_sk_pop_free(STACK *a, void (*b)(void *)); 260 #if OPENSSL_VERSION_NUMBER >= 0x10000000L 261 void q_sk_free(_STACK *a); 262 void * q_sk_value(STACK *a, int b); 263 #else 257 264 void q_sk_free(STACK *a); 258 int q_sk_num(STACK *a);259 265 char * q_sk_value(STACK *a, int b); 266 #endif 260 267 int q_SSL_accept(SSL *a); 261 268 int q_SSL_clear(SSL *a); … … 270 277 long q_SSL_CTX_ctrl(SSL_CTX *a, int b, long c, void *d); 271 278 void q_SSL_CTX_free(SSL_CTX *a); 279 #if OPENSSL_VERSION_NUMBER >= 0x10000000L 280 SSL_CTX *q_SSL_CTX_new(const SSL_METHOD *a); 281 #else 272 282 SSL_CTX *q_SSL_CTX_new(SSL_METHOD *a); 283 #endif 273 284 int q_SSL_CTX_set_cipher_list(SSL_CTX *a, const char *b); 274 285 int q_SSL_CTX_set_default_verify_paths(SSL_CTX *a); … … 287 298 STACK_OF(SSL_CIPHER) *q_SSL_get_ciphers(SSL *a); 288 299 #endif 300 #if OPENSSL_VERSION_NUMBER >= 0x10000000L 301 const SSL_CIPHER *q_SSL_get_current_cipher(SSL *a); 302 #else 289 303 SSL_CIPHER *q_SSL_get_current_cipher(SSL *a); 304 #endif 290 305 int q_SSL_get_error(SSL *a, int b); 291 306 STACK_OF(X509) *q_SSL_get_peer_cert_chain(SSL *a); … … 305 320 void q_SSL_set_connect_state(SSL *a); 306 321 int q_SSL_shutdown(SSL *a); 322 #if OPENSSL_VERSION_NUMBER >= 0x10000000L 323 const SSL_METHOD *q_SSLv2_client_method(); 324 const SSL_METHOD *q_SSLv3_client_method(); 325 const SSL_METHOD *q_SSLv23_client_method(); 326 const SSL_METHOD *q_TLSv1_client_method(); 327 const SSL_METHOD *q_SSLv2_server_method(); 328 const SSL_METHOD *q_SSLv3_server_method(); 329 const SSL_METHOD *q_SSLv23_server_method(); 330 const SSL_METHOD *q_TLSv1_server_method(); 331 #else 307 332 SSL_METHOD *q_SSLv2_client_method(); 308 333 SSL_METHOD *q_SSLv3_client_method(); … … 313 338 SSL_METHOD *q_SSLv23_server_method(); 314 339 SSL_METHOD *q_TLSv1_server_method(); 340 #endif 315 341 int q_SSL_write(SSL *a, const void *b, int c); 316 342 int q_X509_cmp(X509 *a, X509 *b); -
trunk/src/network/ssl/qsslsocket_p.h
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtNetwork module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 80 80 bool autoStartHandshake; 81 81 bool connectionEncrypted; 82 bool ignoreSslErrors; 82 bool ignoreAllSslErrors; 83 QList<QSslError> ignoreErrorsList; 83 84 bool* readyReadEmittedPointer; 84 85 … … 88 89 QSslConfigurationPrivate configuration; 89 90 QList<QSslError> sslErrors; 91 92 // if set, this hostname is used for certificate validation instead of the hostname 93 // that was used for connecting to. 94 QString verificationPeerName; 90 95 91 96 static bool ensureInitialized(); … … 116 121 void _q_bytesWrittenSlot(qint64); 117 122 void _q_flushWriteBuffer(); 123 void _q_flushReadBuffer(); 118 124 119 125 // Platform specific functions -
trunk/src/network/ssl/ssl.pri
r2 r561 1 1 # OpenSSL support; compile in QSslSocket. 2 2 contains(QT_CONFIG, openssl) | contains(QT_CONFIG, openssl-linked) { 3 include($$QT_SOURCE_TREE/config.tests/unix/openssl/openssl.pri) 3 4 5 symbian { 6 INCLUDEPATH *= $$OS_LAYER_SSL_SYSTEMINCLUDE 7 } else { 8 include($$QT_SOURCE_TREE/config.tests/unix/openssl/openssl.pri) 9 } 4 10 5 11 HEADERS += ssl/qssl.h \ … … 30 36 31 37 # Add optional SSL libs 32 LIBS += $$OPENSSL_LIBS38 LIBS_PRIVATE += $$OPENSSL_LIBS 33 39 }
Note:
See TracChangeset
for help on using the changeset viewer.