From 7d1e6ca1998f6fd26795b1f9e408ccd7c7c0b558 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20L=C3=B6sch?= Date: Thu, 31 Mar 2016 15:09:20 +0200 Subject: Limit URLs for proxy auto config to 2083 chars On Windows only URLs up to 2083 characters are supported, so longer URLs are truncated. Task-number: QTBUG-52271 Change-Id: I625e4d089df4d977d39e61e5831611e04260e729 Reviewed-by: Markus Goetz (Woboq GmbH) --- src/network/kernel/qnetworkproxy_win.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'src/network') diff --git a/src/network/kernel/qnetworkproxy_win.cpp b/src/network/kernel/qnetworkproxy_win.cpp index 9e571bfe7f..15ef7d7cee 100644 --- a/src/network/kernel/qnetworkproxy_win.cpp +++ b/src/network/kernel/qnetworkproxy_win.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -590,8 +591,16 @@ QList QNetworkProxyFactory::systemProxyForQuery(const QNetworkPro url.setScheme(QLatin1String("https")); } + QString urlQueryString = url.toString(); + if (urlQueryString.size() > 2083) { + // calls to WinHttpGetProxyForUrl with urls longer than 2083 characters + // fail with error code ERROR_INVALID_PARAMETER(87), so we truncate it + qWarning("Proxy query URL too long for windows API, try with truncated URL"); + urlQueryString = url.toString().left(2083); + } + bool getProxySucceeded = ptrWinHttpGetProxyForUrl(sp->hHttpSession, - (LPCWSTR)url.toString().utf16(), + (LPCWSTR)urlQueryString.utf16(), &sp->autoProxyOptions, &proxyInfo); DWORD getProxyError = GetLastError(); @@ -608,7 +617,7 @@ QList QNetworkProxyFactory::systemProxyForQuery(const QNetworkPro sp->autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL; sp->autoProxyOptions.lpszAutoConfigUrl = (LPCWSTR)sp->autoConfigUrl.utf16(); getProxySucceeded = ptrWinHttpGetProxyForUrl(sp->hHttpSession, - (LPCWSTR)url.toString().utf16(), + (LPCWSTR)urlQueryString.utf16(), &sp->autoProxyOptions, &proxyInfo); getProxyError = GetLastError(); @@ -621,7 +630,7 @@ QList QNetworkProxyFactory::systemProxyForQuery(const QNetworkPro // But now we've to enable it (http://msdn.microsoft.com/en-us/library/aa383153%28v=VS.85%29.aspx) sp->autoProxyOptions.fAutoLogonIfChallenged = TRUE; getProxySucceeded = ptrWinHttpGetProxyForUrl(sp->hHttpSession, - (LPCWSTR)url.toString().utf16(), + (LPCWSTR)urlQueryString.utf16(), &sp->autoProxyOptions, &proxyInfo); getProxyError = GetLastError(); -- cgit v1.2.3 From 34e0e908c896126138a95abdeba7456499d0fb68 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Thu, 17 Mar 2016 10:29:43 +0100 Subject: winrt: Add capabilities as specified by modules So far no capabilities (but internetClient for Windows 10) were added by default, which forced developers to always manually edit the WINRT_MANIFEST.capabilities(_device) property. This allowed to leave out non-required capabilities and keep the created manifest clean, examples being microphone for multimedia. However, this also breaks first user experience as deeper knowledge about this topic is required. Furthermore this is inconsistent with other platforms like Android, where all capabilities are set by default and developers need to edit the manifest manually in any case. With this change, modules can define the capability set to enable all features in the module. If developers want to disable some again, they need to adapt the generated manifest. From our experience this needs to be done in any case, latest at publishing stage when the store manipulates the manifest. Task-number: QTBUG-38802 Change-Id: I6d522268ee0afbfa00a30dbdd5e6ec9f415bebf3 Reviewed-by: Oswald Buddenhagen --- src/network/network.pro | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/network') diff --git a/src/network/network.pro b/src/network/network.pro index cdea190222..fed14616af 100644 --- a/src/network/network.pro +++ b/src/network/network.pro @@ -32,6 +32,10 @@ MODULE_PLUGIN_TYPES = \ ANDROID_PERMISSIONS += \ android.permission.ACCESS_NETWORK_STATE +MODULE_WINRT_CAPABILITIES = \ + internetClient \ + internetClientServer + MODULE_PLUGIN_TYPES = \ bearer load(qt_module) -- cgit v1.2.3 From b0bfe8de68a27de34b9493e7d5263cad1e5823c9 Mon Sep 17 00:00:00 2001 From: Weng Xuetian Date: Tue, 29 Mar 2016 15:24:01 -0700 Subject: Delete the dangling generic engine object. Change-Id: I7d7531f1a678bf186e3a992091344fff64721dec Reviewed-by: Marc Mutz Reviewed-by: Lorn Potter --- src/network/bearer/qnetworkconfigmanager_p.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/network') diff --git a/src/network/bearer/qnetworkconfigmanager_p.cpp b/src/network/bearer/qnetworkconfigmanager_p.cpp index 71e435b771..ccda9dd509 100644 --- a/src/network/bearer/qnetworkconfigmanager_p.cpp +++ b/src/network/bearer/qnetworkconfigmanager_p.cpp @@ -418,6 +418,8 @@ void QNetworkConfigurationManagerPrivate::updateConfigurations() if (generic) { if (!envOK || skipGeneric <= 0) sessionEngines.append(generic); + else + delete generic; } #endif // QT_NO_LIBRARY } -- cgit v1.2.3 From 57ecc00978115ec919d78be622c08d95f141032e Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Thu, 7 Apr 2016 11:43:00 -0700 Subject: Note the introductory version of network redirection related enums. These were missed in d815de8c26ccee33713e37a0fec2982755dcfe1f which originally added these values. Change-Id: I69618c90e71f7cc01eef3db477427759e62f626b Reviewed-by: Allan Sandfeld Jensen Reviewed-by: Mandeep Sandhu --- src/network/access/qnetworkreply.cpp | 2 ++ src/network/access/qnetworkrequest.cpp | 1 + 2 files changed, 3 insertions(+) (limited to 'src/network') diff --git a/src/network/access/qnetworkreply.cpp b/src/network/access/qnetworkreply.cpp index 26f7034c09..a7565560ac 100644 --- a/src/network/access/qnetworkreply.cpp +++ b/src/network/access/qnetworkreply.cpp @@ -135,10 +135,12 @@ QNetworkReplyPrivate::QNetworkReplyPrivate() \value TooManyRedirectsError while following redirects, the maximum limit was reached. The limit is by default set to 50 or as set by QNetworkRequest::setMaxRedirectsAllowed(). + (This value was introduced in 5.6.) \value InsecureRedirectError while following redirects, the network access API detected a redirect from a encrypted protocol (https) to an unencrypted one (http). + (This value was introduced in 5.6.) \value ProxyConnectionRefusedError the connection to the proxy server was refused (the proxy server is not accepting requests) diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp index f5010198f3..2a62cb5f39 100644 --- a/src/network/access/qnetworkrequest.cpp +++ b/src/network/access/qnetworkrequest.cpp @@ -263,6 +263,7 @@ QT_BEGIN_NAMESPACE Indicates whether the Network Access API should automatically follow a HTTP redirect response or not. Currently redirects that are insecure, that is redirecting from "https" to "http" protocol, are not allowed. + (This value was introduced in 5.6.) \value User Special type. Additional information can be passed in -- cgit v1.2.3 From 8686ff0d9c09af255a16d03a1f5a2f794c631424 Mon Sep 17 00:00:00 2001 From: David Faure Date: Sun, 27 Mar 2016 22:32:19 +0200 Subject: Doc: clarify redirection handling in QNetworkRequest The text for RedirectionTargetAttribute said the app has to handle redirections, and only said that this attribute wouldn't be set if FollowRedirectsAttribute is set, which was a bit confusing to read, before reading what exactly FollowRedirectsAttribute does. It does more than removing the other attribute, it actually follows the redirection... Change-Id: Idc634996e7b521ba05c05ca52438e47f1a411c85 Reviewed-by: Mandeep Sandhu Reviewed-by: Allan Sandfeld Jensen --- src/network/access/qnetworkrequest.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/network') diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp index 2a62cb5f39..29a7c2c46d 100644 --- a/src/network/access/qnetworkrequest.cpp +++ b/src/network/access/qnetworkrequest.cpp @@ -138,11 +138,12 @@ QT_BEGIN_NAMESPACE Replies only, type: QMetaType::QUrl (no default) If present, it indicates that the server is redirecting the request to a different URL. The Network Access API does not by - default follow redirections: it's up to the application to + default follow redirections: the application can determine if the requested redirection should be allowed, - according to its security policies. However, if - QNetworkRequest::FollowRedirectsAttribute is set, then this attribute - will not be present in the reply. + according to its security policies, or it can set + QNetworkRequest::FollowRedirectsAttribute to true (in which case + the redirection will be followed and this attribute will not + be present in the reply). The returned URL might be relative. Use QUrl::resolved() to create an absolute URL out of it. -- cgit v1.2.3 From 09487deeaea584b2abcc2b1049df2a8542bc113e Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Fri, 1 Apr 2016 13:42:32 +0200 Subject: WinRT: Enable broadcasts The CanBroadcast flag for QNetworkInterface indicates the ability to work in broadcast mode. As WinRT natively supports udp broadcasts and they work out of the box this flag should be set there. Task-number: QTBUG-49026 Change-Id: I6623014287fe63dc1c353a6de265ebdf9114d013 Reviewed-by: Maurice Kalinowski --- src/network/kernel/qnetworkinterface_winrt.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/network') diff --git a/src/network/kernel/qnetworkinterface_winrt.cpp b/src/network/kernel/qnetworkinterface_winrt.cpp index 1945b2427f..d0a22e9a16 100644 --- a/src/network/kernel/qnetworkinterface_winrt.cpp +++ b/src/network/kernel/qnetworkinterface_winrt.cpp @@ -73,6 +73,7 @@ static QNetworkInterfacePrivate *interfaceFromProfile(IConnectionProfile *profil Q_ASSERT_SUCCEEDED(hr); if (connectivityLevel != NetworkConnectivityLevel_None) iface->flags = QNetworkInterface::IsUp | QNetworkInterface::IsRunning; + iface->flags |= QNetworkInterface::CanBroadcast; ComPtr adapter; hr = profile->get_NetworkAdapter(&adapter); -- cgit v1.2.3 From 14399b427cdb7662cbca6aa89443521301507b41 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Wed, 6 Apr 2016 10:42:05 +0200 Subject: winrt: fix callbacks by moving them to the xaml thread Change-Id: I7b4f007107e21c02646140acd5ebe5745ca79bce Reviewed-by: Maurice Kalinowski --- src/network/socket/qnativesocketengine_winrt.cpp | 118 +++++++++++++---------- 1 file changed, 67 insertions(+), 51 deletions(-) (limited to 'src/network') diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index 35b7d5474b..d1ebd19cca 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -298,8 +298,10 @@ bool QNativeSocketEngine::connectToHostByName(const QString &name, quint16 port) Q_ASSERT_SUCCEEDED(hr); d->socketState = QAbstractSocket::ConnectingState; - hr = d->connectOp->put_Completed(Callback( + hr = QEventDispatcherWinRT::runOnXamlThread([d]() { + return d->connectOp->put_Completed(Callback( d, &QNativeSocketEnginePrivate::handleConnectToHost).Get()); + }); Q_ASSERT_SUCCEEDED(hr); return d->socketState == QAbstractSocket::ConnectedState; @@ -309,50 +311,53 @@ bool QNativeSocketEngine::bind(const QHostAddress &address, quint16 port) { Q_D(QNativeSocketEngine); HRESULT hr; - ComPtr hostAddress; + hr = QEventDispatcherWinRT::runOnXamlThread([address, d, port, this]() { + HRESULT hr; + ComPtr hostAddress; - if (address != QHostAddress::Any && address != QHostAddress::AnyIPv4 && address != QHostAddress::AnyIPv6) { - ComPtr hostNameFactory; - hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_HostName).Get(), - &hostNameFactory); - Q_ASSERT_SUCCEEDED(hr); - const QString addressString = address.toString(); - HStringReference addressRef(reinterpret_cast(addressString.utf16())); - hr = hostNameFactory->CreateHostName(addressRef.Get(), &hostAddress); - RETURN_FALSE_IF_FAILED("QNativeSocketEngine::bind: Could not create hostname."); - } + if (address != QHostAddress::Any && address != QHostAddress::AnyIPv4 && address != QHostAddress::AnyIPv6) { + ComPtr hostNameFactory; + hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_HostName).Get(), + &hostNameFactory); + RETURN_HR_IF_FAILED("QNativeSocketEngine::bind: Could not obtain hostname factory"); + const QString addressString = address.toString(); + HStringReference addressRef(reinterpret_cast(addressString.utf16())); + hr = hostNameFactory->CreateHostName(addressRef.Get(), &hostAddress); + RETURN_HR_IF_FAILED("QNativeSocketEngine::bind: Could not create hostname."); + } - QString portQString = port ? QString::number(port) : QString(); - HStringReference portString(reinterpret_cast(portQString.utf16())); + QString portQString = port ? QString::number(port) : QString(); + HStringReference portString(reinterpret_cast(portQString.utf16())); - ComPtr op; - if (d->socketType == QAbstractSocket::TcpSocket) { - if (!d->tcpListener) { - hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_StreamSocketListener).Get(), - &d->tcpListener); - Q_ASSERT_SUCCEEDED(hr); - } + ComPtr op; + if (d->socketType == QAbstractSocket::TcpSocket) { + if (!d->tcpListener) { + hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_StreamSocketListener).Get(), + &d->tcpListener); + RETURN_HR_IF_FAILED("QNativeSocketEngine::bind: Could not create tcp listener"); + } - hr = QEventDispatcherWinRT::runOnXamlThread([d]() { - return d->tcpListener->add_ConnectionReceived( + hr = d->tcpListener->add_ConnectionReceived( Callback(d, &QNativeSocketEnginePrivate::handleClientConnection).Get(), &d->connectionToken); - }); - Q_ASSERT_SUCCEEDED(hr); - hr = d->tcpListener->BindEndpointAsync(hostAddress.Get(), portString.Get(), &op); - } else if (d->socketType == QAbstractSocket::UdpSocket) { - hr = d->udpSocket()->BindEndpointAsync(hostAddress.Get(), portString.Get(), &op); - } - if (hr == E_ACCESSDENIED) { - qErrnoWarning(hr, "Unable to bind socket (%s:%hu/%s). Please check your manifest capabilities.", - qPrintable(address.toString()), port, socketDescription(this).constData()); - return false; - } - Q_ASSERT_SUCCEEDED(hr); + RETURN_HR_IF_FAILED("QNativeSocketEngine::bind: Could not register client connection callback"); + hr = d->tcpListener->BindEndpointAsync(hostAddress.Get(), portString.Get(), &op); + } else if (d->socketType == QAbstractSocket::UdpSocket) { + hr = d->udpSocket()->BindEndpointAsync(hostAddress.Get(), portString.Get(), &op); + } + if (hr == E_ACCESSDENIED) { + qErrnoWarning(hr, "Unable to bind socket (%s:%hu/%s). Please check your manifest capabilities.", + qPrintable(address.toString()), port, socketDescription(this).constData()); + return hr; + } + RETURN_HR_IF_FAILED("QNativeSocketEngine::bind: Unable to bind socket"); - hr = op->put_Completed(Callback(d, &QNativeSocketEnginePrivate::handleBindCompleted).Get()); - Q_ASSERT_SUCCEEDED(hr); - hr = QWinRTFunctions::await(op); + hr = op->put_Completed(Callback(d, &QNativeSocketEnginePrivate::handleBindCompleted).Get()); + RETURN_HR_IF_FAILED("QNativeSocketEngine::bind: Could not register bind callback"); + hr = QWinRTFunctions::await(op); + RETURN_HR_IF_FAILED("QNativeSocketEngine::bind: Could not wait for bind to finish"); + return S_OK; + }); Q_ASSERT_SUCCEEDED(hr); d->socketState = QAbstractSocket::BoundState; @@ -404,7 +409,9 @@ int QNativeSocketEngine::accept() socketDescription(this).constData()); return -1; } - hr = op->put_Completed(Callback(d, &QNativeSocketEnginePrivate::handleReadyRead).Get()); + hr = QEventDispatcherWinRT::runOnXamlThread([d, op]() { + return op->put_Completed(Callback(d, &QNativeSocketEnginePrivate::handleReadyRead).Get()); + }); if (FAILED(hr)) { qErrnoWarning(hr, "accept(): Failed to set socket read callback (%s).", socketDescription(this).constData()); @@ -774,18 +781,22 @@ void QNativeSocketEngine::establishRead() Q_D(QNativeSocketEngine); HRESULT hr; - ComPtr stream; - hr = d->tcpSocket()->get_InputStream(&stream); - RETURN_VOID_IF_FAILED("Failed to get socket input stream"); + hr = QEventDispatcherWinRT::runOnXamlThread([d]() { + ComPtr stream; + HRESULT hr = d->tcpSocket()->get_InputStream(&stream); + RETURN_HR_IF_FAILED("QNativeSocketEngine::establishRead: Failed to get socket input stream"); - ComPtr buffer; - hr = g->bufferFactory->Create(READ_BUFFER_SIZE, &buffer); - Q_ASSERT_SUCCEEDED(hr); + ComPtr buffer; + hr = g->bufferFactory->Create(READ_BUFFER_SIZE, &buffer); + RETURN_HR_IF_FAILED("QNativeSocketEngine::establishRead: Failed to create buffer"); - ComPtr op; - hr = stream->ReadAsync(buffer.Get(), READ_BUFFER_SIZE, InputStreamOptions_Partial, &op); - RETURN_VOID_IF_FAILED("Failed to initiate socket read"); - hr = op->put_Completed(Callback(d, &QNativeSocketEnginePrivate::handleReadyRead).Get()); + ComPtr op; + hr = stream->ReadAsync(buffer.Get(), READ_BUFFER_SIZE, InputStreamOptions_Partial, &op); + RETURN_HR_IF_FAILED("QNativeSocketEngine::establishRead: Failed to initiate socket read"); + hr = op->put_Completed(Callback(d, &QNativeSocketEnginePrivate::handleReadyRead).Get()); + RETURN_HR_IF_FAILED("QNativeSocketEngine::establishRead: Failed to register read callback"); + return S_OK; + }); Q_ASSERT_SUCCEEDED(hr); } @@ -807,7 +818,10 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(), &socket); Q_ASSERT_SUCCEEDED(hr); socketDescriptor = qintptr(socket.Detach()); - hr = udpSocket()->add_MessageReceived(Callback(this, &QNativeSocketEnginePrivate::handleNewDatagram).Get(), &connectionToken); + hr = QEventDispatcherWinRT::runOnXamlThread([this]() { + HRESULT hr = udpSocket()->add_MessageReceived(Callback(this, &QNativeSocketEnginePrivate::handleNewDatagram).Get(), &connectionToken); + return hr; + }); Q_ASSERT_SUCCEEDED(hr); break; } @@ -1297,7 +1311,9 @@ HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *async socketDescription(q).constData()); return S_OK; } - hr = op->put_Completed(Callback(this, &QNativeSocketEnginePrivate::handleReadyRead).Get()); + hr = QEventDispatcherWinRT::runOnXamlThread([op, this]() { + return op->put_Completed(Callback(this, &QNativeSocketEnginePrivate::handleReadyRead).Get()); + }); if (FAILED(hr)) { qErrnoWarning(hr, "handleReadyRead(): Failed to set socket read callback (%s).", socketDescription(q).constData()); -- cgit v1.2.3 From cd17321213917607fe8804f90698ff94301aa3fc Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Wed, 6 Apr 2016 10:46:00 +0200 Subject: winrt: Use correct socket error on socket close Change-Id: I6d39b091e48a911534cb79d42d33d16041261cfb Reviewed-by: Maurice Kalinowski --- src/network/socket/qnativesocketengine_winrt.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/network') diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index d1ebd19cca..0ff76adecf 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -1246,7 +1246,7 @@ HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *async // that the connection was closed. The socket cannot be closed here, as the subsequent read // might fail then. if (status == Error || status == Canceled) { - setError(QAbstractSocket::NetworkError, RemoteHostClosedErrorString); + setError(QAbstractSocket::RemoteHostClosedError, RemoteHostClosedErrorString); socketState = QAbstractSocket::UnconnectedState; if (notifyOnRead) emit q->readReady(); @@ -1265,7 +1265,7 @@ HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *async // the closing of the socket won't be communicated to the caller. So only the error is set. The // actual socket close happens inside of read. if (!bufferLength) { - setError(QAbstractSocket::NetworkError, RemoteHostClosedErrorString); + setError(QAbstractSocket::RemoteHostClosedError, RemoteHostClosedErrorString); socketState = QAbstractSocket::UnconnectedState; if (notifyOnRead) emit q->readReady(); -- cgit v1.2.3