summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
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
}