summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2013-11-26 22:30:27 +0100
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2013-11-26 22:35:48 +0100
commit4a8273a6fc2e741e811cf5dabc9a3c240306cf7f (patch)
tree2148abc88f8543eecdc0b97b2dd92594836af9b2 /src/network
parent036c5db468164297d213764c59a4b59daa76d90a (diff)
parent1c2be58fecaff1de5f2849192eb712984ebd59bd (diff)
Merge remote-tracking branch 'origin/stable' into dev
For the conflicts in msvc_nmake.cpp the ifdefs are extended since we need to support windows phone in the target branch while it is not there in the current stable branch (as of Qt 5.2). Conflicts: configure qmake/generators/win32/msvc_nmake.cpp src/3rdparty/angle/src/libEGL/Surface.cpp src/angle/src/common/common.pri src/corelib/global/qglobal.h src/corelib/io/qstandardpaths.cpp src/plugins/platforms/qnx/qqnxintegration.cpp src/plugins/platforms/qnx/qqnxscreeneventhandler.h src/plugins/platforms/xcb/qglxintegration.h src/widgets/kernel/win.pri tests/auto/corelib/thread/qreadwritelock/tst_qreadwritelock.cpp tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp tools/configure/configureapp.cpp Change-Id: I00b579eefebaf61d26ab9b00046d2b5bd5958812
Diffstat (limited to 'src/network')
-rw-r--r--src/network/access/access.pri12
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp10
-rw-r--r--src/network/access/qnetworkreplynsurlconnectionimpl.mm449
-rw-r--r--src/network/access/qnetworkreplynsurlconnectionimpl_p.h89
-rw-r--r--src/network/bearer/qnetworkconfiguration.cpp1
-rw-r--r--src/network/doc/qtnetwork.qdocconf2
-rw-r--r--src/network/kernel/kernel.pri2
-rw-r--r--src/network/kernel/qauthenticator.cpp5
-rw-r--r--src/network/kernel/qnetworkproxy_win.cpp52
-rw-r--r--src/network/socket/socket.pri2
-rw-r--r--src/network/ssl/qssl.cpp2
-rw-r--r--src/network/ssl/qsslconfiguration.cpp24
-rw-r--r--src/network/ssl/qsslconfiguration.h4
-rw-r--r--src/network/ssl/qsslcontext.cpp4
-rw-r--r--src/network/ssl/qsslsocket.cpp2
-rw-r--r--src/network/ssl/ssl.pri2
16 files changed, 603 insertions, 59 deletions
diff --git a/src/network/access/access.pri b/src/network/access/access.pri
index 590a37bf15..aaaf05b551 100644
--- a/src/network/access/access.pri
+++ b/src/network/access/access.pri
@@ -64,6 +64,14 @@ SOURCES += \
access/qhttpthreaddelegate.cpp \
access/qhttpmultipart.cpp
-include($$PWD/../../3rdparty/zlib_dependency.pri)
+mac: LIBS_PRIVATE += -framework Security
+
+ios {
+ HEADERS += \
+ access/qnetworkreplynsurlconnectionimpl_p.h
-mac:LIBS_PRIVATE += -framework Security
+ OBJECTIVE_SOURCES += \
+ access/qnetworkreplynsurlconnectionimpl.mm
+}
+
+include($$PWD/../../3rdparty/zlib_dependency.pri)
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index 101e1a8c25..980b19b7e4 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -58,6 +58,10 @@
#include "qnetworkreplydataimpl_p.h"
#include "qnetworkreplyfileimpl_p.h"
+#if defined(Q_OS_IOS) && defined(QT_NO_SSL)
+#include "qnetworkreplynsurlconnectionimpl_p.h"
+#endif
+
#include "QtCore/qbuffer.h"
#include "QtCore/qurl.h"
#include "QtCore/qvector.h"
@@ -1159,6 +1163,12 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
}
}
+// Use NSURLConnection for https on iOS when OpenSSL is disabled.
+#if defined(Q_OS_IOS) && defined(QT_NO_SSL)
+ if (scheme == QLatin1String("https"))
+ return new QNetworkReplyNSURLConnectionImpl(this, request, op, outgoingData);
+#endif
+
#ifndef QT_NO_HTTP
// Since Qt 5 we use the new QNetworkReplyHttpImpl
if (scheme == QLatin1String("http") || scheme == QLatin1String("preconnect-http")
diff --git a/src/network/access/qnetworkreplynsurlconnectionimpl.mm b/src/network/access/qnetworkreplynsurlconnectionimpl.mm
new file mode 100644
index 0000000000..293a505912
--- /dev/null
+++ b/src/network/access/qnetworkreplynsurlconnectionimpl.mm
@@ -0,0 +1,449 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnetworkreplynsurlconnectionimpl_p.h"
+
+#include "QtCore/qdatetime.h"
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qdebug.h>
+#include <Foundation/Foundation.h>
+
+QT_BEGIN_NAMESPACE
+
+// Network reply implementation using NSUrlConnection.
+//
+// Class/object structure:
+//
+// QNetworkReplyNSURLConnectionImpl
+// |- QNetworkReplyNSURLConnectionImplPrivate
+// |- (bytes read)
+// |- (QIODevice and CFStream for async POST data transfer)
+// |- NSURLConnection
+// |- QtNSURLConnectionDelegate <NSURLConnectionDataDelegate>
+// |- NSURLResponse/NSHTTPURLResponse
+// |- (response data)
+//
+// The main entry point is the QNetworkReplyNSURLConnectionImpl constructor, which
+// receives a network request from QNetworkAccessManager. The constructor
+// creates a NSURLRequest and initiates a NSURLConnection with a QtNSURLConnectionDelegate.
+// The delegate callbacks are then called asynchronously as the request completes.
+//
+
+@class QtNSURLConnectionDelegate;
+class QNetworkReplyNSURLConnectionImplPrivate: public QNetworkReplyPrivate
+{
+public:
+ QNetworkReplyNSURLConnectionImplPrivate();
+ virtual ~QNetworkReplyNSURLConnectionImplPrivate();
+
+ Q_DECLARE_PUBLIC(QNetworkReplyNSURLConnectionImpl)
+ NSURLConnection * urlConnection;
+ QtNSURLConnectionDelegate *urlConnectionDelegate;
+ qint64 bytesRead;
+
+ // Sequental outgiong data streaming
+ QIODevice *outgoingData;
+ CFReadStreamRef readStream;
+ CFWriteStreamRef writeStream;
+ CFIndex transferBufferSize;
+
+ // Forwarding functions to the public class.
+ void setFinished();
+ void setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value);
+ void setRawHeader(const QByteArray &headerName, const QByteArray &value);
+ void setError(QNetworkReply::NetworkError errorCode, const QString &errorString);
+};
+
+@interface QtNSURLConnectionDelegate : NSObject
+{
+ NSURLResponse *response;
+ NSMutableData *responseData;
+ QNetworkReplyNSURLConnectionImplPrivate * replyprivate;
+}
+
+- (id)initWithQNetworkReplyNSURLConnectionImplPrivate:(QNetworkReplyNSURLConnectionImplPrivate *)a_replyPrivate ;
+#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_7, __IPHONE_3_0)
+- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;
+#endif
+- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError*)error;
+- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse*)response;
+- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData*)data;
+- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten
+ totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite;
+- (NSCachedURLResponse*)connection:(NSURLConnection*)connection willCacheResponse:(NSCachedURLResponse*)cachedResponse;
+- (NSURLRequest*)connection:(NSURLConnection*)connection willSendRequest:(NSURLRequest*)request redirectResponse:(NSURLResponse*)redirectResponse;
+- (void)connectionDidFinishLoading:(NSURLConnection*)connection;
+- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection*)connection;
+
+@end
+
+QNetworkReplyNSURLConnectionImplPrivate::QNetworkReplyNSURLConnectionImplPrivate()
+ : QNetworkReplyPrivate()
+ , urlConnection(0)
+ , urlConnectionDelegate(0)
+ , bytesRead(0)
+ , readStream(0)
+ , writeStream(0)
+ , transferBufferSize(4096)
+{
+}
+
+QNetworkReplyNSURLConnectionImplPrivate::~QNetworkReplyNSURLConnectionImplPrivate()
+{
+ [urlConnection release];
+ [urlConnectionDelegate release];
+ if (readStream)
+ CFRelease(readStream);
+ if (writeStream)
+ CFRelease(writeStream);
+}
+
+void QNetworkReplyNSURLConnectionImplPrivate::setFinished()
+{
+ q_func()->setFinished(true);
+}
+
+void QNetworkReplyNSURLConnectionImplPrivate::setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value)
+{
+ q_func()->setHeader(header, value);
+}
+
+void QNetworkReplyNSURLConnectionImplPrivate::setRawHeader(const QByteArray &headerName, const QByteArray &value)
+{
+ q_func()->setRawHeader(headerName, value);
+}
+
+void QNetworkReplyNSURLConnectionImplPrivate::setError(QNetworkReply::NetworkError errorCode, const QString &errorString)
+{
+ q_func()->setError(errorCode, errorString);
+}
+
+void QNetworkReplyNSURLConnectionImpl::readyReadOutgoingData()
+{
+ Q_D(QNetworkReplyNSURLConnectionImpl);
+ int bytesRead = 0;
+ do {
+ char data[d->transferBufferSize];
+ bytesRead = d->outgoingData->read(data, d->transferBufferSize);
+ if (bytesRead <= 0)
+ break;
+ CFIndex bytesWritten = CFWriteStreamWrite(d->writeStream, reinterpret_cast<unsigned char *>(data), bytesRead);
+ if (bytesWritten != bytesRead) {
+ CFErrorRef err = CFWriteStreamCopyError(d->writeStream);
+ qWarning() << "QNetworkReplyNSURLConnectionImpl: CFWriteStreamWrite error"
+ << (err ? QString::number(CFErrorGetCode(err)) : QStringLiteral(""));
+ }
+ } while (bytesRead > 0);
+
+ if (d->outgoingData->atEnd())
+ CFWriteStreamClose(d->writeStream);
+}
+
+@interface QtNSURLConnectionDelegate ()
+
+@property (nonatomic, retain) NSURLResponse* response;
+@property (nonatomic, retain) NSMutableData* responseData;
+
+@end
+
+@implementation QtNSURLConnectionDelegate
+
+@synthesize response;
+@synthesize responseData;
+
+- (id)initWithQNetworkReplyNSURLConnectionImplPrivate:(QNetworkReplyNSURLConnectionImplPrivate *)a_replyPrivate
+{
+ if (self = [super init])
+ replyprivate = a_replyPrivate;
+ return self;
+}
+
+- (void)dealloc
+{
+ [response release];
+ [responseData release];
+ [super dealloc];
+}
+
+#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_7, __IPHONE_3_0)
+- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
+{
+ Q_UNUSED(connection)
+ Q_UNUSED(challenge)
+
+ if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
+ SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
+ SecTrustResultType resultType;
+ SecTrustEvaluate(serverTrust, &resultType);
+ if (resultType == kSecTrustResultUnspecified) {
+ // All good
+ [challenge.sender performDefaultHandlingForAuthenticationChallenge:challenge];
+ } else if (resultType == kSecTrustResultRecoverableTrustFailure) {
+ // Certificate verification error, ask user
+ // ### TODO actually ask user
+ // (test site: https://testssl-expire.disig.sk/index.en.html)
+ qWarning() << "QNetworkReplyNSURLConnection: Certificate verification error handlig is"
+ << "not implemented. Connection will time out.";
+ } else {
+ // other error, which the default handler will handle
+ [challenge.sender performDefaultHandlingForAuthenticationChallenge:challenge];
+ }
+ }
+
+ [challenge.sender performDefaultHandlingForAuthenticationChallenge:challenge];
+}
+#endif
+
+- (void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error
+{
+ Q_UNUSED(connection)
+
+ QNetworkReply::NetworkError qtError = QNetworkReply::UnknownNetworkError;
+ if ([error domain] == NSURLErrorDomain) {
+ switch ([error code]) {
+ case NSURLErrorTimedOut: qtError = QNetworkReply::TimeoutError; break;
+ case NSURLErrorUnsupportedURL: qtError = QNetworkReply::ProtocolUnknownError; break;
+ case NSURLErrorCannotFindHost: qtError = QNetworkReply::HostNotFoundError; break;
+ case NSURLErrorCannotConnectToHost: qtError = QNetworkReply::ConnectionRefusedError; break;
+ case NSURLErrorNetworkConnectionLost: qtError = QNetworkReply::NetworkSessionFailedError; break;
+ case NSURLErrorDNSLookupFailed: qtError = QNetworkReply::HostNotFoundError; break;
+ case NSURLErrorNotConnectedToInternet: qtError = QNetworkReply::NetworkSessionFailedError; break;
+ case NSURLErrorUserAuthenticationRequired: qtError = QNetworkReply::AuthenticationRequiredError; break;
+ default: break;
+ }
+ }
+
+ replyprivate->setError(qtError, QString::fromNSString([error localizedDescription]));
+}
+
+- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)aResponse
+{
+ Q_UNUSED(connection)
+ self.response = aResponse;
+ self.responseData = [NSMutableData data];
+
+ // copy headers
+ if ([aResponse isKindOfClass:[NSHTTPURLResponse class]]) {
+ NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)aResponse;
+ NSDictionary *headers = [httpResponse allHeaderFields];
+ for (NSString *key in headers) {
+ NSString *value = [headers objectForKey:key];
+ replyprivate->setRawHeader(QString::fromNSString(key).toUtf8(), QString::fromNSString(value).toUtf8());
+ }
+ } else {
+ if ([aResponse expectedContentLength] != NSURLResponseUnknownLength)
+ replyprivate->setHeader(QNetworkRequest::ContentLengthHeader, [aResponse expectedContentLength]);
+ }
+
+ QMetaObject::invokeMethod(replyprivate->q_func(), "metaDataChanged", Qt::QueuedConnection);
+}
+
+- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data
+{
+ Q_UNUSED(connection)
+ [responseData appendData:data];
+
+ if ([response expectedContentLength] != NSURLResponseUnknownLength) {
+ QMetaObject::invokeMethod(replyprivate->q_func(), "downloadProgress", Qt::QueuedConnection,
+ Q_ARG(qint64, qint64([responseData length])),
+ Q_ARG(qint64, qint64([response expectedContentLength])));
+ }
+
+ QMetaObject::invokeMethod(replyprivate->q_func(), "readyRead", Qt::QueuedConnection);
+}
+
+- (void)connection:(NSURLConnection*)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten
+ totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite
+{
+ Q_UNUSED(connection)
+ Q_UNUSED(bytesWritten)
+ QMetaObject::invokeMethod(replyprivate->q_func(), "uploadProgress", Qt::QueuedConnection,
+ Q_ARG(qint64, qint64(totalBytesWritten)),
+ Q_ARG(qint64, qint64(totalBytesExpectedToWrite)));
+}
+
+- (NSCachedURLResponse*)connection:(NSURLConnection*)connection willCacheResponse:(NSCachedURLResponse*)cachedResponse
+{
+ Q_UNUSED(connection)
+ return cachedResponse;
+}
+
+- (NSURLRequest*)connection:(NSURLConnection*)connection willSendRequest:(NSURLRequest*)request redirectResponse:(NSURLResponse*)redirectResponse
+{
+ Q_UNUSED(connection)
+ Q_UNUSED(redirectResponse)
+ return request;
+}
+
+- (void)connectionDidFinishLoading:(NSURLConnection*)connection
+{
+ Q_UNUSED(connection)
+ replyprivate->setFinished();
+ QMetaObject::invokeMethod(replyprivate->q_func(), "finished", Qt::QueuedConnection);
+}
+
+- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection*)connection
+{
+ Q_UNUSED(connection)
+ return YES;
+}
+
+@end
+
+QNetworkReplyNSURLConnectionImpl::~QNetworkReplyNSURLConnectionImpl()
+{
+}
+
+QNetworkReplyNSURLConnectionImpl::QNetworkReplyNSURLConnectionImpl(QObject *parent,
+ const QNetworkRequest &request, const QNetworkAccessManager::Operation operation, QIODevice* outgoingData)
+ : QNetworkReply(*new QNetworkReplyNSURLConnectionImplPrivate(), parent)
+{
+ setRequest(request);
+ setUrl(request.url());
+ setOperation(operation);
+ QNetworkReply::open(QIODevice::ReadOnly);
+
+ QNetworkReplyNSURLConnectionImplPrivate *d = (QNetworkReplyNSURLConnectionImplPrivate*) d_func();
+
+ QUrl url = request.url();
+ if (url.host() == QLatin1String("localhost"))
+ url.setHost(QString());
+
+ if (url.path().isEmpty())
+ url.setPath(QLatin1String("/"));
+ setUrl(url);
+
+ // Create a NSMutableURLRequest from QNetworkRequest
+ NSMutableURLRequest *nsRequest = [NSMutableURLRequest requestWithURL:request.url().toNSURL()
+ cachePolicy:NSURLRequestUseProtocolCachePolicy
+ timeoutInterval:60.0];
+ // copy headers
+ foreach (const QByteArray &header, request.rawHeaderList()) {
+ QByteArray headerValue = request.rawHeader(header);
+ [nsRequest addValue:QString::fromUtf8(headerValue).toNSString()
+ forHTTPHeaderField:QString::fromUtf8(header).toNSString()];
+ }
+
+ if (operation == QNetworkAccessManager::GetOperation)
+ [nsRequest setHTTPMethod:@"GET"];
+ else if (operation == QNetworkAccessManager::PostOperation)
+ [nsRequest setHTTPMethod:@"POST"];
+ else if (operation == QNetworkAccessManager::PutOperation)
+ [nsRequest setHTTPMethod:@"PUT"];
+ else if (operation == QNetworkAccessManager::DeleteOperation)
+ [nsRequest setHTTPMethod:@"DELETE"];
+ else
+ qWarning() << "QNetworkReplyNSURLConnection: Unsupported netork operation" << operation;
+
+ if (outgoingData) {
+ d->outgoingData = outgoingData;
+ if (outgoingData->isSequential()) {
+ // set up streaming from outgoingData iodevice to request
+ CFStreamCreateBoundPair(kCFAllocatorDefault, &d->readStream, &d->writeStream, d->transferBufferSize);
+ CFWriteStreamOpen(d->writeStream);
+ [nsRequest setHTTPBodyStream:reinterpret_cast<NSInputStream *>(d->readStream)];
+ connect(outgoingData, SIGNAL(readyRead()), this, SLOT(readyReadOutgoingData()));
+ readyReadOutgoingData();
+ } else {
+ // move all data at once
+ QByteArray data = outgoingData->readAll();
+ [nsRequest setHTTPBody:[NSData dataWithBytes:data.constData() length:data.length()]];
+ }
+ }
+
+ // Create connection
+ d->urlConnectionDelegate = [[QtNSURLConnectionDelegate alloc] initWithQNetworkReplyNSURLConnectionImplPrivate:d];
+ d->urlConnection = [[NSURLConnection alloc] initWithRequest:nsRequest delegate:d->urlConnectionDelegate];
+ if (!d->urlConnection) {
+ // ### what type of error is an initWithRequest fail?
+ setError(QNetworkReply::ProtocolUnknownError, QStringLiteral("QNetworkReplyNSURLConnection internal error"));
+ }
+}
+
+void QNetworkReplyNSURLConnectionImpl::close()
+{
+ // No-op? Network ops should continue (especially POSTs)
+ QNetworkReply::close();
+}
+
+void QNetworkReplyNSURLConnectionImpl::abort()
+{
+ Q_D(QNetworkReplyNSURLConnectionImpl);
+ [d->urlConnection cancel];
+ QNetworkReply::close();
+}
+
+qint64 QNetworkReplyNSURLConnectionImpl::bytesAvailable() const
+{
+ Q_D(const QNetworkReplyNSURLConnectionImpl);
+ qint64 available = QNetworkReply::bytesAvailable() +
+ [[d->urlConnectionDelegate responseData] length] -
+ d->bytesRead;
+
+ return available;
+}
+
+bool QNetworkReplyNSURLConnectionImpl::isSequential() const
+{
+ return true;
+}
+
+qint64 QNetworkReplyNSURLConnectionImpl::size() const
+{
+ Q_D(const QNetworkReplyNSURLConnectionImpl);
+ return [[d->urlConnectionDelegate responseData] length];
+}
+
+/*!
+ \internal
+*/
+qint64 QNetworkReplyNSURLConnectionImpl::readData(char *data, qint64 maxlen)
+{
+ Q_D(QNetworkReplyNSURLConnectionImpl);
+ qint64 dataSize = [[d->urlConnectionDelegate responseData] length];
+ qint64 canRead = qMin(maxlen, dataSize - d->bytesRead);
+ const char *sourceBase = static_cast<const char *>([[d->urlConnectionDelegate responseData] bytes]);
+ memcpy(data, sourceBase + d->bytesRead, canRead);
+ d->bytesRead += canRead;
+ return canRead;
+}
+
+QT_END_NAMESPACE
diff --git a/src/network/access/qnetworkreplynsurlconnectionimpl_p.h b/src/network/access/qnetworkreplynsurlconnectionimpl_p.h
new file mode 100644
index 0000000000..967eb13246
--- /dev/null
+++ b/src/network/access/qnetworkreplynsurlconnectionimpl_p.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNETWORKREPLYNSURLCONNECTIONIMPL_H
+#define QNETWORKREPLYNSURLCONNECTIONIMPL_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the Network Access API. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qnetworkreply.h"
+#include "qnetworkreply_p.h"
+#include "qnetworkaccessmanager.h"
+#include <QFile>
+#include <private/qabstractfileengine_p.h>
+
+QT_BEGIN_NAMESPACE
+
+
+class QNetworkReplyNSURLConnectionImplPrivate;
+class QNetworkReplyNSURLConnectionImpl: public QNetworkReply
+{
+ Q_OBJECT
+public:
+ QNetworkReplyNSURLConnectionImpl(QObject *parent, const QNetworkRequest &req, const QNetworkAccessManager::Operation op, QIODevice* outgoingData);
+ virtual ~QNetworkReplyNSURLConnectionImpl();
+ virtual void abort();
+
+ // reimplemented from QNetworkReply
+ virtual void close();
+ virtual qint64 bytesAvailable() const;
+ virtual bool isSequential () const;
+ qint64 size() const;
+
+ virtual qint64 readData(char *data, qint64 maxlen);
+public Q_SLOTS:
+ void readyReadOutgoingData();
+
+ Q_DECLARE_PRIVATE(QNetworkReplyNSURLConnectionImpl)
+};
+
+QT_END_NAMESPACE
+
+#endif // QNetworkReplyNSURLConnectionImpl_H
diff --git a/src/network/bearer/qnetworkconfiguration.cpp b/src/network/bearer/qnetworkconfiguration.cpp
index 8d34db19cd..a66b39f733 100644
--- a/src/network/bearer/qnetworkconfiguration.cpp
+++ b/src/network/bearer/qnetworkconfiguration.cpp
@@ -591,7 +591,6 @@ QNetworkConfiguration::BearerType QNetworkConfiguration::bearerTypeFamily() cons
\li Value
\row
\li BearerUnknown
- \li
\li The session is based on an unknown or unspecified bearer type. The value of the
string returned describes the bearer type.
\row
diff --git a/src/network/doc/qtnetwork.qdocconf b/src/network/doc/qtnetwork.qdocconf
index f4779ae8fe..33d6c24461 100644
--- a/src/network/doc/qtnetwork.qdocconf
+++ b/src/network/doc/qtnetwork.qdocconf
@@ -2,7 +2,7 @@ include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf)
project = QtNetwork
description = Qt Network Reference Documentation
-url = http://qt-project.org/doc/qt-$QT_VER/qtnetwork
+url = http://qt-project.org/doc/qt-$QT_VER
version = $QT_VERSION
examplesinstallpath = network
diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri
index a4a19988b3..97f52fdb6e 100644
--- a/src/network/kernel/kernel.pri
+++ b/src/network/kernel/kernel.pri
@@ -35,7 +35,7 @@ android {
win32: {
HEADERS += kernel/qnetworkinterface_win_p.h
SOURCES += kernel/qdnslookup_win.cpp kernel/qhostinfo_win.cpp kernel/qnetworkinterface_win.cpp
- LIBS += -ldnsapi
+ LIBS_PRIVATE += -ldnsapi
}
integrity:SOURCES += kernel/qdnslookup_unix.cpp kernel/qhostinfo_unix.cpp kernel/qnetworkinterface_unix.cpp
diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp
index e1a24a226f..8c16486878 100644
--- a/src/network/kernel/qauthenticator.cpp
+++ b/src/network/kernel/qauthenticator.cpp
@@ -189,7 +189,7 @@ QAuthenticator &QAuthenticator::operator=(const QAuthenticator &other)
d->realm = other.d->realm;
d->method = other.d->method;
d->options = other.d->options;
- } else {
+ } else if (d->phase == QAuthenticatorPrivate::Start) {
delete d;
d = 0;
}
@@ -267,7 +267,8 @@ void QAuthenticator::detach()
return;
}
- d->phase = QAuthenticatorPrivate::Start;
+ if (d->phase == QAuthenticatorPrivate::Done)
+ d->phase = QAuthenticatorPrivate::Start;
}
/*!
diff --git a/src/network/kernel/qnetworkproxy_win.cpp b/src/network/kernel/qnetworkproxy_win.cpp
index f1893ae322..e16d7e557e 100644
--- a/src/network/kernel/qnetworkproxy_win.cpp
+++ b/src/network/kernel/qnetworkproxy_win.cpp
@@ -53,6 +53,7 @@
#include <string.h>
#include <qt_windows.h>
#include <wininet.h>
+#include <lmcons.h>
#include "qnetworkfunctions_wince.h"
/*
@@ -115,48 +116,38 @@ typedef HINTERNET (WINAPI * PtrWinHttpOpen)(LPCWSTR, DWORD, LPCWSTR, LPCWSTR,DWO
typedef BOOL (WINAPI * PtrWinHttpGetDefaultProxyConfiguration)(WINHTTP_PROXY_INFO*);
typedef BOOL (WINAPI * PtrWinHttpGetIEProxyConfigForCurrentUser)(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG*);
typedef BOOL (WINAPI * PtrWinHttpCloseHandle)(HINTERNET);
-typedef SC_HANDLE (WINAPI * PtrOpenSCManager)(LPCWSTR lpMachineName, LPCWSTR lpDatabaseName, DWORD dwDesiredAccess);
-typedef BOOL (WINAPI * PtrEnumServicesStatusEx)(SC_HANDLE hSCManager, SC_ENUM_TYPE InfoLevel, DWORD dwServiceType, DWORD dwServiceState, LPBYTE lpServices, DWORD cbBufSize, LPDWORD pcbBytesNeeded,
- LPDWORD lpServicesReturned, LPDWORD lpResumeHandle, LPCWSTR pszGroupName);
typedef BOOL (WINAPI * PtrCloseServiceHandle)(SC_HANDLE hSCObject);
static PtrWinHttpGetProxyForUrl ptrWinHttpGetProxyForUrl = 0;
static PtrWinHttpOpen ptrWinHttpOpen = 0;
static PtrWinHttpGetDefaultProxyConfiguration ptrWinHttpGetDefaultProxyConfiguration = 0;
static PtrWinHttpGetIEProxyConfigForCurrentUser ptrWinHttpGetIEProxyConfigForCurrentUser = 0;
static PtrWinHttpCloseHandle ptrWinHttpCloseHandle = 0;
-static PtrOpenSCManager ptrOpenSCManager = 0;
-static PtrEnumServicesStatusEx ptrEnumServicesStatusEx = 0;
-static PtrCloseServiceHandle ptrCloseServiceHandle = 0;
+#ifndef Q_OS_WINCE
static bool currentProcessIsService()
{
- if (!ptrOpenSCManager || !ptrEnumServicesStatusEx|| !ptrCloseServiceHandle)
- return false;
-
- SC_HANDLE hSCM = ptrOpenSCManager(0, 0, SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_CONNECT);
- if (!hSCM)
- return false;
-
- ULONG bufSize = 0;
- ULONG nbServices = 0;
- if (ptrEnumServicesStatusEx(hSCM, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_ACTIVE, 0, bufSize, &bufSize, &nbServices, 0, 0))
- return false; //error case
-
- LPENUM_SERVICE_STATUS_PROCESS info = reinterpret_cast<LPENUM_SERVICE_STATUS_PROCESS>(malloc(bufSize));
- bool foundService = false;
- if (ptrEnumServicesStatusEx(hSCM, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_ACTIVE, (LPBYTE)info, bufSize, &bufSize, &nbServices, 0, 0)) {
- DWORD currProcId = GetCurrentProcessId();
- for (ULONG i = 0; i < nbServices && !foundService; i++) {
- if (info[i].ServiceStatusProcess.dwProcessId == currProcId)
- foundService = true;
+ typedef BOOL (WINAPI *PtrGetUserName)(LPTSTR lpBuffer, LPDWORD lpnSize);
+ typedef BOOL (WINAPI *PtrLookupAccountName)(LPCTSTR lpSystemName, LPCTSTR lpAccountName, PSID Sid,
+ LPDWORD cbSid, LPTSTR ReferencedDomainName, LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse);
+ static PtrGetUserName ptrGetUserName = (PtrGetUserName)QSystemLibrary::resolve(QLatin1String("Advapi32"), "GetUserNameW");
+ static PtrLookupAccountName ptrLookupAccountName = (PtrLookupAccountName)QSystemLibrary::resolve(QLatin1String("Advapi32"), "LookupAccountNameW");
+
+ if (ptrGetUserName && ptrLookupAccountName) {
+ wchar_t userName[UNLEN + 1] = L"";
+ DWORD size = UNLEN;
+ if (ptrGetUserName(userName, &size)) {
+ SID_NAME_USE type = SidTypeUser;
+ DWORD dummy = MAX_PATH;
+ wchar_t dummyStr[MAX_PATH] = L"";
+ PSID psid = 0;
+ if (ptrLookupAccountName(NULL, userName, &psid, &dummy, dummyStr, &dummy, &type))
+ return type != SidTypeUser; //returns true if the current user is not a user
}
}
-
- ptrCloseServiceHandle(hSCM);
- free(info);
- return foundService;
+ return false;
}
+#endif // ! Q_OS_WINCE
static QStringList splitSpaceSemicolon(const QString &source)
{
@@ -418,9 +409,6 @@ void QWindowsSystemProxy::init()
ptrWinHttpGetProxyForUrl = (PtrWinHttpGetProxyForUrl)lib.resolve("WinHttpGetProxyForUrl");
ptrWinHttpGetDefaultProxyConfiguration = (PtrWinHttpGetDefaultProxyConfiguration)lib.resolve("WinHttpGetDefaultProxyConfiguration");
ptrWinHttpGetIEProxyConfigForCurrentUser = (PtrWinHttpGetIEProxyConfigForCurrentUser)lib.resolve("WinHttpGetIEProxyConfigForCurrentUser");
- ptrOpenSCManager = (PtrOpenSCManager) QSystemLibrary(L"advapi32").resolve("OpenSCManagerW");
- ptrEnumServicesStatusEx = (PtrEnumServicesStatusEx) QSystemLibrary(L"advapi32").resolve("EnumServicesStatusExW");
- ptrCloseServiceHandle = (PtrCloseServiceHandle) QSystemLibrary(L"advapi32").resolve("CloseServiceHandle");
// Try to obtain the Internet Explorer configuration.
WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ieProxyConfig;
diff --git a/src/network/socket/socket.pri b/src/network/socket/socket.pri
index 0204a92999..c0c6d750d9 100644
--- a/src/network/socket/socket.pri
+++ b/src/network/socket/socket.pri
@@ -40,7 +40,7 @@ win32:SOURCES += socket/qnativesocketengine_win.cpp \
socket/qlocalsocket_win.cpp \
socket/qlocalserver_win.cpp
-win32:!wince*:LIBS += -ladvapi32
+win32:!wince*: LIBS_PRIVATE += -ladvapi32
wince*: {
SOURCES -= socket/qlocalsocket_win.cpp \
diff --git a/src/network/ssl/qssl.cpp b/src/network/ssl/qssl.cpp
index ec771e1f49..5b7274e3e6 100644
--- a/src/network/ssl/qssl.cpp
+++ b/src/network/ssl/qssl.cpp
@@ -164,7 +164,7 @@ QT_BEGIN_NAMESPACE
\value SslOptionDisableSessionSharing Disables SSL session sharing via
the session ID handshake attribute.
\value SslOptionDisableSessionPersistence Disables storing the SSL session
- in ASN.1 format as returned by QSslConfiguration::session(). Enabling
+ in ASN.1 format as returned by QSslConfiguration::sessionTicket(). Enabling
this feature adds memory overhead of approximately 1K per used session
ticket.
diff --git a/src/network/ssl/qsslconfiguration.cpp b/src/network/ssl/qsslconfiguration.cpp
index 8979c48d5d..4aad7c04c5 100644
--- a/src/network/ssl/qsslconfiguration.cpp
+++ b/src/network/ssl/qsslconfiguration.cpp
@@ -602,19 +602,19 @@ bool QSslConfiguration::testSslOption(QSsl::SslOption option) const
\since 5.2
If QSsl::SslOptionDisableSessionPersistence was turned off, this
- function returns the session used in the SSL handshake in ASN.1
- format, suitable to e.g. be persisted to disk. If no session was
+ function returns the session ticket used in the SSL handshake in ASN.1
+ format, suitable to e.g. be persisted to disk. If no session ticket was
used or QSsl::SslOptionDisableSessionPersistence was not turned off,
this function returns an empty QByteArray.
- \b{Note:} When persisting the session to disk or similar, be
+ \b{Note:} When persisting the session ticket to disk or similar, be
careful not to expose the session to a potential attacker, as
knowledge of the session allows for eavesdropping on data
encrypted with the session parameters.
- \sa setSession(), QSsl::SslOptionDisableSessionPersistence, setSslOption()
+ \sa setSessionTicket(), QSsl::SslOptionDisableSessionPersistence, setSslOption()
*/
-QByteArray QSslConfiguration::session() const
+QByteArray QSslConfiguration::sessionTicket() const
{
return d->sslSession;
}
@@ -622,16 +622,16 @@ QByteArray QSslConfiguration::session() const
/*!
\since 5.2
- Sets the session to be used in an SSL handshake.
+ Sets the session ticket to be used in an SSL handshake.
QSsl::SslOptionDisableSessionPersistence must be turned off
- for this to work, and \a session must be in ASN.1 format
- as returned by session().
+ for this to work, and \a sessionTicket must be in ASN.1 format
+ as returned by sessionTicket().
- \sa session(), QSsl::SslOptionDisableSessionPersistence, setSslOption()
+ \sa sessionTicket(), QSsl::SslOptionDisableSessionPersistence, setSslOption()
*/
-void QSslConfiguration::setSession(const QByteArray &session)
+void QSslConfiguration::setSessionTicket(const QByteArray &sessionTicket)
{
- d->sslSession = session;
+ d->sslSession = sessionTicket;
}
/*!
@@ -645,7 +645,7 @@ void QSslConfiguration::setSession(const QByteArray &session)
QSsl::SslOptionDisableSessionPersistence was not turned off,
this function returns -1.
- \sa session(), QSsl::SslOptionDisableSessionPersistence, setSslOption()
+ \sa sessionTicket(), QSsl::SslOptionDisableSessionPersistence, setSslOption()
*/
int QSslConfiguration::sessionTicketLifeTimeHint() const
{
diff --git a/src/network/ssl/qsslconfiguration.h b/src/network/ssl/qsslconfiguration.h
index 949ce70d4c..a48eceb63e 100644
--- a/src/network/ssl/qsslconfiguration.h
+++ b/src/network/ssl/qsslconfiguration.h
@@ -124,8 +124,8 @@ public:
void setSslOption(QSsl::SslOption option, bool on);
bool testSslOption(QSsl::SslOption option) const;
- QByteArray session() const;
- void setSession(const QByteArray &session);
+ QByteArray sessionTicket() const;
+ void setSessionTicket(const QByteArray &sessionTicket);
int sessionTicketLifeTimeHint() const;
static QSslConfiguration defaultConfiguration();
diff --git a/src/network/ssl/qsslcontext.cpp b/src/network/ssl/qsslcontext.cpp
index 6d281c390d..037ee8c672 100644
--- a/src/network/ssl/qsslcontext.cpp
+++ b/src/network/ssl/qsslcontext.cpp
@@ -260,8 +260,8 @@ init_context:
q_SSL_CTX_set_verify_depth(sslContext->ctx, sslContext->sslConfiguration.peerVerifyDepth());
// set persisted session if the user set it
- if (!configuration.session().isEmpty())
- sslContext->setSessionASN1(configuration.session());
+ if (!configuration.sessionTicket().isEmpty())
+ sslContext->setSessionASN1(configuration.sessionTicket());
return sslContext;
}
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index 24843e9f92..38b493a769 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -903,7 +903,7 @@ void QSslSocket::setSslConfiguration(const QSslConfiguration &configuration)
d->configuration.peerVerifyMode = configuration.peerVerifyMode();
d->configuration.protocol = configuration.protocol();
d->configuration.sslOptions = configuration.d->sslOptions;
- d->configuration.sslSession = configuration.session();
+ d->configuration.sslSession = configuration.sessionTicket();
d->configuration.sslSessionTicketLifeTimeHint = configuration.sessionTicketLifeTimeHint();
// if the CA certificates were set explicitly (either via
diff --git a/src/network/ssl/ssl.pri b/src/network/ssl/ssl.pri
index 0fe231357b..eb8268515e 100644
--- a/src/network/ssl/ssl.pri
+++ b/src/network/ssl/ssl.pri
@@ -45,5 +45,5 @@ android:!android-no-sdk: SOURCES += ssl/qsslsocket_openssl_android.cpp
QMAKE_CXXFLAGS += $$OPENSSL_CFLAGS
LIBS_PRIVATE += $$OPENSSL_LIBS
- windows:LIBS += -lcrypt32
+ win32: LIBS_PRIVATE += -lcrypt32
}