[Pkg-owncloud-commits] [owncloud-client] 336/484: Add the set of currently used patches
Sandro Knauß
hefee-guest at moszumanska.debian.org
Wed Dec 16 00:38:01 UTC 2015
This is an automated email from the git hooks/post-receive script.
hefee-guest pushed a commit to branch master
in repository owncloud-client.
commit b3c2c594bd8c91d49a45c783347b92908c7cf67f
Author: Daniel Molkentin <danimo at owncloud.com>
Date: Mon Nov 16 18:34:52 2015 +0100
Add the set of currently used patches
---
...n-Mac-OS-if-PAC-URL-contains-non-URL-lega.patch | 42 ++
...ble-crash-when-passing-an-invalid-PAC-URL.patch | 38 ++
...f-PAC-script-retrieval-returns-a-null-CFD.patch | 39 ++
.../0004-OSX-Fix-disapearing-tray-icon.patch | 115 ++++
...rce-debug-info-with-macx-clang_NOUPSTREAM.patch | 30 +
...load-corruptions-when-server-closes-conne.patch | 691 +++++++++++++++++++++
...ply-deadlocks-on-server-closing-connectio.patch | 64 ++
...-proper-channel-before-sslErrors-emission.patch | 33 +
...re-to-report-correct-NetworkAccessibility.patch | 113 ++++
...re-networkAccessibilityChanged-is-emitted.patch | 233 +++++++
...e-UnknownAccessibility-not-block-requests.patch | 52 ++
admin/qt/patches/README.md | 37 ++
12 files changed, 1487 insertions(+)
diff --git a/admin/qt/patches/0001-Fix-crash-on-Mac-OS-if-PAC-URL-contains-non-URL-lega.patch b/admin/qt/patches/0001-Fix-crash-on-Mac-OS-if-PAC-URL-contains-non-URL-lega.patch
new file mode 100644
index 0000000..1e46cd9
--- /dev/null
+++ b/admin/qt/patches/0001-Fix-crash-on-Mac-OS-if-PAC-URL-contains-non-URL-lega.patch
@@ -0,0 +1,42 @@
+From ea4dcc5931d455e4ee3e958ffa54a9f54ab022c8 Mon Sep 17 00:00:00 2001
+From: Daniel Molkentin <daniel at molkentin.de>
+Date: Mon, 5 Jan 2015 10:45:25 +0100
+Subject: [PATCH 1/3] Fix crash on Mac OS if PAC URL contains non-URL legal
+ chars
+
+macQueryInternal() was retrieving the PAC URL string as-entered by
+the user in the 'Proxies' tab of the system network settings dialog
+and passing it to CFURLCreateWithString().
+
+CFURLCreateWithString() returns null if the input string contains
+non-URL legal chars or is empty.
+
+Change-Id: I9166d0433a62c7b2274b5435a7dea0a16997d10e
+Patch-By: Robert Knight
+Task-number: QTBUG-36787
+Reviewed-by: Peter Hartmann <phartmann at blackberry.com>
+Reviewed-by: Markus Goetz <markus at woboq.com>
+---
+ src/network/kernel/qnetworkproxy_mac.cpp | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/src/network/kernel/qnetworkproxy_mac.cpp b/src/network/kernel/qnetworkproxy_mac.cpp
+index 7d26246..81bce0c 100644
+--- a/src/network/kernel/qnetworkproxy_mac.cpp
++++ b/src/network/kernel/qnetworkproxy_mac.cpp
+@@ -221,7 +221,11 @@ QList<QNetworkProxy> macQueryInternal(const QNetworkProxyQuery &query)
+ int enabled;
+ if (CFNumberGetValue(pacEnabled, kCFNumberIntType, &enabled) && enabled) {
+ // PAC is enabled
+- CFStringRef cfPacLocation = (CFStringRef)CFDictionaryGetValue(dict, kSCPropNetProxiesProxyAutoConfigURLString);
++ // kSCPropNetProxiesProxyAutoConfigURLString returns the URL string
++ // as entered in the system proxy configuration dialog
++ CFStringRef pacLocationSetting = (CFStringRef)CFDictionaryGetValue(dict, kSCPropNetProxiesProxyAutoConfigURLString);
++ QCFType<CFStringRef> cfPacLocation = CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, pacLocationSetting, NULL, NULL,
++ kCFStringEncodingUTF8);
+
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
+ QCFType<CFDataRef> pacData;
+--
+1.8.3.4 (Apple Git-47)
+
diff --git a/admin/qt/patches/0002-Fix-possible-crash-when-passing-an-invalid-PAC-URL.patch b/admin/qt/patches/0002-Fix-possible-crash-when-passing-an-invalid-PAC-URL.patch
new file mode 100644
index 0000000..275b347
--- /dev/null
+++ b/admin/qt/patches/0002-Fix-possible-crash-when-passing-an-invalid-PAC-URL.patch
@@ -0,0 +1,38 @@
+From a83e4d1d9dd90d4563ce60f27dfb7802a780e33e Mon Sep 17 00:00:00 2001
+From: Daniel Molkentin <daniel at molkentin.de>
+Date: Mon, 5 Jan 2015 11:42:52 +0100
+Subject: [PATCH 2/3] Fix possible crash when passing an invalid PAC URL
+
+This commit checks whether CFURLCreateWithString() succeeded.
+
+It does not appear to be possible to enter an empty URL directly in the
+PAC configuration dialog but I can't rule out the possibility
+that it could find its way into the settings via some other means.
+
+Change-Id: I6c2053d385503bf0330f5ae9fb1ec36a473d425d
+Patch-By: Robert Knight
+Task-number: QTBUG-36787
+Reviewed-by: Markus Goetz <markus at woboq.com>
+Reviewed-by: Peter Hartmann <phartmann at blackberry.com>
+---
+ src/network/kernel/qnetworkproxy_mac.cpp | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/network/kernel/qnetworkproxy_mac.cpp b/src/network/kernel/qnetworkproxy_mac.cpp
+index 81bce0c..6be032e 100644
+--- a/src/network/kernel/qnetworkproxy_mac.cpp
++++ b/src/network/kernel/qnetworkproxy_mac.cpp
+@@ -230,6 +230,10 @@ QList<QNetworkProxy> macQueryInternal(const QNetworkProxyQuery &query)
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
+ QCFType<CFDataRef> pacData;
+ QCFType<CFURLRef> pacUrl = CFURLCreateWithString(kCFAllocatorDefault, cfPacLocation, NULL);
++ if (!pacUrl) {
++ qWarning("Invalid PAC URL \"%s\"", qPrintable(QCFString::toQString(cfPacLocation)));
++ return result;
++ }
+ SInt32 errorCode;
+ if (!CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, pacUrl, &pacData, NULL, NULL, &errorCode)) {
+ QString pacLocation = QCFString::toQString(cfPacLocation);
+--
+1.8.3.4 (Apple Git-47)
+
diff --git a/admin/qt/patches/0003-Fix-crash-if-PAC-script-retrieval-returns-a-null-CFD.patch b/admin/qt/patches/0003-Fix-crash-if-PAC-script-retrieval-returns-a-null-CFD.patch
new file mode 100644
index 0000000..c144c2d
--- /dev/null
+++ b/admin/qt/patches/0003-Fix-crash-if-PAC-script-retrieval-returns-a-null-CFD.patch
@@ -0,0 +1,39 @@
+From 83bd9393e5564ea9168fda90c0f44456633a483a Mon Sep 17 00:00:00 2001
+From: Daniel Molkentin <daniel at molkentin.de>
+Date: Mon, 5 Jan 2015 15:22:57 +0100
+Subject: [PATCH 3/3] Fix crash if PAC script retrieval returns a null CFData
+ instance
+
+The documentation for CFURLCreateDataAndPropertiesFromResource()
+does not make this clear but from looking at the CFNetwork implementation
+and a user stacktrace it appears that this function can return true
+but not set the data argument under certain circumstances.
+
+Change-Id: I48034a640d6f47a51cd5883bbafacad4bcbd0415
+Task-number: QTBUG-36787
+Patch-By: Robert Knight
+Reviewed-by: Markus Goetz <markus at woboq.com>
+Reviewed-by: Peter Hartmann <phartmann at blackberry.com>
+---
+ src/network/kernel/qnetworkproxy_mac.cpp | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/src/network/kernel/qnetworkproxy_mac.cpp b/src/network/kernel/qnetworkproxy_mac.cpp
+index 6be032e..a1ac349 100644
+--- a/src/network/kernel/qnetworkproxy_mac.cpp
++++ b/src/network/kernel/qnetworkproxy_mac.cpp
+@@ -240,7 +240,10 @@ QList<QNetworkProxy> macQueryInternal(const QNetworkProxyQuery &query)
+ qWarning("Unable to get the PAC script at \"%s\" (%s)", qPrintable(pacLocation), cfurlErrorDescription(errorCode));
+ return result;
+ }
+-
++ if (!pacData) {
++ qWarning("\"%s\" returned an empty PAC script", qPrintable(QCFString::toQString(cfPacLocation)));
++ return result;
++ }
+ QCFType<CFStringRef> pacScript = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, pacData, kCFStringEncodingISOLatin1);
+ if (!pacScript) {
+ // This should never happen, but the documentation says it may return NULL if there was a problem creating the object.
+--
+1.8.3.4 (Apple Git-47)
+
diff --git a/admin/qt/patches/0004-OSX-Fix-disapearing-tray-icon.patch b/admin/qt/patches/0004-OSX-Fix-disapearing-tray-icon.patch
new file mode 100644
index 0000000..df6b4ef
--- /dev/null
+++ b/admin/qt/patches/0004-OSX-Fix-disapearing-tray-icon.patch
@@ -0,0 +1,115 @@
+From ee7fea33383726f0bb72e8082a357820e3ee3675 Mon Sep 17 00:00:00 2001
+From: Jocelyn Turcotte <jturcotte at woboq.com>
+Date: Tue, 24 Feb 2015 17:02:02 +0100
+Subject: [PATCH] OSX Fix disapearing tray icon
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+It would happen together with an error:
+ QPainter::begin: Paint device returned engine == 0
+and would be caused by the size provided to QIcon::pixmap being empty,
+itself caused by the availableSizes list being empty for the Selected
+mode.
+
+This bug was most often hidden by the fact that the Selected icon mode
+was not triggered properly since we usually only set menuVisible after
+calling updateIcon, and most of the time when it did, we would overwrite
+it right after with a Normal mode icon.
+
+Fix the issue by disabling the broken feature completely since the
+default Selected icon is grayed out while tray icons are now usually
+black (or white when selected). To support the dark menu bar mode on
+10.10 we'll need to use NSImage's setTemplate anyway and that
+knowing in advance if we can invert the colors ourselves would also
+better solve the menuVisible usecase.
+
+Task-number: QTBUG-42910
+Change-Id: If9ec9659af28ecceb841bfc2f11721e6029fe891
+Reviewed-by: Morten Johan Sørvig <morten.sorvig at theqtcompany.com>
+---
+ src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm | 17 +++--------------
+ 1 file changed, 3 insertions(+), 14 deletions(-)
+
+diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
+index 8a35705..d366a3c 100755
+--- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
++++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
+@@ -102,7 +102,6 @@ QT_USE_NAMESPACE
+ QCocoaSystemTrayIcon *systray;
+ NSStatusItem *item;
+ QCocoaMenu *menu;
+- bool menuVisible;
+ QIcon icon;
+ QT_MANGLE_NAMESPACE(QNSImageView) *imageCell;
+ }
+@@ -202,8 +201,6 @@ void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon)
+
+ m_sys->item->icon = icon;
+
+- const bool menuVisible = m_sys->item->menu && m_sys->item->menuVisible;
+-
+ // The reccomended maximum title bar icon height is 18 points
+ // (device independent pixels). The menu height on past and
+ // current OS X versions is 22 points. Provide some future-proofing
+@@ -218,9 +215,8 @@ void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon)
+ // devicePixelRatio for the "best" screen on the system.
+ qreal devicePixelRatio = qApp->devicePixelRatio();
+ const int maxPixmapHeight = maxImageHeight * devicePixelRatio;
+- const QIcon::Mode mode = menuVisible ? QIcon::Selected : QIcon::Normal;
+ QSize selectedSize;
+- Q_FOREACH (const QSize& size, sortByHeight(icon.availableSizes(mode))) {
++ Q_FOREACH (const QSize& size, sortByHeight(icon.availableSizes())) {
+ // Select a pixmap based on the height. We want the largest pixmap
+ // with a height smaller or equal to maxPixmapHeight. The pixmap
+ // may rectangular; assume it has a reasonable size. If there is
+@@ -236,9 +232,9 @@ void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon)
+
+ // Handle SVG icons, which do not return anything for availableSizes().
+ if (!selectedSize.isValid())
+- selectedSize = icon.actualSize(QSize(maxPixmapHeight, maxPixmapHeight), mode);
++ selectedSize = icon.actualSize(QSize(maxPixmapHeight, maxPixmapHeight));
+
+- QPixmap pixmap = icon.pixmap(selectedSize, mode);
++ QPixmap pixmap = icon.pixmap(selectedSize);
+
+ // Draw a low-resolution icon if there is not enough pixels for a retina
+ // icon. This prevents showing a small icon on retina displays.
+@@ -385,9 +381,6 @@ QT_END_NAMESPACE
+ Q_UNUSED(notification);
+ down = NO;
+
+- parent->systray->updateIcon(parent->icon);
+- parent->menuVisible = false;
+-
+ [self setNeedsDisplay:YES];
+ }
+
+@@ -397,8 +390,6 @@ QT_END_NAMESPACE
+ int clickCount = [mouseEvent clickCount];
+ [self setNeedsDisplay:YES];
+
+- parent->systray->updateIcon(parent->icon);
+-
+ if (clickCount == 2) {
+ [self menuTrackingDone:nil];
+ [parent doubleClickSelector:self];
+@@ -454,7 +445,6 @@ QT_END_NAMESPACE
+ if (self) {
+ item = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength] retain];
+ menu = 0;
+- menuVisible = false;
+ systray = sys;
+ imageCell = [[QNSImageView alloc] initWithParent:self];
+ [item setView: imageCell];
+@@ -498,7 +488,6 @@ QT_END_NAMESPACE
+ selector:@selector(menuTrackingDone:)
+ name:NSMenuDidEndTrackingNotification
+ object:m];
+- menuVisible = true;
+ [item popUpStatusItemMenu: m];
+ }
+ }
+--
+1.9.1
+
diff --git a/admin/qt/patches/0005-Fix-force-debug-info-with-macx-clang_NOUPSTREAM.patch b/admin/qt/patches/0005-Fix-force-debug-info-with-macx-clang_NOUPSTREAM.patch
new file mode 100644
index 0000000..ea9c8b8
--- /dev/null
+++ b/admin/qt/patches/0005-Fix-force-debug-info-with-macx-clang_NOUPSTREAM.patch
@@ -0,0 +1,30 @@
+From f3cd07c11e0b7327ffc629f48a89c8c457cdba75 Mon Sep 17 00:00:00 2001
+From: Jocelyn Turcotte <jturcotte at woboq.com>
+Date: Fri, 6 Mar 2015 16:12:37 +0100
+Subject: [PATCH] Fix -force-debug-info with macx-clang
+
+---
+ mkspecs/common/clang.conf | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/mkspecs/common/clang.conf b/mkspecs/common/clang.conf
+index 2c29bb8..110d380 100644
+--- a/mkspecs/common/clang.conf
++++ b/mkspecs/common/clang.conf
+@@ -20,11 +20,13 @@ QMAKE_CFLAGS_ISYSTEM = -isystem
+ QMAKE_CFLAGS_PRECOMPILE = -x c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
+ QMAKE_CFLAGS_USE_PRECOMPILE = -Xclang -include-pch -Xclang ${QMAKE_PCH_OUTPUT}
+ QMAKE_CFLAGS_LTCG = -flto
++QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = $$QMAKE_CFLAGS_OPTIMIZE -g
+
+ QMAKE_CXXFLAGS_PRECOMPILE = -x c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
+ QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE
+ QMAKE_CXXFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG
+ QMAKE_CXXFLAGS_CXX11 = -std=c++11
++QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO = $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
+
+ QMAKE_LFLAGS_CXX11 =
+ QMAKE_LFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG
+--
+2.2.0
+
diff --git a/admin/qt/patches/0006-QNAM-Fix-upload-corruptions-when-server-closes-conne.patch b/admin/qt/patches/0006-QNAM-Fix-upload-corruptions-when-server-closes-conne.patch
new file mode 100644
index 0000000..edd46eb
--- /dev/null
+++ b/admin/qt/patches/0006-QNAM-Fix-upload-corruptions-when-server-closes-conne.patch
@@ -0,0 +1,691 @@
+From cff39fba10ffc10ee4dcfdc66ff6528eb26462d3 Mon Sep 17 00:00:00 2001
+From: Markus Goetz <markus at woboq.com>
+Date: Fri, 10 Apr 2015 14:09:53 +0200
+Subject: [PATCH] QNAM: Fix upload corruptions when server closes connection
+
+This patch fixes several upload corruptions if the server closes the connection
+while/before we send data into it. They happen inside multiple places in the HTTP
+layer and are explained in the comments.
+Corruptions are:
+* The upload byte device has an in-flight signal with pending upload data, if
+it gets reset (because server closes the connection) then the re-send of the
+request was sometimes taking this stale in-flight pending upload data.
+* Because some signals were DirectConnection and some were QueuedConnection, there
+was a chance that a direct signal overtakes a queued signal. The state machine
+then sent data down the socket which was buffered there (and sent later) although
+it did not match the current state of the state machine when it was actually sent.
+* A socket was seen as being able to have requests sent even though it was not
+encrypted yet. This relates to the previous corruption where data is stored inside
+the socket's buffer and then sent later.
+
+The included auto test produces all fixed corruptions, I detected no regressions
+via the other tests.
+This code also adds a bit of sanity checking to protect from possible further
+problems.
+
+[ChangeLog][QtNetwork] Fix HTTP(s) upload corruption when server closes connection
+
+Change-Id: I54c883925ec897050941498f139c4b523030432e
+Reviewed-by: Peter Hartmann <peter-qt at hartmann.tk>
+---
+ src/corelib/io/qnoncontiguousbytedevice.cpp | 18 +++
+ src/corelib/io/qnoncontiguousbytedevice_p.h | 4 +
+ .../access/qhttpnetworkconnectionchannel.cpp | 35 ++++-
+ .../access/qhttpnetworkconnectionchannel_p.h | 2 +
+ src/network/access/qhttpprotocolhandler.cpp | 7 +
+ src/network/access/qhttpthreaddelegate_p.h | 36 ++++-
+ src/network/access/qnetworkreplyhttpimpl.cpp | 25 ++-
+ src/network/access/qnetworkreplyhttpimpl_p.h | 7 +-
+ .../access/qnetworkreply/tst_qnetworkreply.cpp | 175 ++++++++++++++++++++-
+ 9 files changed, 279 insertions(+), 30 deletions(-)
+
+diff --git a/src/corelib/io/qnoncontiguousbytedevice.cpp b/src/corelib/io/qnoncontiguousbytedevice.cpp
+index 11510a8..760ca3d 100644
+--- a/src/corelib/io/qnoncontiguousbytedevice.cpp
++++ b/src/corelib/io/qnoncontiguousbytedevice.cpp
+@@ -236,6 +236,11 @@ qint64 QNonContiguousByteDeviceByteArrayImpl::size()
+ return byteArray->size();
+ }
+
++qint64 QNonContiguousByteDeviceByteArrayImpl::pos()
++{
++ return currentPosition;
++}
++
+ QNonContiguousByteDeviceRingBufferImpl::QNonContiguousByteDeviceRingBufferImpl(QSharedPointer<QRingBuffer> rb)
+ : QNonContiguousByteDevice(), currentPosition(0)
+ {
+@@ -273,6 +278,11 @@ bool QNonContiguousByteDeviceRingBufferImpl::atEnd()
+ return currentPosition >= size();
+ }
+
++qint64 QNonContiguousByteDeviceRingBufferImpl::pos()
++{
++ return currentPosition;
++}
++
+ bool QNonContiguousByteDeviceRingBufferImpl::reset()
+ {
+ if (resetDisabled)
+@@ -406,6 +416,14 @@ qint64 QNonContiguousByteDeviceIoDeviceImpl::size()
+ return device->size() - initialPosition;
+ }
+
++qint64 QNonContiguousByteDeviceIoDeviceImpl::pos()
++{
++ if (device->isSequential())
++ return -1;
++
++ return device->pos();
++}
++
+ QByteDeviceWrappingIoDevice::QByteDeviceWrappingIoDevice(QNonContiguousByteDevice *bd) : QIODevice((QObject*)0)
+ {
+ byteDevice = bd;
+diff --git a/src/corelib/io/qnoncontiguousbytedevice_p.h b/src/corelib/io/qnoncontiguousbytedevice_p.h
+index c05ae11..4d7b7b0 100644
+--- a/src/corelib/io/qnoncontiguousbytedevice_p.h
++++ b/src/corelib/io/qnoncontiguousbytedevice_p.h
+@@ -61,6 +61,7 @@ public:
+ virtual const char* readPointer(qint64 maximumLength, qint64 &len) = 0;
+ virtual bool advanceReadPointer(qint64 amount) = 0;
+ virtual bool atEnd() = 0;
++ virtual qint64 pos() { return -1; }
+ virtual bool reset() = 0;
+ void disableReset();
+ bool isResetDisabled() { return resetDisabled; }
+@@ -106,6 +107,7 @@ public:
+ bool atEnd();
+ bool reset();
+ qint64 size();
++ qint64 pos() Q_DECL_OVERRIDE;
+ protected:
+ QByteArray* byteArray;
+ qint64 currentPosition;
+@@ -121,6 +123,7 @@ public:
+ bool atEnd();
+ bool reset();
+ qint64 size();
++ qint64 pos() Q_DECL_OVERRIDE;
+ protected:
+ QSharedPointer<QRingBuffer> ringBuffer;
+ qint64 currentPosition;
+@@ -138,6 +141,7 @@ public:
+ bool atEnd();
+ bool reset();
+ qint64 size();
++ qint64 pos() Q_DECL_OVERRIDE;
+ protected:
+ QIODevice* device;
+ QByteArray* currentReadBuffer;
+diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
+index 9f63280..49c6793 100644
+--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
++++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
+@@ -106,15 +106,19 @@ void QHttpNetworkConnectionChannel::init()
+ socket->setProxy(QNetworkProxy::NoProxy);
+ #endif
+
++ // We want all signals (except the interactive ones) be connected as QueuedConnection
++ // because else we're falling into cases where we recurse back into the socket code
++ // and mess up the state. Always going to the event loop (and expecting that when reading/writing)
++ // is safer.
+ QObject::connect(socket, SIGNAL(bytesWritten(qint64)),
+ this, SLOT(_q_bytesWritten(qint64)),
+- Qt::DirectConnection);
++ Qt::QueuedConnection);
+ QObject::connect(socket, SIGNAL(connected()),
+ this, SLOT(_q_connected()),
+- Qt::DirectConnection);
++ Qt::QueuedConnection);
+ QObject::connect(socket, SIGNAL(readyRead()),
+ this, SLOT(_q_readyRead()),
+- Qt::DirectConnection);
++ Qt::QueuedConnection);
+
+ // The disconnected() and error() signals may already come
+ // while calling connectToHost().
+@@ -143,13 +147,13 @@ void QHttpNetworkConnectionChannel::init()
+ // won't be a sslSocket if encrypt is false
+ QObject::connect(sslSocket, SIGNAL(encrypted()),
+ this, SLOT(_q_encrypted()),
+- Qt::DirectConnection);
++ Qt::QueuedConnection);
+ QObject::connect(sslSocket, SIGNAL(sslErrors(QList<QSslError>)),
+ this, SLOT(_q_sslErrors(QList<QSslError>)),
+ Qt::DirectConnection);
+ QObject::connect(sslSocket, SIGNAL(encryptedBytesWritten(qint64)),
+ this, SLOT(_q_encryptedBytesWritten(qint64)),
+- Qt::DirectConnection);
++ Qt::QueuedConnection);
+
+ if (ignoreAllSslErrors)
+ sslSocket->ignoreSslErrors();
+@@ -186,8 +190,11 @@ void QHttpNetworkConnectionChannel::close()
+ // pendingEncrypt must only be true in between connected and encrypted states
+ pendingEncrypt = false;
+
+- if (socket)
++ if (socket) {
++ // socket can be 0 since the host lookup is done from qhttpnetworkconnection.cpp while
++ // there is no socket yet.
+ socket->close();
++ }
+ }
+
+
+@@ -353,6 +360,14 @@ bool QHttpNetworkConnectionChannel::ensureConnection()
+ }
+ return false;
+ }
++
++ // This code path for ConnectedState
++ if (pendingEncrypt) {
++ // Let's only be really connected when we have received the encrypted() signal. Else the state machine seems to mess up
++ // and corrupt the things sent to the server.
++ return false;
++ }
++
+ return true;
+ }
+
+@@ -659,6 +674,12 @@ bool QHttpNetworkConnectionChannel::isSocketReading() const
+ void QHttpNetworkConnectionChannel::_q_bytesWritten(qint64 bytes)
+ {
+ Q_UNUSED(bytes);
++ if (ssl) {
++ // In the SSL case we want to send data from encryptedBytesWritten signal since that one
++ // is the one going down to the actual network, not only into some SSL buffer.
++ return;
++ }
++
+ // bytes have been written to the socket. write even more of them :)
+ if (isSocketWriting())
+ sendRequest();
+@@ -734,7 +755,7 @@ void QHttpNetworkConnectionChannel::_q_connected()
+
+ // ### FIXME: if the server closes the connection unexpectedly, we shouldn't send the same broken request again!
+ //channels[i].reconnectAttempts = 2;
+- if (pendingEncrypt) {
++ if (ssl || pendingEncrypt) { // FIXME: Didn't work properly with pendingEncrypt only, we should refactor this into an EncrypingState
+ #ifndef QT_NO_SSL
+ if (connection->sslContext().isNull()) {
+ // this socket is making the 1st handshake for this connection,
+diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h
+index 692c0e6..231fe11 100644
+--- a/src/network/access/qhttpnetworkconnectionchannel_p.h
++++ b/src/network/access/qhttpnetworkconnectionchannel_p.h
+@@ -83,6 +83,8 @@ typedef QPair<QHttpNetworkRequest, QHttpNetworkReply*> HttpMessagePair;
+ class QHttpNetworkConnectionChannel : public QObject {
+ Q_OBJECT
+ public:
++ // TODO: Refactor this to add an EncryptingState (and remove pendingEncrypt).
++ // Also add an Unconnected state so IdleState does not have double meaning.
+ enum ChannelState {
+ IdleState = 0, // ready to send request
+ ConnectingState = 1, // connecting to host
+diff --git a/src/network/access/qhttpprotocolhandler.cpp b/src/network/access/qhttpprotocolhandler.cpp
+index 28e10f7..3357948 100644
+--- a/src/network/access/qhttpprotocolhandler.cpp
++++ b/src/network/access/qhttpprotocolhandler.cpp
+@@ -368,6 +368,13 @@ bool QHttpProtocolHandler::sendRequest()
+ // nothing to read currently, break the loop
+ break;
+ } else {
++ if (m_channel->written != uploadByteDevice->pos()) {
++ // Sanity check. This was useful in tracking down an upload corruption.
++ qWarning() << "QHttpProtocolHandler: Internal error in sendRequest. Expected to write at position" << m_channel->written << "but read device is at" << uploadByteDevice->pos();
++ Q_ASSERT(m_channel->written == uploadByteDevice->pos());
++ m_connection->d_func()->emitReplyError(m_socket, m_reply, QNetworkReply::ProtocolFailure);
++ return false;
++ }
+ qint64 currentWriteSize = m_socket->write(readPointer, currentReadSize);
+ if (currentWriteSize == -1 || currentWriteSize != currentReadSize) {
+ // socket broke down
+diff --git a/src/network/access/qhttpthreaddelegate_p.h b/src/network/access/qhttpthreaddelegate_p.h
+index 1661082..b553409 100644
+--- a/src/network/access/qhttpthreaddelegate_p.h
++++ b/src/network/access/qhttpthreaddelegate_p.h
+@@ -187,6 +187,7 @@ protected:
+ QByteArray m_dataArray;
+ bool m_atEnd;
+ qint64 m_size;
++ qint64 m_pos; // to match calls of haveDataSlot with the expected position
+ public:
+ QNonContiguousByteDeviceThreadForwardImpl(bool aE, qint64 s)
+ : QNonContiguousByteDevice(),
+@@ -194,7 +195,8 @@ public:
+ m_amount(0),
+ m_data(0),
+ m_atEnd(aE),
+- m_size(s)
++ m_size(s),
++ m_pos(0)
+ {
+ }
+
+@@ -202,6 +204,11 @@ public:
+ {
+ }
+
++ qint64 pos() Q_DECL_OVERRIDE
++ {
++ return m_pos;
++ }
++
+ const char* readPointer(qint64 maximumLength, qint64 &len)
+ {
+ if (m_amount > 0) {
+@@ -229,11 +236,10 @@ public:
+
+ m_amount -= a;
+ m_data += a;
++ m_pos += a;
+
+- // To main thread to inform about our state
+- emit processedData(a);
+-
+- // FIXME possible optimization, already ask user thread for some data
++ // To main thread to inform about our state. The m_pos will be sent as a sanity check.
++ emit processedData(m_pos, a);
+
+ return true;
+ }
+@@ -250,10 +256,21 @@ public:
+ {
+ m_amount = 0;
+ m_data = 0;
++ m_dataArray.clear();
++
++ if (wantDataPending) {
++ // had requested the user thread to send some data (only 1 in-flight at any moment)
++ wantDataPending = false;
++ }
+
+ // Communicate as BlockingQueuedConnection
+ bool b = false;
+ emit resetData(&b);
++ if (b) {
++ // the reset succeeded, we're at pos 0 again
++ m_pos = 0;
++ // the HTTP code will anyway abort the request if !b.
++ }
+ return b;
+ }
+
+@@ -264,8 +281,13 @@ public:
+
+ public slots:
+ // From user thread:
+- void haveDataSlot(QByteArray dataArray, bool dataAtEnd, qint64 dataSize)
++ void haveDataSlot(qint64 pos, QByteArray dataArray, bool dataAtEnd, qint64 dataSize)
+ {
++ if (pos != m_pos) {
++ // Sometimes when re-sending a request in the qhttpnetwork* layer there is a pending haveData from the
++ // user thread on the way to us. We need to ignore it since it is the data for the wrong(later) chunk.
++ return;
++ }
+ wantDataPending = false;
+
+ m_dataArray = dataArray;
+@@ -285,7 +307,7 @@ signals:
+
+ // to main thread:
+ void wantData(qint64);
+- void processedData(qint64);
++ void processedData(qint64 pos, qint64 amount);
+ void resetData(bool *b);
+ };
+
+diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp
+index 4ce7303..974a101 100644
+--- a/src/network/access/qnetworkreplyhttpimpl.cpp
++++ b/src/network/access/qnetworkreplyhttpimpl.cpp
+@@ -424,6 +424,7 @@ QNetworkReplyHttpImplPrivate::QNetworkReplyHttpImplPrivate()
+ , synchronous(false)
+ , state(Idle)
+ , statusCode(0)
++ , uploadByteDevicePosition(false)
+ , uploadDeviceChoking(false)
+ , outgoingData(0)
+ , bytesUploaded(-1)
+@@ -863,9 +864,9 @@ void QNetworkReplyHttpImplPrivate::postRequest()
+ q, SLOT(uploadByteDeviceReadyReadSlot()),
+ Qt::QueuedConnection);
+
+- // From main thread to user thread:
+- QObject::connect(q, SIGNAL(haveUploadData(QByteArray,bool,qint64)),
+- forwardUploadDevice, SLOT(haveDataSlot(QByteArray,bool,qint64)), Qt::QueuedConnection);
++ // From user thread to http thread:
++ QObject::connect(q, SIGNAL(haveUploadData(qint64,QByteArray,bool,qint64)),
++ forwardUploadDevice, SLOT(haveDataSlot(qint64,QByteArray,bool,qint64)), Qt::QueuedConnection);
+ QObject::connect(uploadByteDevice.data(), SIGNAL(readyRead()),
+ forwardUploadDevice, SIGNAL(readyRead()),
+ Qt::QueuedConnection);
+@@ -873,8 +874,8 @@ void QNetworkReplyHttpImplPrivate::postRequest()
+ // From http thread to user thread:
+ QObject::connect(forwardUploadDevice, SIGNAL(wantData(qint64)),
+ q, SLOT(wantUploadDataSlot(qint64)));
+- QObject::connect(forwardUploadDevice, SIGNAL(processedData(qint64)),
+- q, SLOT(sentUploadDataSlot(qint64)));
++ QObject::connect(forwardUploadDevice,SIGNAL(processedData(qint64, qint64)),
++ q, SLOT(sentUploadDataSlot(qint64,qint64)));
+ QObject::connect(forwardUploadDevice, SIGNAL(resetData(bool*)),
+ q, SLOT(resetUploadDataSlot(bool*)),
+ Qt::BlockingQueuedConnection); // this is the only one with BlockingQueued!
+@@ -1268,12 +1269,22 @@ void QNetworkReplyHttpImplPrivate::replySslConfigurationChanged(const QSslConfig
+ void QNetworkReplyHttpImplPrivate::resetUploadDataSlot(bool *r)
+ {
+ *r = uploadByteDevice->reset();
++ if (*r) {
++ // reset our own position which is used for the inter-thread communication
++ uploadByteDevicePosition = 0;
++ }
+ }
+
+ // Coming from QNonContiguousByteDeviceThreadForwardImpl in HTTP thread
+-void QNetworkReplyHttpImplPrivate::sentUploadDataSlot(qint64 amount)
++void QNetworkReplyHttpImplPrivate::sentUploadDataSlot(qint64 pos, qint64 amount)
+ {
++ if (uploadByteDevicePosition + amount != pos) {
++ // Sanity check, should not happen.
++ error(QNetworkReply::UnknownNetworkError, "");
++ return;
++ }
+ uploadByteDevice->advanceReadPointer(amount);
++ uploadByteDevicePosition += amount;
+ }
+
+ // Coming from QNonContiguousByteDeviceThreadForwardImpl in HTTP thread
+@@ -1298,7 +1309,7 @@ void QNetworkReplyHttpImplPrivate::wantUploadDataSlot(qint64 maxSize)
+ QByteArray dataArray(data, currentUploadDataLength);
+
+ // Communicate back to HTTP thread
+- emit q->haveUploadData(dataArray, uploadByteDevice->atEnd(), uploadByteDevice->size());
++ emit q->haveUploadData(uploadByteDevicePosition, dataArray, uploadByteDevice->atEnd(), uploadByteDevice->size());
+ }
+
+ void QNetworkReplyHttpImplPrivate::uploadByteDeviceReadyReadSlot()
+diff --git a/src/network/access/qnetworkreplyhttpimpl_p.h b/src/network/access/qnetworkreplyhttpimpl_p.h
+index 77d9c5a..1940922 100644
+--- a/src/network/access/qnetworkreplyhttpimpl_p.h
++++ b/src/network/access/qnetworkreplyhttpimpl_p.h
+@@ -120,7 +120,7 @@ public:
+
+ Q_PRIVATE_SLOT(d_func(), void resetUploadDataSlot(bool *r))
+ Q_PRIVATE_SLOT(d_func(), void wantUploadDataSlot(qint64))
+- Q_PRIVATE_SLOT(d_func(), void sentUploadDataSlot(qint64))
++ Q_PRIVATE_SLOT(d_func(), void sentUploadDataSlot(qint64,qint64))
+ Q_PRIVATE_SLOT(d_func(), void uploadByteDeviceReadyReadSlot())
+ Q_PRIVATE_SLOT(d_func(), void emitReplyUploadProgress(qint64, qint64))
+ Q_PRIVATE_SLOT(d_func(), void _q_cacheSaveDeviceAboutToClose())
+@@ -144,7 +144,7 @@ signals:
+
+ void startHttpRequestSynchronously();
+
+- void haveUploadData(QByteArray dataArray, bool dataAtEnd, qint64 dataSize);
++ void haveUploadData(const qint64 pos, QByteArray dataArray, bool dataAtEnd, qint64 dataSize);
+ };
+
+ class QNetworkReplyHttpImplPrivate: public QNetworkReplyPrivate
+@@ -195,6 +195,7 @@ public:
+ // upload
+ QNonContiguousByteDevice* createUploadByteDevice();
+ QSharedPointer<QNonContiguousByteDevice> uploadByteDevice;
++ qint64 uploadByteDevicePosition;
+ bool uploadDeviceChoking; // if we couldn't readPointer() any data at the moment
+ QIODevice *outgoingData;
+ QSharedPointer<QRingBuffer> outgoingDataBuffer;
+@@ -283,7 +284,7 @@ public:
+ // From QNonContiguousByteDeviceThreadForwardImpl in HTTP thread:
+ void resetUploadDataSlot(bool *r);
+ void wantUploadDataSlot(qint64);
+- void sentUploadDataSlot(qint64);
++ void sentUploadDataSlot(qint64, qint64);
+
+ // From user's QNonContiguousByteDevice
+ void uploadByteDeviceReadyReadSlot();
+diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
+index 3ccedf6..d2edf67 100644
+--- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
++++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
+@@ -457,6 +457,10 @@ private Q_SLOTS:
+
+ void putWithRateLimiting();
+
++#ifndef QT_NO_SSL
++ void putWithServerClosingConnectionImmediately();
++#endif
++
+ // NOTE: This test must be last!
+ void parentingRepliesToTheApp();
+ private:
+@@ -4718,18 +4722,22 @@ void tst_QNetworkReply::ioPostToHttpNoBufferFlag()
+ class SslServer : public QTcpServer {
+ Q_OBJECT
+ public:
+- SslServer() : socket(0) {};
++ SslServer() : socket(0), m_ssl(true) {}
+ void incomingConnection(qintptr socketDescriptor) {
+ QSslSocket *serverSocket = new QSslSocket;
+ serverSocket->setParent(this);
+
+ if (serverSocket->setSocketDescriptor(socketDescriptor)) {
++ connect(serverSocket, SIGNAL(readyRead()), this, SLOT(readyReadSlot()));
++ if (!m_ssl) {
++ emit newPlainConnection(serverSocket);
++ return;
++ }
+ QString testDataDir = QFileInfo(QFINDTESTDATA("rfc3252.txt")).absolutePath();
+ if (testDataDir.isEmpty())
+ testDataDir = QCoreApplication::applicationDirPath();
+
+ connect(serverSocket, SIGNAL(encrypted()), this, SLOT(encryptedSlot()));
+- connect(serverSocket, SIGNAL(readyRead()), this, SLOT(readyReadSlot()));
+ serverSocket->setProtocol(QSsl::AnyProtocol);
+ connect(serverSocket, SIGNAL(sslErrors(QList<QSslError>)), serverSocket, SLOT(ignoreSslErrors()));
+ serverSocket->setLocalCertificate(testDataDir + "/certs/server.pem");
+@@ -4740,11 +4748,12 @@ public:
+ }
+ }
+ signals:
+- void newEncryptedConnection();
++ void newEncryptedConnection(QSslSocket *s);
++ void newPlainConnection(QSslSocket *s);
+ public slots:
+ void encryptedSlot() {
+ socket = (QSslSocket*) sender();
+- emit newEncryptedConnection();
++ emit newEncryptedConnection(socket);
+ }
+ void readyReadSlot() {
+ // for the incoming sockets, not the server socket
+@@ -4753,6 +4762,7 @@ public slots:
+
+ public:
+ QSslSocket *socket;
++ bool m_ssl;
+ };
+
+ // very similar to ioPostToHttpUploadProgress but for SSL
+@@ -4780,7 +4790,7 @@ void tst_QNetworkReply::ioPostToHttpsUploadProgress()
+ QNetworkReplyPtr reply(manager.post(request, sourceFile));
+
+ QSignalSpy spy(reply.data(), SIGNAL(uploadProgress(qint64,qint64)));
+- connect(&server, SIGNAL(newEncryptedConnection()), &QTestEventLoop::instance(), SLOT(exitLoop()));
++ connect(&server, SIGNAL(newEncryptedConnection(QSslSocket*)), &QTestEventLoop::instance(), SLOT(exitLoop()));
+ connect(reply, SIGNAL(sslErrors(QList<QSslError>)), reply.data(), SLOT(ignoreSslErrors()));
+
+ // get the request started and the incoming socket connected
+@@ -4788,7 +4798,7 @@ void tst_QNetworkReply::ioPostToHttpsUploadProgress()
+ QVERIFY(!QTestEventLoop::instance().timeout());
+ QTcpSocket *incomingSocket = server.socket;
+ QVERIFY(incomingSocket);
+- disconnect(&server, SIGNAL(newEncryptedConnection()), &QTestEventLoop::instance(), SLOT(exitLoop()));
++ disconnect(&server, SIGNAL(newEncryptedConnection(QSslSocket*)), &QTestEventLoop::instance(), SLOT(exitLoop()));
+
+
+ incomingSocket->setReadBufferSize(1*1024);
+@@ -7905,6 +7915,159 @@ void tst_QNetworkReply::putWithRateLimiting()
+ }
+
+
++#ifndef QT_NO_SSL
++
++class PutWithServerClosingConnectionImmediatelyHandler: public QObject
++{
++ Q_OBJECT
++public:
++ bool m_parsedHeaders;
++ QByteArray m_receivedData;
++ QByteArray m_expectedData;
++ QSslSocket *m_socket;
++ PutWithServerClosingConnectionImmediatelyHandler(QSslSocket *s, QByteArray expected) :m_parsedHeaders(false), m_expectedData(expected), m_socket(s)
++ {
++ m_socket->setParent(this);
++ connect(m_socket, SIGNAL(readyRead()), SLOT(readyReadSlot()));
++ connect(m_socket, SIGNAL(disconnected()), SLOT(disconnectedSlot()));
++ }
++signals:
++ void correctFileUploadReceived();
++ void corruptFileUploadReceived();
++
++public slots:
++ void closeDelayed() {
++ m_socket->close();
++ }
++
++ void readyReadSlot()
++ {
++ QByteArray data = m_socket->readAll();
++ m_receivedData += data;
++ if (!m_parsedHeaders && m_receivedData.contains("\r\n\r\n")) {
++ m_parsedHeaders = true;
++ QTimer::singleShot(qrand()%10, this, SLOT(closeDelayed())); // simulate random network latency
++ // This server simulates a web server connection closing, e.g. because of Apaches MaxKeepAliveRequests or KeepAliveTimeout
++ // In this case QNAM needs to re-send the upload data but it had a bug which then corrupts the upload
++ // This test catches that.
++ }
++
++ }
++ void disconnectedSlot()
++ {
++ if (m_parsedHeaders) {
++ //qDebug() << m_receivedData.left(m_receivedData.indexOf("\r\n\r\n"));
++ m_receivedData = m_receivedData.mid(m_receivedData.indexOf("\r\n\r\n")+4); // check only actual data
++ }
++ if (m_receivedData.length() > 0 && !m_expectedData.startsWith(m_receivedData)) {
++ // We had received some data but it is corrupt!
++ qDebug() << "CORRUPT" << m_receivedData.count();
++
++ // Use this to track down the pattern of the corruption and conclude the source
++// QFile a("/tmp/corrupt");
++// a.open(QIODevice::WriteOnly);
++// a.write(m_receivedData);
++// a.close();
++
++// QFile b("/tmp/correct");
++// b.open(QIODevice::WriteOnly);
++// b.write(m_expectedData);
++// b.close();
++ //exit(1);
++ emit corruptFileUploadReceived();
++ } else {
++ emit correctFileUploadReceived();
++ }
++ }
++};
++
++class PutWithServerClosingConnectionImmediatelyServer: public SslServer
++{
++ Q_OBJECT
++public:
++ int m_correctUploads;
++ int m_corruptUploads;
++ int m_repliesFinished;
++ int m_expectedReplies;
++ QByteArray m_expectedData;
++ PutWithServerClosingConnectionImmediatelyServer() : SslServer(), m_correctUploads(0), m_corruptUploads(0), m_repliesFinished(0), m_expectedReplies(0)
++ {
++ QObject::connect(this, SIGNAL(newEncryptedConnection(QSslSocket*)), this, SLOT(createHandlerForConnection(QSslSocket*)));
++ QObject::connect(this, SIGNAL(newPlainConnection(QSslSocket*)), this, SLOT(createHandlerForConnection(QSslSocket*)));
++ }
++
++public slots:
++ void createHandlerForConnection(QSslSocket* s) {
++ PutWithServerClosingConnectionImmediatelyHandler *handler = new PutWithServerClosingConnectionImmediatelyHandler(s, m_expectedData);
++ handler->setParent(this);
++ QObject::connect(handler, SIGNAL(correctFileUploadReceived()), this, SLOT(increaseCorrect()));
++ QObject::connect(handler, SIGNAL(corruptFileUploadReceived()), this, SLOT(increaseCorrupt()));
++ }
++ void increaseCorrect() {
++ m_correctUploads++;
++ }
++ void increaseCorrupt() {
++ m_corruptUploads++;
++ }
++ void replyFinished() {
++ m_repliesFinished++;
++ if (m_repliesFinished == m_expectedReplies) {
++ QTestEventLoop::instance().exitLoop();
++ }
++ }
++};
++
++
++
++void tst_QNetworkReply::putWithServerClosingConnectionImmediately()
++{
++ const int numUploads = 40;
++ qint64 wantedSize = 512*1024; // 512 kB
++ QByteArray sourceFile;
++ for (int i = 0; i < wantedSize; ++i) {
++ sourceFile += (char)'a' +(i%26);
++ }
++ bool withSsl = false;
++
++ for (int s = 0; s <= 1; s++) {
++ withSsl = (s == 1);
++ // Test also needs to run several times because of 9c2ecf89
++ for (int j = 0; j < 20; j++) {
++ // emulate a minimal https server
++ PutWithServerClosingConnectionImmediatelyServer server;
++ server.m_ssl = withSsl;
++ server.m_expectedData = sourceFile;
++ server.m_expectedReplies = numUploads;
++ server.listen(QHostAddress(QHostAddress::LocalHost), 0);
++
++ for (int i = 0; i < numUploads; i++) {
++ // create the request
++ QUrl url = QUrl(QString("http%1://127.0.0.1:%2/file=%3").arg(withSsl ? "s" : "").arg(server.serverPort()).arg(i));
++ QNetworkRequest request(url);
++ QNetworkReply *reply = manager.put(request, sourceFile);
++ connect(reply, SIGNAL(sslErrors(QList<QSslError>)), reply, SLOT(ignoreSslErrors()));
++ connect(reply, SIGNAL(finished()), &server, SLOT(replyFinished()));
++ reply->setParent(&server);
++ }
++
++ // get the request started and the incoming socket connected
++ QTestEventLoop::instance().enterLoop(10);
++
++ //qDebug() << "correct=" << server.m_correctUploads << "corrupt=" << server.m_corruptUploads << "expected=" <<numUploads;
++
++ // Sanity check because ecause of 9c2ecf89 most replies will error out but we want to make sure at least some of them worked
++ QVERIFY(server.m_correctUploads > 5);
++ // Because actually important is that we don't get any corruption:
++ QCOMPARE(server.m_corruptUploads, 0);
++
++ server.close();
++ }
++ }
++
++
++}
++
++#endif
+
+ // NOTE: This test must be last testcase in tst_qnetworkreply!
+ void tst_QNetworkReply::parentingRepliesToTheApp()
+--
+1.9.1
+
diff --git a/admin/qt/patches/0008-QNAM-Fix-reply-deadlocks-on-server-closing-connectio.patch b/admin/qt/patches/0008-QNAM-Fix-reply-deadlocks-on-server-closing-connectio.patch
new file mode 100644
index 0000000..c425118
--- /dev/null
+++ b/admin/qt/patches/0008-QNAM-Fix-reply-deadlocks-on-server-closing-connectio.patch
@@ -0,0 +1,64 @@
+From bc32c0ebc0bc00db84ca2f28eb16ab2e5b53a1b6 Mon Sep 17 00:00:00 2001
+From: Markus Goetz <markus at woboq.com>
+Date: Fri, 24 Jul 2015 09:53:20 +0200
+Subject: [PATCH] QNAM: Fix reply deadlocks on server closing connection
+
+The _q_readyRead can also be called from readMoreLater() because we implemented
+it so that bandwidth limited reading can be implemented.
+This can lead to a race condition if the socket is closing at the specific moment
+and then deadlock the channel: It will stay unusable with a zombie request.
+The fix in QHttpProtocolaHandler checks if there is actually bytes available to read
+from the socket and only then continue.
+
+The fix in the HTTP channel needs to be done to properly finish the reply in
+cases of a server replying with HTTP/1.0 or "Connection: close".
+The delayed incovation of _q_receiveReply will properly finish up the reply.
+
+Change-Id: I19ce2ae595f91d56386cc7406ccacc9935672b6b
+Reviewed-by: Richard J. Moore <rich at kde.org>
+---
+ src/network/access/qhttpnetworkconnectionchannel.cpp | 4 ++++
+ src/network/access/qhttpprotocolhandler.cpp | 7 ++++++-
+ 2 files changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
+index 7428f9b..257aa13 100644
+--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
++++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
+@@ -829,11 +829,15 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
+
+ if (!reply->d_func()->expectContent()) {
+ // No content expected, this is a valid way to have the connection closed by the server
++ // We need to invoke this asynchronously to make sure the state() of the socket is on QAbstractSocket::UnconnectedState
++ QMetaObject::invokeMethod(this, "_q_receiveReply", Qt::QueuedConnection);
+ return;
+ }
+ if (reply->contentLength() == -1 && !reply->d_func()->isChunked()) {
+ // There was no content-length header and it's not chunked encoding,
+ // so this is a valid way to have the connection closed by the server
++ // We need to invoke this asynchronously to make sure the state() of the socket is on QAbstractSocket::UnconnectedState
++ QMetaObject::invokeMethod(this, "_q_receiveReply", Qt::QueuedConnection);
+ return;
+ }
+ // ok, we got a disconnect even though we did not expect it
+diff --git a/src/network/access/qhttpprotocolhandler.cpp b/src/network/access/qhttpprotocolhandler.cpp
+index ab2e3da..a208315 100644
+--- a/src/network/access/qhttpprotocolhandler.cpp
++++ b/src/network/access/qhttpprotocolhandler.cpp
+@@ -237,7 +237,12 @@ void QHttpProtocolHandler::_q_readyRead()
+ }
+
+ if (m_channel->isSocketWaiting() || m_channel->isSocketReading()) {
+- m_channel->state = QHttpNetworkConnectionChannel::ReadingState;
++ if (m_socket->bytesAvailable()) {
++ // We might get a spurious call from readMoreLater()
++ // call of the QHttpNetworkConnection even while the socket is disconnecting.
++ // Therefore check if there is actually bytes available before changing the channel state.
++ m_channel->state = QHttpNetworkConnectionChannel::ReadingState;
++ }
+ if (m_reply)
+ _q_receiveReply();
+ }
+--
+1.9.1
+
diff --git a/admin/qt/patches/0009-QNAM-Assign-proper-channel-before-sslErrors-emission.patch b/admin/qt/patches/0009-QNAM-Assign-proper-channel-before-sslErrors-emission.patch
new file mode 100644
index 0000000..e66c4c2
--- /dev/null
+++ b/admin/qt/patches/0009-QNAM-Assign-proper-channel-before-sslErrors-emission.patch
@@ -0,0 +1,33 @@
+From 63cf5d3d26a6f65938c3cdec1734eac9faaaf8cb Mon Sep 17 00:00:00 2001
+From: Markus Goetz <markus at woboq.com>
+Date: Tue, 22 Sep 2015 14:26:24 -0400
+Subject: [PATCH] QNAM: Assign proper channel before sslErrors() emission
+
+There can be a race condition where another channel connects
+and gets the sslErrors() from the socket first. Then the
+QSslConfiguration from the wrong socket (the default
+channel 0's socket) was used.
+
+Task-number: QTBUG-18722
+Change-Id: Ibbfa48c27f181563745daf540fa792a57cc09682
+Reviewed-by: Richard J. Moore <rich at kde.org>
+---
+ src/network/access/qhttpnetworkconnectionchannel.cpp | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
+index 257aa13..477cba2 100644
+--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
++++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
+@@ -1066,6 +1066,8 @@ void QHttpNetworkConnectionChannel::_q_sslErrors(const QList<QSslError> &errors)
+ connection->d_func()->pauseConnection();
+ if (pendingEncrypt && !reply)
+ connection->d_func()->dequeueRequest(socket);
++ if (reply) // a reply was actually dequeued.
++ reply->d_func()->connectionChannel = this; // set correct channel like in sendRequest() and queueRequest();
+ if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP) {
+ if (reply)
+ emit reply->sslErrors(errors);
+--
+1.9.1
+
diff --git a/admin/qt/patches/0011-Make-sure-to-report-correct-NetworkAccessibility.patch b/admin/qt/patches/0011-Make-sure-to-report-correct-NetworkAccessibility.patch
new file mode 100644
index 0000000..9fe366d
--- /dev/null
+++ b/admin/qt/patches/0011-Make-sure-to-report-correct-NetworkAccessibility.patch
@@ -0,0 +1,113 @@
+From c056e63cea1915667997c982f48296ce5acdcc80 Mon Sep 17 00:00:00 2001
+From: Lorn Potter <lorn.potter at gmail.com>
+Date: Tue, 2 Jun 2015 13:22:23 +1000
+Subject: [PATCH] Make sure to report correct NetworkAccessibility
+
+Task-number: QTBUG-46323
+Change-Id: Ibdeb3280091a97d785d4314340678a63e88fb219
+Reviewed-by: Markus Goetz (Woboq GmbH) <markus at woboq.com>
+Reviewed-by: Alex Blasche <alexander.blasche at theqtcompany.com>
+---
+ src/network/access/qnetworkaccessmanager.cpp | 25 +++++++++++++++++--------
+ src/network/access/qnetworkaccessmanager_p.h | 2 ++
+ 2 files changed, 19 insertions(+), 8 deletions(-)
+
+diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
+index e878feb..84931cb 100644
+--- a/src/network/access/qnetworkaccessmanager.cpp
++++ b/src/network/access/qnetworkaccessmanager.cpp
+@@ -472,11 +472,11 @@ QNetworkAccessManager::QNetworkAccessManager(QObject *parent)
+ // the QNetworkSession's signals
+ connect(&d->networkConfigurationManager, SIGNAL(onlineStateChanged(bool)),
+ SLOT(_q_onlineStateChanged(bool)));
+- // we would need all active configurations to check for
+- // d->networkConfigurationManager.isOnline(), which is asynchronous
+- // and potentially expensive. We can just check the configuration here
+- d->online = (d->networkConfiguration.state() & QNetworkConfiguration::Active);
+ }
++ // we would need all active configurations to check for
++ // d->networkConfigurationManager.isOnline(), which is asynchronous
++ // and potentially expensive. We can just check the configuration here
++ d->online = (d->networkConfiguration.state() & QNetworkConfiguration::Active);
+ #endif
+ }
+
+@@ -946,6 +946,7 @@ QNetworkConfiguration QNetworkAccessManager::activeConfiguration() const
+ void QNetworkAccessManager::setNetworkAccessible(QNetworkAccessManager::NetworkAccessibility accessible)
+ {
+ Q_D(QNetworkAccessManager);
++ d->defaultAccessControl = false;
+
+ if (d->networkAccessible != accessible) {
+ NetworkAccessibility previous = networkAccessible();
+@@ -964,7 +965,6 @@ void QNetworkAccessManager::setNetworkAccessible(QNetworkAccessManager::NetworkA
+ QNetworkAccessManager::NetworkAccessibility QNetworkAccessManager::networkAccessible() const
+ {
+ Q_D(const QNetworkAccessManager);
+-
+ if (d->networkSessionRequired) {
+ QSharedPointer<QNetworkSession> networkSession(d->getNetworkSession());
+ if (networkSession) {
+@@ -975,7 +975,13 @@ QNetworkAccessManager::NetworkAccessibility QNetworkAccessManager::networkAccess
+ return NotAccessible;
+ } else {
+ // Network accessibility is either disabled or unknown.
+- return (d->networkAccessible == NotAccessible) ? NotAccessible : UnknownAccessibility;
++ if (d->defaultAccessControl) {
++ if (d->online)
++ return d->networkAccessible;
++ else
++ return NotAccessible;
++ }
++ return (d->networkAccessible);
+ }
+ } else {
+ if (d->online)
+@@ -1568,7 +1574,7 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co
+ if (!networkSessionStrongRef) {
+ online = false;
+
+- if (networkAccessible == QNetworkAccessManager::NotAccessible)
++ if (networkAccessible == QNetworkAccessManager::NotAccessible || !online)
+ emit q->networkAccessibleChanged(QNetworkAccessManager::NotAccessible);
+ else
+ emit q->networkAccessibleChanged(QNetworkAccessManager::UnknownAccessibility);
+@@ -1616,11 +1622,14 @@ void QNetworkAccessManagerPrivate::_q_networkSessionStateChanged(QNetworkSession
+ if (online) {
+ if (state != QNetworkSession::Connected && state != QNetworkSession::Roaming) {
+ online = false;
+- emit q->networkAccessibleChanged(QNetworkAccessManager::NotAccessible);
++ networkAccessible = QNetworkAccessManager::NotAccessible;
++ emit q->networkAccessibleChanged(networkAccessible);
+ }
+ } else {
+ if (state == QNetworkSession::Connected || state == QNetworkSession::Roaming) {
+ online = true;
++ if (defaultAccessControl)
++ networkAccessible = QNetworkAccessManager::Accessible;
+ emit q->networkAccessibleChanged(networkAccessible);
+ }
+ }
+diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h
+index f513324..c715da0 100644
+--- a/src/network/access/qnetworkaccessmanager_p.h
++++ b/src/network/access/qnetworkaccessmanager_p.h
+@@ -84,6 +84,7 @@ public:
+ initializeSession(true),
+ #endif
+ cookieJarCreated(false),
++ defaultAccessControl(true),
+ authenticationManager(QSharedPointer<QNetworkAccessAuthenticationManager>::create())
+ { }
+ ~QNetworkAccessManagerPrivate();
+@@ -164,6 +165,7 @@ public:
+ #endif
+
+ bool cookieJarCreated;
++ bool defaultAccessControl;
+
+ // The cache with authorization data:
+ QSharedPointer<QNetworkAccessAuthenticationManager> authenticationManager;
+--
+1.9.1
+
diff --git a/admin/qt/patches/0012-Make-sure-networkAccessibilityChanged-is-emitted.patch b/admin/qt/patches/0012-Make-sure-networkAccessibilityChanged-is-emitted.patch
new file mode 100644
index 0000000..5879b53
--- /dev/null
+++ b/admin/qt/patches/0012-Make-sure-networkAccessibilityChanged-is-emitted.patch
@@ -0,0 +1,233 @@
+From bb281eea179d50a413f4ec1ff172d27ee48d3a41 Mon Sep 17 00:00:00 2001
+From: Lorn Potter <lorn.potter at gmail.com>
+Date: Fri, 17 Jul 2015 15:32:23 +1000
+Subject: [PATCH] Make sure networkAccessibilityChanged is emitted
+
+Task-number: QTBUG-46323
+Change-Id: I8297072b62763136f457ca6ae15282d1c22244f4
+Reviewed-by: Timo Jyrinki <timo.jyrinki at canonical.com>
+Reviewed-by: Alex Blasche <alexander.blasche at theqtcompany.com>
+---
+ src/network/access/qnetworkaccessmanager.cpp | 70 +++++++++++++++-------
+ src/network/access/qnetworkaccessmanager_p.h | 14 ++++-
+ .../tst_qnetworkaccessmanager.cpp | 31 +++++-----
+ 3 files changed, 77 insertions(+), 38 deletions(-)
+
+diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
+index 84931cb..f9e9513 100644
+--- a/src/network/access/qnetworkaccessmanager.cpp
++++ b/src/network/access/qnetworkaccessmanager.cpp
+@@ -278,7 +278,8 @@ static void ensureInitialized()
+
+ \snippet code/src_network_access_qnetworkaccessmanager.cpp 4
+
+- Network requests can be reenabled again by calling
++ Network requests can be re-enabled again, and this property will resume to
++ reflect the actual device state by calling
+
+ \snippet code/src_network_access_qnetworkaccessmanager.cpp 5
+
+@@ -467,16 +468,12 @@ QNetworkAccessManager::QNetworkAccessManager(QObject *parent)
+ qRegisterMetaType<QSharedPointer<char> >();
+
+ #ifndef QT_NO_BEARERMANAGEMENT
+- if (!d->networkSessionRequired) {
+- // if a session is required, we track online state through
+- // the QNetworkSession's signals
+- connect(&d->networkConfigurationManager, SIGNAL(onlineStateChanged(bool)),
+- SLOT(_q_onlineStateChanged(bool)));
+- }
+- // we would need all active configurations to check for
+- // d->networkConfigurationManager.isOnline(), which is asynchronous
+- // and potentially expensive. We can just check the configuration here
+- d->online = (d->networkConfiguration.state() & QNetworkConfiguration::Active);
++ // if a session is required, we track online state through
++ // the QNetworkSession's signals if a request is already made.
++ // we need to track current accessibility state by default
++ //
++ connect(&d->networkConfigurationManager, SIGNAL(onlineStateChanged(bool)),
++ SLOT(_q_onlineStateChanged(bool)));
+ #endif
+ }
+
+@@ -946,7 +943,8 @@ QNetworkConfiguration QNetworkAccessManager::activeConfiguration() const
+ void QNetworkAccessManager::setNetworkAccessible(QNetworkAccessManager::NetworkAccessibility accessible)
+ {
+ Q_D(QNetworkAccessManager);
+- d->defaultAccessControl = false;
++
++ d->defaultAccessControl = accessible == NotAccessible ? false : true;
+
+ if (d->networkAccessible != accessible) {
+ NetworkAccessibility previous = networkAccessible();
+@@ -965,6 +963,10 @@ void QNetworkAccessManager::setNetworkAccessible(QNetworkAccessManager::NetworkA
+ QNetworkAccessManager::NetworkAccessibility QNetworkAccessManager::networkAccessible() const
+ {
+ Q_D(const QNetworkAccessManager);
++
++ if (d->networkConfiguration.state().testFlag(QNetworkConfiguration::Undefined))
++ return UnknownAccessibility;
++
+ if (d->networkSessionRequired) {
+ QSharedPointer<QNetworkSession> networkSession(d->getNetworkSession());
+ if (networkSession) {
+@@ -1622,32 +1624,56 @@ void QNetworkAccessManagerPrivate::_q_networkSessionStateChanged(QNetworkSession
+ if (online) {
+ if (state != QNetworkSession::Connected && state != QNetworkSession::Roaming) {
+ online = false;
+- networkAccessible = QNetworkAccessManager::NotAccessible;
+- emit q->networkAccessibleChanged(networkAccessible);
++ if (networkAccessible != QNetworkAccessManager::NotAccessible) {
++ networkAccessible = QNetworkAccessManager::NotAccessible;
++ emit q->networkAccessibleChanged(networkAccessible);
++ }
+ }
+ } else {
+ if (state == QNetworkSession::Connected || state == QNetworkSession::Roaming) {
+ online = true;
+ if (defaultAccessControl)
+- networkAccessible = QNetworkAccessManager::Accessible;
+- emit q->networkAccessibleChanged(networkAccessible);
++ if (networkAccessible != QNetworkAccessManager::Accessible) {
++ networkAccessible = QNetworkAccessManager::Accessible;
++ emit q->networkAccessibleChanged(networkAccessible);
++ }
+ }
+ }
+ }
+
+ void QNetworkAccessManagerPrivate::_q_onlineStateChanged(bool isOnline)
+ {
+- // if the user set a config, we only care whether this one is active.
++ Q_Q(QNetworkAccessManager);
++ // if the user set a config, we only care whether this one is active.
+ // Otherwise, this QNAM is online if there is an online config.
+ if (customNetworkConfiguration) {
+ online = (networkConfiguration.state() & QNetworkConfiguration::Active);
+ } else {
+- if (isOnline && online != isOnline) {
+- networkSessionStrongRef.clear();
+- networkSessionWeakRef.clear();
++ if (online != isOnline) {
++ if (isOnline) {
++ networkSessionStrongRef.clear();
++ networkSessionWeakRef.clear();
++ }
++ online = isOnline;
++ }
++ }
++ if (online) {
++ if (defaultAccessControl) {
++ if (networkAccessible != QNetworkAccessManager::Accessible) {
++ networkAccessible = QNetworkAccessManager::Accessible;
++ emit q->networkAccessibleChanged(networkAccessible);
++ }
++ }
++ } else if (networkConfiguration.state().testFlag(QNetworkConfiguration::Undefined)) {
++ if (networkAccessible != QNetworkAccessManager::UnknownAccessibility) {
++ networkAccessible = QNetworkAccessManager::UnknownAccessibility;
++ emit q->networkAccessibleChanged(networkAccessible);
++ }
++ } else {
++ if (networkAccessible != QNetworkAccessManager::NotAccessible) {
++ networkAccessible = QNetworkAccessManager::NotAccessible;
++ emit q->networkAccessibleChanged(networkAccessible);
+ }
+-
+- online = isOnline;
+ }
+ }
+
+diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h
+index c715da0..54ae114 100644
+--- a/src/network/access/qnetworkaccessmanager_p.h
++++ b/src/network/access/qnetworkaccessmanager_p.h
+@@ -78,7 +78,6 @@ public:
+ customNetworkConfiguration(false),
+ networkSessionRequired(networkConfigurationManager.capabilities()
+ & QNetworkConfigurationManager::NetworkSessionRequired),
+- networkAccessible(QNetworkAccessManager::Accessible),
+ activeReplyCount(0),
+ online(false),
+ initializeSession(true),
+@@ -86,7 +85,18 @@ public:
+ cookieJarCreated(false),
+ defaultAccessControl(true),
+ authenticationManager(QSharedPointer<QNetworkAccessAuthenticationManager>::create())
+- { }
++ {
++#ifndef QT_NO_BEARERMANAGEMENT
++ // we would need all active configurations to check for
++ // d->networkConfigurationManager.isOnline(), which is asynchronous
++ // and potentially expensive. We can just check the configuration here
++ online = (networkConfiguration.state().testFlag(QNetworkConfiguration::Active));
++ if (online)
++ networkAccessible = QNetworkAccessManager::Accessible;
++ else
++ networkAccessible = QNetworkAccessManager::NotAccessible;
++#endif
++ }
+ ~QNetworkAccessManagerPrivate();
+
+ void _q_replyFinished();
+diff --git a/tests/auto/network/access/qnetworkaccessmanager/tst_qnetworkaccessmanager.cpp b/tests/auto/network/access/qnetworkaccessmanager/tst_qnetworkaccessmanager.cpp
+index b4e4b9c..8ecb57d 100644
+--- a/tests/auto/network/access/qnetworkaccessmanager/tst_qnetworkaccessmanager.cpp
++++ b/tests/auto/network/access/qnetworkaccessmanager/tst_qnetworkaccessmanager.cpp
+@@ -74,6 +74,10 @@ void tst_QNetworkAccessManager::networkAccessible()
+ // if there is no session, we cannot know in which state we are in
+ QNetworkAccessManager::NetworkAccessibility initialAccessibility =
+ manager.networkAccessible();
++
++ if (initialAccessibility == QNetworkAccessManager::UnknownAccessibility)
++ QSKIP("Unknown accessibility", SkipAll);
++
+ QCOMPARE(manager.networkAccessible(), initialAccessibility);
+
+ manager.setNetworkAccessible(QNetworkAccessManager::NotAccessible);
+@@ -94,29 +98,28 @@ void tst_QNetworkAccessManager::networkAccessible()
+ QCOMPARE(manager.networkAccessible(), initialAccessibility);
+
+ QNetworkConfigurationManager configManager;
+- bool sessionRequired = (configManager.capabilities()
+- & QNetworkConfigurationManager::NetworkSessionRequired);
+ QNetworkConfiguration defaultConfig = configManager.defaultConfiguration();
+ if (defaultConfig.isValid()) {
+ manager.setConfiguration(defaultConfig);
+
+- // the accessibility has not changed if no session is required
+- if (sessionRequired) {
++ QCOMPARE(spy.count(), 0);
++
++ if (defaultConfig.state().testFlag(QNetworkConfiguration::Active))
++ QCOMPARE(manager.networkAccessible(), QNetworkAccessManager::Accessible);
++ else
++ QCOMPARE(manager.networkAccessible(), QNetworkAccessManager::NotAccessible);
++
++ manager.setNetworkAccessible(QNetworkAccessManager::NotAccessible);
++
++ if (defaultConfig.state().testFlag(QNetworkConfiguration::Active)) {
+ QCOMPARE(spy.count(), 1);
+- QCOMPARE(spy.takeFirst().at(0).value<QNetworkAccessManager::NetworkAccessibility>(),
+- QNetworkAccessManager::Accessible);
++ QCOMPARE(QNetworkAccessManager::NetworkAccessibility(spy.takeFirst().at(0).toInt()),
++ QNetworkAccessManager::NotAccessible);
+ } else {
+ QCOMPARE(spy.count(), 0);
+ }
+- QCOMPARE(manager.networkAccessible(), QNetworkAccessManager::Accessible);
+-
+- manager.setNetworkAccessible(QNetworkAccessManager::NotAccessible);
+-
+- QCOMPARE(spy.count(), 1);
+- QCOMPARE(QNetworkAccessManager::NetworkAccessibility(spy.takeFirst().at(0).toInt()),
+- QNetworkAccessManager::NotAccessible);
+- QCOMPARE(manager.networkAccessible(), QNetworkAccessManager::NotAccessible);
+ }
++ QCOMPARE(manager.networkAccessible(), QNetworkAccessManager::NotAccessible);
+ #endif
+ }
+
+--
+1.9.1
+
diff --git a/admin/qt/patches/0013-Make-UnknownAccessibility-not-block-requests.patch b/admin/qt/patches/0013-Make-UnknownAccessibility-not-block-requests.patch
new file mode 100644
index 0000000..7714254
--- /dev/null
+++ b/admin/qt/patches/0013-Make-UnknownAccessibility-not-block-requests.patch
@@ -0,0 +1,52 @@
+From e996d68f6130847637ba287518cff1289cfa48e5 Mon Sep 17 00:00:00 2001
+From: Lorn Potter <lorn.potter at gmail.com>
+Date: Fri, 6 Nov 2015 14:22:44 +1000
+Subject: [PATCH] Make UnknownAccessibility not block requests
+
+This allows requests to proceed without needing bearer plugins.
+
+Task-number: QTBUG-49267
+Change-Id: Ie5ce188ddefebd14d666bb5846e8f93ee2925ed1
+Reviewed-by: Markus Goetz (Woboq GmbH) <markus at woboq.com>
+---
+ src/network/access/qnetworkaccessmanager.cpp | 3 +--
+ src/network/access/qnetworkaccessmanager_p.h | 2 ++
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
+index 086140f..0e5870a 100644
+--- a/src/network/access/qnetworkaccessmanager.cpp
++++ b/src/network/access/qnetworkaccessmanager.cpp
+@@ -976,7 +976,6 @@ QNetworkAccessManager::NetworkAccessibility QNetworkAccessManager::networkAccess
+ else
+ return NotAccessible;
+ } else {
+- // Network accessibility is either disabled or unknown.
+ if (d->defaultAccessControl) {
+ if (d->online)
+ return d->networkAccessible;
+@@ -1161,7 +1160,7 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
+ #ifndef QT_NO_BEARERMANAGEMENT
+ // Return a disabled network reply if network access is disabled.
+ // Except if the scheme is empty or file://.
+- if (!d->networkAccessible && !isLocalFile) {
++ if (d->networkAccessible == NotAccessible && !isLocalFile) {
+ return new QDisabledNetworkReply(this, req, op);
+ }
+
+diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h
+index 54ae114..3fc33b5 100644
+--- a/src/network/access/qnetworkaccessmanager_p.h
++++ b/src/network/access/qnetworkaccessmanager_p.h
+@@ -93,6 +93,8 @@ public:
+ online = (networkConfiguration.state().testFlag(QNetworkConfiguration::Active));
+ if (online)
+ networkAccessible = QNetworkAccessManager::Accessible;
++ else if (networkConfiguration.state().testFlag(QNetworkConfiguration::Undefined))
++ networkAccessible = QNetworkAccessManager::UnknownAccessibility;
+ else
+ networkAccessible = QNetworkAccessManager::NotAccessible;
+ #endif
+--
+1.9.1
+
diff --git a/admin/qt/patches/README.md b/admin/qt/patches/README.md
new file mode 100644
index 0000000..c2327cf
--- /dev/null
+++ b/admin/qt/patches/README.md
@@ -0,0 +1,37 @@
+## Patches used
+
+There are our patches on top of Qt 5.4.0, which we are currently
+using for our binary packages on Windows and Mac OS. Most of them
+have been sent upstream and are part of newer Qt releases.
+
+All changes are designed to up upstream, and all those that are
+special hacks to Qt will bear a NOUPSTREAM in their name
+
+The git-style numeration is ordered by order of creation, their
+purpose is outlined in each patches' front matter.
+
+### Part of Qt v5.4.1 and later
+* 0001-Fix-crash-on-Mac-OS-if-PAC-URL-contains-non-URL-lega.patch
+* 0002-Fix-possible-crash-when-passing-an-invalid-PAC-URL.patch
+* 0003-Fix-crash-if-PAC-script-retrieval-returns-a-null-CFD.patch
+
+### Part of Qt v5.4.2 and later
+* 0004-OSX-Fix-disapearing-tray-icon.patch
+ (TODO: actual patch slighly differs)
+* 0006-QNAM-Fix-upload-corruptions-when-server-closes-conne.patch
+ (TODO: Actual patch on build machine spans over two commit but is identical)
+
+### Part of Qt v5.5.1 and later
+* 0008-QNAM-Fix-reply-deadlocks-on-server-closing-connectio.patch
+ (TODO: actual patch has different name)
+
+### Upstreamed but not in any release yet (as of 2015-11-16)
+* 0009-QNAM-Assign-proper-channel-before-sslErrors-emission.patch
+* 0011-Make-sure-to-report-correct-NetworkAccessibility.patch
+* 0012-Make-sure-networkAccessibilityChanged-is-emitted.patch
+* 0013-Make-UnknownAccessibility-not-block-requests.patch
+
+### Not submitted to be part of any release:
+0005-Fix-force-debug-info-with-macx-clang_NOUPSTREAM.patch
+
+
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/owncloud-client.git
More information about the Pkg-owncloud-commits
mailing list