diff options
Diffstat (limited to 'src/network')
108 files changed, 16811 insertions, 7527 deletions
diff --git a/src/network/.prev_CMakeLists.txt b/src/network/.prev_CMakeLists.txt new file mode 100644 index 0000000000..1af21c806b --- /dev/null +++ b/src/network/.prev_CMakeLists.txt @@ -0,0 +1,436 @@ +# Generated from network.pro. + +##################################################################### +## Network Module: +##################################################################### + +qt_add_module(Network + SOURCES + access/qabstractnetworkcache.cpp access/qabstractnetworkcache.h access/qabstractnetworkcache_p.h + access/qhsts.cpp access/qhsts_p.h + access/qhstspolicy.cpp access/qhstspolicy.h + access/qnetworkaccessauthenticationmanager.cpp access/qnetworkaccessauthenticationmanager_p.h + access/qnetworkaccessbackend.cpp access/qnetworkaccessbackend_p.h + access/qnetworkaccesscache.cpp access/qnetworkaccesscache_p.h + access/qnetworkaccesscachebackend.cpp access/qnetworkaccesscachebackend_p.h + access/qnetworkaccessdebugpipebackend.cpp access/qnetworkaccessdebugpipebackend_p.h + access/qnetworkaccessfilebackend.cpp access/qnetworkaccessfilebackend_p.h + access/qnetworkaccessmanager.cpp access/qnetworkaccessmanager.h access/qnetworkaccessmanager_p.h + access/qnetworkcookie.cpp access/qnetworkcookie.h access/qnetworkcookie_p.h + access/qnetworkcookiejar.cpp access/qnetworkcookiejar.h access/qnetworkcookiejar_p.h + access/qnetworkfile.cpp access/qnetworkfile_p.h + access/qnetworkreply.cpp access/qnetworkreply.h access/qnetworkreply_p.h + access/qnetworkreplydataimpl.cpp access/qnetworkreplydataimpl_p.h + access/qnetworkreplyfileimpl.cpp access/qnetworkreplyfileimpl_p.h + access/qnetworkreplyimpl.cpp access/qnetworkreplyimpl_p.h + access/qnetworkrequest.cpp access/qnetworkrequest.h access/qnetworkrequest_p.h + kernel/qauthenticator.cpp kernel/qauthenticator.h kernel/qauthenticator_p.h + kernel/qhostaddress.cpp kernel/qhostaddress.h kernel/qhostaddress_p.h + kernel/qhostinfo.cpp kernel/qhostinfo.h kernel/qhostinfo_p.h + kernel/qnetconmonitor_p.h + kernel/qnetworkdatagram.cpp kernel/qnetworkdatagram.h kernel/qnetworkdatagram_p.h + kernel/qnetworkinterface.cpp kernel/qnetworkinterface.h kernel/qnetworkinterface_p.h + kernel/qnetworkinterface_unix_p.h + kernel/qnetworkproxy.cpp kernel/qnetworkproxy.h + kernel/qtnetworkglobal.h kernel/qtnetworkglobal_p.h + socket/qabstractsocket.cpp socket/qabstractsocket.h socket/qabstractsocket_p.h + socket/qabstractsocketengine.cpp socket/qabstractsocketengine_p.h + socket/qtcpserver.cpp socket/qtcpserver.h socket/qtcpserver_p.h + socket/qtcpsocket.cpp socket/qtcpsocket.h socket/qtcpsocket_p.h + socket/qudpsocket.cpp socket/qudpsocket.h + ssl/qasn1element.cpp ssl/qasn1element_p.h + ssl/qpassworddigestor.cpp ssl/qpassworddigestor.h + ssl/qssl.cpp ssl/qssl.h ssl/qssl_p.h + ssl/qsslcertificate.cpp ssl/qsslcertificate.h ssl/qsslcertificate_p.h + ssl/qsslcertificateextension.cpp ssl/qsslcertificateextension.h ssl/qsslcertificateextension_p.h + DEFINES + QT_NO_FOREACH + QT_NO_USING_NAMESPACE + INCLUDE_DIRECTORIES + kernel + LIBRARIES + Qt::CorePrivate + PUBLIC_LIBRARIES + Qt::Core + PRIVATE_MODULE_INTERFACE + Qt::CorePrivate + PRECOMPILED_HEADER + "../corelib/global/qt_pch.h" +) + +#### Keys ignored in scope 1:.:.:network.pro:<TRUE>: +# MODULE_WINRT_CAPABILITIES = "internetClient" "internetClientServer" "privateNetworkClientServer" +# QMAKE_LIBS = "$$QMAKE_LIBS_NETWORK" + +## Scopes: +##################################################################### + +qt_extend_target(Network CONDITION MSVC AND (TEST_architecture_arch STREQUAL "i386") + LINK_OPTIONS + "/BASE:0x64000000" +) + +qt_extend_target(Network CONDITION QT_FEATURE_ftp + SOURCES + access/qftp.cpp access/qftp_p.h + access/qnetworkaccessftpbackend.cpp access/qnetworkaccessftpbackend_p.h + kernel/qurlinfo.cpp kernel/qurlinfo_p.h +) + +qt_extend_target(Network CONDITION QT_FEATURE_networkdiskcache + SOURCES + access/qnetworkdiskcache.cpp access/qnetworkdiskcache.h access/qnetworkdiskcache_p.h +) + +qt_extend_target(Network CONDITION QT_FEATURE_settings + SOURCES + access/qhstsstore.cpp access/qhstsstore_p.h +) + +qt_extend_target(Network CONDITION APPLE + LIBRARIES + ${FWCoreFoundation} + ${FWSecurity} +) + +qt_extend_target(Network CONDITION WASM + SOURCES + access/qnetworkreplywasmimpl.cpp access/qnetworkreplywasmimpl_p.h +) + +qt_extend_target(Network CONDITION QT_FEATURE_http + SOURCES + access/http2/bitstreams.cpp access/http2/bitstreams_p.h + access/http2/hpack.cpp access/http2/hpack_p.h + access/http2/hpacktable.cpp access/http2/hpacktable_p.h + access/http2/http2frames.cpp access/http2/http2frames_p.h + access/http2/http2protocol.cpp access/http2/http2protocol_p.h + access/http2/http2streams.cpp access/http2/http2streams_p.h + access/http2/huffman.cpp access/http2/huffman_p.h + access/qabstractprotocolhandler.cpp access/qabstractprotocolhandler_p.h + access/qhttp2configuration.cpp access/qhttp2configuration.h + access/qhttp2protocolhandler.cpp access/qhttp2protocolhandler_p.h + access/qhttpmultipart.cpp access/qhttpmultipart.h access/qhttpmultipart_p.h + access/qhttpnetworkconnection.cpp access/qhttpnetworkconnection_p.h + access/qhttpnetworkconnectionchannel.cpp access/qhttpnetworkconnectionchannel_p.h + access/qhttpnetworkheader.cpp access/qhttpnetworkheader_p.h + access/qhttpnetworkreply.cpp access/qhttpnetworkreply_p.h + access/qhttpnetworkrequest.cpp access/qhttpnetworkrequest_p.h + access/qhttpprotocolhandler.cpp access/qhttpprotocolhandler_p.h + access/qhttpthreaddelegate.cpp access/qhttpthreaddelegate_p.h + access/qnetworkreplyhttpimpl.cpp access/qnetworkreplyhttpimpl_p.h + socket/qhttpsocketengine.cpp socket/qhttpsocketengine_p.h +) + +qt_extend_target(Network CONDITION QT_FEATURE_system_zlib + LIBRARIES + ZLIB::ZLIB +) + +qt_extend_target(Network CONDITION NOT QT_FEATURE_system_zlib + INCLUDE_DIRECTORIES + ../3rdparty/zlib/src +) + +qt_extend_target(Network CONDITION NOT QT_FEATURE_system_zlib AND NOT no_core_dep + LIBRARIES + Qt::Core +) + +qt_extend_target(Network CONDITION QT_FEATURE_topleveldomain + SOURCES + kernel/qtldurl.cpp kernel/qtldurl_p.h + kernel/qurltlds_p.h +) + +qt_extend_target(Network CONDITION QT_FEATURE_dnslookup + SOURCES + kernel/qdnslookup.cpp kernel/qdnslookup.h kernel/qdnslookup_p.h +) + +qt_extend_target(Network CONDITION UNIX + SOURCES + kernel/qhostinfo_unix.cpp + socket/qnativesocketengine_unix.cpp + socket/qnet_unix_p.h +) + +qt_extend_target(Network CONDITION QT_FEATURE_dlopen AND UNIX + LIBRARIES + ${CMAKE_DL_LIBS} +) + +qt_extend_target(Network CONDITION QT_FEATURE_linux_netlink AND UNIX + SOURCES + kernel/qnetworkinterface_linux.cpp +) + +qt_extend_target(Network CONDITION UNIX AND NOT QT_FEATURE_linux_netlink + SOURCES + kernel/qnetworkinterface_unix.cpp +) + +qt_extend_target(Network CONDITION ANDROID AND QT_FEATURE_dnslookup + SOURCES + kernel/qdnslookup_android.cpp +) + +qt_extend_target(Network CONDITION WIN32 + SOURCES + kernel/qhostinfo_win.cpp +) + +qt_extend_target(Network CONDITION WIN32 AND NOT WINRT + SOURCES + kernel/qnetworkinterface_win.cpp + kernel/qnetworkproxy_win.cpp + socket/qnativesocketengine_win.cpp + LIBRARIES + advapi32 + dnsapi + iphlpapi +) + +qt_extend_target(Network CONDITION QT_FEATURE_dnslookup AND WIN32 AND NOT WINRT + SOURCES + kernel/qdnslookup_win.cpp +) + +qt_extend_target(Network CONDITION WINRT + SOURCES + kernel/qnetworkinterface_winrt.cpp + socket/qnativesocketengine_winrt.cpp socket/qnativesocketengine_winrt_p.h +) + +qt_extend_target(Network CONDITION QT_FEATURE_dnslookup AND WINRT + SOURCES + kernel/qdnslookup_winrt.cpp +) + +qt_extend_target(Network CONDITION APPLE AND NOT UIKIT + LIBRARIES + ${FWCoreServices} + ${FWSystemConfiguration} +) + +qt_extend_target(Network CONDITION IOS OR MACOS + SOURCES + kernel/qnetconmonitor_darwin.mm + LIBRARIES + ${FWSystemConfiguration} +) + +qt_extend_target(Network CONDITION QT_FEATURE_netlistmgr AND NOT IOS AND NOT MACOS + SOURCES + kernel/qnetconmonitor_win.cpp +) + +qt_extend_target(Network CONDITION NOT IOS AND NOT MACOS AND NOT QT_FEATURE_netlistmgr + SOURCES + kernel/qnetconmonitor_stub.cpp +) + +qt_extend_target(Network CONDITION QT_FEATURE_gssapi + LIBRARIES + GSSAPI::GSSAPI +) + +qt_extend_target(Network CONDITION UIKIT + SOURCES + kernel/qnetworkinterface_uikit_p.h +) + +qt_extend_target(Network CONDITION MACOS + SOURCES + kernel/qnetworkproxy_mac.cpp +) + +qt_extend_target(Network CONDITION QT_FEATURE_libproxy AND NOT MACOS AND (UNIX OR WINRT) + SOURCES + kernel/qnetworkproxy_libproxy.cpp + LIBRARIES + ${CMAKE_DL_LIBS} + PkgConfig::Libproxy +) + +qt_extend_target(Network CONDITION NOT MACOS AND NOT QT_FEATURE_libproxy AND (UNIX OR WINRT) + SOURCES + kernel/qnetworkproxy_generic.cpp +) + +qt_extend_target(Network CONDITION QT_FEATURE_socks5 + SOURCES + socket/qsocks5socketengine.cpp socket/qsocks5socketengine_p.h +) + +qt_extend_target(Network CONDITION QT_FEATURE_sctp + SOURCES + socket/qsctpserver.cpp socket/qsctpserver.h socket/qsctpserver_p.h + socket/qsctpsocket.cpp socket/qsctpsocket.h socket/qsctpsocket_p.h +) + +qt_extend_target(Network CONDITION NOT WINRT + SOURCES + socket/qnativesocketengine.cpp socket/qnativesocketengine_p.h +) + +qt_extend_target(Network CONDITION MSVC + MOC_OPTIONS + "-D_WINSOCK_DEPRECATED_NO_WARNINGS" +) + +qt_extend_target(Network CONDITION QT_FEATURE_localserver + SOURCES + socket/qlocalserver.cpp socket/qlocalserver.h socket/qlocalserver_p.h + socket/qlocalsocket.cpp socket/qlocalsocket.h socket/qlocalsocket_p.h +) + +qt_extend_target(Network CONDITION QT_FEATURE_localserver AND (INTEGRITY OR WINRT) + SOURCES + socket/qlocalserver_tcp.cpp + socket/qlocalsocket_tcp.cpp + DEFINES + QT_LOCALSOCKET_TCP +) + +qt_extend_target(Network CONDITION QT_FEATURE_localserver AND UNIX AND NOT INTEGRITY AND NOT WINRT + SOURCES + socket/qlocalserver_unix.cpp + socket/qlocalsocket_unix.cpp +) + +qt_extend_target(Network CONDITION QT_FEATURE_localserver AND WIN32 AND NOT WINRT + SOURCES + socket/qlocalserver_win.cpp + socket/qlocalsocket_win.cpp +) + +qt_extend_target(Network CONDITION QT_FEATURE_system_proxies + DEFINES + QT_USE_SYSTEM_PROXIES +) + +qt_extend_target(Network CONDITION NOT QT_FEATURE_openssl + SOURCES + ssl/qsslcertificate_qt.cpp +) + +qt_extend_target(Network CONDITION QT_FEATURE_ssl + SOURCES + ssl/qocspresponse.cpp ssl/qocspresponse.h ssl/qocspresponse_p.h + ssl/qsslcipher.cpp ssl/qsslcipher.h ssl/qsslcipher_p.h + ssl/qsslconfiguration.cpp ssl/qsslconfiguration.h ssl/qsslconfiguration_p.h + ssl/qssldiffiehellmanparameters.cpp ssl/qssldiffiehellmanparameters.h ssl/qssldiffiehellmanparameters_p.h + ssl/qsslellipticcurve.cpp ssl/qsslellipticcurve.h + ssl/qsslerror.cpp ssl/qsslerror.h + ssl/qsslkey.h ssl/qsslkey_p.cpp ssl/qsslkey_p.h + ssl/qsslpresharedkeyauthenticator.cpp ssl/qsslpresharedkeyauthenticator.h ssl/qsslpresharedkeyauthenticator_p.h + ssl/qsslsocket.cpp ssl/qsslsocket.h ssl/qsslsocket_p.h +) + +qt_extend_target(Network CONDITION QT_FEATURE_ssl AND WINRT + SOURCES + ssl/qsslcertificate_winrt.cpp + ssl/qssldiffiehellmanparameters_dummy.cpp + ssl/qsslellipticcurve_dummy.cpp + ssl/qsslkey_qt.cpp + ssl/qsslkey_winrt.cpp + ssl/qsslsocket_winrt.cpp ssl/qsslsocket_winrt_p.h +) + +qt_extend_target(Network CONDITION QT_FEATURE_schannel AND QT_FEATURE_ssl + SOURCES + ssl/qsslcertificate_schannel.cpp + ssl/qssldiffiehellmanparameters_dummy.cpp + ssl/qsslellipticcurve_dummy.cpp + ssl/qsslkey_qt.cpp + ssl/qsslkey_schannel.cpp + ssl/qsslsocket_qt.cpp + ssl/qsslsocket_schannel.cpp ssl/qsslsocket_schannel_p.h + LIBRARIES + Crypt32 + Secur32 + bcrypt + ncrypt +) + +qt_extend_target(Network CONDITION QT_FEATURE_securetransport AND QT_FEATURE_ssl + SOURCES + ssl/qssldiffiehellmanparameters_dummy.cpp + ssl/qsslellipticcurve_dummy.cpp + ssl/qsslkey_mac.cpp + ssl/qsslkey_qt.cpp + ssl/qsslsocket_mac.cpp ssl/qsslsocket_mac_p.h + ssl/qsslsocket_mac_shared.cpp + ssl/qsslsocket_qt.cpp +) + +qt_extend_target(Network CONDITION QT_FEATURE_dtls AND QT_FEATURE_ssl + SOURCES + ssl/qdtls.cpp ssl/qdtls.h ssl/qdtls_p.h +) + +qt_extend_target(Network CONDITION QT_FEATURE_openssl AND QT_FEATURE_ssl + SOURCES + ssl/qsslcertificate_openssl.cpp + ssl/qsslcontext_openssl.cpp ssl/qsslcontext_openssl_p.h + ssl/qssldiffiehellmanparameters_openssl.cpp + ssl/qsslellipticcurve_openssl.cpp + ssl/qsslkey_openssl.cpp + ssl/qsslsocket_openssl.cpp ssl/qsslsocket_openssl_p.h + ssl/qsslsocket_openssl_symbols.cpp ssl/qsslsocket_openssl_symbols_p.h + DEFINES + OPENSSL_API_COMPAT=0x10100000L +) + +qt_extend_target(Network CONDITION QT_FEATURE_dtls AND QT_FEATURE_openssl AND QT_FEATURE_ssl + SOURCES + ssl/qdtls_openssl.cpp ssl/qdtls_openssl_p.h +) + +qt_extend_target(Network CONDITION QT_FEATURE_ocsp AND QT_FEATURE_openssl AND QT_FEATURE_ssl + SOURCES + ssl/qocsp_p.h +) + +qt_extend_target(Network CONDITION APPLE AND QT_FEATURE_openssl AND QT_FEATURE_ssl + SOURCES + ssl/qsslsocket_mac_shared.cpp +) + +qt_extend_target(Network CONDITION ANDROID AND QT_FEATURE_openssl AND QT_FEATURE_ssl AND NOT ANDROID_EMBEDDED + SOURCES + ssl/qsslsocket_openssl_android.cpp +) + +qt_extend_target(Network CONDITION ANDROID AND QT_FEATURE_openssl AND QT_FEATURE_openssl_linked AND QT_FEATURE_ssl AND build_pass + LIBRARIES + crypto_${CMAKE_SYSTEM_PROCESSOR} + ssl_${CMAKE_SYSTEM_PROCESSOR} +) + +qt_extend_target(Network CONDITION QT_FEATURE_openssl AND QT_FEATURE_openssl_linked AND QT_FEATURE_ssl AND NOT ANDROID + LIBRARIES + WrapOpenSSL::WrapOpenSSL +) + +qt_extend_target(Network CONDITION QT_FEATURE_openssl AND QT_FEATURE_ssl AND NOT QT_FEATURE_openssl_linked + LIBRARIES + WrapOpenSSLHeaders::WrapOpenSSLHeaders +) + +qt_extend_target(Network CONDITION QT_FEATURE_openssl AND QT_FEATURE_ssl AND WIN32 + SOURCES + ssl/qwindowscarootfetcher.cpp ssl/qwindowscarootfetcher_p.h + LIBRARIES + crypt32 +) + +qt_extend_target(Network CONDITION QT_FEATURE_dnslookup AND UNIX AND NOT ANDROID AND NOT INTEGRITY + SOURCES + kernel/qdnslookup_unix.cpp +) +qt_add_docs(Network + doc/qtnetwork.qdocconf +) + diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt new file mode 100644 index 0000000000..6ff806fef9 --- /dev/null +++ b/src/network/CMakeLists.txt @@ -0,0 +1,437 @@ +# Generated from network.pro. + +##################################################################### +## Network Module: +##################################################################### + +qt_add_module(Network + SOURCES + access/qabstractnetworkcache.cpp access/qabstractnetworkcache.h access/qabstractnetworkcache_p.h + access/qhsts.cpp access/qhsts_p.h + access/qhstspolicy.cpp access/qhstspolicy.h + access/qnetworkaccessauthenticationmanager.cpp access/qnetworkaccessauthenticationmanager_p.h + access/qnetworkaccessbackend.cpp access/qnetworkaccessbackend_p.h + access/qnetworkaccesscache.cpp access/qnetworkaccesscache_p.h + access/qnetworkaccesscachebackend.cpp access/qnetworkaccesscachebackend_p.h + access/qnetworkaccessdebugpipebackend.cpp access/qnetworkaccessdebugpipebackend_p.h + access/qnetworkaccessfilebackend.cpp access/qnetworkaccessfilebackend_p.h + access/qnetworkaccessmanager.cpp access/qnetworkaccessmanager.h access/qnetworkaccessmanager_p.h + access/qnetworkcookie.cpp access/qnetworkcookie.h access/qnetworkcookie_p.h + access/qnetworkcookiejar.cpp access/qnetworkcookiejar.h access/qnetworkcookiejar_p.h + access/qnetworkfile.cpp access/qnetworkfile_p.h + access/qnetworkreply.cpp access/qnetworkreply.h access/qnetworkreply_p.h + access/qnetworkreplydataimpl.cpp access/qnetworkreplydataimpl_p.h + access/qnetworkreplyfileimpl.cpp access/qnetworkreplyfileimpl_p.h + access/qnetworkreplyimpl.cpp access/qnetworkreplyimpl_p.h + access/qnetworkrequest.cpp access/qnetworkrequest.h access/qnetworkrequest_p.h + kernel/qauthenticator.cpp kernel/qauthenticator.h kernel/qauthenticator_p.h + kernel/qhostaddress.cpp kernel/qhostaddress.h kernel/qhostaddress_p.h + kernel/qhostinfo.cpp kernel/qhostinfo.h kernel/qhostinfo_p.h + kernel/qnetconmonitor_p.h + kernel/qnetworkdatagram.cpp kernel/qnetworkdatagram.h kernel/qnetworkdatagram_p.h + kernel/qnetworkinterface.cpp kernel/qnetworkinterface.h kernel/qnetworkinterface_p.h + kernel/qnetworkinterface_unix_p.h + kernel/qnetworkproxy.cpp kernel/qnetworkproxy.h + kernel/qtnetworkglobal.h kernel/qtnetworkglobal_p.h + socket/qabstractsocket.cpp socket/qabstractsocket.h socket/qabstractsocket_p.h + socket/qabstractsocketengine.cpp socket/qabstractsocketengine_p.h + socket/qtcpserver.cpp socket/qtcpserver.h socket/qtcpserver_p.h + socket/qtcpsocket.cpp socket/qtcpsocket.h socket/qtcpsocket_p.h + socket/qudpsocket.cpp socket/qudpsocket.h + ssl/qasn1element.cpp ssl/qasn1element_p.h + ssl/qpassworddigestor.cpp ssl/qpassworddigestor.h + ssl/qssl.cpp ssl/qssl.h ssl/qssl_p.h + ssl/qsslcertificate.cpp ssl/qsslcertificate.h ssl/qsslcertificate_p.h + ssl/qsslcertificateextension.cpp ssl/qsslcertificateextension.h ssl/qsslcertificateextension_p.h + DEFINES + QT_NO_FOREACH + QT_NO_USING_NAMESPACE + INCLUDE_DIRECTORIES + kernel + LIBRARIES + Qt::CorePrivate + PUBLIC_LIBRARIES + Qt::Core + PRIVATE_MODULE_INTERFACE + Qt::CorePrivate + PRECOMPILED_HEADER + "../corelib/global/qt_pch.h" +) + +#### Keys ignored in scope 1:.:.:network.pro:<TRUE>: +# MODULE_WINRT_CAPABILITIES = "internetClient" "internetClientServer" "privateNetworkClientServer" +# QMAKE_LIBS = "$$QMAKE_LIBS_NETWORK" + +## Scopes: +##################################################################### + +qt_extend_target(Network CONDITION MSVC AND (TEST_architecture_arch STREQUAL "i386") + LINK_OPTIONS + "/BASE:0x64000000" +) + +qt_extend_target(Network CONDITION QT_FEATURE_ftp + SOURCES + access/qftp.cpp access/qftp_p.h + access/qnetworkaccessftpbackend.cpp access/qnetworkaccessftpbackend_p.h + kernel/qurlinfo.cpp kernel/qurlinfo_p.h +) + +qt_extend_target(Network CONDITION QT_FEATURE_networkdiskcache + SOURCES + access/qnetworkdiskcache.cpp access/qnetworkdiskcache.h access/qnetworkdiskcache_p.h +) + +qt_extend_target(Network CONDITION QT_FEATURE_settings + SOURCES + access/qhstsstore.cpp access/qhstsstore_p.h +) + +qt_extend_target(Network CONDITION APPLE + LIBRARIES + ${FWCoreFoundation} + ${FWSecurity} +) + +qt_extend_target(Network CONDITION WASM + SOURCES + access/qnetworkreplywasmimpl.cpp access/qnetworkreplywasmimpl_p.h +) + +qt_extend_target(Network CONDITION QT_FEATURE_http + SOURCES + access/http2/bitstreams.cpp access/http2/bitstreams_p.h + access/http2/hpack.cpp access/http2/hpack_p.h + access/http2/hpacktable.cpp access/http2/hpacktable_p.h + access/http2/http2frames.cpp access/http2/http2frames_p.h + access/http2/http2protocol.cpp access/http2/http2protocol_p.h + access/http2/http2streams.cpp access/http2/http2streams_p.h + access/http2/huffman.cpp access/http2/huffman_p.h + access/qabstractprotocolhandler.cpp access/qabstractprotocolhandler_p.h + access/qhttp2configuration.cpp access/qhttp2configuration.h + access/qhttp2protocolhandler.cpp access/qhttp2protocolhandler_p.h + access/qhttpmultipart.cpp access/qhttpmultipart.h access/qhttpmultipart_p.h + access/qhttpnetworkconnection.cpp access/qhttpnetworkconnection_p.h + access/qhttpnetworkconnectionchannel.cpp access/qhttpnetworkconnectionchannel_p.h + access/qhttpnetworkheader.cpp access/qhttpnetworkheader_p.h + access/qhttpnetworkreply.cpp access/qhttpnetworkreply_p.h + access/qhttpnetworkrequest.cpp access/qhttpnetworkrequest_p.h + access/qhttpprotocolhandler.cpp access/qhttpprotocolhandler_p.h + access/qhttpthreaddelegate.cpp access/qhttpthreaddelegate_p.h + access/qnetworkreplyhttpimpl.cpp access/qnetworkreplyhttpimpl_p.h + socket/qhttpsocketengine.cpp socket/qhttpsocketengine_p.h +) + +qt_extend_target(Network CONDITION QT_FEATURE_system_zlib + LIBRARIES + ZLIB::ZLIB +) + +qt_extend_target(Network CONDITION NOT QT_FEATURE_system_zlib + INCLUDE_DIRECTORIES + ../3rdparty/zlib/src +) + +qt_extend_target(Network CONDITION NOT QT_FEATURE_system_zlib AND NOT no_core_dep + LIBRARIES + Qt::Core +) + +qt_extend_target(Network CONDITION QT_FEATURE_topleveldomain + SOURCES + kernel/qtldurl.cpp kernel/qtldurl_p.h + kernel/qurltlds_p.h +) + +qt_extend_target(Network CONDITION QT_FEATURE_dnslookup + SOURCES + kernel/qdnslookup.cpp kernel/qdnslookup.h kernel/qdnslookup_p.h +) + +qt_extend_target(Network CONDITION UNIX + SOURCES + kernel/qhostinfo_unix.cpp + socket/qnativesocketengine_unix.cpp + socket/qnet_unix_p.h +) + +qt_extend_target(Network CONDITION QT_FEATURE_dlopen AND UNIX + LIBRARIES + ${CMAKE_DL_LIBS} +) + +qt_extend_target(Network CONDITION QT_FEATURE_linux_netlink AND UNIX + SOURCES + kernel/qnetworkinterface_linux.cpp +) + +qt_extend_target(Network CONDITION UNIX AND NOT QT_FEATURE_linux_netlink + SOURCES + kernel/qnetworkinterface_unix.cpp +) + +qt_extend_target(Network CONDITION ANDROID AND QT_FEATURE_dnslookup + SOURCES + kernel/qdnslookup_android.cpp +) + +qt_extend_target(Network CONDITION WIN32 + SOURCES + kernel/qhostinfo_win.cpp +) + +qt_extend_target(Network CONDITION WIN32 AND NOT WINRT + SOURCES + kernel/qnetworkinterface_win.cpp + kernel/qnetworkproxy_win.cpp + socket/qnativesocketengine_win.cpp + LIBRARIES + advapi32 + dnsapi + iphlpapi +) + +qt_extend_target(Network CONDITION QT_FEATURE_dnslookup AND WIN32 AND NOT WINRT + SOURCES + kernel/qdnslookup_win.cpp +) + +qt_extend_target(Network CONDITION WINRT + SOURCES + kernel/qnetworkinterface_winrt.cpp + socket/qnativesocketengine_winrt.cpp socket/qnativesocketengine_winrt_p.h +) + +qt_extend_target(Network CONDITION QT_FEATURE_dnslookup AND WINRT + SOURCES + kernel/qdnslookup_winrt.cpp +) + +qt_extend_target(Network CONDITION APPLE AND NOT UIKIT + LIBRARIES + ${FWCoreServices} + ${FWSystemConfiguration} +) + +qt_extend_target(Network CONDITION IOS OR MACOS + SOURCES + kernel/qnetconmonitor_darwin.mm + LIBRARIES + ${FWSystemConfiguration} +) + +qt_extend_target(Network CONDITION QT_FEATURE_netlistmgr AND NOT IOS AND NOT MACOS + SOURCES + kernel/qnetconmonitor_win.cpp +) + +qt_extend_target(Network CONDITION NOT IOS AND NOT MACOS AND NOT QT_FEATURE_netlistmgr + SOURCES + kernel/qnetconmonitor_stub.cpp +) + +qt_extend_target(Network CONDITION QT_FEATURE_gssapi + LIBRARIES + GSSAPI::GSSAPI +) + +qt_extend_target(Network CONDITION UIKIT + SOURCES + kernel/qnetworkinterface_uikit_p.h +) + +qt_extend_target(Network CONDITION MACOS + SOURCES + kernel/qnetworkproxy_mac.cpp +) + +qt_extend_target(Network CONDITION QT_FEATURE_libproxy AND NOT MACOS AND (UNIX OR WINRT) + SOURCES + kernel/qnetworkproxy_libproxy.cpp + LIBRARIES + ${CMAKE_DL_LIBS} + PkgConfig::Libproxy +) + +qt_extend_target(Network CONDITION NOT MACOS AND NOT QT_FEATURE_libproxy AND (UNIX OR WINRT) + SOURCES + kernel/qnetworkproxy_generic.cpp +) + +qt_extend_target(Network CONDITION QT_FEATURE_socks5 + SOURCES + socket/qsocks5socketengine.cpp socket/qsocks5socketengine_p.h +) + +qt_extend_target(Network CONDITION QT_FEATURE_sctp + SOURCES + socket/qsctpserver.cpp socket/qsctpserver.h socket/qsctpserver_p.h + socket/qsctpsocket.cpp socket/qsctpsocket.h socket/qsctpsocket_p.h +) + +qt_extend_target(Network CONDITION NOT WINRT + SOURCES + socket/qnativesocketengine.cpp socket/qnativesocketengine_p.h +) + +qt_extend_target(Network CONDITION MSVC + MOC_OPTIONS + "-D_WINSOCK_DEPRECATED_NO_WARNINGS" +) + +qt_extend_target(Network CONDITION QT_FEATURE_localserver + SOURCES + socket/qlocalserver.cpp socket/qlocalserver.h socket/qlocalserver_p.h + socket/qlocalsocket.cpp socket/qlocalsocket.h socket/qlocalsocket_p.h +) + +qt_extend_target(Network CONDITION QT_FEATURE_localserver AND (INTEGRITY OR WINRT) + SOURCES + socket/qlocalserver_tcp.cpp + socket/qlocalsocket_tcp.cpp + DEFINES + QT_LOCALSOCKET_TCP +) + +qt_extend_target(Network CONDITION QT_FEATURE_localserver AND UNIX AND NOT INTEGRITY AND NOT WINRT + SOURCES + socket/qlocalserver_unix.cpp + socket/qlocalsocket_unix.cpp +) + +qt_extend_target(Network CONDITION QT_FEATURE_localserver AND WIN32 AND NOT WINRT + SOURCES + socket/qlocalserver_win.cpp + socket/qlocalsocket_win.cpp +) + +qt_extend_target(Network CONDITION QT_FEATURE_system_proxies + DEFINES + QT_USE_SYSTEM_PROXIES +) + +qt_extend_target(Network CONDITION NOT QT_FEATURE_openssl + SOURCES + ssl/qsslcertificate_qt.cpp +) + +qt_extend_target(Network CONDITION QT_FEATURE_ssl + SOURCES + ssl/qocspresponse.cpp ssl/qocspresponse.h ssl/qocspresponse_p.h + ssl/qsslcipher.cpp ssl/qsslcipher.h ssl/qsslcipher_p.h + ssl/qsslconfiguration.cpp ssl/qsslconfiguration.h ssl/qsslconfiguration_p.h + ssl/qssldiffiehellmanparameters.cpp ssl/qssldiffiehellmanparameters.h ssl/qssldiffiehellmanparameters_p.h + ssl/qsslellipticcurve.cpp ssl/qsslellipticcurve.h + ssl/qsslerror.cpp ssl/qsslerror.h + ssl/qsslkey.h ssl/qsslkey_p.cpp ssl/qsslkey_p.h + ssl/qsslpresharedkeyauthenticator.cpp ssl/qsslpresharedkeyauthenticator.h ssl/qsslpresharedkeyauthenticator_p.h + ssl/qsslsocket.cpp ssl/qsslsocket.h ssl/qsslsocket_p.h +) + +qt_extend_target(Network CONDITION QT_FEATURE_ssl AND WINRT + SOURCES + ssl/qsslcertificate_winrt.cpp + ssl/qssldiffiehellmanparameters_dummy.cpp + ssl/qsslellipticcurve_dummy.cpp + ssl/qsslkey_qt.cpp + ssl/qsslkey_winrt.cpp + ssl/qsslsocket_winrt.cpp ssl/qsslsocket_winrt_p.h +) + +qt_extend_target(Network CONDITION QT_FEATURE_schannel AND QT_FEATURE_ssl + SOURCES + ssl/qsslcertificate_schannel.cpp + ssl/qssldiffiehellmanparameters_dummy.cpp + ssl/qsslellipticcurve_dummy.cpp + ssl/qsslkey_qt.cpp + ssl/qsslkey_schannel.cpp + ssl/qsslsocket_qt.cpp + ssl/qsslsocket_schannel.cpp ssl/qsslsocket_schannel_p.h + LIBRARIES + Crypt32 + Secur32 + bcrypt + ncrypt +) + +qt_extend_target(Network CONDITION QT_FEATURE_securetransport AND QT_FEATURE_ssl + SOURCES + ssl/qssldiffiehellmanparameters_dummy.cpp + ssl/qsslellipticcurve_dummy.cpp + ssl/qsslkey_mac.cpp + ssl/qsslkey_qt.cpp + ssl/qsslsocket_mac.cpp ssl/qsslsocket_mac_p.h + ssl/qsslsocket_mac_shared.cpp + ssl/qsslsocket_qt.cpp +) + +qt_extend_target(Network CONDITION QT_FEATURE_dtls AND QT_FEATURE_ssl + SOURCES + ssl/qdtls.cpp ssl/qdtls.h ssl/qdtls_p.h +) + +qt_extend_target(Network CONDITION QT_FEATURE_openssl AND QT_FEATURE_ssl + SOURCES + ssl/qsslcertificate_openssl.cpp + ssl/qsslcontext_openssl.cpp ssl/qsslcontext_openssl_p.h + ssl/qssldiffiehellmanparameters_openssl.cpp + ssl/qsslellipticcurve_openssl.cpp + ssl/qsslkey_openssl.cpp + ssl/qsslsocket_openssl.cpp ssl/qsslsocket_openssl_p.h + ssl/qsslsocket_openssl_symbols.cpp ssl/qsslsocket_openssl_symbols_p.h + DEFINES + OPENSSL_API_COMPAT=0x10100000L +) + +qt_extend_target(Network CONDITION QT_FEATURE_dtls AND QT_FEATURE_openssl AND QT_FEATURE_ssl + SOURCES + ssl/qdtls_openssl.cpp ssl/qdtls_openssl_p.h +) + +qt_extend_target(Network CONDITION QT_FEATURE_ocsp AND QT_FEATURE_openssl AND QT_FEATURE_ssl + SOURCES + ssl/qocsp_p.h +) + +qt_extend_target(Network CONDITION APPLE AND QT_FEATURE_openssl AND QT_FEATURE_ssl + SOURCES + ssl/qsslsocket_mac_shared.cpp +) + +qt_extend_target(Network CONDITION ANDROID AND QT_FEATURE_openssl AND QT_FEATURE_ssl AND NOT ANDROID_EMBEDDED + SOURCES + ssl/qsslsocket_openssl_android.cpp +) + +qt_extend_target(Network CONDITION ANDROID AND QT_FEATURE_openssl AND QT_FEATURE_openssl_linked AND QT_FEATURE_ssl AND build_pass + LIBRARIES + crypto_${CMAKE_SYSTEM_PROCESSOR} + ssl_${CMAKE_SYSTEM_PROCESSOR} +) + +qt_extend_target(Network CONDITION QT_FEATURE_openssl AND QT_FEATURE_openssl_linked AND QT_FEATURE_ssl AND NOT ANDROID + LIBRARIES + WrapOpenSSL::WrapOpenSSL +) + +qt_extend_target(Network CONDITION QT_FEATURE_openssl AND QT_FEATURE_ssl AND NOT QT_FEATURE_openssl_linked + LIBRARIES + WrapOpenSSLHeaders::WrapOpenSSLHeaders +) + +qt_extend_target(Network CONDITION QT_FEATURE_openssl AND QT_FEATURE_ssl AND WIN32 + SOURCES + ssl/qwindowscarootfetcher.cpp ssl/qwindowscarootfetcher_p.h + LIBRARIES + crypt32 +) + +qt_extend_target(Network CONDITION QT_FEATURE_dnslookup AND UNIX AND NOT ANDROID AND NOT INTEGRITY + SOURCES + kernel/qdnslookup_unix.cpp +) +qt_add_docs(Network + doc/qtnetwork.qdocconf +) + +qt_extend_target(Network CONDITION WIN32 PUBLIC_LIBRARIES ws2_32) # special case: mkspecs/common/msvc-desktop.conf diff --git a/src/network/access/access.pri b/src/network/access/access.pri index cfb20dcd71..083fbbf5fd 100644 --- a/src/network/access/access.pri +++ b/src/network/access/access.pri @@ -114,11 +114,4 @@ qtConfig(http) { access/qhttpthreaddelegate_p.h \ access/qnetworkreplyhttpimpl_p.h \ access/qhttp2configuration.h - - qtConfig(ssl) { - SOURCES += \ - access/qspdyprotocolhandler.cpp - HEADERS += \ - access/qspdyprotocolhandler_p.h - } } diff --git a/src/network/access/qabstractnetworkcache.h b/src/network/access/qabstractnetworkcache.h index e357dfe58f..a4048c5b8f 100644 --- a/src/network/access/qabstractnetworkcache.h +++ b/src/network/access/qabstractnetworkcache.h @@ -52,7 +52,6 @@ QT_BEGIN_NAMESPACE class QIODevice; class QDateTime; class QUrl; -template<class T> class QList; class QNetworkCacheMetaDataPrivate; class Q_NETWORK_EXPORT QNetworkCacheMetaData diff --git a/src/network/access/qftp.cpp b/src/network/access/qftp.cpp index 2589c64b1c..048c272780 100644 --- a/src/network/access/qftp.cpp +++ b/src/network/access/qftp.cpp @@ -47,7 +47,7 @@ #include "qtcpsocket.h" #include "qurlinfo_p.h" #include "qstringlist.h" -#include "qregexp.h" +#include "qregularexpression.h" #include "qtimer.h" #include "qfileinfo.h" #include "qtcpserver.h" @@ -317,10 +317,6 @@ void QFtpDTP::connectToHost(const QString & host, quint16 port) socket = nullptr; } socket = new QTcpSocket(this); -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - //copy network session down to the socket - socket->setProperty("_q_networksession", property("_q_networksession")); -#endif socket->setObjectName(QLatin1String("QFtpDTP Passive state socket")); connect(socket, SIGNAL(connected()), SLOT(socketConnected())); connect(socket, SIGNAL(readyRead()), SLOT(socketReadyRead())); @@ -333,10 +329,6 @@ void QFtpDTP::connectToHost(const QString & host, quint16 port) int QFtpDTP::setupListener(const QHostAddress &address) { -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - //copy network session down to the socket - listener.setProperty("_q_networksession", property("_q_networksession")); -#endif if (!listener.isListening() && !listener.listen(address, 0)) return -1; return listener.serverPort(); @@ -621,18 +613,20 @@ bool QFtpDTP::parseDir(const QByteArray &buffer, const QString &userName, QUrlIn QString bufferStr = QString::fromUtf8(buffer).trimmed(); // Unix style FTP servers - QRegExp unixPattern(QLatin1String("^([\\-dl])([a-zA-Z\\-]{9,9})\\s+\\d+\\s+(\\S*)\\s+" - "(\\S*)\\s+(\\d+)\\s+(\\S+\\s+\\S+\\s+\\S+)\\s+(\\S.*)")); - if (unixPattern.indexIn(bufferStr) == 0) { - _q_parseUnixDir(unixPattern.capturedTexts(), userName, info); + QRegularExpression unixPattern(QLatin1String("^([\\-dl])([a-zA-Z\\-]{9,9})\\s+\\d+\\s+(\\S*)\\s+" + "(\\S*)\\s+(\\d+)\\s+(\\S+\\s+\\S+\\s+\\S+)\\s+(\\S.*)")); + auto unixPatternMatch = unixPattern.match(bufferStr); + if (unixPatternMatch.hasMatch()) { + _q_parseUnixDir(unixPatternMatch.capturedTexts(), userName, info); return true; } // DOS style FTP servers - QRegExp dosPattern(QLatin1String("^(\\d\\d-\\d\\d-\\d\\d\\ \\ \\d\\d:\\d\\d[AP]M)\\s+" - "(<DIR>|\\d+)\\s+(\\S.*)$")); - if (dosPattern.indexIn(bufferStr) == 0) { - _q_parseDosDir(dosPattern.capturedTexts(), userName, info); + QRegularExpression dosPattern(QLatin1String("^(\\d\\d-\\d\\d-\\d\\d\\ \\ \\d\\d:\\d\\d[AP]M)\\s+" + "(<DIR>|\\d+)\\s+(\\S.*)$")); + auto dosPatternMatch = dosPattern.match(bufferStr); + if (dosPatternMatch.hasMatch()) { + _q_parseDosDir(dosPatternMatch.capturedTexts(), userName, info); return true; } @@ -817,11 +811,6 @@ QFtpPI::QFtpPI(QObject *parent) : void QFtpPI::connectToHost(const QString &host, quint16 port) { emit connectState(QFtp::HostLookup); -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - //copy network session down to the socket & DTP - commandSocket.setProperty("_q_networksession", property("_q_networksession")); - dtp.setProperty("_q_networksession", property("_q_networksession")); -#endif commandSocket.connectToHost(host, port); } @@ -1064,14 +1053,15 @@ bool QFtpPI::processReply() // both examples where the parenthesis are used, and where // they are missing. We need to scan for the address and host // info. - QRegExp addrPortPattern(QLatin1String("(\\d+),(\\d+),(\\d+),(\\d+),(\\d+),(\\d+)")); - if (addrPortPattern.indexIn(replyText) == -1) { + QRegularExpression addrPortPattern(QLatin1String("(\\d+),(\\d+),(\\d+),(\\d+),(\\d+),(\\d+)")); + auto addrPortMatch = addrPortPattern.match(replyText); + if (!addrPortMatch.hasMatch()) { #if defined(QFTPPI_DEBUG) qDebug("QFtp: bad 227 response -- address and port information missing"); #endif // this error should be reported } else { - const QStringList lst = addrPortPattern.capturedTexts(); + const QStringList lst = addrPortMatch.capturedTexts(); QString host = lst[1] + QLatin1Char('.') + lst[2] + QLatin1Char('.') + lst[3] + QLatin1Char('.') + lst[4]; quint16 port = (lst[5].toUInt() << 8) + lst[6].toUInt(); waitForDtpToConnect = true; @@ -2287,10 +2277,6 @@ void QFtpPrivate::_q_startNextCommand() c->rawCmds.clear(); _q_piFinished(QLatin1String("Proxy set to ") + proxyHost + QLatin1Char(':') + QString::number(proxyPort)); } else if (c->command == QFtp::ConnectToHost) { -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - //copy network session down to the PI - pi.setProperty("_q_networksession", q->property("_q_networksession")); -#endif if (!proxyHost.isEmpty()) { host = c->rawCmds.at(0); port = c->rawCmds.at(1).toUInt(); diff --git a/src/network/access/qhsts_p.h b/src/network/access/qhsts_p.h index c219d9eab5..b5be4ff455 100644 --- a/src/network/access/qhsts_p.h +++ b/src/network/access/qhsts_p.h @@ -66,7 +66,6 @@ QT_BEGIN_NAMESPACE -template<typename T> class QList; template <typename T> class QVector; class Q_AUTOTEST_EXPORT QHstsCache diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp index 03f7261275..ac90714132 100644 --- a/src/network/access/qhttp2protocolhandler.cpp +++ b/src/network/access/qhttp2protocolhandler.cpp @@ -338,13 +338,13 @@ bool QHttp2ProtocolHandler::sendRequest() // so we cannot create new streams. m_channel->emitFinishedWithError(QNetworkReply::ProtocolUnknownError, "GOAWAY received, cannot start a request"); - m_channel->spdyRequestsToSend.clear(); + m_channel->h2RequestsToSend.clear(); return false; } // Process 'fake' (created by QNetworkAccessManager::connectToHostEncrypted()) // requests first: - auto &requests = m_channel->spdyRequestsToSend; + auto &requests = m_channel->h2RequestsToSend; for (auto it = requests.begin(), endIt = requests.end(); it != endIt;) { const auto &pair = *it; const QString scheme(pair.first.url().scheme()); @@ -868,7 +868,7 @@ void QHttp2ProtocolHandler::handleGOAWAY() m_channel->emitFinishedWithError(QNetworkReply::ProtocolUnknownError, "GOAWAY received, cannot start a request"); // Also, prevent further calls to sendRequest: - m_channel->spdyRequestsToSend.clear(); + m_channel->h2RequestsToSend.clear(); QNetworkReply::NetworkError error = QNetworkReply::NoError; QString message; @@ -1287,7 +1287,7 @@ quint32 QHttp2ProtocolHandler::createNewStream(const HttpMessagePair &message, b const auto replyPrivate = reply->d_func(); replyPrivate->connection = m_connection; replyPrivate->connectionChannel = m_channel; - reply->setSpdyWasUsed(true); + reply->setHttp2WasUsed(true); streamIDs.insert(reply, newStreamID); connect(reply, SIGNAL(destroyed(QObject*)), this, SLOT(_q_replyDestroyed(QObject*))); @@ -1393,7 +1393,7 @@ void QHttp2ProtocolHandler::deleteActiveStream(quint32 streamID) } removeFromSuspended(streamID); - if (m_channel->spdyRequestsToSend.size()) + if (m_channel->h2RequestsToSend.size()) QMetaObject::invokeMethod(this, "sendRequest", Qt::QueuedConnection); } @@ -1512,7 +1512,7 @@ void QHttp2ProtocolHandler::initReplyFromPushPromise(const HttpMessagePair &mess Q_ASSERT(promisedData.contains(cacheKey)); auto promise = promisedData.take(cacheKey); Q_ASSERT(message.second); - message.second->setSpdyWasUsed(true); + message.second->setHttp2WasUsed(true); qCDebug(QT_HTTP2) << "found cached/promised response on stream" << promise.reservedID; diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index fce01bf349..f916ee2981 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -82,9 +82,6 @@ QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(const QString &host hostName(hostName), port(port), encrypt(encrypt), delayIpv4(true) , activeChannelCount(type == QHttpNetworkConnection::ConnectionTypeHTTP2 || type == QHttpNetworkConnection::ConnectionTypeHTTP2Direct -#ifndef QT_NO_SSL - || type == QHttpNetworkConnection::ConnectionTypeSPDY -#endif ? 1 : defaultHttpChannelCount) , channelCount(defaultHttpChannelCount) #ifndef QT_NO_NETWORKPROXY @@ -93,9 +90,9 @@ QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(const QString &host , preConnectRequests(0) , connectionType(type) { - // We allocate all 6 channels even if it's SPDY or HTTP/2 enabled - // connection: in case the protocol negotiation via NPN/ALPN fails, - // we will have normally working HTTP/1.1. + // We allocate all 6 channels even if it's HTTP/2 enabled connection: + // in case the protocol negotiation via NPN/ALPN fails, we will have + // normally working HTTP/1.1. Q_ASSERT(channelCount >= activeChannelCount); channels = new QHttpNetworkConnectionChannel[channelCount]; } @@ -135,10 +132,6 @@ void QHttpNetworkConnectionPrivate::init() for (int i = 0; i < channelCount; i++) { channels[i].setConnection(this->q_func()); channels[i].ssl = encrypt; -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - //push session down to channels - channels[i].networkSession = networkSession; -#endif } delayedConnectionTimer.setSingleShot(true); @@ -641,10 +634,10 @@ QHttpNetworkReply* QHttpNetworkConnectionPrivate::queueRequest(const QHttpNetwor break; } } - else { // SPDY, HTTP/2 ('h2' mode) + else { // HTTP/2 ('h2' mode) if (!pair.second->d_func()->requestIsPrepared) prepareRequest(pair); - channels[0].spdyRequestsToSend.insert(request.priority(), pair); + channels[0].h2RequestsToSend.insert(request.priority(), pair); } #ifndef Q_OS_WINRT @@ -680,7 +673,7 @@ void QHttpNetworkConnectionPrivate::fillHttp2Queue() for (auto &pair : highPriorityQueue) { if (!pair.second->d_func()->requestIsPrepared) prepareRequest(pair); - channels[0].spdyRequestsToSend.insert(QHttpNetworkRequest::HighPriority, pair); + channels[0].h2RequestsToSend.insert(QHttpNetworkRequest::HighPriority, pair); } highPriorityQueue.clear(); @@ -688,7 +681,7 @@ void QHttpNetworkConnectionPrivate::fillHttp2Queue() for (auto &pair : lowPriorityQueue) { if (!pair.second->d_func()->requestIsPrepared) prepareRequest(pair); - channels[0].spdyRequestsToSend.insert(pair.first.priority(), pair); + channels[0].h2RequestsToSend.insert(pair.first.priority(), pair); } lowPriorityQueue.clear(); @@ -984,12 +977,12 @@ void QHttpNetworkConnectionPrivate::removeReply(QHttpNetworkReply *reply) } } #ifndef QT_NO_SSL - // is the reply inside the SPDY pipeline of this channel already? - QMultiMap<int, HttpMessagePair>::iterator it = channels[i].spdyRequestsToSend.begin(); - QMultiMap<int, HttpMessagePair>::iterator end = channels[i].spdyRequestsToSend.end(); + // is the reply inside the H2 pipeline of this channel already? + QMultiMap<int, HttpMessagePair>::iterator it = channels[i].h2RequestsToSend.begin(); + QMultiMap<int, HttpMessagePair>::iterator end = channels[i].h2RequestsToSend.end(); for (; it != end; ++it) { if (it.value().second == reply) { - channels[i].spdyRequestsToSend.remove(it.key()); + channels[i].h2RequestsToSend.remove(it.key()); QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection); return; @@ -1068,9 +1061,8 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest() break; } case QHttpNetworkConnection::ConnectionTypeHTTP2Direct: - case QHttpNetworkConnection::ConnectionTypeHTTP2: - case QHttpNetworkConnection::ConnectionTypeSPDY: { - if (channels[0].spdyRequestsToSend.isEmpty() && channels[0].switchedToHttp2) + case QHttpNetworkConnection::ConnectionTypeHTTP2: { + if (channels[0].h2RequestsToSend.isEmpty() && channels[0].switchedToHttp2) return; if (networkLayerState == IPv4) @@ -1079,7 +1071,7 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest() channels[0].networkLayerPreference = QAbstractSocket::IPv6Protocol; channels[0].ensureConnection(); if (channels[0].socket && channels[0].socket->state() == QAbstractSocket::ConnectedState - && !channels[0].pendingEncrypt && channels[0].spdyRequestsToSend.size()) + && !channels[0].pendingEncrypt && channels[0].h2RequestsToSend.size()) channels[0].sendRequest(); break; } @@ -1234,19 +1226,18 @@ void QHttpNetworkConnectionPrivate::_q_hostLookupFinished(const QHostInfo &info) if (dequeueRequest(channels[0].socket)) { emitReplyError(channels[0].socket, channels[0].reply, QNetworkReply::HostNotFoundError); networkLayerState = QHttpNetworkConnectionPrivate::Unknown; - } else if (connectionType == QHttpNetworkConnection::ConnectionTypeSPDY - || connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2 + } else if (connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2 || connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2Direct) { - for (const HttpMessagePair &spdyPair : qAsConst(channels[0].spdyRequestsToSend)) { + for (const HttpMessagePair &h2Pair : qAsConst(channels[0].h2RequestsToSend)) { // emit error for all replies - QHttpNetworkReply *currentReply = spdyPair.second; + QHttpNetworkReply *currentReply = h2Pair.second; Q_ASSERT(currentReply); emitReplyError(channels[0].socket, currentReply, QNetworkReply::HostNotFoundError); } } else { // Should not happen: we start a host lookup before sending a request, - // so it's natural to have requests either in SPDY/HTTP/2 queue, - // or in low/high priority queues. + // so it's natural to have requests either in HTTP/2 queue, or in low/high + // priority queues. qWarning("QHttpNetworkConnectionPrivate::_q_hostLookupFinished" " could not de-queue request, failed to report HostNotFoundError"); networkLayerState = QHttpNetworkConnectionPrivate::Unknown; @@ -1272,19 +1263,6 @@ void QHttpNetworkConnectionPrivate::startNetworkLayerStateLookup() channels[1].networkLayerPreference = QAbstractSocket::IPv6Protocol; int timeout = 300; -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - if (networkSession) { - const QNetworkConfiguration::BearerType bearerType = networkSession->configuration().bearerType(); - if (bearerType == QNetworkConfiguration::Bearer2G) - timeout = 800; - else if (bearerType == QNetworkConfiguration::BearerCDMA2000) - timeout = 500; - else if (bearerType == QNetworkConfiguration::BearerWCDMA) - timeout = 500; - else if (bearerType == QNetworkConfiguration::BearerHSPA) - timeout = 400; - } -#endif delayedConnectionTimer.start(timeout); if (delayIpv4) channels[1].ensureConnection(); @@ -1314,37 +1292,6 @@ void QHttpNetworkConnectionPrivate::_q_connectDelayedChannel() channels[1].ensureConnection(); } -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section -QHttpNetworkConnection::QHttpNetworkConnection(const QString &hostName, quint16 port, bool encrypt, - QHttpNetworkConnection::ConnectionType connectionType, - QObject *parent, QSharedPointer<QNetworkSession> networkSession) - : QObject(*(new QHttpNetworkConnectionPrivate(hostName, port, encrypt, connectionType)), parent) -{ - Q_D(QHttpNetworkConnection); - d->networkSession = std::move(networkSession); - d->init(); - if (QNetworkStatusMonitor::isEnabled()) { - connect(&d->connectionMonitor, &QNetworkConnectionMonitor::reachabilityChanged, - this, &QHttpNetworkConnection::onlineStateChanged, Qt::QueuedConnection); - } -} - -QHttpNetworkConnection::QHttpNetworkConnection(quint16 connectionCount, const QString &hostName, - quint16 port, bool encrypt, QObject *parent, - QSharedPointer<QNetworkSession> networkSession, - QHttpNetworkConnection::ConnectionType connectionType) - : QObject(*(new QHttpNetworkConnectionPrivate(connectionCount, hostName, port, encrypt, - connectionType)), parent) -{ - Q_D(QHttpNetworkConnection); - d->networkSession = std::move(networkSession); - d->init(); - if (QNetworkStatusMonitor::isEnabled()) { - connect(&d->connectionMonitor, &QNetworkConnectionMonitor::reachabilityChanged, - this, &QHttpNetworkConnection::onlineStateChanged, Qt::QueuedConnection); - } -} -#else QHttpNetworkConnection::QHttpNetworkConnection(const QString &hostName, quint16 port, bool encrypt, QHttpNetworkConnection::ConnectionType connectionType, QObject *parent) : QObject(*(new QHttpNetworkConnectionPrivate(hostName, port, encrypt , connectionType)), parent) @@ -1370,7 +1317,6 @@ QHttpNetworkConnection::QHttpNetworkConnection(quint16 connectionCount, const QS this, &QHttpNetworkConnection::onlineStateChanged, Qt::QueuedConnection); } } -#endif // QT_NO_BEARERMANAGEMENT QHttpNetworkConnection::~QHttpNetworkConnection() { @@ -1576,17 +1522,12 @@ void QHttpNetworkConnectionPrivate::emitProxyAuthenticationRequired(const QHttpN pauseConnection(); QHttpNetworkReply *reply; if (connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2 - || connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2Direct -#if QT_CONFIG(ssl) - || connectionType == QHttpNetworkConnection::ConnectionTypeSPDY -#endif - ) { - + || connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2Direct) { // we choose the reply to emit the proxyAuth signal from somewhat arbitrarily, // but that does not matter because the signal will ultimately be emitted // by the QNetworkAccessManager. - Q_ASSERT(chan->spdyRequestsToSend.count() > 0); - reply = chan->spdyRequestsToSend.cbegin().value().second; + Q_ASSERT(chan->h2RequestsToSend.count() > 0); + reply = chan->h2RequestsToSend.cbegin().value().second; } else { // HTTP reply = chan->reply; } diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h index 845b55bc5d..7aecbba2a4 100644 --- a/src/network/access/qhttpnetworkconnection_p.h +++ b/src/network/access/qhttpnetworkconnection_p.h @@ -55,7 +55,6 @@ #include <QtNetwork/qnetworkrequest.h> #include <QtNetwork/qnetworkreply.h> #include <QtNetwork/qabstractsocket.h> -#include <QtNetwork/qnetworksession.h> #include <qhttp2configuration.h> @@ -96,28 +95,16 @@ public: enum ConnectionType { ConnectionTypeHTTP, - ConnectionTypeSPDY, ConnectionTypeHTTP2, ConnectionTypeHTTP2Direct }; -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - explicit QHttpNetworkConnection(const QString &hostName, quint16 port = 80, bool encrypt = false, - ConnectionType connectionType = ConnectionTypeHTTP, - QObject *parent = nullptr, QSharedPointer<QNetworkSession> networkSession - = QSharedPointer<QNetworkSession>()); - QHttpNetworkConnection(quint16 channelCount, const QString &hostName, quint16 port = 80, - bool encrypt = false, QObject *parent = nullptr, - QSharedPointer<QNetworkSession> networkSession = QSharedPointer<QNetworkSession>(), - ConnectionType connectionType = ConnectionTypeHTTP); -#else explicit QHttpNetworkConnection(const QString &hostName, quint16 port = 80, bool encrypt = false, ConnectionType connectionType = ConnectionTypeHTTP, QObject *parent = 0); QHttpNetworkConnection(quint16 channelCount, const QString &hostName, quint16 port = 80, bool encrypt = false, QObject *parent = 0, ConnectionType connectionType = ConnectionTypeHTTP); -#endif ~QHttpNetworkConnection(); //The hostname to which this is connected to. @@ -172,7 +159,6 @@ private: friend class QHttpNetworkConnectionChannel; friend class QHttp2ProtocolHandler; friend class QHttpProtocolHandler; - friend class QSpdyProtocolHandler; Q_PRIVATE_SLOT(d_func(), void _q_startNextRequest()) Q_PRIVATE_SLOT(d_func(), void _q_hostLookupFinished(QHostInfo)) @@ -292,10 +278,6 @@ public: QSharedPointer<QSslContext> sslContext; #endif -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - QSharedPointer<QNetworkSession> networkSession; -#endif - QHttp2Configuration http2Parameters; QString peerVerifyName; diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 95850efe36..ba05e75794 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -48,7 +48,6 @@ #include <private/qhttp2protocolhandler_p.h> #include <private/qhttpprotocolhandler_p.h> -#include <private/qspdyprotocolhandler_p.h> #include <private/http2protocol_p.h> #ifndef QT_NO_SSL @@ -57,10 +56,6 @@ # include <QtNetwork/qsslcipher.h> #endif -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section -#include "private/qnetworksession_p.h" -#endif - #include "private/qnetconmonitor_p.h" QT_BEGIN_NAMESPACE @@ -124,11 +119,6 @@ void QHttpNetworkConnectionChannel::init() #else socket = new QTcpSocket; #endif -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - //push session down to socket - if (networkSession) - socket->setProperty("_q_networksession", QVariant::fromValue(networkSession)); -#endif #ifndef QT_NO_NETWORKPROXY // Set by QNAM anyway, but let's be safe here socket->setProxy(QNetworkProxy::NoProxy); @@ -934,7 +924,7 @@ void QHttpNetworkConnectionChannel::_q_connected() } else if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2Direct) { state = QHttpNetworkConnectionChannel::IdleState; protocolHandler.reset(new QHttp2ProtocolHandler(this)); - if (spdyRequestsToSend.count() > 0) { + if (h2RequestsToSend.count() > 0) { // In case our peer has sent us its settings (window size, max concurrent streams etc.) // let's give _q_receiveReply a chance to read them first ('invokeMethod', QueuedConnection). QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); @@ -1112,15 +1102,11 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket || !connection->d_func()->lowPriorityQueue.isEmpty()); if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2 - || connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2Direct -#ifndef QT_NO_SSL - || connection->connectionType() == QHttpNetworkConnection::ConnectionTypeSPDY -#endif - ) { - QList<HttpMessagePair> spdyPairs = spdyRequestsToSend.values(); - for (int a = 0; a < spdyPairs.count(); ++a) { + || connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2Direct) { + QList<HttpMessagePair> h2Pairs = h2RequestsToSend.values(); + for (int a = 0; a < h2Pairs.count(); ++a) { // emit error for all replies - QHttpNetworkReply *currentReply = spdyPairs.at(a).second; + QHttpNetworkReply *currentReply = h2Pairs.at(a).second; Q_ASSERT(currentReply); emit currentReply->finishedWithError(errorCode, errorString); } @@ -1147,12 +1133,8 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket void QHttpNetworkConnectionChannel::_q_proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator* auth) { if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2 - || connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2Direct -#ifndef QT_NO_SSL - || connection->connectionType() == QHttpNetworkConnection::ConnectionTypeSPDY -#endif - ) { - if (spdyRequestsToSend.count() > 0) + || connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2Direct) { + if (h2RequestsToSend.count() > 0) connection->d_func()->emitProxyAuthenticationRequired(this, proxy, auth); } else { // HTTP // Need to dequeue the request before we can emit the error. @@ -1175,9 +1157,9 @@ void QHttpNetworkConnectionChannel::emitFinishedWithError(QNetworkReply::Network { if (reply) emit reply->finishedWithError(error, QHttpNetworkConnectionChannel::tr(message)); - QList<HttpMessagePair> spdyPairs = spdyRequestsToSend.values(); - for (int a = 0; a < spdyPairs.count(); ++a) { - QHttpNetworkReply *currentReply = spdyPairs.at(a).second; + QList<HttpMessagePair> h2Pairs = h2RequestsToSend.values(); + for (int a = 0; a < h2Pairs.count(); ++a) { + QHttpNetworkReply *currentReply = h2Pairs.at(a).second; Q_ASSERT(currentReply); emit currentReply->finishedWithError(error, QHttpNetworkConnectionChannel::tr(message)); } @@ -1199,12 +1181,6 @@ void QHttpNetworkConnectionChannel::_q_encrypted() QByteArray nextProtocol = sslSocket->sslConfiguration().nextNegotiatedProtocol(); if (nextProtocol == QSslConfiguration::NextProtocolHttp1_1) { // fall through to create a QHttpProtocolHandler - } else if (nextProtocol == QSslConfiguration::NextProtocolSpdy3_0) { - protocolHandler.reset(new QSpdyProtocolHandler(this)); - connection->setConnectionType(QHttpNetworkConnection::ConnectionTypeSPDY); - // no need to re-queue requests, if SPDY was enabled on the request it - // has gone to the SPDY queue already - break; } else if (nextProtocol == QSslConfiguration::ALPNProtocolHTTP2) { switchedToHttp2 = true; protocolHandler.reset(new QHttp2ProtocolHandler(this)); @@ -1233,8 +1209,6 @@ void QHttpNetworkConnectionChannel::_q_encrypted() // it again on other channels that our connection can create/open. if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2) protocols.removeAll(QSslConfiguration::ALPNProtocolHTTP2); - else if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeSPDY) - protocols.removeAll(QSslConfiguration::NextProtocolSpdy3_0); if (nProtocols > protocols.size()) { sslConfiguration->setAllowedNextProtocols(protocols); @@ -1244,13 +1218,13 @@ void QHttpNetworkConnectionChannel::_q_encrypted() } connection->setConnectionType(QHttpNetworkConnection::ConnectionTypeHTTP); - // We use only one channel for SPDY or HTTP/2, but normally six for + // We use only one channel for HTTP/2, but normally six for // HTTP/1.1 - let's restore this number to the reserved number of // channels: if (connection->d_func()->activeChannelCount < connection->d_func()->channelCount) { connection->d_func()->activeChannelCount = connection->d_func()->channelCount; - // re-queue requests from SPDY queue to HTTP queue, if any - requeueSpdyRequests(); + // re-queue requests from HTTP/2 queue to HTTP queue, if any + requeueHttp2Requests(); } break; } @@ -1270,11 +1244,9 @@ void QHttpNetworkConnectionChannel::_q_encrypted() state = QHttpNetworkConnectionChannel::IdleState; pendingEncrypt = false; - if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeSPDY || - connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2 || + if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2 || connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2Direct) { - // we call setSpdyWasUsed(true) on the replies in the SPDY handler when the request is sent - if (spdyRequestsToSend.count() > 0) { + if (h2RequestsToSend.count() > 0) { // In case our peer has sent us its settings (window size, max concurrent streams etc.) // let's give _q_receiveReply a chance to read them first ('invokeMethod', QueuedConnection). QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); @@ -1283,7 +1255,7 @@ void QHttpNetworkConnectionChannel::_q_encrypted() if (!reply) connection->d_func()->dequeueRequest(socket); if (reply) { - reply->setSpdyWasUsed(false); + reply->setHttp2WasUsed(false); Q_ASSERT(reply->d_func()->connectionChannel == this); emit reply->encrypted(); } @@ -1292,13 +1264,12 @@ void QHttpNetworkConnectionChannel::_q_encrypted() } } -void QHttpNetworkConnectionChannel::requeueSpdyRequests() +void QHttpNetworkConnectionChannel::requeueHttp2Requests() { - QList<HttpMessagePair> spdyPairs = spdyRequestsToSend.values(); - for (int a = 0; a < spdyPairs.count(); ++a) { - connection->d_func()->requeueRequest(spdyPairs.at(a)); - } - spdyRequestsToSend.clear(); + QList<HttpMessagePair> h2Pairs = h2RequestsToSend.values(); + for (int a = 0; a < h2Pairs.count(); ++a) + connection->d_func()->requeueRequest(h2Pairs.at(a)); + h2RequestsToSend.clear(); } void QHttpNetworkConnectionChannel::_q_sslErrors(const QList<QSslError> &errors) @@ -1316,11 +1287,11 @@ void QHttpNetworkConnectionChannel::_q_sslErrors(const QList<QSslError> &errors) emit reply->sslErrors(errors); } #ifndef QT_NO_SSL - else { // SPDY - QList<HttpMessagePair> spdyPairs = spdyRequestsToSend.values(); - for (int a = 0; a < spdyPairs.count(); ++a) { + else { // HTTP/2 + QList<HttpMessagePair> h2Pairs = h2RequestsToSend.values(); + for (int a = 0; a < h2Pairs.count(); ++a) { // emit SSL errors for all replies - QHttpNetworkReply *currentReply = spdyPairs.at(a).second; + QHttpNetworkReply *currentReply = h2Pairs.at(a).second; Q_ASSERT(currentReply); emit currentReply->sslErrors(errors); } @@ -1340,10 +1311,10 @@ void QHttpNetworkConnectionChannel::_q_preSharedKeyAuthenticationRequired(QSslPr if (reply) emit reply->preSharedKeyAuthenticationRequired(authenticator); } else { - QList<HttpMessagePair> spdyPairs = spdyRequestsToSend.values(); - for (int a = 0; a < spdyPairs.count(); ++a) { + QList<HttpMessagePair> h2Pairs = h2RequestsToSend.values(); + for (int a = 0; a < h2Pairs.count(); ++a) { // emit SSL errors for all replies - QHttpNetworkReply *currentReply = spdyPairs.at(a).second; + QHttpNetworkReply *currentReply = h2Pairs.at(a).second; Q_ASSERT(currentReply); emit currentReply->preSharedKeyAuthenticationRequired(authenticator); } diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h index d8ac3979d1..a0f25a6430 100644 --- a/src/network/access/qhttpnetworkconnectionchannel_p.h +++ b/src/network/access/qhttpnetworkconnectionchannel_p.h @@ -123,10 +123,7 @@ public: bool authenticationCredentialsSent; bool proxyCredentialsSent; QScopedPointer<QAbstractProtocolHandler> protocolHandler; - // SPDY or HTTP/2 requests; SPDY is TLS-only, but - // HTTP/2 can be cleartext also, that's why it's - // outside of QT_NO_SSL section. Sorted by priority: - QMultiMap<int, HttpMessagePair> spdyRequestsToSend; + QMultiMap<int, HttpMessagePair> h2RequestsToSend; bool switchedToHttp2 = false; #ifndef QT_NO_SSL bool ignoreAllSslErrors; @@ -135,13 +132,10 @@ public: void ignoreSslErrors(); void ignoreSslErrors(const QList<QSslError> &errors); void setSslConfiguration(const QSslConfiguration &config); - void requeueSpdyRequests(); // when we wanted SPDY but got HTTP + void requeueHttp2Requests(); // when we wanted HTTP/2 but got HTTP/1.1 #endif // to emit the signal for all in-flight replies: void emitFinishedWithError(QNetworkReply::NetworkError error, const char *message); -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - QSharedPointer<QNetworkSession> networkSession; -#endif // HTTP pipelining -> http://en.wikipedia.org/wiki/Http_pipelining enum PipeliningSupport { diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp index 2024c0fefb..66a431c5f9 100644 --- a/src/network/access/qhttpnetworkreply.cpp +++ b/src/network/access/qhttpnetworkreply.cpp @@ -292,14 +292,14 @@ bool QHttpNetworkReply::isPipeliningUsed() const return d_func()->pipeliningUsed; } -bool QHttpNetworkReply::isSpdyUsed() const +bool QHttpNetworkReply::isHttp2Used() const { - return d_func()->spdyUsed; + return d_func()->h2Used; } -void QHttpNetworkReply::setSpdyWasUsed(bool spdy) +void QHttpNetworkReply::setHttp2WasUsed(bool h2) { - d_func()->spdyUsed = spdy; + d_func()->h2Used = h2; } qint64 QHttpNetworkReply::removedContentLength() const @@ -329,15 +329,11 @@ QHttpNetworkReplyPrivate::QHttpNetworkReplyPrivate(const QUrl &newUrl) forceConnectionCloseEnabled(false), lastChunkRead(false), currentChunkSize(0), currentChunkRead(0), readBufferMaxSize(0), - windowSizeDownload(65536), // 64K initial window size according to SPDY standard - windowSizeUpload(65536), // 64K initial window size according to SPDY standard - currentlyReceivedDataInWindow(0), - currentlyUploadedDataInWindow(0), totallyUploadedData(0), removedContentLength(-1), connection(nullptr), autoDecompress(false), responseData(), requestIsPrepared(false) - ,pipeliningUsed(false), spdyUsed(false), downstreamLimited(false) + ,pipeliningUsed(false), h2Used(false), downstreamLimited(false) ,userProvidedDownloadBuffer(nullptr) #ifndef QT_NO_COMPRESS ,inflateStrm(nullptr) @@ -994,7 +990,6 @@ bool QHttpNetworkReplyPrivate::expectContent() void QHttpNetworkReplyPrivate::eraseData() { - compressedData.clear(); responseData.clear(); } diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h index 9c03a403e1..59010606b9 100644 --- a/src/network/access/qhttpnetworkreply_p.h +++ b/src/network/access/qhttpnetworkreply_p.h @@ -139,8 +139,8 @@ public: bool isFinished() const; bool isPipeliningUsed() const; - bool isSpdyUsed() const; - void setSpdyWasUsed(bool spdy); + bool isHttp2Used() const; + void setHttp2WasUsed(bool h2Used); qint64 removedContentLength() const; bool isRedirecting() const; @@ -253,11 +253,7 @@ public: qint64 currentChunkSize; qint64 currentChunkRead; qint64 readBufferMaxSize; - qint32 windowSizeDownload; // only for SPDY - qint32 windowSizeUpload; // only for SPDY - qint32 currentlyReceivedDataInWindow; // only for SPDY - qint32 currentlyUploadedDataInWindow; // only for SPDY - qint64 totallyUploadedData; // only for SPDY + qint64 totallyUploadedData; // HTTP/2 qint64 removedContentLength; QPointer<QHttpNetworkConnection> connection; QPointer<QHttpNetworkConnectionChannel> connectionChannel; @@ -266,11 +262,10 @@ public: bool autoDecompress; QByteDataBuffer responseData; // uncompressed body - QByteArray compressedData; // compressed body (temporary) bool requestIsPrepared; bool pipeliningUsed; - bool spdyUsed; + bool h2Used; bool downstreamLimited; char* userProvidedDownloadBuffer; diff --git a/src/network/access/qhttpnetworkrequest.cpp b/src/network/access/qhttpnetworkrequest.cpp index 5fb8885bdf..0b03e6e69e 100644 --- a/src/network/access/qhttpnetworkrequest.cpp +++ b/src/network/access/qhttpnetworkrequest.cpp @@ -45,7 +45,7 @@ QT_BEGIN_NAMESPACE QHttpNetworkRequestPrivate::QHttpNetworkRequestPrivate(QHttpNetworkRequest::Operation op, QHttpNetworkRequest::Priority pri, const QUrl &newUrl) : QHttpNetworkHeaderPrivate(newUrl), operation(op), priority(pri), uploadByteDevice(nullptr), - autoDecompress(false), pipeliningAllowed(false), spdyAllowed(false), http2Allowed(false), + autoDecompress(false), pipeliningAllowed(false), http2Allowed(false), http2Direct(false), withCredentials(true), preConnect(false), redirectCount(0), redirectPolicy(QNetworkRequest::ManualRedirectPolicy) { @@ -59,7 +59,6 @@ QHttpNetworkRequestPrivate::QHttpNetworkRequestPrivate(const QHttpNetworkRequest uploadByteDevice(other.uploadByteDevice), autoDecompress(other.autoDecompress), pipeliningAllowed(other.pipeliningAllowed), - spdyAllowed(other.spdyAllowed), http2Allowed(other.http2Allowed), http2Direct(other.http2Direct), withCredentials(other.withCredentials), @@ -83,7 +82,6 @@ bool QHttpNetworkRequestPrivate::operator==(const QHttpNetworkRequestPrivate &ot && (uploadByteDevice == other.uploadByteDevice) && (autoDecompress == other.autoDecompress) && (pipeliningAllowed == other.pipeliningAllowed) - && (spdyAllowed == other.spdyAllowed) && (http2Allowed == other.http2Allowed) && (http2Direct == other.http2Direct) // we do not clear the customVerb in setOperation @@ -339,16 +337,6 @@ void QHttpNetworkRequest::setPipeliningAllowed(bool b) d->pipeliningAllowed = b; } -bool QHttpNetworkRequest::isSPDYAllowed() const -{ - return d->spdyAllowed; -} - -void QHttpNetworkRequest::setSPDYAllowed(bool b) -{ - d->spdyAllowed = b; -} - bool QHttpNetworkRequest::isHTTP2Allowed() const { return d->http2Allowed; diff --git a/src/network/access/qhttpnetworkrequest_p.h b/src/network/access/qhttpnetworkrequest_p.h index fb4896195b..f263e348ef 100644 --- a/src/network/access/qhttpnetworkrequest_p.h +++ b/src/network/access/qhttpnetworkrequest_p.h @@ -116,9 +116,6 @@ public: bool isPipeliningAllowed() const; void setPipeliningAllowed(bool b); - bool isSPDYAllowed() const; - void setSPDYAllowed(bool b); - bool isHTTP2Allowed() const; void setHTTP2Allowed(bool b); @@ -176,7 +173,6 @@ public: mutable QNonContiguousByteDevice* uploadByteDevice; bool autoDecompress; bool pipeliningAllowed; - bool spdyAllowed; bool http2Allowed; bool http2Direct; bool withCredentials; diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp index dcc8c9337e..30403b1848 100644 --- a/src/network/access/qhttpthreaddelegate.cpp +++ b/src/network/access/qhttpthreaddelegate.cpp @@ -181,17 +181,9 @@ class QNetworkAccessCachedHttpConnection: public QHttpNetworkConnection, { // Q_OBJECT public: -#ifdef QT_NO_BEARERMANAGEMENT QNetworkAccessCachedHttpConnection(const QString &hostName, quint16 port, bool encrypt, QHttpNetworkConnection::ConnectionType connectionType) : QHttpNetworkConnection(hostName, port, encrypt, connectionType) -#else // ### Qt6: Remove section - QNetworkAccessCachedHttpConnection(const QString &hostName, quint16 port, bool encrypt, - QHttpNetworkConnection::ConnectionType connectionType, - QSharedPointer<QNetworkSession> networkSession) - : QHttpNetworkConnection(hostName, port, encrypt, connectionType, /*parent=*/nullptr, - std::move(networkSession)) -#endif { setExpires(true); setShareable(true); @@ -236,7 +228,7 @@ QHttpThreadDelegate::QHttpThreadDelegate(QObject *parent) : , synchronous(false) , incomingStatusCode(0) , isPipeliningUsed(false) - , isSpdyUsed(false) + , isHttp2Used(false) , incomingContentLength(-1) , removedContentLength(-1) , incomingErrorCode(QNetworkReply::NoError) @@ -320,17 +312,6 @@ void QHttpThreadDelegate::startRequest() } } -#ifndef QT_NO_SSL - if (!isH2 && httpRequest.isSPDYAllowed() && ssl) { - connectionType = QHttpNetworkConnection::ConnectionTypeSPDY; - urlCopy.setScheme(QStringLiteral("spdy")); // to differentiate SPDY requests from HTTPS requests - QList<QByteArray> nextProtocols; - nextProtocols << QSslConfiguration::NextProtocolSpdy3_0 - << QSslConfiguration::NextProtocolHttp1_1; - incomingSslConfiguration->setAllowedNextProtocols(nextProtocols); - } -#endif // QT_NO_SSL - #ifndef QT_NO_NETWORKPROXY if (transparentProxy.type() != QNetworkProxy::NoProxy) cacheKey = makeCacheKey(urlCopy, &transparentProxy, httpRequest.peerVerifyName()); @@ -345,14 +326,8 @@ void QHttpThreadDelegate::startRequest() if (!httpConnection) { // no entry in cache; create an object // the http object is actually a QHttpNetworkConnection -#ifdef QT_NO_BEARERMANAGEMENT httpConnection = new QNetworkAccessCachedHttpConnection(urlCopy.host(), urlCopy.port(), ssl, connectionType); -#else // ### Qt6: Remove section - httpConnection = new QNetworkAccessCachedHttpConnection(urlCopy.host(), urlCopy.port(), ssl, - connectionType, - networkSession); -#endif // QT_NO_BEARERMANAGEMENT if (connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2 || connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2Direct) { httpConnection->setHttp2Parameters(http2Parameters); @@ -658,7 +633,7 @@ void QHttpThreadDelegate::headerChangedSlot() isPipeliningUsed = httpReply->isPipeliningUsed(); incomingContentLength = httpReply->contentLength(); removedContentLength = httpReply->removedContentLength(); - isSpdyUsed = httpReply->isSpdyUsed(); + isHttp2Used = httpReply->isHttp2Used(); emit downloadMetaData(incomingHeaders, incomingStatusCode, @@ -667,7 +642,7 @@ void QHttpThreadDelegate::headerChangedSlot() downloadBuffer, incomingContentLength, removedContentLength, - isSpdyUsed); + isHttp2Used); } void QHttpThreadDelegate::synchronousHeaderChangedSlot() @@ -683,7 +658,7 @@ void QHttpThreadDelegate::synchronousHeaderChangedSlot() incomingStatusCode = httpReply->statusCode(); incomingReasonPhrase = httpReply->reasonPhrase(); isPipeliningUsed = httpReply->isPipeliningUsed(); - isSpdyUsed = httpReply->isSpdyUsed(); + isHttp2Used = httpReply->isHttp2Used(); incomingContentLength = httpReply->contentLength(); } diff --git a/src/network/access/qhttpthreaddelegate_p.h b/src/network/access/qhttpthreaddelegate_p.h index a5272fc15c..5849d3427f 100644 --- a/src/network/access/qhttpthreaddelegate_p.h +++ b/src/network/access/qhttpthreaddelegate_p.h @@ -112,15 +112,12 @@ public: int incomingStatusCode; QString incomingReasonPhrase; bool isPipeliningUsed; - bool isSpdyUsed; + bool isHttp2Used; qint64 incomingContentLength; qint64 removedContentLength; QNetworkReply::NetworkError incomingErrorCode; QString incomingErrorDetail; QHttp2Configuration http2Parameters; -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - QSharedPointer<QNetworkSession> networkSession; -#endif protected: // The zerocopy download buffer, if used: diff --git a/src/network/access/qnetworkaccessbackend.cpp b/src/network/access/qnetworkaccessbackend.cpp index 9d7e7200fa..8013785cc1 100644 --- a/src/network/access/qnetworkaccessbackend.cpp +++ b/src/network/access/qnetworkaccessbackend.cpp @@ -39,13 +39,11 @@ #include "qnetworkaccessbackend_p.h" #include "qnetworkaccessmanager_p.h" -#include "qnetworkconfigmanager.h" #include "qnetworkrequest.h" #include "qnetworkreply.h" #include "qnetworkreply_p.h" #include "QtCore/qmutex.h" #include "QtCore/qstringlist.h" -#include "QtNetwork/private/qnetworksession_p.h" #include "qnetworkaccesscachebackend_p.h" #include "qabstractnetworkcache.h" @@ -371,30 +369,6 @@ void QNetworkAccessBackend::sslErrors(const QList<QSslError> &errors) */ bool QNetworkAccessBackend::start() { -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - // For bearer, check if session start is required - QSharedPointer<QNetworkSession> networkSession(manager->getNetworkSession()); - if (networkSession) { - // session required - if (networkSession->isOpen() && - networkSession->state() == QNetworkSession::Connected) { - // Session is already open and ready to use. - // copy network session down to the backend - setProperty("_q_networksession", QVariant::fromValue(networkSession)); - } else { - // Session not ready, but can skip for loopback connections - - // This is not ideal. - // Don't need an open session for localhost access. - if (!reply->url.isLocalFile()) { - const QString host = reply->url.host(); - if (host != QLatin1String("localhost") && !QHostAddress(host).isLoopback()) - return false; // need to wait for session to be opened - } - } - } -#endif - #ifndef QT_NO_NETWORKPROXY reply->proxyList = manager->queryProxy(QNetworkProxyQuery(url())); #endif diff --git a/src/network/access/qnetworkaccesscache.cpp b/src/network/access/qnetworkaccesscache.cpp index ba092f2618..4d65761a0b 100644 --- a/src/network/access/qnetworkaccesscache.cpp +++ b/src/network/access/qnetworkaccesscache.cpp @@ -121,8 +121,9 @@ void QNetworkAccessCache::clear() NodeHash::Iterator it = hashCopy.begin(); NodeHash::Iterator end = hashCopy.end(); for ( ; it != end; ++it) { - it->object->key.clear(); - it->object->dispose(); + (*it)->object->key.clear(); + (*it)->object->dispose(); + delete (*it); } // now delete: @@ -139,11 +140,10 @@ void QNetworkAccessCache::clear() */ void QNetworkAccessCache::linkEntry(const QByteArray &key) { - NodeHash::Iterator it = hash.find(key); - if (it == hash.end()) + Node * const node = hash.value(key); + if (!node) return; - Node *const node = &it.value(); Q_ASSERT(node != oldest && node != newest); Q_ASSERT(node->older == nullptr && node->newer == nullptr); Q_ASSERT(node->useCount == 0); @@ -168,12 +168,10 @@ void QNetworkAccessCache::linkEntry(const QByteArray &key) */ bool QNetworkAccessCache::unlinkEntry(const QByteArray &key) { - NodeHash::Iterator it = hash.find(key); - if (it == hash.end()) + Node * const node = hash.value(key); + if (!node) return false; - Node *const node = &it.value(); - bool wasOldest = false; if (node == oldest) { oldest = node->newer; @@ -230,6 +228,7 @@ void QNetworkAccessCache::timerEvent(QTimerEvent *) oldest->object->dispose(); hash.remove(oldest->key); // oldest gets deleted + delete oldest; oldest = next; } @@ -249,16 +248,20 @@ void QNetworkAccessCache::addEntry(const QByteArray &key, CacheableObject *entry if (unlinkEntry(key)) updateTimer(); - Node &node = hash[key]; // create the entry in the hash if it didn't exist - if (node.useCount) - qWarning("QNetworkAccessCache::addEntry: overriding active cache entry '%s'", - key.constData()); - if (node.object) - node.object->dispose(); - node.object = entry; - node.object->key = key; - node.key = key; - node.useCount = 1; + Node *node = hash.value(key); + if (!node) { + node = new Node; + hash.insert(key, node); + } + + if (node->useCount) + qWarning("QNetworkAccessCache::addEntry: overriding active cache entry '%s'", key.constData()); + if (node->object) + node->object->dispose(); + node->object = entry; + node->object->key = key; + node->key = key; + node->useCount = 1; } bool QNetworkAccessCache::hasEntry(const QByteArray &key) const @@ -268,11 +271,9 @@ bool QNetworkAccessCache::hasEntry(const QByteArray &key) const bool QNetworkAccessCache::requestEntry(const QByteArray &key, QObject *target, const char *member) { - NodeHash::Iterator it = hash.find(key); - if (it == hash.end()) - return false; // no such entry - - Node *node = &it.value(); + Node *node = hash.value(key); + if (!node) + return false; if (node->useCount > 0 && !node->object->shareable) { // object is not shareable and is in use @@ -294,13 +295,14 @@ bool QNetworkAccessCache::requestEntry(const QByteArray &key, QObject *target, c QNetworkAccessCache::CacheableObject *QNetworkAccessCache::requestEntryNow(const QByteArray &key) { - NodeHash::Iterator it = hash.find(key); - if (it == hash.end()) + Node *node = hash.value(key); + if (!node) return nullptr; - if (it->useCount > 0) { - if (it->object->shareable) { - ++it->useCount; - return it->object; + + if (node->useCount > 0) { + if (node->object->shareable) { + ++node->useCount; + return node->object; } // object in use and not shareable @@ -309,23 +311,21 @@ QNetworkAccessCache::CacheableObject *QNetworkAccessCache::requestEntryNow(const // entry not in use, let the caller have it bool wasOldest = unlinkEntry(key); - ++it->useCount; + ++node->useCount; if (wasOldest) updateTimer(); - return it->object; + return node->object; } void QNetworkAccessCache::releaseEntry(const QByteArray &key) { - NodeHash::Iterator it = hash.find(key); - if (it == hash.end()) { - qWarning("QNetworkAccessCache::releaseEntry: trying to release key '%s' that is not in cache", - key.constData()); + Node *node = hash.value(key); + if (!node) { + qWarning("QNetworkAccessCache::releaseEntry: trying to release key '%s' that is not in cache", key.constData()); return; } - Node *node = &it.value(); Q_ASSERT(node->useCount > 0); // are there other objects waiting? @@ -356,14 +356,12 @@ void QNetworkAccessCache::releaseEntry(const QByteArray &key) void QNetworkAccessCache::removeEntry(const QByteArray &key) { - NodeHash::Iterator it = hash.find(key); - if (it == hash.end()) { - qWarning("QNetworkAccessCache::removeEntry: trying to remove key '%s' that is not in cache", - key.constData()); + Node *node = hash.value(key); + if (!node) { + qWarning("QNetworkAccessCache::removeEntry: trying to remove key '%s' that is not in cache", key.constData()); return; } - Node *node = &it.value(); if (unlinkEntry(key)) updateTimer(); if (node->useCount > 1) @@ -372,6 +370,7 @@ void QNetworkAccessCache::removeEntry(const QByteArray &key) node->object->key.clear(); hash.remove(node->key); + delete node; } QT_END_NAMESPACE diff --git a/src/network/access/qnetworkaccesscache_p.h b/src/network/access/qnetworkaccesscache_p.h index 69ea649a8a..9f7001d044 100644 --- a/src/network/access/qnetworkaccesscache_p.h +++ b/src/network/access/qnetworkaccesscache_p.h @@ -71,7 +71,7 @@ class QNetworkAccessCache: public QObject Q_OBJECT public: struct Node; - typedef QHash<QByteArray, Node> NodeHash; + typedef QHash<QByteArray, Node *> NodeHash; class CacheableObject { diff --git a/src/network/access/qnetworkaccessftpbackend.cpp b/src/network/access/qnetworkaccessftpbackend.cpp index 7b09608499..7f5439a16e 100644 --- a/src/network/access/qnetworkaccessftpbackend.cpp +++ b/src/network/access/qnetworkaccessftpbackend.cpp @@ -161,10 +161,6 @@ void QNetworkAccessFtpBackend::open() if (!objectCache->requestEntry(cacheKey, this, SLOT(ftpConnectionReady(QNetworkAccessCache::CacheableObject*)))) { ftp = new QNetworkAccessCachedFtpConnection; -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - //copy network session down to the QFtp - ftp->setProperty("_q_networksession", property("_q_networksession")); -#endif #ifndef QT_NO_NETWORKPROXY if (proxy.type() == QNetworkProxy::FtpCachingProxy) ftp->setProxy(proxy.hostName(), proxy.port()); diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 6f6aa73f62..63a816b9dc 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -54,9 +54,6 @@ #include "qhstsstore_p.h" #endif // QT_CONFIG(settings) -#include "QtNetwork/qnetworksession.h" -#include "QtNetwork/private/qsharednetworksession_p.h" - #if QT_CONFIG(ftp) #include "qnetworkaccessftpbackend_p.h" #endif @@ -71,7 +68,6 @@ #include "QtCore/qvector.h" #include "QtNetwork/private/qauthenticator_p.h" #include "QtNetwork/qsslconfiguration.h" -#include "QtNetwork/qnetworkconfigmanager.h" #include "QtNetwork/private/http2protocol_p.h" #if QT_CONFIG(http) @@ -479,20 +475,7 @@ QNetworkAccessManager::QNetworkAccessManager(QObject *parent) if (QNetworkStatusMonitor::isEnabled()) { connect(&d->statusMonitor, SIGNAL(onlineStateChanged(bool)), SLOT(_q_onlineStateChanged(bool))); -#ifdef QT_NO_BEARERMANAGEMENT d->networkAccessible = d->statusMonitor.isNetworkAccessible(); -#else - d->networkAccessible = d->statusMonitor.isNetworkAccessible() ? Accessible : NotAccessible; - } else { - // 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))); - connect(&d->networkConfigurationManager, SIGNAL(configurationChanged(QNetworkConfiguration)), - SLOT(_q_configurationChanged(QNetworkConfiguration))); -#endif // QT_NO_BEARERMANAGEMENT } } @@ -993,186 +976,6 @@ QNetworkReply *QNetworkAccessManager::deleteResource(const QNetworkRequest &requ return d_func()->postProcess(createRequest(QNetworkAccessManager::DeleteOperation, request)); } -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - -/*! - \since 4.7 - \obsolete - - Sets the network configuration that will be used when creating the - \l {QNetworkSession}{network session} to \a config. - - The network configuration is used to create and open a network session before any request that - requires network access is process. If no network configuration is explicitly set via this - function the network configuration returned by - QNetworkConfigurationManager::defaultConfiguration() will be used. - - To restore the default network configuration set the network configuration to the value - returned from QNetworkConfigurationManager::defaultConfiguration(). - - Setting a network configuration means that the QNetworkAccessManager instance will only - be using the specified one. In particular, if the default network configuration changes - (upon e.g. Wifi being available), this new configuration needs to be enabled - manually if desired. - - \snippet code/src_network_access_qnetworkaccessmanager.cpp 2 - - If an invalid network configuration is set, a network session will not be created. In this - case network requests will be processed regardless, but may fail. For example: - - \snippet code/src_network_access_qnetworkaccessmanager.cpp 3 - - \sa configuration(), QNetworkSession -*/ -void QNetworkAccessManager::setConfiguration(const QNetworkConfiguration &config) -{ - Q_D(QNetworkAccessManager); - - d->networkConfiguration = config; - d->customNetworkConfiguration = true; - d->createSession(config); -} - -/*! - \since 4.7 - \obsolete - - Returns the network configuration that will be used to create the - \l {QNetworkSession}{network session} which will be used when processing network requests. - - \sa setConfiguration(), activeConfiguration() -*/ -QNetworkConfiguration QNetworkAccessManager::configuration() const -{ - Q_D(const QNetworkAccessManager); - - QSharedPointer<QNetworkSession> session(d->getNetworkSession()); - if (session && !d->statusMonitor.isEnabled()) { - return session->configuration(); - } else { - return d->networkConfigurationManager.defaultConfiguration(); - } -} - -/*! - \since 4.7 - \obsolete - - Returns the current active network configuration. - - If the network configuration returned by configuration() is of type - QNetworkConfiguration::ServiceNetwork this function will return the current active child - network configuration of that configuration. Otherwise returns the same network configuration - as configuration(). - - Use this function to return the actual network configuration currently in use by the network - session. - - \sa configuration() -*/ -QNetworkConfiguration QNetworkAccessManager::activeConfiguration() const -{ - Q_D(const QNetworkAccessManager); - - QSharedPointer<QNetworkSession> networkSession(d->getNetworkSession()); - if (networkSession && !d->statusMonitor.isEnabled()) { - return d->networkConfigurationManager.configurationFromIdentifier( - networkSession->sessionProperty(QLatin1String("ActiveConfiguration")).toString()); - } else { - return d->networkConfigurationManager.defaultConfiguration(); - } -} - -/*! - \since 4.7 - \obsolete - - Overrides the reported network accessibility. If \a accessible is NotAccessible the reported - network accessiblity will always be NotAccessible. Otherwise the reported network - accessibility will reflect the actual device state. -*/ -void QNetworkAccessManager::setNetworkAccessible(QNetworkAccessManager::NetworkAccessibility accessible) -{ - Q_D(QNetworkAccessManager); - - d->defaultAccessControl = accessible == NotAccessible ? false : true; - - if (d->networkAccessible != accessible) { -QT_WARNING_PUSH -QT_WARNING_DISABLE_DEPRECATED - NetworkAccessibility previous = networkAccessible(); - d->networkAccessible = accessible; - NetworkAccessibility current = networkAccessible(); - if (previous != current) - emit networkAccessibleChanged(current); -QT_WARNING_POP - } -} - -/*! - \since 4.7 - \obsolete - - Returns the current network accessibility. -*/ -QNetworkAccessManager::NetworkAccessibility QNetworkAccessManager::networkAccessible() const -{ - Q_D(const QNetworkAccessManager); - - if (d->statusMonitor.isEnabled()) { - if (!d->statusMonitor.isMonitoring()) - d->statusMonitor.start(); - return d->networkAccessible; - } - - if (d->customNetworkConfiguration && d->networkConfiguration.state().testFlag(QNetworkConfiguration::Undefined)) - return UnknownAccessibility; - - if (d->networkSessionRequired) { - QSharedPointer<QNetworkSession> networkSession(d->getNetworkSession()); - if (networkSession) { - // d->online holds online/offline state of this network session. - if (d->online) - return d->networkAccessible; - else - return NotAccessible; - } else { - if (d->defaultAccessControl) { - if (d->online) - return d->networkAccessible; - else - return NotAccessible; - } - return (d->networkAccessible); - } - } else { - if (d->online) - return d->networkAccessible; - else - return NotAccessible; - } -} - -/*! - \internal - - Returns the network session currently in use. - This can be changed at any time, ownership remains with the QNetworkAccessManager -*/ -const QWeakPointer<const QNetworkSession> QNetworkAccessManagerPrivate::getNetworkSession(const QNetworkAccessManager *q) -{ - return q->d_func()->networkSessionWeakRef; -} - -QSharedPointer<QNetworkSession> QNetworkAccessManagerPrivate::getNetworkSession() const -{ - if (networkSessionStrongRef) - return networkSessionStrongRef; - return networkSessionWeakRef.toStrongRef(); -} - -#endif // QT_NO_BEARERMANAGEMENT - #ifndef QT_NO_SSL /*! \since 5.2 @@ -1230,12 +1033,10 @@ void QNetworkAccessManager::connectToHostEncrypted(const QString &hostName, quin if (sslConfiguration != QSslConfiguration::defaultConfiguration()) request.setSslConfiguration(sslConfiguration); - // There is no way to enable SPDY/HTTP2 via a request, so we need to check - // the ssl configuration whether SPDY/HTTP2 is allowed here. + // There is no way to enable HTTP2 via a request, so we need to check + // the ssl configuration whether HTTP2 is allowed here. if (sslConfiguration.allowedNextProtocols().contains(QSslConfiguration::ALPNProtocolHTTP2)) request.setAttribute(QNetworkRequest::Http2AllowedAttribute, true); - else if (sslConfiguration.allowedNextProtocols().contains(QSslConfiguration::NextProtocolSpdy3_0)) - request.setAttribute(QNetworkRequest::SpdyAllowedAttribute, true); request.setPeerVerifyName(peerName); get(request); @@ -1450,12 +1251,7 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera // See the code in ctor - QNetworkStatusMonitor allows us to // immediately set 'networkAccessible' even before we start // the monitor. -#ifdef QT_NO_BEARERMANAGEMENT - if (!d->networkAccessible -#else - if (d->networkAccessible == NotAccessible -#endif // QT_NO_BEARERMANAGEMENT - && !isLocalFile) { + if (!d->networkAccessible && !isLocalFile) { QHostAddress dest; QString host = req.url().host().toLower(); if (!(dest.setAddress(host) && dest.isLoopback()) @@ -1467,35 +1263,6 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera if (!d->statusMonitor.isMonitoring() && !d->statusMonitor.start()) qWarning(lcNetMon, "failed to start network status monitoring"); - } else { -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - // Return a disabled network reply if network access is disabled. - // Except if the scheme is empty or file:// or if the host resolves to a loopback address. - if (d->networkAccessible == NotAccessible && !isLocalFile) { - QHostAddress dest; - QString host = req.url().host().toLower(); - if (!(dest.setAddress(host) && dest.isLoopback()) && host != QLatin1String("localhost") - && host != QHostInfo::localHostName().toLower()) { - return new QDisabledNetworkReply(this, req, op); - } - } - - if (!d->networkSessionStrongRef && (d->initializeSession || !d->networkConfiguration.identifier().isEmpty())) { - if (!d->networkConfiguration.identifier().isEmpty()) { - if ((d->networkConfiguration.state() & QNetworkConfiguration::Defined) - && d->networkConfiguration != d->networkConfigurationManager.defaultConfiguration()) - d->createSession(d->networkConfigurationManager.defaultConfiguration()); - else - d->createSession(d->networkConfiguration); - - } else { - if (d->networkSessionRequired) - d->createSession(d->networkConfigurationManager.defaultConfiguration()); - else - d->initializeSession = false; - } - } -#endif } #endif QNetworkRequest request = req; @@ -1552,26 +1319,12 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera } #endif QNetworkReplyHttpImpl *reply = new QNetworkReplyHttpImpl(this, request, op, outgoingData); -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - if (!d->statusMonitor.isEnabled()) { - connect(this, SIGNAL(networkSessionConnected()), - reply, SLOT(_q_networkSessionConnected())); - } -#endif return reply; } #endif // QT_CONFIG(http) // first step: create the reply QNetworkReplyImpl *reply = new QNetworkReplyImpl(this); -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - // NETMONTODO: network reply impl must be augmented to use the same monitoring - // capabilities as http network reply impl does. Once it does: uncomment the condition below - if (!isLocalFile /*&& !d->statusMonitor.isEnabled()*/) { - connect(this, SIGNAL(networkSessionConnected()), - reply, SLOT(_q_networkSessionConnected())); - } -#endif QNetworkReplyImplPrivate *priv = reply->d_func(); priv->manager = this; @@ -1754,15 +1507,6 @@ void QNetworkAccessManagerPrivate::_q_replyFinished(QNetworkReply *reply) emit q->finished(reply); if (reply->request().attribute(QNetworkRequest::AutoDeleteReplyOnFinishAttribute, false).toBool()) QMetaObject::invokeMethod(reply, [reply] { reply->deleteLater(); }, Qt::QueuedConnection); - -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - // If there are no active requests, release our reference to the network session. - // It will not be destroyed immediately, but rather when the connection cache is flushed - // after 2 minutes. - activeReplyCount--; - if (networkSessionStrongRef && activeReplyCount == 0) - networkSessionStrongRef.clear(); -#endif } void QNetworkAccessManagerPrivate::_q_replyEncrypted(QNetworkReply *reply) @@ -1813,9 +1557,6 @@ QNetworkReply *QNetworkAccessManagerPrivate::postProcess(QNetworkReply *reply) q->connect(reply, SIGNAL(sslErrors(QList<QSslError>)), SLOT(_q_replySslErrors(QList<QSslError>))); q->connect(reply, SIGNAL(preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator*)), SLOT(_q_replyPreSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator*))); #endif -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - activeReplyCount++; -#endif return reply; } @@ -1983,233 +1724,11 @@ void QNetworkAccessManagerPrivate::destroyThread() } } -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section -void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &config) -{ - Q_Q(QNetworkAccessManager); - - initializeSession = false; - - //resurrect weak ref if possible - networkSessionStrongRef = networkSessionWeakRef.toStrongRef(); - - QSharedPointer<QNetworkSession> newSession; - if (config.isValid()) - newSession = QSharedNetworkSessionManager::getSession(config); - - QNetworkSession::State oldState = QNetworkSession::Invalid; - if (networkSessionStrongRef) { - //do nothing if new and old session are the same - if (networkSessionStrongRef == newSession) - return; - //disconnect from old session - QObject::disconnect(networkSessionStrongRef.data(), SIGNAL(opened()), q, SIGNAL(networkSessionConnected())); - QObject::disconnect(networkSessionStrongRef.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed())); - QObject::disconnect(networkSessionStrongRef.data(), SIGNAL(stateChanged(QNetworkSession::State)), - q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State))); - QObject::disconnect(networkSessionStrongRef.data(), SIGNAL(error(QNetworkSession::SessionError)), - q, SLOT(_q_networkSessionFailed(QNetworkSession::SessionError))); - oldState = networkSessionStrongRef->state(); - } - - //switch to new session (null if config was invalid) - networkSessionStrongRef = newSession; - networkSessionWeakRef = networkSessionStrongRef.toWeakRef(); - - if (!networkSessionStrongRef) { - -QT_WARNING_PUSH -QT_WARNING_DISABLE_DEPRECATED - if (networkAccessible == QNetworkAccessManager::NotAccessible || !online) - emit q->networkAccessibleChanged(QNetworkAccessManager::NotAccessible); - else - emit q->networkAccessibleChanged(QNetworkAccessManager::UnknownAccessibility); -QT_WARNING_POP - - return; - } - - //connect to new session - QObject::connect(networkSessionStrongRef.data(), SIGNAL(opened()), q, SIGNAL(networkSessionConnected()), Qt::QueuedConnection); - //QueuedConnection is used to avoid deleting the networkSession inside its closed signal - QObject::connect(networkSessionStrongRef.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed()), Qt::QueuedConnection); - QObject::connect(networkSessionStrongRef.data(), SIGNAL(stateChanged(QNetworkSession::State)), - q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)), Qt::QueuedConnection); - QObject::connect(networkSessionStrongRef.data(), SIGNAL(error(QNetworkSession::SessionError)), - q, SLOT(_q_networkSessionFailed(QNetworkSession::SessionError))); - - const QNetworkSession::State newState = networkSessionStrongRef->state(); - if (newState != oldState) { - QMetaObject::invokeMethod(q, "_q_networkSessionStateChanged", Qt::QueuedConnection, - Q_ARG(QNetworkSession::State, newState)); - } -} - -void QNetworkAccessManagerPrivate::_q_networkSessionClosed() -{ - Q_Q(QNetworkAccessManager); - QSharedPointer<QNetworkSession> networkSession(getNetworkSession()); - if (networkSession) { - networkConfiguration = networkSession->configuration(); - - //disconnect from old session - QObject::disconnect(networkSession.data(), SIGNAL(opened()), q, SIGNAL(networkSessionConnected())); - QObject::disconnect(networkSession.data(), SIGNAL(closed()), q, SLOT(_q_networkSessionClosed())); - QObject::disconnect(networkSession.data(), SIGNAL(stateChanged(QNetworkSession::State)), - q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State))); - QObject::disconnect(networkSession.data(), SIGNAL(error(QNetworkSession::SessionError)), - q, SLOT(_q_networkSessionFailed(QNetworkSession::SessionError))); - - networkSessionStrongRef.clear(); - networkSessionWeakRef.clear(); - } -} - -void QNetworkAccessManagerPrivate::_q_networkSessionStateChanged(QNetworkSession::State state) -{ - Q_Q(QNetworkAccessManager); - bool reallyOnline = false; - //Do not emit the networkSessionConnected signal here, except for roaming -> connected - //transition, otherwise it is emitted twice in a row when opening a connection. -QT_WARNING_PUSH -QT_WARNING_DISABLE_DEPRECATED - if (state == QNetworkSession::Connected && lastSessionState != QNetworkSession::Roaming) - emit q->networkSessionConnected(); - lastSessionState = state; - - if (online && (state == QNetworkSession::Disconnected - || state == QNetworkSession::NotAvailable)) { - const auto cfgs = networkConfigurationManager.allConfigurations(); - for (const QNetworkConfiguration &cfg : cfgs) { - if (cfg.state().testFlag(QNetworkConfiguration::Active)) { - reallyOnline = true; - } - } - } else if (state == QNetworkSession::Connected || state == QNetworkSession::Roaming) { - reallyOnline = true; - } - online = reallyOnline; - - if (!reallyOnline) { - if (state != QNetworkSession::Connected && state != QNetworkSession::Roaming) { - if (networkAccessible != QNetworkAccessManager::NotAccessible) { - networkAccessible = QNetworkAccessManager::NotAccessible; - emit q->networkAccessibleChanged(networkAccessible); - } - } - } else { - if (defaultAccessControl) - if (networkAccessible != QNetworkAccessManager::Accessible) { - networkAccessible = QNetworkAccessManager::Accessible; - emit q->networkAccessibleChanged(networkAccessible); - } - } - if (online && (state != QNetworkSession::Connected && state != QNetworkSession::Roaming)) { - _q_networkSessionClosed(); - createSession(q->configuration()); - } -QT_WARNING_POP -} - -void QNetworkAccessManagerPrivate::_q_onlineStateChanged(bool isOnline) -{ - Q_Q(QNetworkAccessManager); - - if (statusMonitor.isEnabled()) { - networkAccessible = isOnline ? QNetworkAccessManager::Accessible : QNetworkAccessManager::NotAccessible; - return; - } - -QT_WARNING_PUSH -QT_WARNING_DISABLE_DEPRECATED - - // 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 (online != isOnline) { - online = isOnline; - _q_networkSessionClosed(); - createSession(q->configuration()); - } - } - if (online) { - if (defaultAccessControl) { - if (networkAccessible != QNetworkAccessManager::Accessible) { - networkAccessible = QNetworkAccessManager::Accessible; - emit q->networkAccessibleChanged(networkAccessible); - } - } - } else { - if (networkAccessible != QNetworkAccessManager::NotAccessible) { - networkAccessible = QNetworkAccessManager::NotAccessible; - emit q->networkAccessibleChanged(networkAccessible); - } - } -QT_WARNING_POP -} - -void QNetworkAccessManagerPrivate::_q_configurationChanged(const QNetworkConfiguration &configuration) -{ - if (statusMonitor.isEnabled()) - return; - - const QString id = configuration.identifier(); - if (configuration.state().testFlag(QNetworkConfiguration::Active)) { - if (!onlineConfigurations.contains(id)) { - QSharedPointer<QNetworkSession> session(getNetworkSession()); - if (session) { - if (online && session->configuration().identifier() - != networkConfigurationManager.defaultConfiguration().identifier()) { - - onlineConfigurations.insert(id); - // CHECK: If it's having Active flag - why would it be disconnected ??? - //this one disconnected but another one is online, - // close and create new session - _q_networkSessionClosed(); - createSession(networkConfigurationManager.defaultConfiguration()); - } - } - } - - } else if (onlineConfigurations.contains(id)) { - //this one is disconnecting - // CHECK: If it disconnected while we create a session over a down configuration ??? - onlineConfigurations.remove(id); - if (!onlineConfigurations.isEmpty()) { - _q_networkSessionClosed(); - createSession(configuration); - } - } -} - - -void QNetworkAccessManagerPrivate::_q_networkSessionFailed(QNetworkSession::SessionError) -{ - if (statusMonitor.isEnabled()) - return; - - const auto cfgs = networkConfigurationManager.allConfigurations(); - for (const QNetworkConfiguration &cfg : cfgs) { - if (cfg.state().testFlag(QNetworkConfiguration::Active)) { - online = true; - _q_networkSessionClosed(); - createSession(networkConfigurationManager.defaultConfiguration()); - return; - } - } -} - -#else - void QNetworkAccessManagerPrivate::_q_onlineStateChanged(bool isOnline) { networkAccessible = isOnline; } -#endif // QT_NO_BEARERMANAGEMENT - #if QT_CONFIG(http) QNetworkRequest QNetworkAccessManagerPrivate::prepareMultipart(const QNetworkRequest &request, QHttpMultiPart *multiPart) { diff --git a/src/network/access/qnetworkaccessmanager.h b/src/network/access/qnetworkaccessmanager.h index 6f7f90ce14..3a08c30a21 100644 --- a/src/network/access/qnetworkaccessmanager.h +++ b/src/network/access/qnetworkaccessmanager.h @@ -56,7 +56,6 @@ class QIODevice; class QAbstractNetworkCache; class QAuthenticator; class QByteArray; -template<typename T> class QList; class QNetworkCookie; class QNetworkCookieJar; class QNetworkReply; @@ -64,9 +63,6 @@ class QNetworkProxy; class QNetworkProxyFactory; class QSslError; class QHstsPolicy; -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section -class QNetworkConfiguration; -#endif class QHttpMultiPart; class QNetworkReplyImplPrivate; @@ -75,9 +71,6 @@ class Q_NETWORK_EXPORT QNetworkAccessManager: public QObject { Q_OBJECT -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - Q_PROPERTY(NetworkAccessibility networkAccessible READ networkAccessible WRITE setNetworkAccessible NOTIFY networkAccessibleChanged) -#endif public: enum Operation { @@ -91,18 +84,6 @@ public: UnknownOperation = 0 }; -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - enum QT_DEPRECATED_NETWORK_API_5_15 NetworkAccessibility { - UnknownAccessibility = -1, - NotAccessible = 0, - Accessible = 1 - }; -QT_WARNING_PUSH -QT_WARNING_DISABLE_DEPRECATED - Q_ENUM(NetworkAccessibility) -QT_WARNING_POP -#endif - explicit QNetworkAccessManager(QObject *parent = nullptr); ~QNetworkAccessManager(); @@ -149,18 +130,6 @@ QT_WARNING_POP QNetworkReply *sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, QHttpMultiPart *multiPart); #endif -#if !defined(QT_NO_BEARERMANAGEMENT) // ### Qt6: Remove section - QT_DEPRECATED_VERSION_5_15 void setConfiguration(const QNetworkConfiguration &config); - QT_DEPRECATED_VERSION_5_15 QNetworkConfiguration configuration() const; - QT_DEPRECATED_VERSION_5_15 QNetworkConfiguration activeConfiguration() const; - -QT_WARNING_PUSH -QT_WARNING_DISABLE_DEPRECATED - QT_DEPRECATED_VERSION_5_15 void setNetworkAccessible(NetworkAccessibility accessible); - QT_DEPRECATED_VERSION_5_15 NetworkAccessibility networkAccessible() const; -QT_WARNING_POP -#endif - #ifndef QT_NO_SSL void connectToHostEncrypted(const QString &hostName, quint16 port = 443, const QSslConfiguration &sslConfiguration = QSslConfiguration::defaultConfiguration()); @@ -191,19 +160,6 @@ Q_SIGNALS: void preSharedKeyAuthenticationRequired(QNetworkReply *reply, QSslPreSharedKeyAuthenticator *authenticator); #endif -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - QT_DEPRECATED_VERSION_5_15 void networkSessionConnected(); - -#ifndef Q_MOC_RUN // moc has trouble with the expansion of these macros -QT_WARNING_PUSH -QT_WARNING_DISABLE_DEPRECATED -#endif - QT_DEPRECATED_VERSION_5_15 void networkAccessibleChanged(QNetworkAccessManager::NetworkAccessibility accessible); -#ifndef Q_MOC_RUN // moc has trouble with the expansion of these macros -QT_WARNING_POP -#endif -#endif - protected: virtual QNetworkReply *createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData = nullptr); @@ -223,12 +179,6 @@ private: Q_DECLARE_PRIVATE(QNetworkAccessManager) Q_PRIVATE_SLOT(d_func(), void _q_replySslErrors(QList<QSslError>)) Q_PRIVATE_SLOT(d_func(), void _q_replyPreSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator*)) -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - Q_PRIVATE_SLOT(d_func(), void _q_networkSessionClosed()) - Q_PRIVATE_SLOT(d_func(), void _q_networkSessionStateChanged(QNetworkSession::State)) - Q_PRIVATE_SLOT(d_func(), void _q_configurationChanged(const QNetworkConfiguration &)) - Q_PRIVATE_SLOT(d_func(), void _q_networkSessionFailed(QNetworkSession::SessionError)) -#endif Q_PRIVATE_SLOT(d_func(), void _q_onlineStateChanged(bool)) }; diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h index 7926463d56..e0f4d19d6f 100644 --- a/src/network/access/qnetworkaccessmanager_p.h +++ b/src/network/access/qnetworkaccessmanager_p.h @@ -60,11 +60,7 @@ #include "qhsts_p.h" #include "private/qobject_p.h" #include "QtNetwork/qnetworkproxy.h" -#include "QtNetwork/qnetworksession.h" #include "qnetworkaccessauthenticationmanager_p.h" -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section -#include "QtNetwork/qnetworkconfigmanager.h" -#endif #if QT_CONFIG(settings) #include "qhstsstore_p.h" @@ -87,33 +83,11 @@ public: #ifndef QT_NO_NETWORKPROXY proxyFactory(nullptr), #endif -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - lastSessionState(QNetworkSession::Invalid), - networkConfiguration(networkConfigurationManager.defaultConfiguration()), - customNetworkConfiguration(false), - networkSessionRequired(networkConfigurationManager.capabilities() - & QNetworkConfigurationManager::NetworkSessionRequired), - activeReplyCount(0), - online(false), - initializeSession(true), -#endif cookieJarCreated(false), defaultAccessControl(true), redirectPolicy(QNetworkRequest::ManualRedirectPolicy), authenticationManager(QSharedPointer<QNetworkAccessAuthenticationManager>::create()) { -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - // 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 if (networkConfiguration.state().testFlag(QNetworkConfiguration::Undefined)) - networkAccessible = QNetworkAccessManager::UnknownAccessibility; - else - networkAccessible = QNetworkAccessManager::NotAccessible; -#endif } ~QNetworkAccessManagerPrivate(); @@ -153,21 +127,6 @@ public: QStringList backendSupportedSchemes() const; void _q_onlineStateChanged(bool isOnline); -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - void createSession(const QNetworkConfiguration &config); - QSharedPointer<QNetworkSession> getNetworkSession() const; - - void _q_networkSessionClosed(); - void _q_networkSessionNewConfigurationActivated(); - void _q_networkSessionPreferredConfigurationChanged(const QNetworkConfiguration &config, - bool isSeamless); - void _q_networkSessionStateChanged(QNetworkSession::State state); - - void _q_configurationChanged(const QNetworkConfiguration &configuration); - void _q_networkSessionFailed(QNetworkSession::SessionError error); - - QSet<QString> onlineConfigurations; -#endif #if QT_CONFIG(http) QNetworkRequest prepareMultipart(const QNetworkRequest &request, QHttpMultiPart *multiPart); @@ -186,23 +145,7 @@ public: QNetworkProxyFactory *proxyFactory; #endif -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - QSharedPointer<QNetworkSession> networkSessionStrongRef; - QWeakPointer<QNetworkSession> networkSessionWeakRef; - QNetworkSession::State lastSessionState; - QNetworkConfigurationManager networkConfigurationManager; - QNetworkConfiguration networkConfiguration; - // we need to track whether the user set a config or not, - // because the default config might change - bool customNetworkConfiguration; - bool networkSessionRequired; - QNetworkAccessManager::NetworkAccessibility networkAccessible; - int activeReplyCount; - bool online; - bool initializeSession; -#else bool networkAccessible = true; -#endif bool cookieJarCreated; bool defaultAccessControl; @@ -231,9 +174,6 @@ public: int transferTimeout = 0; -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - Q_AUTOTEST_EXPORT static const QWeakPointer<const QNetworkSession> getNetworkSession(const QNetworkAccessManager *manager); -#endif Q_DECLARE_PUBLIC(QNetworkAccessManager) }; diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp index 47f6112b22..16c38d89ab 100644 --- a/src/network/access/qnetworkcookie.cpp +++ b/src/network/access/qnetworkcookie.cpp @@ -46,7 +46,7 @@ #include "QtCore/qdebug.h" #include "QtCore/qlist.h" #include "QtCore/qlocale.h" -#include <QtCore/qregexp.h> +#include <QtCore/qregularexpression.h> #include "QtCore/qstring.h" #include "QtCore/qstringlist.h" #include "QtCore/qurl.h" @@ -593,7 +593,7 @@ static QDateTime parseDateString(const QByteArray &dateString) int zoneOffset = -1; // hour:minute:second.ms pm - QRegExp timeRx(QLatin1String("(\\d{1,2}):(\\d{1,2})(:(\\d{1,2})|)(\\.(\\d{1,3})|)((\\s{0,}(am|pm))|)")); + QRegularExpression timeRx(QLatin1String("(\\d{1,2}):(\\d{1,2})(:(\\d{1,2})|)(\\.(\\d{1,3})|)((\\s{0,}(am|pm))|)")); int at = 0; while (at < dateString.length()) { @@ -673,21 +673,23 @@ static QDateTime parseDateString(const QByteArray &dateString) && (dateString[at + 2] == ':' || dateString[at + 1] == ':')) { // While the date can be found all over the string the format // for the time is set and a nice regexp can be used. - int pos = timeRx.indexIn(QLatin1String(dateString), at); + QRegularExpressionMatch match; + int pos = QString::fromLatin1(dateString).indexOf(timeRx, at, &match); if (pos != -1) { - QStringList list = timeRx.capturedTexts(); - int h = atoi(list.at(1).toLatin1().constData()); - int m = atoi(list.at(2).toLatin1().constData()); - int s = atoi(list.at(4).toLatin1().constData()); - int ms = atoi(list.at(6).toLatin1().constData()); - if (h < 12 && !list.at(9).isEmpty()) - if (list.at(9) == QLatin1String("pm")) + QStringList list = match.capturedTexts(); + int h = match.captured(1).toInt(); + int m = match.captured(2).toInt(); + int s = match.captured(4).toInt(); + int ms = match.captured(6).toInt(); + QString ampm = match.captured(9); + if (h < 12 && !ampm.isEmpty()) + if (ampm == QLatin1String("pm")) h += 12; time = QTime(h, m, s, ms); #ifdef PARSEDATESTRINGDEBUG qDebug() << "Time:" << list << timeRx.matchedLength(); #endif - at += timeRx.matchedLength(); + at += match.capturedLength(); continue; } } diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index 2a9d281256..d02b209d51 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -164,21 +164,6 @@ static QHash<QByteArray, QByteArray> parseHttpOptionHeader(const QByteArray &hea } } -#if QT_CONFIG(bearermanagement) // ### Qt6: Remove section -static bool isSessionNeeded(const QUrl &url) -{ - if (QNetworkStatusMonitor::isEnabled()) { - // In case QNetworkStatus/QNetConManager are in business, - // no session, no bearer manager are involved. - return false; - } - // Connections to the local machine does not require a session - QString host = url.host().toLower(); - return !QHostAddress(host).isLoopback() && host != QLatin1String("localhost") - && host != QSysInfo::machineHostName().toLower(); -} -#endif // bearer management - QNetworkReplyHttpImpl::QNetworkReplyHttpImpl(QNetworkAccessManager* const manager, const QNetworkRequest& request, QNetworkAccessManager::Operation& operation, @@ -775,9 +760,6 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq if (newHttpRequest.attribute(QNetworkRequest::HttpPipeliningAllowedAttribute).toBool()) httpRequest.setPipeliningAllowed(true); - if (request.attribute(QNetworkRequest::SpdyAllowedAttribute).toBool()) - httpRequest.setSPDYAllowed(true); - if (request.attribute(QNetworkRequest::Http2AllowedAttribute).toBool()) httpRequest.setHTTP2Allowed(true); @@ -801,10 +783,6 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq QHttpThreadDelegate *delegate = new QHttpThreadDelegate; // Propagate Http/2 settings: delegate->http2Parameters = request.http2Configuration(); -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - if (!QNetworkStatusMonitor::isEnabled()) - delegate->networkSession = managerPrivate->getNetworkSession(); -#endif // For the synchronous HTTP, this is the normal way the delegate gets deleted // For the asynchronous HTTP this is a safety measure, the delegate deletes itself when HTTP is finished @@ -969,7 +947,7 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq QSharedPointer<char>(), delegate->incomingContentLength, delegate->removedContentLength, - delegate->isSpdyUsed); + delegate->isHttp2Used); replyDownloadData(delegate->synchronousDownloadData); httpError(delegate->incomingErrorCode, delegate->incomingErrorDetail); } else { @@ -981,7 +959,7 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq QSharedPointer<char>(), delegate->incomingContentLength, delegate->removedContentLength, - delegate->isSpdyUsed); + delegate->isHttp2Used); replyDownloadData(delegate->synchronousDownloadData); } @@ -1209,24 +1187,6 @@ void QNetworkReplyHttpImplPrivate::followRedirect() if (managerPrivate->thread) managerPrivate->thread->disconnect(); -#if QT_CONFIG(bearermanagement) // ### Qt6: Remove section - // If the original request didn't need a session (i.e. it was to localhost) - // then we might not have a session open, to which to redirect, if the - // new URL is remote. When this happens, we need to open the session now: - if (isSessionNeeded(url)) { - if (auto session = managerPrivate->getNetworkSession()) { - if (session->state() != QNetworkSession::State::Connected || !session->isOpen()) { - startWaitForSession(session); - // Need to set 'request' to the redirectRequest so that when QNAM restarts - // the request after the session starts it will not repeat the previous request. - request = redirectRequest; - // Return now, QNAM will start the request when the session has started. - return; - } - } - } -#endif // bearer management - QMetaObject::invokeMethod(q, "start", Qt::QueuedConnection, Q_ARG(QNetworkRequest, redirectRequest)); } @@ -1256,7 +1216,7 @@ void QNetworkReplyHttpImplPrivate::replyDownloadMetaData(const QList<QPair<QByte QSharedPointer<char> db, qint64 contentLength, qint64 removedContentLength, - bool spdyWasUsed) + bool h2Used) { Q_Q(QNetworkReplyHttpImpl); Q_UNUSED(contentLength); @@ -1282,16 +1242,7 @@ void QNetworkReplyHttpImplPrivate::replyDownloadMetaData(const QList<QPair<QByte } q->setAttribute(QNetworkRequest::HttpPipeliningWasUsedAttribute, pu); - const QVariant http2Allowed = request.attribute(QNetworkRequest::Http2AllowedAttribute); - const QVariant http2Direct = request.attribute(QNetworkRequest::Http2DirectAttribute); - if ((http2Allowed.isValid() && http2Allowed.toBool()) - || (http2Direct.isValid() && http2Direct.toBool())) { - q->setAttribute(QNetworkRequest::Http2WasUsedAttribute, spdyWasUsed); - q->setAttribute(QNetworkRequest::SpdyWasUsedAttribute, false); - } else { - q->setAttribute(QNetworkRequest::SpdyWasUsedAttribute, spdyWasUsed); - q->setAttribute(QNetworkRequest::Http2WasUsedAttribute, false); - } + q->setAttribute(QNetworkRequest::Http2WasUsedAttribute, h2Used); // reconstruct the HTTP header QList<QPair<QByteArray, QByteArray> > headerMap = hm; @@ -1794,68 +1745,9 @@ void QNetworkReplyHttpImplPrivate::setResumeOffset(quint64 offset) */ bool QNetworkReplyHttpImplPrivate::start(const QNetworkRequest &newHttpRequest) { -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - QSharedPointer<QNetworkSession> networkSession(managerPrivate->getNetworkSession()); - if (!networkSession || QNetworkStatusMonitor::isEnabled()) { -#endif - postRequest(newHttpRequest); - return true; -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - } - - // This is not ideal. - if (!isSessionNeeded(url)) { - // Don't need to check for an open session if we don't need one. - postRequest(newHttpRequest); - return true; - } - - if (networkSession->isOpen() && - networkSession->state() == QNetworkSession::Connected) { - Q_Q(QNetworkReplyHttpImpl); - QObject::connect(networkSession.data(), SIGNAL(usagePoliciesChanged(QNetworkSession::UsagePolicies)), - q, SLOT(_q_networkSessionUsagePoliciesChanged(QNetworkSession::UsagePolicies))); - postRequest(newHttpRequest); - return true; - } else if (synchronous) { - // Command line applications using the synchronous path such as xmlpatterns may need an extra push. - networkSession->open(); - if (networkSession->waitForOpened()) { - postRequest(newHttpRequest); - return true; - } - } - return false; -#endif -} - -#if QT_CONFIG(bearermanagement) // ### Qt6: Remove section -bool QNetworkReplyHttpImplPrivate::startWaitForSession(QSharedPointer<QNetworkSession> &session) -{ - Q_Q(QNetworkReplyHttpImpl); - state = WaitingForSession; - - if (session) { - QObject::connect(session.data(), SIGNAL(error(QNetworkSession::SessionError)), - q, SLOT(_q_networkSessionFailed()), Qt::QueuedConnection); - - if (!session->isOpen()) { - QVariant isBackground = request.attribute(QNetworkRequest::BackgroundRequestAttribute, - QVariant::fromValue(false)); - session->setSessionProperty(QStringLiteral("ConnectInBackground"), isBackground); - session->open(); - } - return true; - } - const Qt::ConnectionType connection = synchronous ? Qt::DirectConnection : Qt::QueuedConnection; - qWarning("Backend is waiting for QNetworkSession to connect, but there is none!"); - QMetaObject::invokeMethod(q, "_q_error", connection, - Q_ARG(QNetworkReply::NetworkError, QNetworkReply::NetworkSessionFailedError), - Q_ARG(QString, QCoreApplication::translate("QNetworkReply", "Network session error."))); - QMetaObject::invokeMethod(q, "_q_finished", connection); - return false; + postRequest(newHttpRequest); + return true; } -#endif // QT_CONFIG(bearermanagement) void QNetworkReplyHttpImplPrivate::_q_startOperation() { @@ -1865,31 +1757,7 @@ void QNetworkReplyHttpImplPrivate::_q_startOperation() state = Working; -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - // Do not start background requests if they are not allowed by session policy - QSharedPointer<QNetworkSession> session(manager->d_func()->getNetworkSession()); - QVariant isBackground = request.attribute(QNetworkRequest::BackgroundRequestAttribute, QVariant::fromValue(false)); - if (isBackground.toBool() && session && session->usagePolicies().testFlag(QNetworkSession::NoBackgroundTrafficPolicy)) { - QMetaObject::invokeMethod(q, "_q_error", synchronous ? Qt::DirectConnection : Qt::QueuedConnection, - Q_ARG(QNetworkReply::NetworkError, QNetworkReply::BackgroundRequestNotAllowedError), - Q_ARG(QString, QCoreApplication::translate("QNetworkReply", "Background request not allowed."))); - QMetaObject::invokeMethod(q, "_q_finished", synchronous ? Qt::DirectConnection : Qt::QueuedConnection); - return; - } - - if (!start(request)) { - // backend failed to start because the session state is not Connected. - // QNetworkAccessManager will call reply->backend->start() again for us when the session - // state changes. - if (!startWaitForSession(session)) - return; - } else if (session && !QNetworkStatusMonitor::isEnabled()) { - QObject::connect(session.data(), SIGNAL(stateChanged(QNetworkSession::State)), - q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)), - Qt::QueuedConnection); - } -#else - if (!start(request)) { + if (!start(request)) { // @todo next commit: cleanup, start now always returns true qWarning("Backend start failed"); QMetaObject::invokeMethod(q, "_q_error", synchronous ? Qt::DirectConnection : Qt::QueuedConnection, Q_ARG(QNetworkReply::NetworkError, QNetworkReply::UnknownNetworkError), @@ -1897,7 +1765,6 @@ void QNetworkReplyHttpImplPrivate::_q_startOperation() QMetaObject::invokeMethod(q, "_q_finished", synchronous ? Qt::DirectConnection : Qt::QueuedConnection); return; } -#endif // QT_NO_BEARERMANAGEMENT setupTransferTimeout(); if (synchronous) { @@ -2061,80 +1928,6 @@ void QNetworkReplyHttpImplPrivate::setupTransferTimeout() } } -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section -void QNetworkReplyHttpImplPrivate::_q_networkSessionConnected() -{ - Q_Q(QNetworkReplyHttpImpl); - Q_ASSERT(managerPrivate); - - QSharedPointer<QNetworkSession> session = managerPrivate->getNetworkSession(); - if (!session) - return; - - if (session->state() != QNetworkSession::Connected) - return; - - switch (state) { - case QNetworkReplyPrivate::Buffering: - case QNetworkReplyPrivate::Working: - case QNetworkReplyPrivate::Reconnecting: - // Migrate existing downloads to new network connection. - migrateBackend(); - break; - case QNetworkReplyPrivate::WaitingForSession: - // Start waiting requests. - QMetaObject::invokeMethod(q, "_q_startOperation", Qt::QueuedConnection); - break; - default: - ; - } -} - -void QNetworkReplyHttpImplPrivate::_q_networkSessionStateChanged(QNetworkSession::State sessionState) -{ - if (sessionState == QNetworkSession::Disconnected - && state != Idle && state != Reconnecting) { - error(QNetworkReplyImpl::NetworkSessionFailedError, - QCoreApplication::translate("QNetworkReply", "Network session error.")); - finished(); - } -} - -void QNetworkReplyHttpImplPrivate::_q_networkSessionFailed() -{ - // Abort waiting and working replies. - if (state == WaitingForSession || state == Working) { - state = Working; - QSharedPointer<QNetworkSession> session(manager->d_func()->getNetworkSession()); - QString errorStr; - if (session) - errorStr = session->errorString(); - else - errorStr = QCoreApplication::translate("QNetworkReply", "Network session error."); - error(QNetworkReplyImpl::NetworkSessionFailedError, errorStr); - finished(); - } -} - -void QNetworkReplyHttpImplPrivate::_q_networkSessionUsagePoliciesChanged(QNetworkSession::UsagePolicies newPolicies) -{ - if (request.attribute(QNetworkRequest::BackgroundRequestAttribute).toBool()) { - if (newPolicies & QNetworkSession::NoBackgroundTrafficPolicy) { - // Abort waiting and working replies. - if (state == WaitingForSession || state == Working) { - state = Working; - error(QNetworkReply::BackgroundRequestNotAllowedError, - QCoreApplication::translate("QNetworkReply", "Background request not allowed.")); - finished(); - } - // ### if canResume(), then we could resume automatically - } - } - -} -#endif - - // need to have this function since the reply is a private member variable // and the special backends need to access this. void QNetworkReplyHttpImplPrivate::emitReplyUploadProgress(qint64 bytesSent, qint64 bytesTotal) @@ -2197,28 +1990,6 @@ void QNetworkReplyHttpImplPrivate::finished() if (preMigrationDownloaded != Q_INT64_C(-1)) totalSize = totalSize.toLongLong() + preMigrationDownloaded; -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - Q_ASSERT(managerPrivate); - QSharedPointer<QNetworkSession> session = managerPrivate->getNetworkSession(); - if (!QNetworkStatusMonitor::isEnabled() && session && session->state() == QNetworkSession::Roaming && - state == Working && errorCode != QNetworkReply::OperationCanceledError) { - // only content with a known size will fail with a temporary network failure error - if (!totalSize.isNull()) { - if (bytesDownloaded != totalSize) { - if (migrateBackend()) { - // either we are migrating or the request is finished/aborted - if (state == Reconnecting || state == WaitingForSession) { - return; // exit early if we are migrating. - } - } else { - error(QNetworkReply::TemporaryNetworkFailureError, - QNetworkReply::tr("Temporary network failure.")); - } - } - } - } -#endif - // if we don't know the total size of or we received everything save the cache if (totalSize.isNull() || totalSize == -1 || bytesDownloaded == totalSize) completeCacheSave(); diff --git a/src/network/access/qnetworkreplyhttpimpl_p.h b/src/network/access/qnetworkreplyhttpimpl_p.h index c4de63990b..eef4b13d12 100644 --- a/src/network/access/qnetworkreplyhttpimpl_p.h +++ b/src/network/access/qnetworkreplyhttpimpl_p.h @@ -66,7 +66,6 @@ #include <private/qhttpnetworkrequest_p.h> #include <private/qnetworkreply_p.h> #include <QtNetwork/QNetworkProxy> -#include <QtNetwork/QNetworkSession> // ### Qt6: Remove include #ifndef QT_NO_SSL #include <QtNetwork/QSslConfiguration> @@ -102,12 +101,6 @@ public: Q_PRIVATE_SLOT(d_func(), void _q_bufferOutgoingData()) Q_PRIVATE_SLOT(d_func(), void _q_bufferOutgoingDataFinished()) Q_PRIVATE_SLOT(d_func(), void _q_transferTimedOut()) -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - Q_PRIVATE_SLOT(d_func(), void _q_networkSessionConnected()) - Q_PRIVATE_SLOT(d_func(), void _q_networkSessionFailed()) - Q_PRIVATE_SLOT(d_func(), void _q_networkSessionStateChanged(QNetworkSession::State)) - Q_PRIVATE_SLOT(d_func(), void _q_networkSessionUsagePoliciesChanged(QNetworkSession::UsagePolicies)) -#endif Q_PRIVATE_SLOT(d_func(), void _q_finished()) Q_PRIVATE_SLOT(d_func(), void _q_error(QNetworkReply::NetworkError, const QString &)) @@ -162,10 +155,6 @@ signals: class QNetworkReplyHttpImplPrivate: public QNetworkReplyPrivate { -#if QT_CONFIG(bearermanagement) // ### Qt6: Remove section - bool startWaitForSession(QSharedPointer<QNetworkSession> &session); -#endif - public: static QHttpNetworkRequest::Priority convert(const QNetworkRequest::Priority& prio); @@ -186,12 +175,6 @@ public: void _q_transferTimedOut(); void setupTransferTimeout(); -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - void _q_networkSessionConnected(); - void _q_networkSessionFailed(); - void _q_networkSessionStateChanged(QNetworkSession::State); - void _q_networkSessionUsagePoliciesChanged(QNetworkSession::UsagePolicies); -#endif void _q_finished(); void finished(); diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index a0b4ace470..b0674823f7 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -45,7 +45,6 @@ #include "QtCore/qcoreapplication.h" #include "QtCore/qdatetime.h" #include "QtNetwork/qsslconfiguration.h" -#include "QtNetwork/qnetworksession.h" // ### Qt6: Remove include #include "qnetworkaccessmanager_p.h" #include <QtCore/QCoreApplication> @@ -81,6 +80,7 @@ void QNetworkReplyImplPrivate::_q_startOperation() // note: if that method is called directly, it cannot happen that the backend is 0, // because we just checked via a qobject_cast that we got a http backend (see // QNetworkReplyImplPrivate::setup()) + qDebug() << "backend:" << backend; // @temp if (!backend) { error(QNetworkReplyImpl::ProtocolUnknownError, QCoreApplication::translate("QNetworkReply", "Protocol \"%1\" is unknown").arg(url.scheme())); // not really true!; @@ -88,66 +88,15 @@ void QNetworkReplyImplPrivate::_q_startOperation() return; } -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - Q_Q(QNetworkReplyImpl); - // Do not start background requests if they are not allowed by session policy - QSharedPointer<QNetworkSession> session(manager->d_func()->getNetworkSession()); - QVariant isBackground = backend->request().attribute(QNetworkRequest::BackgroundRequestAttribute, QVariant::fromValue(false)); - if (isBackground.toBool() && session && session->usagePolicies().testFlag(QNetworkSession::NoBackgroundTrafficPolicy)) { - error(QNetworkReply::BackgroundRequestNotAllowedError, - QCoreApplication::translate("QNetworkReply", "Background request not allowed.")); - finished(); - return; - } -#endif - if (!backend->start()) { -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - // backend failed to start because the session state is not Connected. - // QNetworkAccessManager will call _q_startOperation again for us when the session - // state changes. - state = WaitingForSession; - - if (session) { - QObject::connect(session.data(), SIGNAL(error(QNetworkSession::SessionError)), - q, SLOT(_q_networkSessionFailed())); - - if (!session->isOpen()) { - session->setSessionProperty(QStringLiteral("ConnectInBackground"), isBackground); - session->open(); - } - } else { - qWarning("Backend is waiting for QNetworkSession to connect, but there is none!"); - state = Working; - error(QNetworkReplyImpl::NetworkSessionFailedError, - QCoreApplication::translate("QNetworkReply", "Network session error.")); - finished(); - } -#else qWarning("Backend start failed"); state = Working; error(QNetworkReplyImpl::UnknownNetworkError, QCoreApplication::translate("QNetworkReply", "backend start error.")); finished(); -#endif return; - } else { -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - if (session) { - QObject::connect(session.data(), SIGNAL(stateChanged(QNetworkSession::State)), - q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)), Qt::QueuedConnection); - } -#endif } -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - if (session) { - //get notification of policy changes. - QObject::connect(session.data(), SIGNAL(usagePoliciesChanged(QNetworkSession::UsagePolicies)), - q, SLOT(_q_networkSessionUsagePoliciesChanged(QNetworkSession::UsagePolicies))); - } -#endif - // Prepare timer for progress notifications downloadProgressSignalChoke.start(); uploadProgressSignalChoke.invalidate(); @@ -287,80 +236,6 @@ void QNetworkReplyImplPrivate::_q_bufferOutgoingData() } } -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section -void QNetworkReplyImplPrivate::_q_networkSessionConnected() -{ - Q_Q(QNetworkReplyImpl); - - if (manager.isNull()) - return; - - QSharedPointer<QNetworkSession> session = manager->d_func()->getNetworkSession(); - if (!session) - return; - - if (session->state() != QNetworkSession::Connected) - return; - - switch (state) { - case QNetworkReplyPrivate::Buffering: - case QNetworkReplyPrivate::Working: - case QNetworkReplyPrivate::Reconnecting: - // Migrate existing downloads to new network connection. - migrateBackend(); - break; - case QNetworkReplyPrivate::WaitingForSession: - // Start waiting requests. - QMetaObject::invokeMethod(q, "_q_startOperation", Qt::QueuedConnection); - break; - default: - ; - } -} - -void QNetworkReplyImplPrivate::_q_networkSessionStateChanged(QNetworkSession::State sessionState) -{ - if (sessionState == QNetworkSession::Disconnected - && state != Idle && state != Reconnecting) { - error(QNetworkReplyImpl::NetworkSessionFailedError, - QCoreApplication::translate("QNetworkReply", "Network session error.")); - finished(); - } -} - -void QNetworkReplyImplPrivate::_q_networkSessionFailed() -{ - // Abort waiting and working replies. - if (state == WaitingForSession || state == Working) { - state = Working; - QSharedPointer<QNetworkSession> session(manager->d_func()->getNetworkSession()); - QString errorStr; - if (session) - errorStr = session->errorString(); - else - errorStr = QCoreApplication::translate("QNetworkReply", "Network session error."); - error(QNetworkReplyImpl::NetworkSessionFailedError, errorStr); - finished(); - } -} - -void QNetworkReplyImplPrivate::_q_networkSessionUsagePoliciesChanged(QNetworkSession::UsagePolicies newPolicies) -{ - if (backend->request().attribute(QNetworkRequest::BackgroundRequestAttribute).toBool()) { - if (newPolicies & QNetworkSession::NoBackgroundTrafficPolicy) { - // Abort waiting and working replies. - if (state == WaitingForSession || state == Working) { - state = Working; - error(QNetworkReply::BackgroundRequestNotAllowedError, - QCoreApplication::translate("QNetworkReply", "Background request not allowed.")); - finished(); - } - // ### if backend->canResume(), then we could resume automatically, however no backend supports resuming - } - } -} -#endif - void QNetworkReplyImplPrivate::setup(QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *data) { @@ -786,29 +661,6 @@ void QNetworkReplyImplPrivate::finished() if (preMigrationDownloaded != Q_INT64_C(-1)) totalSize = totalSize.toLongLong() + preMigrationDownloaded; - if (!manager.isNull()) { -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - QSharedPointer<QNetworkSession> session (manager->d_func()->getNetworkSession()); - if (session && session->state() == QNetworkSession::Roaming && - state == Working && errorCode != QNetworkReply::OperationCanceledError) { - // only content with a known size will fail with a temporary network failure error - if (!totalSize.isNull()) { - if (bytesDownloaded != totalSize) { - if (migrateBackend()) { - // either we are migrating or the request is finished/aborted - if (state == Reconnecting || state == WaitingForSession) { - resumeNotificationHandling(); - return; // exit early if we are migrating. - } - } else { - error(QNetworkReply::TemporaryNetworkFailureError, - QNetworkReply::tr("Temporary network failure.")); - } - } - } - } -#endif - } resumeNotificationHandling(); state = Finished; diff --git a/src/network/access/qnetworkreplyimpl_p.h b/src/network/access/qnetworkreplyimpl_p.h index f98f773775..6a100d9a03 100644 --- a/src/network/access/qnetworkreplyimpl_p.h +++ b/src/network/access/qnetworkreplyimpl_p.h @@ -62,7 +62,6 @@ #include "private/qringbuffer_p.h" #include "private/qbytedata_p.h" #include <QSharedPointer> -#include <QtNetwork/QNetworkSession> // ### Qt6: Remove include QT_BEGIN_NAMESPACE @@ -92,12 +91,6 @@ public: Q_PRIVATE_SLOT(d_func(), void _q_copyReadChannelFinished()) Q_PRIVATE_SLOT(d_func(), void _q_bufferOutgoingData()) Q_PRIVATE_SLOT(d_func(), void _q_bufferOutgoingDataFinished()) -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - Q_PRIVATE_SLOT(d_func(), void _q_networkSessionConnected()) - Q_PRIVATE_SLOT(d_func(), void _q_networkSessionFailed()) - Q_PRIVATE_SLOT(d_func(), void _q_networkSessionStateChanged(QNetworkSession::State)) - Q_PRIVATE_SLOT(d_func(), void _q_networkSessionUsagePoliciesChanged(QNetworkSession::UsagePolicies)) -#endif #ifndef QT_NO_SSL protected: @@ -124,12 +117,6 @@ public: void _q_copyReadChannelFinished(); void _q_bufferOutgoingData(); void _q_bufferOutgoingDataFinished(); -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - void _q_networkSessionConnected(); - void _q_networkSessionFailed(); - void _q_networkSessionStateChanged(QNetworkSession::State); - void _q_networkSessionUsagePoliciesChanged(QNetworkSession::UsagePolicies); -#endif void setup(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *outgoingData); diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp index 6cd56499c5..f8cb3feb69 100644 --- a/src/network/access/qnetworkrequest.cpp +++ b/src/network/access/qnetworkrequest.cpp @@ -269,20 +269,6 @@ QT_BEGIN_NAMESPACE Indicates that this is a background transfer, rather than a user initiated transfer. Depending on the platform, background transfers may be subject to different policies. - The QNetworkSession ConnectInBackground property will be set according to - this attribute. - - \value SpdyAllowedAttribute - Requests only, type: QMetaType::Bool (default: false) - Indicates whether the QNetworkAccessManager code is - allowed to use SPDY with this request. This applies only - to SSL requests, and depends on the server supporting SPDY. - Obsolete, use Http2 instead of Spdy. - - \value SpdyWasUsedAttribute - Replies only, type: QMetaType::Bool - Indicates whether SPDY was used for receiving - this reply. Obsolete, use Http2 instead of Spdy. \value Http2AllowedAttribute Requests only, type: QMetaType::Bool (default: false) @@ -295,12 +281,6 @@ QT_BEGIN_NAMESPACE Indicates whether HTTP/2 was used for receiving this reply. (This value was introduced in 5.9.) - \value HTTP2AllowedAttribute - Obsolete alias for Http2AllowedAttribute. - - \value HTTP2WasUsedAttribute - Obsolete alias for Http2WasUsedAttribute. - \value EmitAllUploadProgressSignalsAttribute Requests only, type: QMetaType::Bool (default: false) Indicates whether all upload signals should be emitted. diff --git a/src/network/access/qnetworkrequest.h b/src/network/access/qnetworkrequest.h index 66b9a43e01..035b5b378a 100644 --- a/src/network/access/qnetworkrequest.h +++ b/src/network/access/qnetworkrequest.h @@ -89,18 +89,10 @@ public: DownloadBufferAttribute, // internal SynchronousRequestAttribute, // internal BackgroundRequestAttribute, -#if QT_DEPRECATED_SINCE(5, 15) - SpdyAllowedAttribute, - SpdyWasUsedAttribute, -#endif // QT_DEPRECATED_SINCE(5, 15) EmitAllUploadProgressSignalsAttribute = BackgroundRequestAttribute + 3, FollowRedirectsAttribute, Http2AllowedAttribute, Http2WasUsedAttribute, -#if QT_DEPRECATED_SINCE(5, 15) - HTTP2AllowedAttribute Q_DECL_ENUMERATOR_DEPRECATED_X("Use Http2AllowedAttribute") = Http2AllowedAttribute, - HTTP2WasUsedAttribute Q_DECL_ENUMERATOR_DEPRECATED_X("Use Http2WasUsedAttribute"), -#endif // QT_DEPRECATED_SINCE(5, 15) OriginalContentLengthAttribute, RedirectPolicyAttribute, Http2DirectAttribute, diff --git a/src/network/access/qspdyprotocolhandler.cpp b/src/network/access/qspdyprotocolhandler.cpp deleted file mode 100644 index eef8df288d..0000000000 --- a/src/network/access/qspdyprotocolhandler.cpp +++ /dev/null @@ -1,1304 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 BlackBerry Limited. All rights reserved. -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <private/qspdyprotocolhandler_p.h> -#include <private/qnoncontiguousbytedevice_p.h> -#include <private/qhttpnetworkconnectionchannel_p.h> -#include <QtCore/QtEndian> - -#if !defined(QT_NO_SSL) - -QT_BEGIN_NAMESPACE - -static const char spdyDictionary[] = { - 0x00, 0x00, 0x00, 0x07, 0x6f, 0x70, 0x74, 0x69, // ....opti - 0x6f, 0x6e, 0x73, 0x00, 0x00, 0x00, 0x04, 0x68, // ons....h - 0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x04, 0x70, // ead....p - 0x6f, 0x73, 0x74, 0x00, 0x00, 0x00, 0x03, 0x70, // ost....p - 0x75, 0x74, 0x00, 0x00, 0x00, 0x06, 0x64, 0x65, // ut....de - 0x6c, 0x65, 0x74, 0x65, 0x00, 0x00, 0x00, 0x05, // lete.... - 0x74, 0x72, 0x61, 0x63, 0x65, 0x00, 0x00, 0x00, // trace... - 0x06, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x00, // .accept. - 0x00, 0x00, 0x0e, 0x61, 0x63, 0x63, 0x65, 0x70, // ...accep - 0x74, 0x2d, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, // t-charse - 0x74, 0x00, 0x00, 0x00, 0x0f, 0x61, 0x63, 0x63, // t....acc - 0x65, 0x70, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f, // ept-enco - 0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x0f, // ding.... - 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x6c, // accept-l - 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x00, // anguage. - 0x00, 0x00, 0x0d, 0x61, 0x63, 0x63, 0x65, 0x70, // ...accep - 0x74, 0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, // t-ranges - 0x00, 0x00, 0x00, 0x03, 0x61, 0x67, 0x65, 0x00, // ....age. - 0x00, 0x00, 0x05, 0x61, 0x6c, 0x6c, 0x6f, 0x77, // ...allow - 0x00, 0x00, 0x00, 0x0d, 0x61, 0x75, 0x74, 0x68, // ....auth - 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, // orizatio - 0x6e, 0x00, 0x00, 0x00, 0x0d, 0x63, 0x61, 0x63, // n....cac - 0x68, 0x65, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, // he-contr - 0x6f, 0x6c, 0x00, 0x00, 0x00, 0x0a, 0x63, 0x6f, // ol....co - 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, // nnection - 0x00, 0x00, 0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74, // ....cont - 0x65, 0x6e, 0x74, 0x2d, 0x62, 0x61, 0x73, 0x65, // ent-base - 0x00, 0x00, 0x00, 0x10, 0x63, 0x6f, 0x6e, 0x74, // ....cont - 0x65, 0x6e, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f, // ent-enco - 0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x10, // ding.... - 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, // content- - 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, // language - 0x00, 0x00, 0x00, 0x0e, 0x63, 0x6f, 0x6e, 0x74, // ....cont - 0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x65, 0x6e, 0x67, // ent-leng - 0x74, 0x68, 0x00, 0x00, 0x00, 0x10, 0x63, 0x6f, // th....co - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x6f, // ntent-lo - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, // cation.. - 0x00, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, // ..conten - 0x74, 0x2d, 0x6d, 0x64, 0x35, 0x00, 0x00, 0x00, // t-md5... - 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, // .content - 0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, // -range.. - 0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, // ..conten - 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x00, 0x00, // t-type.. - 0x00, 0x04, 0x64, 0x61, 0x74, 0x65, 0x00, 0x00, // ..date.. - 0x00, 0x04, 0x65, 0x74, 0x61, 0x67, 0x00, 0x00, // ..etag.. - 0x00, 0x06, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, // ..expect - 0x00, 0x00, 0x00, 0x07, 0x65, 0x78, 0x70, 0x69, // ....expi - 0x72, 0x65, 0x73, 0x00, 0x00, 0x00, 0x04, 0x66, // res....f - 0x72, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04, 0x68, // rom....h - 0x6f, 0x73, 0x74, 0x00, 0x00, 0x00, 0x08, 0x69, // ost....i - 0x66, 0x2d, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x00, // f-match. - 0x00, 0x00, 0x11, 0x69, 0x66, 0x2d, 0x6d, 0x6f, // ...if-mo - 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x2d, 0x73, // dified-s - 0x69, 0x6e, 0x63, 0x65, 0x00, 0x00, 0x00, 0x0d, // ince.... - 0x69, 0x66, 0x2d, 0x6e, 0x6f, 0x6e, 0x65, 0x2d, // if-none- - 0x6d, 0x61, 0x74, 0x63, 0x68, 0x00, 0x00, 0x00, // match... - 0x08, 0x69, 0x66, 0x2d, 0x72, 0x61, 0x6e, 0x67, // .if-rang - 0x65, 0x00, 0x00, 0x00, 0x13, 0x69, 0x66, 0x2d, // e....if- - 0x75, 0x6e, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, // unmodifi - 0x65, 0x64, 0x2d, 0x73, 0x69, 0x6e, 0x63, 0x65, // ed-since - 0x00, 0x00, 0x00, 0x0d, 0x6c, 0x61, 0x73, 0x74, // ....last - 0x2d, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, // -modifie - 0x64, 0x00, 0x00, 0x00, 0x08, 0x6c, 0x6f, 0x63, // d....loc - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, // ation... - 0x0c, 0x6d, 0x61, 0x78, 0x2d, 0x66, 0x6f, 0x72, // .max-for - 0x77, 0x61, 0x72, 0x64, 0x73, 0x00, 0x00, 0x00, // wards... - 0x06, 0x70, 0x72, 0x61, 0x67, 0x6d, 0x61, 0x00, // .pragma. - 0x00, 0x00, 0x12, 0x70, 0x72, 0x6f, 0x78, 0x79, // ...proxy - 0x2d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, // -authent - 0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, // icate... - 0x13, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2d, 0x61, // .proxy-a - 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, // uthoriza - 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x05, // tion.... - 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, 0x00, // range... - 0x07, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x72, // .referer - 0x00, 0x00, 0x00, 0x0b, 0x72, 0x65, 0x74, 0x72, // ....retr - 0x79, 0x2d, 0x61, 0x66, 0x74, 0x65, 0x72, 0x00, // y-after. - 0x00, 0x00, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, // ...serve - 0x72, 0x00, 0x00, 0x00, 0x02, 0x74, 0x65, 0x00, // r....te. - 0x00, 0x00, 0x07, 0x74, 0x72, 0x61, 0x69, 0x6c, // ...trail - 0x65, 0x72, 0x00, 0x00, 0x00, 0x11, 0x74, 0x72, // er....tr - 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2d, 0x65, // ansfer-e - 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x00, // ncoding. - 0x00, 0x00, 0x07, 0x75, 0x70, 0x67, 0x72, 0x61, // ...upgra - 0x64, 0x65, 0x00, 0x00, 0x00, 0x0a, 0x75, 0x73, // de....us - 0x65, 0x72, 0x2d, 0x61, 0x67, 0x65, 0x6e, 0x74, // er-agent - 0x00, 0x00, 0x00, 0x04, 0x76, 0x61, 0x72, 0x79, // ....vary - 0x00, 0x00, 0x00, 0x03, 0x76, 0x69, 0x61, 0x00, // ....via. - 0x00, 0x00, 0x07, 0x77, 0x61, 0x72, 0x6e, 0x69, // ...warni - 0x6e, 0x67, 0x00, 0x00, 0x00, 0x10, 0x77, 0x77, // ng....ww - 0x77, 0x2d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, // w-authen - 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00, // ticate.. - 0x00, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, // ..method - 0x00, 0x00, 0x00, 0x03, 0x67, 0x65, 0x74, 0x00, // ....get. - 0x00, 0x00, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, // ...statu - 0x73, 0x00, 0x00, 0x00, 0x06, 0x32, 0x30, 0x30, // s....200 - 0x20, 0x4f, 0x4b, 0x00, 0x00, 0x00, 0x07, 0x76, // .OK....v - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x00, 0x00, // ersion.. - 0x00, 0x08, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, // ..HTTP.1 - 0x2e, 0x31, 0x00, 0x00, 0x00, 0x03, 0x75, 0x72, // .1....ur - 0x6c, 0x00, 0x00, 0x00, 0x06, 0x70, 0x75, 0x62, // l....pub - 0x6c, 0x69, 0x63, 0x00, 0x00, 0x00, 0x0a, 0x73, // lic....s - 0x65, 0x74, 0x2d, 0x63, 0x6f, 0x6f, 0x6b, 0x69, // et-cooki - 0x65, 0x00, 0x00, 0x00, 0x0a, 0x6b, 0x65, 0x65, // e....kee - 0x70, 0x2d, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x00, // p-alive. - 0x00, 0x00, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, // ...origi - 0x6e, 0x31, 0x30, 0x30, 0x31, 0x30, 0x31, 0x32, // n1001012 - 0x30, 0x31, 0x32, 0x30, 0x32, 0x32, 0x30, 0x35, // 01202205 - 0x32, 0x30, 0x36, 0x33, 0x30, 0x30, 0x33, 0x30, // 20630030 - 0x32, 0x33, 0x30, 0x33, 0x33, 0x30, 0x34, 0x33, // 23033043 - 0x30, 0x35, 0x33, 0x30, 0x36, 0x33, 0x30, 0x37, // 05306307 - 0x34, 0x30, 0x32, 0x34, 0x30, 0x35, 0x34, 0x30, // 40240540 - 0x36, 0x34, 0x30, 0x37, 0x34, 0x30, 0x38, 0x34, // 64074084 - 0x30, 0x39, 0x34, 0x31, 0x30, 0x34, 0x31, 0x31, // 09410411 - 0x34, 0x31, 0x32, 0x34, 0x31, 0x33, 0x34, 0x31, // 41241341 - 0x34, 0x34, 0x31, 0x35, 0x34, 0x31, 0x36, 0x34, // 44154164 - 0x31, 0x37, 0x35, 0x30, 0x32, 0x35, 0x30, 0x34, // 17502504 - 0x35, 0x30, 0x35, 0x32, 0x30, 0x33, 0x20, 0x4e, // 505203.N - 0x6f, 0x6e, 0x2d, 0x41, 0x75, 0x74, 0x68, 0x6f, // on-Autho - 0x72, 0x69, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65, // ritative - 0x20, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, // .Informa - 0x74, 0x69, 0x6f, 0x6e, 0x32, 0x30, 0x34, 0x20, // tion204. - 0x4e, 0x6f, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x65, // No.Conte - 0x6e, 0x74, 0x33, 0x30, 0x31, 0x20, 0x4d, 0x6f, // nt301.Mo - 0x76, 0x65, 0x64, 0x20, 0x50, 0x65, 0x72, 0x6d, // ved.Perm - 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x34, // anently4 - 0x30, 0x30, 0x20, 0x42, 0x61, 0x64, 0x20, 0x52, // 00.Bad.R - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x34, 0x30, // equest40 - 0x31, 0x20, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, // 1.Unauth - 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x34, 0x30, // orized40 - 0x33, 0x20, 0x46, 0x6f, 0x72, 0x62, 0x69, 0x64, // 3.Forbid - 0x64, 0x65, 0x6e, 0x34, 0x30, 0x34, 0x20, 0x4e, // den404.N - 0x6f, 0x74, 0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64, // ot.Found - 0x35, 0x30, 0x30, 0x20, 0x49, 0x6e, 0x74, 0x65, // 500.Inte - 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x53, 0x65, 0x72, // rnal.Ser - 0x76, 0x65, 0x72, 0x20, 0x45, 0x72, 0x72, 0x6f, // ver.Erro - 0x72, 0x35, 0x30, 0x31, 0x20, 0x4e, 0x6f, 0x74, // r501.Not - 0x20, 0x49, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, // .Impleme - 0x6e, 0x74, 0x65, 0x64, 0x35, 0x30, 0x33, 0x20, // nted503. - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20, // Service. - 0x55, 0x6e, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, // Unavaila - 0x62, 0x6c, 0x65, 0x4a, 0x61, 0x6e, 0x20, 0x46, // bleJan.F - 0x65, 0x62, 0x20, 0x4d, 0x61, 0x72, 0x20, 0x41, // eb.Mar.A - 0x70, 0x72, 0x20, 0x4d, 0x61, 0x79, 0x20, 0x4a, // pr.May.J - 0x75, 0x6e, 0x20, 0x4a, 0x75, 0x6c, 0x20, 0x41, // un.Jul.A - 0x75, 0x67, 0x20, 0x53, 0x65, 0x70, 0x74, 0x20, // ug.Sept. - 0x4f, 0x63, 0x74, 0x20, 0x4e, 0x6f, 0x76, 0x20, // Oct.Nov. - 0x44, 0x65, 0x63, 0x20, 0x30, 0x30, 0x3a, 0x30, // Dec.00.0 - 0x30, 0x3a, 0x30, 0x30, 0x20, 0x4d, 0x6f, 0x6e, // 0.00.Mon - 0x2c, 0x20, 0x54, 0x75, 0x65, 0x2c, 0x20, 0x57, // ..Tue..W - 0x65, 0x64, 0x2c, 0x20, 0x54, 0x68, 0x75, 0x2c, // ed..Thu. - 0x20, 0x46, 0x72, 0x69, 0x2c, 0x20, 0x53, 0x61, // .Fri..Sa - 0x74, 0x2c, 0x20, 0x53, 0x75, 0x6e, 0x2c, 0x20, // t..Sun.. - 0x47, 0x4d, 0x54, 0x63, 0x68, 0x75, 0x6e, 0x6b, // GMTchunk - 0x65, 0x64, 0x2c, 0x74, 0x65, 0x78, 0x74, 0x2f, // ed.text. - 0x68, 0x74, 0x6d, 0x6c, 0x2c, 0x69, 0x6d, 0x61, // html.ima - 0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0x2c, 0x69, // ge.png.i - 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x67, // mage.jpg - 0x2c, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, // .image.g - 0x69, 0x66, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69, // if.appli - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78, // cation.x - 0x6d, 0x6c, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69, // ml.appli - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78, // cation.x - 0x68, 0x74, 0x6d, 0x6c, 0x2b, 0x78, 0x6d, 0x6c, // html.xml - 0x2c, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, // .text.pl - 0x61, 0x69, 0x6e, 0x2c, 0x74, 0x65, 0x78, 0x74, // ain.text - 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, // .javascr - 0x69, 0x70, 0x74, 0x2c, 0x70, 0x75, 0x62, 0x6c, // ipt.publ - 0x69, 0x63, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, // icprivat - 0x65, 0x6d, 0x61, 0x78, 0x2d, 0x61, 0x67, 0x65, // emax-age - 0x3d, 0x67, 0x7a, 0x69, 0x70, 0x2c, 0x64, 0x65, // .gzip.de - 0x66, 0x6c, 0x61, 0x74, 0x65, 0x2c, 0x73, 0x64, // flate.sd - 0x63, 0x68, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, // chcharse - 0x74, 0x3d, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x63, // t.utf-8c - 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x69, // harset.i - 0x73, 0x6f, 0x2d, 0x38, 0x38, 0x35, 0x39, 0x2d, // so-8859- - 0x31, 0x2c, 0x75, 0x74, 0x66, 0x2d, 0x2c, 0x2a, // 1.utf-.. - 0x2c, 0x65, 0x6e, 0x71, 0x3d, 0x30, 0x2e // .enq.0. -}; - -// uncomment to debug -//static void printHex(const QByteArray &ba) -//{ -// QByteArray hex; -// QByteArray clearText; -// for (int a = 0; a < ba.count(); ++a) { -// QByteArray currentHexChar = QByteArray(1, ba.at(a)).toHex().rightJustified(2, ' '); -// QByteArray currentChar; -// if (ba.at(a) >= 32 && ba.at(a) < 126) { // if ASCII, print the letter -// currentChar = QByteArray(1, ba.at(a)); -// } else { -// currentChar = " "; -// } -// clearText.append(currentChar.rightJustified(2, ' ')); -// hex.append(currentHexChar); -// hex.append(' '); -// clearText.append(' '); -// } -// int chunkSize = 102; // 12 == 4 bytes per line -// for (int a = 0; a < hex.count(); a += chunkSize) { -// qDebug() << hex.mid(a, chunkSize); -// qDebug() << clearText.mid(a, chunkSize); -// } -//} - -QSpdyProtocolHandler::QSpdyProtocolHandler(QHttpNetworkConnectionChannel *channel) - : QObject(nullptr), QAbstractProtocolHandler(channel), - m_nextStreamID(-1), - m_maxConcurrentStreams(100), // 100 is recommended in the SPDY RFC - m_initialWindowSize(0), - m_waitingForCompleteStream(false) -{ - m_inflateStream.zalloc = Z_NULL; - m_inflateStream.zfree = Z_NULL; - m_inflateStream.opaque = Z_NULL; - int zlibRet = inflateInit(&m_inflateStream); - Q_ASSERT(zlibRet == Z_OK); - - m_deflateStream.zalloc = Z_NULL; - m_deflateStream.zfree = Z_NULL; - m_deflateStream.opaque = Z_NULL; - - // Do actually not compress (i.e. compression level = 0) - // when sending the headers because of the CRIME attack - zlibRet = deflateInit(&m_deflateStream, /* compression level = */ 0); - Q_ASSERT(zlibRet == Z_OK); - Q_UNUSED(zlibRet); // silence -Wunused-variable -} - -QSpdyProtocolHandler::~QSpdyProtocolHandler() -{ - deflateEnd(&m_deflateStream); - deflateEnd(&m_inflateStream); -} - -bool QSpdyProtocolHandler::sendRequest() -{ - Q_ASSERT(!m_reply); - - int maxPossibleRequests = m_maxConcurrentStreams - m_inFlightStreams.count(); - Q_ASSERT(maxPossibleRequests >= 0); - if (maxPossibleRequests == 0) - return true; // return early if max concurrent requests are exceeded - - m_channel->state = QHttpNetworkConnectionChannel::WritingState; - - int requestsToSend = qMin(m_channel->spdyRequestsToSend.size(), maxPossibleRequests); - - QMultiMap<int, HttpMessagePair>::iterator it = m_channel->spdyRequestsToSend.begin(); - // requests will be ordered by priority (see QMultiMap doc) - for (int a = 0; a < requestsToSend; ++a) { - HttpMessagePair currentPair = *it; - QHttpNetworkRequest currentRequest = currentPair.first; - QHttpNetworkReply *currentReply = currentPair.second; - - currentReply->setSpdyWasUsed(true); - qint32 streamID = generateNextStreamID(); - m_streamIDs.insert(currentReply, streamID); - - currentReply->setRequest(currentRequest); - currentReply->d_func()->connection = m_connection; - currentReply->d_func()->connectionChannel = m_channel; - m_inFlightStreams.insert(streamID, currentPair); - connect(currentReply, SIGNAL(destroyed(QObject*)), this, SLOT(_q_replyDestroyed(QObject*))); - - sendSYN_STREAM(currentPair, streamID, /* associatedToStreamID = */ 0); - m_channel->spdyRequestsToSend.erase(it++); - } - m_channel->state = QHttpNetworkConnectionChannel::IdleState; - return true; -} - -void QSpdyProtocolHandler::_q_replyDestroyed(QObject* reply) -{ - qint32 streamID = m_streamIDs.take(reply); - if (m_inFlightStreams.remove(streamID)) - sendRST_STREAM(streamID, RST_STREAM_CANCEL); -} - -void QSpdyProtocolHandler::_q_receiveReply() -{ - Q_ASSERT(m_socket); - - // only run when the QHttpNetworkConnection is not currently being destructed, e.g. - // this function is called from _q_disconnected which is called because - // of ~QHttpNetworkConnectionPrivate - if (!qobject_cast<QHttpNetworkConnection*>(m_connection)) { - return; - } - - if (bytesAvailable() < 8) - return; // cannot read frame headers, wait for more data - - char frameHeadersRaw[8]; - if (!readNextChunk(8, frameHeadersRaw)) - return; // this should not happen, we just checked - - const QByteArray frameHeaders(frameHeadersRaw, 8); // ### try without memcpy - if (frameHeadersRaw[0] & 0x80) { - handleControlFrame(frameHeaders); - } else { - handleDataFrame(frameHeaders); - } - - // after handling the current frame, check whether there is more data waiting - if (m_socket->bytesAvailable() > 0) - QMetaObject::invokeMethod(m_channel, "_q_receiveReply", Qt::QueuedConnection); -} - -void QSpdyProtocolHandler::_q_readyRead() -{ - _q_receiveReply(); -} - -static qint16 twoBytesToInt(const char *bytes) -{ - return qFromBigEndian<qint16>(bytes); -} - -static qint32 threeBytesToInt(const char *bytes) -{ - return qFromBigEndian<qint32>(bytes) >> 8; -} - -static qint32 fourBytesToInt(const char *bytes) -{ - return qFromBigEndian<qint32>(bytes); -} - -static void appendIntToThreeBytes(char *output, qint32 number) -{ - qToBigEndian<qint16>(number, output + 1); - qToBigEndian<qint8>(number >> 16, output); -} - -static void appendIntToFourBytes(char *output, qint32 number) -{ - qToBigEndian<qint32>(number, output); -} - -static QByteArray intToFourBytes(qint32 number) // ### try to use appendIntToFourBytes where possible -{ - char data[4]; - qToBigEndian<qint32>(number, data); - QByteArray ret(data, 4); - return ret; -} - -static QByteArray intToThreeBytes(qint32 number) -{ - char data[4]; - qToBigEndian<qint32>(number << 8, data); - QByteArray ret(data, 3); - return ret; -} - -static qint32 getStreamID(const char *bytes) -{ - // eliminate most significant bit; it might be 0 or 1 depending on whether - // we are dealing with a control or data frame - return fourBytesToInt(bytes) & 0x3fffffff; -} - -static QByteArray headerField(const QByteArray &name, const QByteArray &value) -{ - QByteArray ret; - ret.reserve(name.count() + value.count() + 8); // 4 byte for length each - ret.append(intToFourBytes(name.count())); - ret.append(name); - ret.append(intToFourBytes(value.count())); - ret.append(value); - return ret; -} - -bool QSpdyProtocolHandler::uncompressHeader(const QByteArray &input, QByteArray *output) -{ - const size_t chunkSize = 1024; - char outputRaw[chunkSize]; - // input bytes will not be changed by zlib, so it is safe to const_cast here - m_inflateStream.next_in = const_cast<Bytef *>(reinterpret_cast<const Bytef *>(input.constData())); - m_inflateStream.avail_in = input.count(); - m_inflateStream.total_in = input.count(); - int zlibRet; - - do { - m_inflateStream.next_out = reinterpret_cast<Bytef *>(outputRaw); - m_inflateStream.avail_out = chunkSize; - zlibRet = inflate(&m_inflateStream, Z_SYNC_FLUSH); - if (zlibRet == Z_NEED_DICT) { - zlibRet = inflateSetDictionary(&m_inflateStream, - reinterpret_cast<const Bytef*>(spdyDictionary), - /* dictionaryLength = */ 1423); - Q_ASSERT(zlibRet == Z_OK); - continue; - } - switch (zlibRet) { - case Z_BUF_ERROR: { - if (m_inflateStream.avail_in == 0) { - int outputSize = chunkSize - m_inflateStream.avail_out; - output->append(outputRaw, outputSize); - m_inflateStream.avail_out = chunkSize; - } - break; - } - case Z_OK: { - int outputSize = chunkSize - m_inflateStream.avail_out; - output->append(outputRaw, outputSize); - break; - } - default: { - qWarning("got unexpected zlib return value: %d", zlibRet); - return false; - } - } - } while (m_inflateStream.avail_in > 0 && zlibRet != Z_STREAM_END); - - Q_ASSERT(m_inflateStream.avail_in == 0); - return true; -} - -QByteArray QSpdyProtocolHandler::composeHeader(const QHttpNetworkRequest &request) -{ - QByteArray uncompressedHeader; - uncompressedHeader.reserve(300); // rough estimate - - // calculate additional headers first, because we need to know the size - // ### do not partially copy the list, but restrict the set header fields - // in QHttpNetworkConnection - QVector<QPair<QByteArray, QByteArray> > additionalHeaders; - for (int a = 0; a < request.header().count(); ++a) { - QByteArray key = request.header().at(a).first; - if (key == "Connection" || key == "Host" || key == "Keep-Alive" - || key == "Proxy-Connection" || key == "Transfer-Encoding") - continue; // those headers are not valid (section 3.2.1) - additionalHeaders.append(request.header().at(a)); - } - - qint32 numberOfHeaderPairs = 5 + additionalHeaders.count(); // 5 mandatory below + the additional ones - uncompressedHeader.append(intToFourBytes(numberOfHeaderPairs)); - - // mandatory header fields: - - uncompressedHeader.append(headerField(":method", request.methodName())); -#ifndef QT_NO_NETWORKPROXY - bool useProxy = m_connection->d_func()->networkProxy.type() != QNetworkProxy::NoProxy; - uncompressedHeader.append(headerField(":path", request.uri(useProxy))); -#else - uncompressedHeader.append(headerField(":path", request.uri(false))); -#endif - uncompressedHeader.append(headerField(":version", "HTTP/1.1")); - - uncompressedHeader.append(headerField(":host", request.url().authority(QUrl::FullyEncoded | QUrl::RemoveUserInfo).toLatin1())); - - uncompressedHeader.append(headerField(":scheme", request.url().scheme().toLatin1())); - - // end of mandatory header fields - - // now add the additional headers - for (int a = 0; a < additionalHeaders.count(); ++a) { - uncompressedHeader.append(headerField(additionalHeaders.at(a).first.toLower(), - additionalHeaders.at(a).second)); - } - - m_deflateStream.total_in = uncompressedHeader.count(); - m_deflateStream.avail_in = uncompressedHeader.count(); - m_deflateStream.next_in = reinterpret_cast<unsigned char *>(uncompressedHeader.data()); - int outputBytes = uncompressedHeader.count() + 30; // 30 bytes of compression header overhead - m_deflateStream.avail_out = outputBytes; - unsigned char *out = new unsigned char[outputBytes]; - m_deflateStream.next_out = out; - int availOutBefore = m_deflateStream.avail_out; - int zlibRet = deflate(&m_deflateStream, Z_SYNC_FLUSH); // do everything in one go since we use no compression - int compressedHeaderSize = availOutBefore - m_deflateStream.avail_out; - Q_ASSERT(zlibRet == Z_OK); // otherwise, we need to allocate more outputBytes - Q_UNUSED(zlibRet); // silence -Wunused-variable - Q_ASSERT(m_deflateStream.avail_in == 0); - QByteArray compressedHeader(reinterpret_cast<char *>(out), compressedHeaderSize); - delete[] out; - - return compressedHeader; -} - -quint64 QSpdyProtocolHandler::bytesAvailable() const -{ - Q_ASSERT(m_socket); - return m_spdyBuffer.byteAmount() + m_socket->bytesAvailable(); -} - -bool QSpdyProtocolHandler::readNextChunk(qint64 length, char *sink) -{ - qint64 expectedReadBytes = length; - qint64 requiredBytesFromBuffer = 0; - - if (m_waitingForCompleteStream) { - requiredBytesFromBuffer = qMin(length, m_spdyBuffer.byteAmount()); - // ### if next chunk from buffer bigger than what we want to read, - // we have to call read() (which memcpy's). Otherwise, we can just - // read the next chunk without memcpy'ing. - qint64 bytesReadFromBuffer = m_spdyBuffer.read(sink, requiredBytesFromBuffer); - Q_ASSERT(bytesReadFromBuffer == requiredBytesFromBuffer); - if (length <= bytesReadFromBuffer) { - return true; // buffer > required size -> no need to read from socket - } - expectedReadBytes -= requiredBytesFromBuffer; - } - qint64 readBytes = m_socket->read(sink + requiredBytesFromBuffer, expectedReadBytes); - - if (readBytes < expectedReadBytes) { - m_waitingForCompleteStream = true; - // ### this is inefficient, we should not put back so much data into the buffer - QByteArray temp(sink, requiredBytesFromBuffer + readBytes); - m_spdyBuffer.append(temp); - return false; - } else { - return true; // buffer must be cleared by calling function - } -} - -void QSpdyProtocolHandler::sendControlFrame(FrameType type, - ControlFrameFlags flags, - const char *data, - quint32 length) -{ - // frame type and stream ID - char header[8]; - header[0] = 0x80u; // leftmost bit == 1 -> is a control frame - header[1] = 0x03; // 3 bit == version 3 - header[2] = 0; - switch (type) { - case FrameType_CREDENTIAL: { - qWarning("sending SPDY CREDENTIAL frame is not yet implemented"); // QTBUG-36188 - return; - } - default: - header[3] = type; - } - - // flags - header[4] = 0; - if (flags & ControlFrame_FLAG_FIN || length == 0) { - Q_ASSERT(type == FrameType_SYN_STREAM || type == FrameType_SYN_REPLY - || type == FrameType_HEADERS || length == 0); - header[4] |= ControlFrame_FLAG_FIN; - } - if (flags & ControlFrame_FLAG_UNIDIRECTIONAL) { - Q_ASSERT(type == FrameType_SYN_STREAM); - header[4] |= ControlFrame_FLAG_UNIDIRECTIONAL; - } - - // length - appendIntToThreeBytes(header + 5, length); - - qint64 written = m_socket->write(header, 8); - Q_ASSERT(written == 8); - written = m_socket->write(data, length); - Q_ASSERT(written == length); - Q_UNUSED(written); // silence -Wunused-variable -} - -void QSpdyProtocolHandler::sendSYN_STREAM(const HttpMessagePair &messagePair, - qint32 streamID, qint32 associatedToStreamID) -{ - QHttpNetworkRequest request = messagePair.first; - QHttpNetworkReply *reply = messagePair.second; - - ControlFrameFlags flags; - - if (!request.uploadByteDevice()) { - // no upload -> this is the last frame, send the FIN flag - flags |= ControlFrame_FLAG_FIN; - reply->d_func()->state = QHttpNetworkReplyPrivate::SPDYHalfClosed; - } else { - reply->d_func()->state = QHttpNetworkReplyPrivate::SPDYUploading; - - // hack: set the stream ID on the device directly, so when we get - // the signal for uploading we know which stream we are sending on - m_streamIDs.insert(request.uploadByteDevice(), streamID); - - QObject::connect(request.uploadByteDevice(), SIGNAL(readyRead()), this, - SLOT(_q_uploadDataReadyRead()), Qt::QueuedConnection); - QObject::connect(request.uploadByteDevice(), SIGNAL(destroyed(QObject*)), this, - SLOT(_q_uploadDataDestroyed(QObject *))); - } - - QByteArray namesAndValues = composeHeader(request); - quint32 length = namesAndValues.count() + 10; // 10 == 4 for Stream-ID + 4 for Associated-To-Stream-ID - // + 2 for Priority, Unused and Slot - - QByteArray wireData; - wireData.reserve(length); - wireData.append(intToFourBytes(streamID)); - wireData.append(intToFourBytes(associatedToStreamID)); - - // priority (3 bits) / unused (5 bits) / slot (8 bits) - char prioAndSlot[2]; - switch (request.priority()) { - case QHttpNetworkRequest::HighPriority: - prioAndSlot[0] = 0x00; // == prio 0 (highest) - break; - case QHttpNetworkRequest::NormalPriority: - prioAndSlot[0] = 0x80u; // == prio 4 - break; - case QHttpNetworkRequest::LowPriority: - prioAndSlot[0] = 0xe0u; // == prio 7 (lowest) - break; - } - prioAndSlot[1] = 0x00; // slot in client certificates (not supported currently) - wireData.append(prioAndSlot, 2); - - wireData.append(namesAndValues); - - sendControlFrame(FrameType_SYN_STREAM, flags, wireData.constData(), length); - - if (reply->d_func()->state == QHttpNetworkReplyPrivate::SPDYUploading) - uploadData(streamID); -} - -void QSpdyProtocolHandler::_q_uploadDataDestroyed(QObject *uploadData) -{ - m_streamIDs.remove(uploadData); -} - -void QSpdyProtocolHandler::sendRST_STREAM(qint32 streamID, RST_STREAM_STATUS_CODE statusCode) -{ - char wireData[8]; - appendIntToFourBytes(wireData, streamID); - appendIntToFourBytes(wireData + 4, statusCode); - sendControlFrame(FrameType_RST_STREAM, /* flags = */ { }, wireData, /* length = */ 8); -} - -void QSpdyProtocolHandler::sendPING(quint32 pingID) -{ - char rawData[4]; - appendIntToFourBytes(rawData, pingID); - sendControlFrame(FrameType_PING, /* flags = */ { }, rawData, /* length = */ 4); -} - -bool QSpdyProtocolHandler::uploadData(qint32 streamID) -{ - // we only rely on SPDY flow control here and don't care about TCP buffers - if (!m_inFlightStreams.contains(streamID)) { - sendRST_STREAM(streamID, RST_STREAM_INVALID_STREAM); - return false; - } - - HttpMessagePair messagePair = m_inFlightStreams.value(streamID); - QHttpNetworkRequest request = messagePair.first; - QHttpNetworkReply *reply = messagePair.second; - Q_ASSERT(reply); - QHttpNetworkReplyPrivate *replyPrivate = reply->d_func(); - Q_ASSERT(replyPrivate); - - if (reply->d_func()->state == QHttpNetworkReplyPrivate::SPDYHalfClosed || reply->d_func()->state == QHttpNetworkReplyPrivate::SPDYClosed) { - qWarning("Trying to upload to closed stream"); - return false; - } - - qint32 dataLeftInWindow = replyPrivate->windowSizeUpload - - replyPrivate->currentlyUploadedDataInWindow; - - while (dataLeftInWindow > 0 && !request.uploadByteDevice()->atEnd()) { - - // get pointer to upload data - qint64 currentReadSize = 0; - const char *readPointer = request.uploadByteDevice()->readPointer(dataLeftInWindow, - currentReadSize); - - if (currentReadSize == -1) { - // premature eof happened - m_connection->d_func()->emitReplyError(m_socket, reply, - QNetworkReply::UnknownNetworkError); - return false; - } else if (readPointer == nullptr || currentReadSize == 0) { - // nothing to read currently, break the loop - break; - } else { - DataFrameFlags flags; - // we will send the FIN flag later if appropriate - qint64 currentWriteSize = sendDataFrame(streamID, flags, currentReadSize, readPointer); - if (currentWriteSize == -1 || currentWriteSize != currentReadSize) { - // socket broke down - m_connection->d_func()->emitReplyError(m_socket, reply, - QNetworkReply::UnknownNetworkError); - return false; - } else { - replyPrivate->currentlyUploadedDataInWindow += currentWriteSize; - replyPrivate->totallyUploadedData += currentWriteSize; - dataLeftInWindow = replyPrivate->windowSizeUpload - - replyPrivate->currentlyUploadedDataInWindow; - request.uploadByteDevice()->advanceReadPointer(currentWriteSize); - - emit reply->dataSendProgress(replyPrivate->totallyUploadedData, - request.contentLength()); - } - } - } - if (replyPrivate->totallyUploadedData == request.contentLength()) { - DataFrameFlags finFlag = DataFrame_FLAG_FIN; - qint64 writeSize = sendDataFrame(streamID, finFlag, 0, nullptr); - Q_ASSERT(writeSize == 0); - Q_UNUSED(writeSize); // silence -Wunused-variable - replyPrivate->state = QHttpNetworkReplyPrivate::SPDYHalfClosed; - if (reply->request().uploadByteDevice()) - reply->request().uploadByteDevice()->disconnect(this); - // ### this will not work if the content length is not known, but - // then again many servers will fail in this case anyhow according - // to the SPDY RFC - } - return true; -} - -void QSpdyProtocolHandler::_q_uploadDataReadyRead() -{ - QNonContiguousByteDevice *device = qobject_cast<QNonContiguousByteDevice *>(sender()); - Q_ASSERT(device); - qint32 streamID = m_streamIDs.value(device); - Q_ASSERT(streamID > 0); - uploadData(streamID); -} - -void QSpdyProtocolHandler::sendWINDOW_UPDATE(qint32 streamID, quint32 deltaWindowSize) -{ - char windowUpdateData[8]; - appendIntToFourBytes(windowUpdateData, streamID); - appendIntToFourBytes(windowUpdateData + 4, deltaWindowSize); - - sendControlFrame(FrameType_WINDOW_UPDATE, /* flags = */ { }, windowUpdateData, /* length = */ 8); -} - -qint64 QSpdyProtocolHandler::sendDataFrame(qint32 streamID, DataFrameFlags flags, - quint32 length, const char *data) -{ - QByteArray wireData; - wireData.reserve(8); - - wireData.append(intToFourBytes(streamID)); - wireData.append(flags); - wireData.append(intToThreeBytes(length)); - - Q_ASSERT(m_socket); - m_socket->write(wireData); - - if (data) { - qint64 ret = m_socket->write(data, length); - return ret; - } else { - return 0; // nothing to write, e.g. FIN flag - } -} - -void QSpdyProtocolHandler::handleControlFrame(const QByteArray &frameHeaders) // ### make it char * -{ - Q_ASSERT(frameHeaders.count() >= 8); - qint16 version = twoBytesToInt(frameHeaders.constData()); - version &= 0x3fff; // eliminate most significant bit to determine version - Q_ASSERT(version == 3); - - qint16 type = twoBytesToInt(frameHeaders.constData() + 2); - - char flags = frameHeaders.at(4); - qint32 length = threeBytesToInt(frameHeaders.constData() + 5); - Q_ASSERT(length > 0); - - QByteArray frameData; - frameData.resize(length); - if (!readNextChunk(length, frameData.data())) { - // put back the frame headers to the buffer - m_spdyBuffer.prepend(frameHeaders); - return; // we couldn't read the whole frame and need to wait - } else { - m_spdyBuffer.clear(); - m_waitingForCompleteStream = false; - } - - switch (type) { - case FrameType_SYN_STREAM: { - handleSYN_STREAM(flags, length, frameData); - break; - } - case FrameType_SYN_REPLY: { - handleSYN_REPLY(flags, length, frameData); - break; - } - case FrameType_RST_STREAM: { - handleRST_STREAM(flags, length, frameData); - break; - } - case FrameType_SETTINGS: { - handleSETTINGS(flags, length, frameData); - break; - } - case FrameType_PING: { - handlePING(flags, length, frameData); - break; - } - case FrameType_GOAWAY: { - handleGOAWAY(flags, length, frameData); - break; - } - case FrameType_HEADERS: { - handleHEADERS(flags, length, frameData); - break; - } - case FrameType_WINDOW_UPDATE: { - handleWINDOW_UPDATE(flags, length, frameData); - break; - } - default: - qWarning("cannot handle frame of type %d", int(type)); - } -} - -void QSpdyProtocolHandler::handleSYN_STREAM(char /*flags*/, quint32 /*length*/, - const QByteArray &frameData) -{ - // not implemented; will be implemented when servers start using it - // we just tell the server that we do not accept that - - qint32 streamID = getStreamID(frameData.constData()); - - sendRST_STREAM(streamID, RST_STREAM_REFUSED_STREAM); -} - -void QSpdyProtocolHandler::handleSYN_REPLY(char flags, quint32 /*length*/, const QByteArray &frameData) -{ - parseHttpHeaders(flags, frameData); -} - -void QSpdyProtocolHandler::parseHttpHeaders(char flags, const QByteArray &frameData) -{ - qint32 streamID = getStreamID(frameData.constData()); - const auto it = m_inFlightStreams.constFind(streamID); - if (it == m_inFlightStreams.cend()) { - sendRST_STREAM(streamID, RST_STREAM_INVALID_STREAM); - return; - } - - flags &= 0x3f; - bool flag_fin = flags & 0x01; - - QByteArray headerValuePairs = frameData.mid(4); - - HttpMessagePair pair = it.value(); - QHttpNetworkReply *httpReply = pair.second; - Q_ASSERT(httpReply != nullptr); - - if (httpReply->d_func()->state == QHttpNetworkReplyPrivate::SPDYClosed) { - sendRST_STREAM(streamID, RST_STREAM_STREAM_ALREADY_CLOSED); - return; - } - - QByteArray uncompressedHeader; - if (!uncompressHeader(headerValuePairs, &uncompressedHeader)) { - qWarning("error reading header from SYN_REPLY message"); - return; - } - - qint32 headerCount = fourBytesToInt(uncompressedHeader.constData()); - if (headerCount * 8 > uncompressedHeader.size()) { - qWarning("error parsing header from SYN_REPLY message"); - sendRST_STREAM(streamID, RST_STREAM_PROTOCOL_ERROR); - return; - } - qint32 readPointer = 4; - for (qint32 a = 0; a < headerCount; ++a) { - qint32 count = fourBytesToInt(uncompressedHeader.constData() + readPointer); - readPointer += 4; - QByteArray name = uncompressedHeader.mid(readPointer, count); - readPointer += count; - if (readPointer > uncompressedHeader.size()) { - qWarning("error parsing header from SYN_REPLY message"); - sendRST_STREAM(streamID, RST_STREAM_PROTOCOL_ERROR); - return; - } - count = fourBytesToInt(uncompressedHeader.constData() + readPointer); - readPointer += 4; - QByteArray value = uncompressedHeader.mid(readPointer, count); - readPointer += count; - if (readPointer > uncompressedHeader.size()) { - qWarning("error parsing header from SYN_REPLY message"); - sendRST_STREAM(streamID, RST_STREAM_PROTOCOL_ERROR); - return; - } - if (name == ":status") { - httpReply->setStatusCode(value.left(3).toInt()); - httpReply->d_func()->reasonPhrase = QString::fromLatin1(value.mid(4)); - } else if (name == ":version") { - int majorVersion = value.at(5) - 48; - int minorVersion = value.at(7) - 48; - httpReply->d_func()->majorVersion = majorVersion; - httpReply->d_func()->minorVersion = minorVersion; - } else if (name == "content-length") { - httpReply->setContentLength(value.toLongLong()); - } else { - value.replace('\0', name == "set-cookie" ? "\n" : ", "); - httpReply->setHeaderField(name, value); - } - } - emit httpReply->headerChanged(); - - if (flag_fin) { - if (httpReply->d_func()->state != QHttpNetworkReplyPrivate::SPDYHalfClosed) - sendDataFrame(streamID, DataFrame_FLAG_FIN, 0, nullptr); - replyFinished(httpReply, streamID); - } -} - -void QSpdyProtocolHandler::handleRST_STREAM(char /*flags*/, quint32 length, - const QByteArray &frameData) -{ - // flags are ignored - - Q_ASSERT(length == 8); - Q_UNUSED(length); // silence -Wunused-parameter - qint32 streamID = getStreamID(frameData.constData()); - QHttpNetworkReply *httpReply = m_inFlightStreams.value(streamID).second; - - qint32 statusCodeInt = fourBytesToInt(frameData.constData() + 4); - RST_STREAM_STATUS_CODE statusCode = static_cast<RST_STREAM_STATUS_CODE>(statusCodeInt); - QNetworkReply::NetworkError errorCode; - QByteArray errorMessage; - - switch (statusCode) { - case RST_STREAM_PROTOCOL_ERROR: - errorCode = QNetworkReply::ProtocolFailure; - errorMessage = "SPDY protocol error"; - break; - case RST_STREAM_INVALID_STREAM: - errorCode = QNetworkReply::ProtocolFailure; - errorMessage = "SPDY stream is not active"; - break; - case RST_STREAM_REFUSED_STREAM: - errorCode = QNetworkReply::ProtocolFailure; - errorMessage = "SPDY stream was refused"; - break; - case RST_STREAM_UNSUPPORTED_VERSION: - errorCode = QNetworkReply::ProtocolUnknownError; - errorMessage = "SPDY version is unknown to the server"; - break; - case RST_STREAM_CANCEL: - errorCode = QNetworkReply::ProtocolFailure; - errorMessage = "SPDY stream is no longer needed"; - break; - case RST_STREAM_INTERNAL_ERROR: - errorCode = QNetworkReply::InternalServerError; - errorMessage = "Internal server error"; - break; - case RST_STREAM_FLOW_CONTROL_ERROR: - errorCode = QNetworkReply::ProtocolFailure; - errorMessage = "peer violated the flow control protocol"; - break; - case RST_STREAM_STREAM_IN_USE: - errorCode = QNetworkReply::ProtocolFailure; - errorMessage = "server received a SYN_REPLY for an already open stream"; - break; - case RST_STREAM_STREAM_ALREADY_CLOSED: - errorCode = QNetworkReply::ProtocolFailure; - errorMessage = "server received data or a SYN_REPLY for an already half-closed stream"; - break; - case RST_STREAM_INVALID_CREDENTIALS: - errorCode = QNetworkReply::ContentAccessDenied; - errorMessage = "server received invalid credentials"; - break; - case RST_STREAM_FRAME_TOO_LARGE: - errorCode = QNetworkReply::ProtocolFailure; - errorMessage = "server cannot process the frame because it is too large"; - break; - default: - qWarning("could not understand servers RST_STREAM status code"); - errorCode = QNetworkReply::ProtocolFailure; - errorMessage = "got SPDY RST_STREAM message with unknown error code"; - } - if (httpReply) - replyFinishedWithError(httpReply, streamID, errorCode, errorMessage.constData()); -} - -void QSpdyProtocolHandler::handleSETTINGS(char flags, quint32 /*length*/, const QByteArray &frameData) -{ - Q_ASSERT(frameData.count() > 0); - - SETTINGS_Flags settingsFlags = static_cast<SETTINGS_Flags>(flags); - if (settingsFlags & FLAG_SETTINGS_CLEAR_SETTINGS) { - // ### clear all persistent settings; since we do not persist settings - // as of now, we don't need to clear anything either - } - - qint32 numberOfEntries = fourBytesToInt(frameData.constData()); - Q_ASSERT(numberOfEntries > 0); - for (int a = 0, frameDataIndex = 4; a < numberOfEntries; ++a, frameDataIndex += 8) { - SETTINGS_ID_Flag idFlag = static_cast<SETTINGS_ID_Flag>(frameData[frameDataIndex]); - if (idFlag & FLAG_SETTINGS_PERSIST_VALUE) { - // ### we SHOULD persist the settings here according to the RFC, but we don't have to, - // so implement that later - } // the other value is only sent by us, but not received - - quint32 uniqueID = static_cast<SETTINGS_ID>( - threeBytesToInt(frameData.constData() + frameDataIndex + 1)); - quint32 value = fourBytesToInt(frameData.constData() + frameDataIndex + 4); - switch (uniqueID) { - case SETTINGS_UPLOAD_BANDWIDTH: { - // ignored for now, just an estimated informative value - break; - } - case SETTINGS_DOWNLOAD_BANDWIDTH: { - // ignored for now, just an estimated informative value - break; - } - case SETTINGS_ROUND_TRIP_TIME: { - // ignored for now, just an estimated informative value - break; - } - case SETTINGS_MAX_CONCURRENT_STREAMS: { - m_maxConcurrentStreams = value; - break; - } - case SETTINGS_CURRENT_CWND: { - // ignored for now, just an informative value - break; - } - case SETTINGS_DOWNLOAD_RETRANS_RATE: { - // ignored for now, just an estimated informative value - break; - } - case SETTINGS_INITIAL_WINDOW_SIZE: { - m_initialWindowSize = value; - break; - } - case SETTINGS_CLIENT_CERTIFICATE_VECTOR_SIZE: { - // client certificates are not supported - break; - } - default: - qWarning("found unknown settings value %u", uint(value)); - } - } -} - -void QSpdyProtocolHandler::handlePING(char /*flags*/, quint32 length, const QByteArray &frameData) -{ - // flags are ignored - - Q_ASSERT(length == 4); - Q_UNUSED(length); // silence -Wunused-parameter - quint32 pingID = fourBytesToInt(frameData.constData()); - - // odd numbered IDs must be ignored - if ((pingID & 1) == 0) // is even? - sendPING(pingID); -} - -void QSpdyProtocolHandler::handleGOAWAY(char /*flags*/, quint32 /*length*/, - const QByteArray &frameData) -{ - // flags are ignored - - qint32 statusCode = static_cast<GOAWAY_STATUS>(fourBytesToInt(frameData.constData() + 4)); - QNetworkReply::NetworkError errorCode; - switch (statusCode) { - case GOAWAY_OK: { - errorCode = QNetworkReply::NoError; - break; - } - case GOAWAY_PROTOCOL_ERROR: { - errorCode = QNetworkReply::ProtocolFailure; - break; - } - case GOAWAY_INTERNAL_ERROR: { - errorCode = QNetworkReply::InternalServerError; - break; - } - default: - qWarning("unexpected status code %d", int(statusCode)); - errorCode = QNetworkReply::ProtocolUnknownError; - } - - qint32 lastGoodStreamID = getStreamID(frameData.constData()); - - // emit errors for all replies after the last good stream ID - Q_ASSERT(m_connection); - for (qint32 currentStreamID = lastGoodStreamID + 2; currentStreamID <= m_nextStreamID; - ++currentStreamID) { - QHttpNetworkReply *reply = m_inFlightStreams.value(currentStreamID).second; - Q_ASSERT(reply); - m_connection->d_func()->emitReplyError(m_socket, reply, errorCode); - } - // ### we could make sure a new session is initiated anyhow -} - -void QSpdyProtocolHandler::handleHEADERS(char flags, quint32 /*length*/, - const QByteArray &frameData) -{ - parseHttpHeaders(flags, frameData); -} - -void QSpdyProtocolHandler::handleWINDOW_UPDATE(char /*flags*/, quint32 /*length*/, - const QByteArray &frameData) -{ - qint32 streamID = getStreamID(frameData.constData()); - qint32 deltaWindowSize = fourBytesToInt(frameData.constData() + 4); - - const auto it = m_inFlightStreams.constFind(streamID); - if (it == m_inFlightStreams.cend()) { - sendRST_STREAM(streamID, RST_STREAM_INVALID_STREAM); - return; - } - - QHttpNetworkReply *reply = it.value().second; - Q_ASSERT(reply); - QHttpNetworkReplyPrivate *replyPrivate = reply->d_func(); - Q_ASSERT(replyPrivate); - - // Ignore WINDOW_UPDATE if we are already done. - if (replyPrivate->state == QHttpNetworkReplyPrivate::SPDYHalfClosed || replyPrivate->state == QHttpNetworkReplyPrivate::SPDYClosed) - return; - - replyPrivate->currentlyUploadedDataInWindow = replyPrivate->windowSizeUpload - deltaWindowSize; - uploadData(streamID); // we hopefully can continue to upload -} - - -void QSpdyProtocolHandler::handleDataFrame(const QByteArray &frameHeaders) -{ - Q_ASSERT(frameHeaders.count() >= 8); - - qint32 streamID = getStreamID(frameHeaders.constData()); - const auto it = m_inFlightStreams.constFind(streamID); - if (it == m_inFlightStreams.cend()) { - sendRST_STREAM(streamID, RST_STREAM_INVALID_STREAM); - return; - } - - unsigned char flags = static_cast<unsigned char>(frameHeaders.at(4)); - flags &= 0x3f; - bool flag_fin = flags & 0x01; - bool flag_compress = flags & 0x02; - qint32 length = threeBytesToInt(frameHeaders.constData() + 5); - - QByteArray data; - data.resize(length); - if (!readNextChunk(length, data.data())) { - // put back the frame headers to the buffer - m_spdyBuffer.prepend(frameHeaders); - return; // we couldn't read the whole frame and need to wait - } else { - m_spdyBuffer.clear(); - m_waitingForCompleteStream = false; - } - - HttpMessagePair pair = it.value(); - QHttpNetworkRequest httpRequest = pair.first; - QHttpNetworkReply *httpReply = pair.second; - Q_ASSERT(httpReply != nullptr); - - QHttpNetworkReplyPrivate *replyPrivate = httpReply->d_func(); - - if (replyPrivate->state == QHttpNetworkReplyPrivate::SPDYClosed) { - sendRST_STREAM(streamID, RST_STREAM_STREAM_ALREADY_CLOSED); - return; - } - - // check whether we need to send WINDOW_UPDATE (i.e. tell the sender it can send more) - replyPrivate->currentlyReceivedDataInWindow += length; - qint32 dataLeftInWindow = replyPrivate->windowSizeDownload - replyPrivate->currentlyReceivedDataInWindow; - - if (replyPrivate->currentlyReceivedDataInWindow > 0 - && dataLeftInWindow < replyPrivate->windowSizeDownload / 2) { - - // socket read buffer size is 64K actually, hard coded in the channel - // We can read way more than 64K per socket, because the window size - // here is per stream. - if (replyPrivate->windowSizeDownload >= m_socket->readBufferSize()) { - replyPrivate->windowSizeDownload = m_socket->readBufferSize(); - } else { - replyPrivate->windowSizeDownload *= 1.5; - } - QMetaObject::invokeMethod(this, "sendWINDOW_UPDATE", Qt::QueuedConnection, - Q_ARG(qint32, streamID), - Q_ARG(quint32, replyPrivate->windowSizeDownload)); - // setting the current data count to 0 is a race condition, - // because we call sendWINDOW_UPDATE through the event loop. - // But then again, the whole situation is a race condition because - // we don't know when the packet will arrive at the server; so - // this is most likely good enough here. - replyPrivate->currentlyReceivedDataInWindow = 0; - } - - httpReply->d_func()->compressedData.append(data); - - - replyPrivate->totalProgress += length; - - if (httpRequest.d->autoDecompress && httpReply->d_func()->isCompressed()) { - QByteDataBuffer inDataBuffer; // ### should we introduce one in the http reply? - inDataBuffer.append(data); - qint64 compressedCount = httpReply->d_func()->uncompressBodyData(&inDataBuffer, - &replyPrivate->responseData); - Q_ASSERT(compressedCount >= 0); - Q_UNUSED(compressedCount); // silence -Wunused-variable - } else { - replyPrivate->responseData.append(data); - } - - if (replyPrivate->shouldEmitSignals()) { - emit httpReply->readyRead(); - emit httpReply->dataReadProgress(replyPrivate->totalProgress, replyPrivate->bodyLength); - } - - if (flag_compress) { - qWarning("SPDY level compression is not supported"); - } - - if (flag_fin) { - if (httpReply->d_func()->state != QHttpNetworkReplyPrivate::SPDYHalfClosed) - sendDataFrame(streamID, DataFrame_FLAG_FIN, 0, nullptr); - replyFinished(httpReply, streamID); - } -} - -void QSpdyProtocolHandler::replyFinished(QHttpNetworkReply *httpReply, qint32 streamID) -{ - httpReply->d_func()->state = QHttpNetworkReplyPrivate::SPDYClosed; - httpReply->disconnect(this); - if (httpReply->request().uploadByteDevice()) - httpReply->request().uploadByteDevice()->disconnect(this); - int streamsRemoved = m_inFlightStreams.remove(streamID); - Q_ASSERT(streamsRemoved == 1); - Q_UNUSED(streamsRemoved); // silence -Wunused-variable - emit httpReply->finished(); -} - -void QSpdyProtocolHandler::replyFinishedWithError(QHttpNetworkReply *httpReply, qint32 streamID, - QNetworkReply::NetworkError errorCode, const char *errorMessage) -{ - Q_ASSERT(httpReply); - httpReply->d_func()->state = QHttpNetworkReplyPrivate::SPDYClosed; - httpReply->disconnect(this); - if (httpReply->request().uploadByteDevice()) - httpReply->request().uploadByteDevice()->disconnect(this); - int streamsRemoved = m_inFlightStreams.remove(streamID); - Q_ASSERT(streamsRemoved == 1); - Q_UNUSED(streamsRemoved); // silence -Wunused-variable - emit httpReply->finishedWithError(errorCode, QSpdyProtocolHandler::tr(errorMessage)); -} - -qint32 QSpdyProtocolHandler::generateNextStreamID() -{ - // stream IDs initiated by the client must be odd - m_nextStreamID += 2; - return m_nextStreamID; -} - -QT_END_NAMESPACE - -#endif // !defined(QT_NO_SSL) diff --git a/src/network/access/qspdyprotocolhandler_p.h b/src/network/access/qspdyprotocolhandler_p.h deleted file mode 100644 index 14e2ff388a..0000000000 --- a/src/network/access/qspdyprotocolhandler_p.h +++ /dev/null @@ -1,232 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 BlackBerry Limited. All rights reserved. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSPDYPROTOCOLHANDLER_H -#define QSPDYPROTOCOLHANDLER_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 <QtNetwork/private/qtnetworkglobal_p.h> -#include <private/qabstractprotocolhandler_p.h> -#include <QtNetwork/qnetworkreply.h> -#include <private/qbytedata_p.h> - -#include <zlib.h> - -QT_REQUIRE_CONFIG(http); - -#if !defined(QT_NO_SSL) - -QT_BEGIN_NAMESPACE - -class QHttpNetworkRequest; - -#ifndef HttpMessagePair -typedef QPair<QHttpNetworkRequest, QHttpNetworkReply*> HttpMessagePair; -#endif - -class QSpdyProtocolHandler : public QObject, public QAbstractProtocolHandler { - Q_OBJECT -public: - QSpdyProtocolHandler(QHttpNetworkConnectionChannel *channel); - ~QSpdyProtocolHandler(); - - enum DataFrameFlag { - DataFrame_FLAG_FIN = 0x01, - DataFrame_FLAG_COMPRESS = 0x02 - }; - - Q_DECLARE_FLAGS(DataFrameFlags, DataFrameFlag) - - enum ControlFrameFlag { - ControlFrame_FLAG_FIN = 0x01, - ControlFrame_FLAG_UNIDIRECTIONAL = 0x02 - }; - - Q_DECLARE_FLAGS(ControlFrameFlags, ControlFrameFlag) - - enum SETTINGS_Flag { - FLAG_SETTINGS_CLEAR_SETTINGS = 0x01 - }; - - Q_DECLARE_FLAGS(SETTINGS_Flags, SETTINGS_Flag) - - enum SETTINGS_ID_Flag { - FLAG_SETTINGS_PERSIST_VALUE = 0x01, - FLAG_SETTINGS_PERSISTED = 0x02 - }; - - Q_DECLARE_FLAGS(SETTINGS_ID_Flags, SETTINGS_ID_Flag) - - virtual void _q_receiveReply() override; - virtual void _q_readyRead() override; - virtual bool sendRequest() override; - -private slots: - void _q_uploadDataReadyRead(); - void _q_replyDestroyed(QObject*); - void _q_uploadDataDestroyed(QObject *); - -private: - - enum FrameType { - FrameType_SYN_STREAM = 1, - FrameType_SYN_REPLY = 2, - FrameType_RST_STREAM = 3, - FrameType_SETTINGS = 4, - FrameType_PING = 6, - FrameType_GOAWAY = 7, - FrameType_HEADERS = 8, - FrameType_WINDOW_UPDATE = 9, - FrameType_CREDENTIAL // has a special type - }; - - enum StatusCode { - StatusCode_PROTOCOL_ERROR = 1, - StatusCode_INVALID_STREAM = 2, - StatusCode_REFUSED_STREAM = 3, - StatusCode_UNSUPPORTED_VERSION = 4, - StatusCode_CANCEL = 5, - StatusCode_INTERNAL_ERROR = 6, - StatusCode_FLOW_CONTROL_ERROR = 7, - StatusCode_STREAM_IN_USE = 8, - StatusCode_STREAM_ALREADY_CLOSED = 9, - StatusCode_INVALID_CREDENTIALS = 10, - StatusCode_FRAME_TOO_LARGE = 11 - }; - - enum SETTINGS_ID { - SETTINGS_UPLOAD_BANDWIDTH = 1, - SETTINGS_DOWNLOAD_BANDWIDTH = 2, - SETTINGS_ROUND_TRIP_TIME = 3, - SETTINGS_MAX_CONCURRENT_STREAMS = 4, - SETTINGS_CURRENT_CWND = 5, - SETTINGS_DOWNLOAD_RETRANS_RATE = 6, - SETTINGS_INITIAL_WINDOW_SIZE = 7, - SETTINGS_CLIENT_CERTIFICATE_VECTOR_SIZE = 8 - }; - - enum GOAWAY_STATUS { - GOAWAY_OK = 0, - GOAWAY_PROTOCOL_ERROR = 1, - GOAWAY_INTERNAL_ERROR = 11 - }; - - enum RST_STREAM_STATUS_CODE { - RST_STREAM_PROTOCOL_ERROR = 1, - RST_STREAM_INVALID_STREAM = 2, - RST_STREAM_REFUSED_STREAM = 3, - RST_STREAM_UNSUPPORTED_VERSION = 4, - RST_STREAM_CANCEL = 5, - RST_STREAM_INTERNAL_ERROR = 6, - RST_STREAM_FLOW_CONTROL_ERROR = 7, - RST_STREAM_STREAM_IN_USE = 8, - RST_STREAM_STREAM_ALREADY_CLOSED = 9, - RST_STREAM_INVALID_CREDENTIALS = 10, - RST_STREAM_FRAME_TOO_LARGE = 11 - }; - - quint64 bytesAvailable() const; - bool readNextChunk(qint64 length, char *sink); - - void sendControlFrame(FrameType type, ControlFrameFlags flags, const char *data, quint32 length); - - void sendSYN_STREAM(const HttpMessagePair &pair, qint32 streamID, - qint32 associatedToStreamID); - void sendRST_STREAM(qint32 streamID, RST_STREAM_STATUS_CODE statusCode); - void sendPING(quint32 pingID); - - bool uploadData(qint32 streamID); - Q_INVOKABLE void sendWINDOW_UPDATE(qint32 streamID, quint32 deltaWindowSize); - - qint64 sendDataFrame(qint32 streamID, DataFrameFlags flags, quint32 length, - const char *data); - - QByteArray composeHeader(const QHttpNetworkRequest &request); - bool uncompressHeader(const QByteArray &input, QByteArray *output); - - void handleControlFrame(const QByteArray &frameHeaders); - void handleDataFrame(const QByteArray &frameHeaders); - - void handleSYN_STREAM(char, quint32, const QByteArray &frameData); - void handleSYN_REPLY(char flags, quint32, const QByteArray &frameData); - void handleRST_STREAM(char flags, quint32 length, const QByteArray &frameData); - void handleSETTINGS(char flags, quint32 length, const QByteArray &frameData); - void handlePING(char, quint32 length, const QByteArray &frameData); - void handleGOAWAY(char flags, quint32, const QByteArray &frameData); - void handleHEADERS(char flags, quint32, const QByteArray &frameData); - void handleWINDOW_UPDATE(char, quint32, const QByteArray &frameData); - - qint32 generateNextStreamID(); - void parseHttpHeaders(char flags, const QByteArray &frameData); - - void replyFinished(QHttpNetworkReply *httpReply, qint32 streamID); - void replyFinishedWithError(QHttpNetworkReply *httpReply, qint32 streamID, - QNetworkReply::NetworkError errorCode, const char *errorMessage); - - qint32 m_nextStreamID; - QHash<quint32, HttpMessagePair> m_inFlightStreams; - qint32 m_maxConcurrentStreams; - quint32 m_initialWindowSize; - QByteDataBuffer m_spdyBuffer; - bool m_waitingForCompleteStream; - z_stream m_deflateStream; - z_stream m_inflateStream; - QHash<QObject *, qint32> m_streamIDs; -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(QSpdyProtocolHandler::DataFrameFlags) -Q_DECLARE_OPERATORS_FOR_FLAGS(QSpdyProtocolHandler::ControlFrameFlags) -Q_DECLARE_OPERATORS_FOR_FLAGS(QSpdyProtocolHandler::SETTINGS_Flags) -Q_DECLARE_OPERATORS_FOR_FLAGS(QSpdyProtocolHandler::SETTINGS_ID_Flags) - -QT_END_NAMESPACE - -#endif // !defined(QT_NO_SSL) - -#endif // QSPDYPROTOCOLHANDLER_H diff --git a/src/network/bearer/bearer.pri b/src/network/bearer/bearer.pri deleted file mode 100644 index d58d5ec168..0000000000 --- a/src/network/bearer/bearer.pri +++ /dev/null @@ -1,19 +0,0 @@ -# Qt network bearer management module - -HEADERS += bearer/qnetworkconfiguration.h \ - bearer/qnetworksession.h \ - bearer/qnetworkconfigmanager.h \ - bearer/qnetworkconfigmanager_p.h \ - bearer/qnetworkconfiguration_p.h \ - bearer/qnetworksession_p.h \ - bearer/qbearerengine_p.h \ - bearer/qbearerplugin_p.h \ - bearer/qsharednetworksession_p.h - -SOURCES += bearer/qnetworksession.cpp \ - bearer/qnetworkconfigmanager.cpp \ - bearer/qnetworkconfiguration.cpp \ - bearer/qnetworkconfigmanager_p.cpp \ - bearer/qbearerengine.cpp \ - bearer/qbearerplugin.cpp \ - bearer/qsharednetworksession.cpp diff --git a/src/network/bearer/qbearerengine.cpp b/src/network/bearer/qbearerengine.cpp deleted file mode 100644 index 06bf449611..0000000000 --- a/src/network/bearer/qbearerengine.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qbearerengine_p.h" -#include <QtCore/private/qlocking_p.h> - -#include <algorithm> - -#ifndef QT_NO_BEARERMANAGEMENT - -QT_BEGIN_NAMESPACE - -static void cleanUpConfigurations(QHash<QString, QNetworkConfigurationPrivatePointer> &configurations) -{ - for (auto &ptr : qExchange(configurations, {})) { - ptr->isValid = false; - ptr->id.clear(); - } -} - -static bool hasUsedConfiguration(const QHash<QString, QNetworkConfigurationPrivatePointer> &configurations) -{ - auto isUsed = [](const QNetworkConfigurationPrivatePointer &ptr) { - return ptr->ref.loadRelaxed() > 1; - }; - const auto end = configurations.end(); - return std::find_if(configurations.begin(), end, isUsed) != end; -} - -QBearerEngine::QBearerEngine(QObject *parent) - : QObject(parent) -{ -} - -QBearerEngine::~QBearerEngine() -{ - cleanUpConfigurations(snapConfigurations); - cleanUpConfigurations(accessPointConfigurations); - cleanUpConfigurations(userChoiceConfigurations); -} - -bool QBearerEngine::requiresPolling() const -{ - return false; -} - -/* - Returns \c true if configurations are in use; otherwise returns \c false. - - If configurations are in use and requiresPolling() returns \c true, polling will be enabled for - this engine. -*/ -bool QBearerEngine::configurationsInUse() const -{ - const auto locker = qt_scoped_lock(mutex); - return hasUsedConfiguration(accessPointConfigurations) - || hasUsedConfiguration(snapConfigurations) - || hasUsedConfiguration(userChoiceConfigurations); -} - -QT_END_NAMESPACE - -#include "moc_qbearerengine_p.cpp" - -#endif // QT_NO_BEARERMANAGEMENT diff --git a/src/network/bearer/qbearerengine_p.h b/src/network/bearer/qbearerengine_p.h deleted file mode 100644 index c69f478b26..0000000000 --- a/src/network/bearer/qbearerengine_p.h +++ /dev/null @@ -1,115 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QBEARERENGINE_P_H -#define QBEARERENGINE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtNetwork/private/qtnetworkglobal_p.h> -#include "qnetworkconfiguration_p.h" -#include "qnetworksession.h" -#include "qnetworkconfigmanager.h" - -#include <QtCore/qobject.h> -#include <QtCore/qglobal.h> -#include <QtCore/qlist.h> -#include <QtCore/qstring.h> -#include <QtCore/qhash.h> -#include <QtCore/qsharedpointer.h> -#include <QtCore/qmutex.h> - -#ifndef QT_NO_BEARERMANAGEMENT - -QT_BEGIN_NAMESPACE - -class QNetworkConfiguration; - -class Q_NETWORK_EXPORT QBearerEngine : public QObject -{ - Q_OBJECT - - friend class QNetworkConfigurationManagerPrivate; - -public: - explicit QBearerEngine(QObject *parent = nullptr); - virtual ~QBearerEngine(); - - virtual bool hasIdentifier(const QString &id) = 0; - - virtual QNetworkConfigurationManager::Capabilities capabilities() const = 0; - - virtual QNetworkSessionPrivate *createSessionBackend() = 0; - - virtual QNetworkConfigurationPrivatePointer defaultConfiguration() = 0; - - virtual bool requiresPolling() const; - bool configurationsInUse() const; - -Q_SIGNALS: - void configurationAdded(QNetworkConfigurationPrivatePointer config); - void configurationRemoved(QNetworkConfigurationPrivatePointer config); - void configurationChanged(QNetworkConfigurationPrivatePointer config); - void updateCompleted(); - -protected: - //this table contains an up to date list of all configs at any time. - //it must be updated if configurations change, are added/removed or - //the members of ServiceNetworks change - QHash<QString, QNetworkConfigurationPrivatePointer> accessPointConfigurations; - QHash<QString, QNetworkConfigurationPrivatePointer> snapConfigurations; - QHash<QString, QNetworkConfigurationPrivatePointer> userChoiceConfigurations; - - mutable QRecursiveMutex mutex; -}; - -QT_END_NAMESPACE - -#endif // QT_NO_BEARERMANAGEMENT - -#endif // QBEARERENGINE_P_H diff --git a/src/network/bearer/qbearerplugin.cpp b/src/network/bearer/qbearerplugin.cpp deleted file mode 100644 index ec0d06e94c..0000000000 --- a/src/network/bearer/qbearerplugin.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qbearerplugin_p.h" - -#ifndef QT_NO_BEARERMANAGEMENT - -QT_BEGIN_NAMESPACE - -QBearerEnginePlugin::QBearerEnginePlugin(QObject *parent) - : QObject(parent) -{ -} - -QBearerEnginePlugin::~QBearerEnginePlugin() -{ -} - -QT_END_NAMESPACE - -#endif // QT_NO_BEARERMANAGEMENT diff --git a/src/network/bearer/qnetworkconfigmanager.cpp b/src/network/bearer/qnetworkconfigmanager.cpp deleted file mode 100644 index eb3eb59c83..0000000000 --- a/src/network/bearer/qnetworkconfigmanager.cpp +++ /dev/null @@ -1,389 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtNetwork/private/qtnetworkglobal_p.h> - -#include "qnetworkconfigmanager.h" - -#include "qnetworkconfigmanager_p.h" -#include "qbearerengine_p.h" - -#include <QtCore/qstringlist.h> -#include <QtCore/qcoreapplication.h> -#include <QtCore/qmutex.h> -#include <QtCore/qthread.h> -#include <QtCore/private/qcoreapplication_p.h> - -#ifndef QT_NO_BEARERMANAGEMENT - -QT_BEGIN_NAMESPACE - -static QBasicAtomicPointer<QNetworkConfigurationManagerPrivate> connManager_ptr; -static QBasicAtomicInt appShutdown; - -static void connManager_prepare() -{ - int shutdown = appShutdown.fetchAndStoreAcquire(0); - Q_ASSERT(shutdown == 0 || shutdown == 1); - Q_UNUSED(shutdown); -} - -static void connManager_cleanup() -{ - // this is not atomic or thread-safe! - int shutdown = appShutdown.fetchAndStoreAcquire(1); - Q_ASSERT(shutdown == 0); - Q_UNUSED(shutdown); - QNetworkConfigurationManagerPrivate *cmp = connManager_ptr.fetchAndStoreAcquire(nullptr); - if (cmp) - cmp->cleanup(); -} - -void QNetworkConfigurationManagerPrivate::addPreAndPostRoutine() -{ - qAddPreRoutine(connManager_prepare); - qAddPostRoutine(connManager_cleanup); -} - -QNetworkConfigurationManagerPrivate *qNetworkConfigurationManagerPrivate() -{ - QNetworkConfigurationManagerPrivate *ptr = connManager_ptr.loadAcquire(); - int shutdown = appShutdown.loadAcquire(); - if (!ptr && !shutdown) { - static QBasicMutex connManager_mutex; - QMutexLocker locker(&connManager_mutex); - if (!(ptr = connManager_ptr.loadAcquire())) { - ptr = new QNetworkConfigurationManagerPrivate; - - if (QCoreApplicationPrivate::mainThread() == QThread::currentThread()) { - // right thread or no main thread yet - ptr->addPreAndPostRoutine(); - ptr->initialize(); - } else { - // wrong thread, we need to make the main thread do this - QObject *obj = new QObject; - QObject::connect(obj, SIGNAL(destroyed()), ptr, SLOT(addPreAndPostRoutine()), Qt::DirectConnection); - ptr->initialize(); // this moves us to the right thread - obj->moveToThread(QCoreApplicationPrivate::mainThread()); - obj->deleteLater(); - } - - connManager_ptr.storeRelease(ptr); - } - } - return ptr; -} - -/*! - \class QNetworkConfigurationManager - \obsolete - - \brief The QNetworkConfigurationManager class manages the network configurations provided - by the system. - - \since 4.7 - - \inmodule QtNetwork - \ingroup network - - QNetworkConfigurationManager provides access to the network configurations known to the system and - enables applications to detect the system capabilities (with regards to network sessions) at runtime. - - A QNetworkConfiguration abstracts a set of configuration options describing how a - network interface has to be configured to connect to a particular target network. - QNetworkConfigurationManager maintains and updates the global list of - QNetworkConfigurations. Applications can access and filter this list via - allConfigurations(). If a new configuration is added or an existing one is removed or changed - the configurationAdded(), configurationRemoved() and configurationChanged() signals are emitted - respectively. - - The defaultConfiguration() can be used when intending to immediately create a new - network session without caring about the particular configuration. It returns - a \l QNetworkConfiguration::Discovered configuration. If there are not any - discovered ones an invalid configuration is returned. - - Some configuration updates may require some time to perform updates. A WLAN scan is - such an example. Unless the platform performs internal updates it may be required to - manually trigger configuration updates via QNetworkConfigurationManager::updateConfigurations(). - The completion of the update process is indicated by emitting the updateCompleted() - signal. The update process ensures that every existing QNetworkConfiguration instance - is updated. There is no need to ask for a renewed configuration list via allConfigurations(). - - \sa QNetworkConfiguration -*/ - -/*! - \fn void QNetworkConfigurationManager::configurationAdded(const QNetworkConfiguration &config) - - This signal is emitted whenever a new network configuration is added to the system. The new - configuration is specified by \a config. -*/ - -/*! - \fn void QNetworkConfigurationManager::configurationRemoved(const QNetworkConfiguration &config) - - This signal is emitted when a configuration is about to be removed from the system. The removed - configuration, specified by \a config, is invalid but retains name and identifier. -*/ - -/*! - \fn void QNetworkConfigurationManager::updateCompleted() - - This signal is emitted when the configuration update has been completed. Such an update can - be initiated via \l updateConfigurations(). -*/ - -/*! \fn void QNetworkConfigurationManager::configurationChanged(const QNetworkConfiguration &config) - - This signal is emitted when the \l {QNetworkConfiguration::state()}{state} of \a config changes. -*/ - -/*! - \fn void QNetworkConfigurationManager::onlineStateChanged(bool isOnline) - - This signal is emitted when the device changes from online to offline mode or vice versa. - \a isOnline represents the new state of the device. - - The state is considered to be online for as long as - \l{allConfigurations()}{allConfigurations}(QNetworkConfiguration::Active) returns a list with - at least one entry. -*/ - -/*! - \enum QNetworkConfigurationManager::Capability - - Specifies the system capabilities of the bearer API. The possible values are: - - \value CanStartAndStopInterfaces Network sessions and their underlying access points can be - started and stopped. If this flag is not set QNetworkSession - can only monitor but not influence the state of access points. - On some platforms this feature may require elevated user - permissions. This option is platform specific and may not - always be available. - \value DirectConnectionRouting Network sessions and their sockets can be bound to a - particular network interface. Any packet that passes through - the socket goes to the specified network interface and thus - disregards standard routing table entries. This may be useful - when two interfaces can reach overlapping IP ranges or an - application has specific needs in regards to target networks. - This option is platform specific and may not always be - available. - \value SystemSessionSupport If this flag is set the underlying platform ensures that a - network interface is not shut down until the last network - session has been \l{QNetworkSession::close()}{closed()}. This - works across multiple processes. If the platform session - support is missing this API can only ensure the above behavior - for network sessions within the same process. - In general mobile platforms have such - support whereas most desktop platform lack this capability. - \value ApplicationLevelRoaming The system gives applications control over the systems roaming - behavior. Applications can initiate roaming (in case the - current link is not suitable) and are consulted if the system - has identified a more suitable access point. - \value ForcedRoaming The system disconnects an existing access point and reconnects - via a more suitable one. The application does not have any - control over this process and has to reconnect its active - sockets. - \value DataStatistics If this flag is set QNetworkSession can provide statistics - about transmitted and received data. - \value NetworkSessionRequired If this flag is set the platform requires that a network - session is created before network operations can be performed. -*/ - -/*! - Constructs a QNetworkConfigurationManager with the given \a parent. - - Note that to ensure a valid list of current configurations immediately available, updating - is done during construction which causes some delay. -*/ -QNetworkConfigurationManager::QNetworkConfigurationManager(QObject *parent) - : QObject(parent) -{ - QNetworkConfigurationManagerPrivate *priv = qNetworkConfigurationManagerPrivate(); - if (priv) { - connect(priv, SIGNAL(configurationAdded(QNetworkConfiguration)), - this, SIGNAL(configurationAdded(QNetworkConfiguration))); - connect(priv, SIGNAL(configurationRemoved(QNetworkConfiguration)), - this, SIGNAL(configurationRemoved(QNetworkConfiguration))); - connect(priv, SIGNAL(configurationChanged(QNetworkConfiguration)), - this, SIGNAL(configurationChanged(QNetworkConfiguration))); - connect(priv, SIGNAL(onlineStateChanged(bool)), - this, SIGNAL(onlineStateChanged(bool))); - connect(priv, SIGNAL(configurationUpdateComplete()), - this, SIGNAL(updateCompleted())); - - priv->enablePolling(); - } -} - -/*! - Frees the resources associated with the QNetworkConfigurationManager object. -*/ -QNetworkConfigurationManager::~QNetworkConfigurationManager() -{ - QNetworkConfigurationManagerPrivate *priv = qNetworkConfigurationManagerPrivate(); - if (priv) - priv->disablePolling(); -} - - -/*! - Returns the default configuration to be used. This function always returns a discovered - configuration; otherwise an invalid configuration. - - In some cases it may be required to call updateConfigurations() and wait for the - updateCompleted() signal before calling this function. - - \sa allConfigurations() -*/ -QNetworkConfiguration QNetworkConfigurationManager::defaultConfiguration() const -{ - QNetworkConfigurationManagerPrivate *priv = qNetworkConfigurationManagerPrivate(); - if (priv) - return priv->defaultConfiguration(); - - return QNetworkConfiguration(); -} - -/*! - Returns the list of configurations which comply with the given \a filter. - - By default this function returns all (defined and undefined) configurations. - - A wireless network with a particular SSID may only be accessible in a - certain area despite the fact that the system has a valid configuration - for it. Therefore the filter flag may be used to limit the list to - discovered and possibly connected configurations only. - - If \a filter is set to zero this function returns all possible configurations. - - Note that this function returns the states for all configurations as they are known at - the time of this function call. If for instance a configuration of type WLAN is defined - the system may have to perform a WLAN scan in order to determine whether it is - actually available. To obtain the most accurate state updateConfigurations() should - be used to update each configuration's state. Note that such an update may require - some time. It's completion is signalled by updateCompleted(). In the absence of a - configuration update this function returns the best estimate at the time of the call. - Therefore, if WLAN configurations are of interest, it is recommended that - updateConfigurations() is called once after QNetworkConfigurationManager - instantiation (WLAN scans are too time consuming to perform in constructor). - After this the data is kept automatically up-to-date as the system reports - any changes. -*/ -QList<QNetworkConfiguration> QNetworkConfigurationManager::allConfigurations(QNetworkConfiguration::StateFlags filter) const -{ - QNetworkConfigurationManagerPrivate *priv = qNetworkConfigurationManagerPrivate(); - if (priv) - return priv->allConfigurations(filter); - - return QList<QNetworkConfiguration>(); -} - -/*! - Returns the QNetworkConfiguration for \a identifier; otherwise returns an - invalid QNetworkConfiguration. - - \sa QNetworkConfiguration::identifier() -*/ -QNetworkConfiguration QNetworkConfigurationManager::configurationFromIdentifier(const QString &identifier) const -{ - QNetworkConfigurationManagerPrivate *priv = qNetworkConfigurationManagerPrivate(); - if (priv) - return priv->configurationFromIdentifier(identifier); - - return QNetworkConfiguration(); -} - -/*! - Returns \c true if the system is considered to be connected to another device via an active - network interface; otherwise returns \c false. - - This is equivalent to the following code snippet: - - \snippet code/src_network_bearer_qnetworkconfigmanager.cpp 0 - - \sa onlineStateChanged() -*/ -bool QNetworkConfigurationManager::isOnline() const -{ - QNetworkConfigurationManagerPrivate *priv = qNetworkConfigurationManagerPrivate(); - if (priv) - return priv->isOnline(); - - return false; -} - -/*! - Returns the capabilities supported by the current platform. -*/ -QNetworkConfigurationManager::Capabilities QNetworkConfigurationManager::capabilities() const -{ - QNetworkConfigurationManagerPrivate *priv = qNetworkConfigurationManagerPrivate(); - if (priv) - return priv->capabilities(); - - return {}; -} - -/*! - Initiates an update of all configurations. This may be used to initiate WLAN scans or other - time consuming updates which may be required to obtain the correct state for configurations. - - This call is asynchronous. On completion of this update the updateCompleted() signal is - emitted. If new configurations are discovered or old ones were removed or changed the update - process may trigger the emission of one or multiple configurationAdded(), - configurationRemoved() and configurationChanged() signals. - - If a configuration state changes as a result of this update all existing QNetworkConfiguration - instances are updated automatically. - - \sa allConfigurations() -*/ -void QNetworkConfigurationManager::updateConfigurations() -{ - QNetworkConfigurationManagerPrivate *priv = qNetworkConfigurationManagerPrivate(); - if (priv) - priv->performAsyncConfigurationUpdate(); -} - -QT_END_NAMESPACE - -#include "moc_qnetworkconfigmanager.cpp" - -#endif // QT_NO_BEARERMANAGEMENT diff --git a/src/network/bearer/qnetworkconfigmanager.h b/src/network/bearer/qnetworkconfigmanager.h deleted file mode 100644 index b8f09f3d68..0000000000 --- a/src/network/bearer/qnetworkconfigmanager.h +++ /dev/null @@ -1,109 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QNETWORKCONFIGMANAGER_H -#define QNETWORKCONFIGMANAGER_H - -#if 0 -#pragma qt_class(QNetworkConfigurationManager) -#endif - -#include <QtNetwork/qtnetworkglobal.h> -#include <QtCore/qobject.h> -#include <QtNetwork/qnetworkconfiguration.h> - -QT_WARNING_PUSH -QT_WARNING_DISABLE_DEPRECATED - -#ifndef QT_NO_BEARERMANAGEMENT - -QT_BEGIN_NAMESPACE - -class QNetworkConfigurationManagerPrivate; -class QT_DEPRECATED_BEARER_MANAGEMENT Q_NETWORK_EXPORT QNetworkConfigurationManager : public QObject -{ - Q_OBJECT - -public: - enum Capability { - CanStartAndStopInterfaces = 0x00000001, - DirectConnectionRouting = 0x00000002, - SystemSessionSupport = 0x00000004, - ApplicationLevelRoaming = 0x00000008, - ForcedRoaming = 0x00000010, - DataStatistics = 0x00000020, - NetworkSessionRequired = 0x00000040 - }; - - Q_DECLARE_FLAGS(Capabilities, Capability) - - explicit QNetworkConfigurationManager(QObject *parent = nullptr); - virtual ~QNetworkConfigurationManager(); - - QNetworkConfigurationManager::Capabilities capabilities() const; - - QNetworkConfiguration defaultConfiguration() const; - QList<QNetworkConfiguration> allConfigurations(QNetworkConfiguration::StateFlags flags = QNetworkConfiguration::StateFlags()) const; - QNetworkConfiguration configurationFromIdentifier(const QString &identifier) const; - - bool isOnline() const; - -public Q_SLOTS: - void updateConfigurations(); - -Q_SIGNALS: - void configurationAdded(const QNetworkConfiguration &config); - void configurationRemoved(const QNetworkConfiguration &config); - void configurationChanged(const QNetworkConfiguration &config); - void onlineStateChanged(bool isOnline); - void updateCompleted(); - -private: - Q_DISABLE_COPY(QNetworkConfigurationManager) -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(QNetworkConfigurationManager::Capabilities) - -QT_END_NAMESPACE - -#endif // QT_NO_BEARERMANAGEMENT - -QT_WARNING_POP - -#endif // QNETWORKCONFIGMANAGER_H diff --git a/src/network/bearer/qnetworkconfigmanager_p.cpp b/src/network/bearer/qnetworkconfigmanager_p.cpp deleted file mode 100644 index f0aa452dd3..0000000000 --- a/src/network/bearer/qnetworkconfigmanager_p.cpp +++ /dev/null @@ -1,517 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qnetworkconfigmanager_p.h" -#include "qbearerplugin_p.h" - -#include <QtCore/qdebug.h> -#include <QtCore/qtimer.h> -#include <QtCore/qstringlist.h> -#include <QtCore/qthread.h> -#include <QtCore/private/qcoreapplication_p.h> -#include <QtCore/private/qlocking_p.h> -#include <QtCore/private/qthread_p.h> - -#include <QtCore/qbytearray.h> -#include <QtCore/qglobal.h> - -#include <utility> - - -#ifndef QT_NO_BEARERMANAGEMENT - -QT_BEGIN_NAMESPACE - -QNetworkConfigurationManagerPrivate::QNetworkConfigurationManagerPrivate() - : QObject(), pollTimer(nullptr), - loader(QBearerEngineFactoryInterface_iid, QLatin1String("/bearer")), - forcedPolling(0), firstUpdate(true) -{ - qRegisterMetaType<QNetworkConfiguration>(); - qRegisterMetaType<QNetworkConfigurationPrivatePointer>(); -} - -void QNetworkConfigurationManagerPrivate::initialize() -{ - //Two stage construction, because we only want to do this heavyweight work for the winner of the Q_GLOBAL_STATIC race. - bearerThread = new QDaemonThread(); - bearerThread->setObjectName(QStringLiteral("Qt bearer thread")); - - bearerThread->moveToThread(QCoreApplicationPrivate::mainThread()); // because cleanup() is called in main thread context. - moveToThread(bearerThread); - bearerThread->start(); - updateConfigurations(); -} - -QNetworkConfigurationManagerPrivate::~QNetworkConfigurationManagerPrivate() -{ - QMutexLocker locker(&mutex); - - qDeleteAll(sessionEngines); - sessionEngines.clear(); - if (bearerThread) - bearerThread->quit(); -} - -void QNetworkConfigurationManagerPrivate::cleanup() -{ - QThread* thread = bearerThread; - deleteLater(); - if (thread->wait(QDeadlineTimer(5000))) - delete thread; -} - -QNetworkConfiguration QNetworkConfigurationManagerPrivate::defaultConfiguration() const -{ - QMutexLocker locker(&mutex); - - for (QBearerEngine *engine : sessionEngines) { - QNetworkConfigurationPrivatePointer ptr = engine->defaultConfiguration(); - if (ptr) { - QNetworkConfiguration config; - config.d = ptr; - return config; - } - } - - // Engines don't have a default configuration. - - // Return first active snap - QNetworkConfigurationPrivatePointer defaultConfiguration; - - for (QBearerEngine *engine : sessionEngines) { - const auto locker = qt_scoped_lock(engine->mutex); - - for (const auto &ptr : qAsConst(engine->snapConfigurations)) { - const auto locker = qt_scoped_lock(ptr->mutex); - - if ((ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) { - QNetworkConfiguration config; - config.d = ptr; - return config; - } else if (!defaultConfiguration) { - if ((ptr->state & QNetworkConfiguration::Discovered) == QNetworkConfiguration::Discovered) - defaultConfiguration = ptr; - } - } - } - - // No Active SNAPs return first Discovered SNAP. - if (defaultConfiguration) { - QNetworkConfiguration config; - config.d = defaultConfiguration; - return config; - } - - /* - No Active or Discovered SNAPs, find the perferred access point. - The following priority order is used: - - 1. Active Ethernet - 2. Active WLAN - 3. Active Other - 4. Discovered Ethernet - 5. Discovered WLAN - 6. Discovered Other - */ - - for (QBearerEngine *engine : sessionEngines) { - - QMutexLocker locker(&engine->mutex); - - for (const auto &ptr : qAsConst(engine->accessPointConfigurations)) { - - QMutexLocker configLocker(&ptr->mutex); - QNetworkConfiguration::BearerType bearerType = ptr->bearerType; - - if ((ptr->state & QNetworkConfiguration::Discovered) == QNetworkConfiguration::Discovered) { - if (!defaultConfiguration) { - defaultConfiguration = ptr; - } else { - QMutexLocker defaultConfigLocker(&defaultConfiguration->mutex); - - if (defaultConfiguration->state == ptr->state) { - switch (defaultConfiguration->bearerType) { - case QNetworkConfiguration::BearerEthernet: - // do nothing - break; - case QNetworkConfiguration::BearerWLAN: - // Ethernet beats WLAN - defaultConfiguration = ptr; - break; - default: - // Ethernet and WLAN beats other - if (bearerType == QNetworkConfiguration::BearerEthernet || - bearerType == QNetworkConfiguration::BearerWLAN) { - defaultConfiguration = ptr; - } - } - } else { - // active beats discovered - if ((defaultConfiguration->state & QNetworkConfiguration::Active) != - QNetworkConfiguration::Active) { - defaultConfiguration = ptr; - } - } - } - } - } - } - - // No Active InternetAccessPoint return first Discovered InternetAccessPoint. - if (defaultConfiguration) { - QNetworkConfiguration config; - config.d = defaultConfiguration; - return config; - } - - return QNetworkConfiguration(); -} - -QList<QNetworkConfiguration> QNetworkConfigurationManagerPrivate::allConfigurations(QNetworkConfiguration::StateFlags filter) const -{ - QList<QNetworkConfiguration> result; - - QMutexLocker locker(&mutex); - - for (QBearerEngine *engine : sessionEngines) { - - const auto locker = qt_scoped_lock(engine->mutex); - - //find all InternetAccessPoints - for (const auto &ptr : qAsConst(engine->accessPointConfigurations)) { - const auto locker = qt_scoped_lock(ptr->mutex); - - if ((ptr->state & filter) == filter) { - QNetworkConfiguration pt; - pt.d = ptr; - result << pt; - } - } - - //find all service networks - for (const auto &ptr : qAsConst(engine->snapConfigurations)) { - const auto locker = qt_scoped_lock(ptr->mutex); - - if ((ptr->state & filter) == filter) { - QNetworkConfiguration pt; - pt.d = ptr; - result << pt; - } - } - } - - return result; -} - -QNetworkConfiguration QNetworkConfigurationManagerPrivate::configurationFromIdentifier(const QString &identifier) const -{ - QNetworkConfiguration item; - - const auto locker = qt_scoped_lock(mutex); - - for (QBearerEngine *engine : sessionEngines) { - const auto locker = qt_scoped_lock(engine->mutex); - if (auto ptr = engine->accessPointConfigurations.value(identifier)) { - item.d = std::move(ptr); - break; - } - if (auto ptr = engine->snapConfigurations.value(identifier)) { - item.d = std::move(ptr); - break; - } - if (auto ptr = engine->userChoiceConfigurations.value(identifier)) { - item.d = std::move(ptr); - break; - } - } - - return item; -} - -bool QNetworkConfigurationManagerPrivate::isOnline() const -{ - const auto locker = qt_scoped_lock(mutex); - - // We need allConfigurations since onlineConfigurations is filled with queued connections - // and thus is not always (more importantly just after creation) up to date - return !allConfigurations(QNetworkConfiguration::Active).isEmpty(); -} - -QNetworkConfigurationManager::Capabilities QNetworkConfigurationManagerPrivate::capabilities() const -{ - const auto locker = qt_scoped_lock(mutex); - - QNetworkConfigurationManager::Capabilities capFlags; - - for (QBearerEngine *engine : sessionEngines) - capFlags |= engine->capabilities(); - - return capFlags; -} - -void QNetworkConfigurationManagerPrivate::configurationAdded(QNetworkConfigurationPrivatePointer ptr) -{ - const auto locker = qt_scoped_lock(mutex); - - if (!firstUpdate) { - QNetworkConfiguration item; - item.d = ptr; - emit configurationAdded(item); - } - - auto ptrLocker = qt_unique_lock(ptr->mutex); - if (ptr->state == QNetworkConfiguration::Active) { - const auto id = ptr->id; - ptrLocker.unlock(); - onlineConfigurations.insert(id); - if (!firstUpdate && onlineConfigurations.count() == 1) - emit onlineStateChanged(true); - } -} - -void QNetworkConfigurationManagerPrivate::configurationRemoved(QNetworkConfigurationPrivatePointer ptr) -{ - const auto locker = qt_scoped_lock(mutex); - - { - const auto locker = qt_scoped_lock(ptr->mutex); - ptr->isValid = false; - } - - if (!firstUpdate) { - QNetworkConfiguration item; - item.d = ptr; - emit configurationRemoved(item); - } - - onlineConfigurations.remove(ptr->id); - if (!firstUpdate && onlineConfigurations.isEmpty()) - emit onlineStateChanged(false); -} - -void QNetworkConfigurationManagerPrivate::configurationChanged(QNetworkConfigurationPrivatePointer ptr) -{ - const auto locker = qt_scoped_lock(mutex); - - if (!firstUpdate) { - QNetworkConfiguration item; - item.d = ptr; - emit configurationChanged(item); - } - - bool previous = !onlineConfigurations.isEmpty(); - - { - const auto locker = qt_scoped_lock(ptr->mutex); - if (ptr->state == QNetworkConfiguration::Active) - onlineConfigurations.insert(ptr->id); - else - onlineConfigurations.remove(ptr->id); - } - - bool online = !onlineConfigurations.isEmpty(); - - if (!firstUpdate && online != previous) - emit onlineStateChanged(online); -} - -void QNetworkConfigurationManagerPrivate::updateConfigurations() -{ - typedef QMultiMap<int, QString> PluginKeyMap; - typedef PluginKeyMap::const_iterator PluginKeyMapConstIterator; - - auto locker = qt_unique_lock(mutex); - - if (firstUpdate) { - if (qobject_cast<QBearerEngine *>(sender())) - return; - - updating = false; - - bool envOK = false; - const int skipGeneric = qEnvironmentVariableIntValue("QT_EXCLUDE_GENERIC_BEARER", &envOK); - QBearerEngine *generic = nullptr; - QFactoryLoader *l = &loader; - const PluginKeyMap keyMap = l->keyMap(); - const PluginKeyMapConstIterator cend = keyMap.constEnd(); - QStringList addedEngines; - for (PluginKeyMapConstIterator it = keyMap.constBegin(); it != cend; ++it) { - const QString &key = it.value(); - if (addedEngines.contains(key)) - continue; - - addedEngines.append(key); - if (QBearerEngine *engine = qLoadPlugin<QBearerEngine, QBearerEnginePlugin>(l, key)) { - if (key == QLatin1String("generic")) - generic = engine; - else - sessionEngines.append(engine); - - engine->moveToThread(bearerThread); - - connect(engine, SIGNAL(updateCompleted()), - this, SLOT(updateConfigurations()), - Qt::QueuedConnection); - connect(engine, SIGNAL(configurationAdded(QNetworkConfigurationPrivatePointer)), - this, SLOT(configurationAdded(QNetworkConfigurationPrivatePointer)), - Qt::QueuedConnection); - connect(engine, SIGNAL(configurationRemoved(QNetworkConfigurationPrivatePointer)), - this, SLOT(configurationRemoved(QNetworkConfigurationPrivatePointer)), - Qt::QueuedConnection); - connect(engine, SIGNAL(configurationChanged(QNetworkConfigurationPrivatePointer)), - this, SLOT(configurationChanged(QNetworkConfigurationPrivatePointer)), - Qt::QueuedConnection); - } - } - - if (generic) { - if (!envOK || skipGeneric <= 0) - sessionEngines.append(generic); - else - delete generic; - } - } - - QBearerEngine *engine = qobject_cast<QBearerEngine *>(sender()); - if (engine && !updatingEngines.isEmpty()) - updatingEngines.remove(engine); - - if (updating && updatingEngines.isEmpty()) { - updating = false; - emit configurationUpdateComplete(); - } - - if (engine && !pollingEngines.isEmpty()) { - pollingEngines.remove(engine); - if (pollingEngines.isEmpty()) - startPolling(); - } - - if (firstUpdate) { - firstUpdate = false; - const QList<QBearerEngine*> enginesToInitialize = sessionEngines; //shallow copy the list in case it is modified when we unlock mutex - locker.unlock(); - for (QBearerEngine* engine : enginesToInitialize) - QMetaObject::invokeMethod(engine, "initialize", Qt::BlockingQueuedConnection); - } -} - -void QNetworkConfigurationManagerPrivate::performAsyncConfigurationUpdate() -{ - const auto locker = qt_scoped_lock(mutex); - - if (sessionEngines.isEmpty()) { - emit configurationUpdateComplete(); - return; - } - - updating = true; - - for (QBearerEngine *engine : qAsConst(sessionEngines)) { - updatingEngines.insert(engine); - QMetaObject::invokeMethod(engine, "requestUpdate"); - } -} - -QList<QBearerEngine *> QNetworkConfigurationManagerPrivate::engines() const -{ - const auto locker = qt_scoped_lock(mutex); - - return sessionEngines; -} - -void QNetworkConfigurationManagerPrivate::startPolling() -{ - const auto locker = qt_scoped_lock(mutex); - if (!pollTimer) { - pollTimer = new QTimer(this); - bool ok; - int interval = qEnvironmentVariableIntValue("QT_BEARER_POLL_TIMEOUT", &ok); - if (!ok) - interval = 10000;//default 10 seconds - pollTimer->setInterval(interval); - pollTimer->setSingleShot(true); - connect(pollTimer, SIGNAL(timeout()), this, SLOT(pollEngines())); - } - - if (pollTimer->isActive()) - return; - - for (QBearerEngine *engine : qAsConst(sessionEngines)) { - if (engine->requiresPolling() && (forcedPolling || engine->configurationsInUse())) { - pollTimer->start(); - break; - } - } - performAsyncConfigurationUpdate(); -} - -void QNetworkConfigurationManagerPrivate::pollEngines() -{ - const auto locker = qt_scoped_lock(mutex); - - for (QBearerEngine *engine : qAsConst(sessionEngines)) { - if (engine->requiresPolling() && (forcedPolling || engine->configurationsInUse())) { - pollingEngines.insert(engine); - QMetaObject::invokeMethod(engine, "requestUpdate"); - } - } -} - -void QNetworkConfigurationManagerPrivate::enablePolling() -{ - const auto locker = qt_scoped_lock(mutex); - - ++forcedPolling; - - if (forcedPolling == 1) - QMetaObject::invokeMethod(this, "startPolling"); -} - -void QNetworkConfigurationManagerPrivate::disablePolling() -{ - const auto locker = qt_scoped_lock(mutex); - - --forcedPolling; -} - -QT_END_NAMESPACE - -#endif // QT_NO_BEARERMANAGEMENT diff --git a/src/network/bearer/qnetworkconfigmanager_p.h b/src/network/bearer/qnetworkconfigmanager_p.h deleted file mode 100644 index 4819c2027c..0000000000 --- a/src/network/bearer/qnetworkconfigmanager_p.h +++ /dev/null @@ -1,141 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QNETWORKCONFIGMANAGER_P_H -#define QNETWORKCONFIGMANAGER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtNetwork/private/qtnetworkglobal_p.h> -#include "qnetworkconfigmanager.h" -#include "qnetworkconfiguration_p.h" - -#include <QtCore/private/qfactoryloader_p.h> -#include <QtCore/qmutex.h> -#include <QtCore/qset.h> - -#ifndef QT_NO_BEARERMANAGEMENT - -QT_BEGIN_NAMESPACE - -class QBearerEngine; -class QTimer; - -class Q_NETWORK_EXPORT QNetworkConfigurationManagerPrivate : public QObject -{ - Q_OBJECT - -public: - QNetworkConfigurationManagerPrivate(); - virtual ~QNetworkConfigurationManagerPrivate(); - - QNetworkConfiguration defaultConfiguration() const; - QList<QNetworkConfiguration> allConfigurations(QNetworkConfiguration::StateFlags filter) const; - QNetworkConfiguration configurationFromIdentifier(const QString &identifier) const; - - bool isOnline() const; - - QNetworkConfigurationManager::Capabilities capabilities() const; - - void performAsyncConfigurationUpdate(); - - QList<QBearerEngine *> engines() const; - - void enablePolling(); - void disablePolling(); - - void initialize(); - void cleanup(); -public Q_SLOTS: - void updateConfigurations(); - - static void addPreAndPostRoutine(); - -Q_SIGNALS: - void configurationAdded(const QNetworkConfiguration &config); - void configurationRemoved(const QNetworkConfiguration &config); - void configurationChanged(const QNetworkConfiguration &config); - void configurationUpdateComplete(); - void onlineStateChanged(bool isOnline); - -private Q_SLOTS: - void configurationAdded(QNetworkConfigurationPrivatePointer ptr); - void configurationRemoved(QNetworkConfigurationPrivatePointer ptr); - void configurationChanged(QNetworkConfigurationPrivatePointer ptr); - - void pollEngines(); - - -private: - Q_INVOKABLE void startPolling(); - QTimer *pollTimer; - QThread *bearerThread; - -private: - mutable QRecursiveMutex mutex; - - QFactoryLoader loader; - QList<QBearerEngine *> sessionEngines; - - QSet<QString> onlineConfigurations; - - QSet<QBearerEngine *> pollingEngines; - QSet<QBearerEngine *> updatingEngines; - int forcedPolling; - bool updating; - - bool firstUpdate; -}; - -Q_NETWORK_EXPORT QNetworkConfigurationManagerPrivate *qNetworkConfigurationManagerPrivate(); - -QT_END_NAMESPACE - -#endif // QT_NO_BEARERMANAGEMENT - -#endif // QNETWORKCONFMANAGER_P_H diff --git a/src/network/bearer/qnetworkconfiguration.cpp b/src/network/bearer/qnetworkconfiguration.cpp deleted file mode 100644 index f016dea590..0000000000 --- a/src/network/bearer/qnetworkconfiguration.cpp +++ /dev/null @@ -1,596 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtNetwork/private/qtnetworkglobal_p.h> - -#include "qnetworkconfiguration.h" -#include "qnetworkconfiguration_p.h" -#include <QDebug> - -QT_BEGIN_NAMESPACE - -/*! - \class QNetworkConfiguration - \obsolete - - \brief The QNetworkConfiguration class provides an abstraction of one or more access point configurations. - - \since 4.7 - - \inmodule QtNetwork - \ingroup network - \ingroup shared - - QNetworkConfiguration encapsulates a single access point or service network. - In most cases a single access point configuration can be mapped to one network - interface. However a single network interface may not always map to only one - access point configuration. Multiple configurations for the same - network device may enable multiple access points. An example - device that could exhibit such a configuration might be a - Smartphone which allows the user to manage multiple WLAN - configurations while the device itself has only one WLAN network device. - - The QNetworkConfiguration also supports the concept of service networks. - This concept allows the grouping of multiple access point configurations - into one entity. Such a group is called service network and can be - beneficial in cases whereby a network session to a - particular destination network is required (e.g. a company network). - When using a service network the user doesn't usually care which one of the - connectivity options is chosen (e.g. corporate WLAN or VPN via GPRS) - as long as he can reach the company's target server. Depending - on the current position and time some of the access points that make - up the service network may not even be available. Furthermore - automated access point roaming can be enabled which enables the device - to change the network interface configuration dynamically while maintaining - the applications connection to the target network. It allows adaption - to the changing environment and may enable optimization with regards to - cost, speed or other network parameters. - - Special configurations of type UserChoice provide a placeholder configuration which is - resolved to an actual network configuration by the platform when a - \l {QNetworkSession}{session} is \l {QNetworkSession::open()}{opened}. Not all platforms - support the concept of a user choice configuration. - - \section1 Configuration States - - The list of available configurations can be obtained via - QNetworkConfigurationManager::allConfigurations(). A configuration can have - multiple states. The \l Defined configuration state indicates that the configuration - is stored on the device. However the configuration is not yet ready to be activated - as e.g. a WLAN may not be available at the current time. - - The \l Discovered state implies that the configuration is \l Defined and - the outside conditions are such that the configuration can be used immediately - to open a new network session. An example of such an outside condition may be - that the Ethernet cable is actually connected to the device or that the WLAN - with the specified SSID is in range. - - The \l Active state implies that the configuration is \l Discovered. A configuration - in this state is currently being used by an application. The underlying network - interface has a valid IP configuration and can transfer IP packets between the - device and the target network. - - The \l Undefined state indicates that the system has knowledge of possible target - networks but cannot actually use that knowledge to connect to it. An example - for such a state could be an encrypted WLAN that has been discovered - but the user hasn't actually saved a configuration including the required password - which would allow the device to connect to it. - - Depending on the type of configuration some states are transient in nature. A GPRS/UMTS - connection may almost always be \l Discovered if the GSM/UMTS network is available. - However if the GSM/UMTS network loses the connection the associated configuration may change its state - from \l Discovered to \l Defined as well. A similar use case might be triggered by - WLAN availability. QNetworkConfigurationManager::updateConfigurations() can be used to - manually trigger updates of states. Note that some platforms do not require such updates - as they implicitly change the state once it has been discovered. If the state of a - configuration changes all related QNetworkConfiguration instances change their state automatically. - - \sa QNetworkSession, QNetworkConfigurationManager -*/ - -/*! - \enum QNetworkConfiguration::Type - - This enum describes the type of configuration. - - \value InternetAccessPoint The configuration specifies the details for a single access point. - Note that configurations of type InternetAccessPoint may be part - of other QNetworkConfigurations of type ServiceNetwork. - \value ServiceNetwork The configuration is based on a group of QNetworkConfigurations of - type InternetAccessPoint. All group members can reach the same - target network. This type of configuration is a mandatory - requirement for roaming enabled network sessions. On some - platforms this form of configuration may also be called Service - Network Access Point (SNAP). - \value UserChoice The configuration is a placeholder which will be resolved to an - actual configuration by the platform when a session is opened. Depending - on the platform the selection may generate a popup dialog asking the user - for his preferred choice. - \value Invalid The configuration is invalid. -*/ - -/*! - \enum QNetworkConfiguration::StateFlag - - Specifies the configuration states. - - \value Undefined This state is used for transient configurations such as newly discovered - WLANs for which the user has not actually created a configuration yet. - \value Defined Defined configurations are known to the system but are not immediately - usable (e.g. a configured WLAN is not within range or the Ethernet cable - is currently not plugged into the machine). - \value Discovered A discovered configuration can be immediately used to create a new - QNetworkSession. An example of a discovered configuration could be a WLAN - which is within in range. If the device moves out of range the discovered - flag is dropped. A second example is a GPRS configuration which generally - remains discovered for as long as the device has network coverage. A - configuration that has this state is also in state - QNetworkConfiguration::Defined. If the configuration is a service network - this flag is set if at least one of the underlying access points - configurations has the Discovered state. - \value Active The configuration is currently used by an open network session - (see \l QNetworkSession::isOpen()). However this does not mean that the - current process is the entity that created the open session. It merely - indicates that if a new QNetworkSession were to be constructed based on - this configuration \l QNetworkSession::state() would return - \l QNetworkSession::Connected. This state implies the - QNetworkConfiguration::Discovered state. -*/ - -/*! - \enum QNetworkConfiguration::Purpose - - Specifies the purpose of the configuration. - - \value UnknownPurpose The configuration doesn't specify any purpose. This is the default value. - \value PublicPurpose The configuration can be used for general purpose internet access. - \value PrivatePurpose The configuration is suitable to access a private network such as an office Intranet. - \value ServiceSpecificPurpose The configuration can be used for operator specific services (e.g. - receiving MMS messages or content streaming). -*/ - -/*! - \enum QNetworkConfiguration::BearerType - - Specifies the type of bearer used by a configuration. - - \value BearerUnknown The type of bearer is unknown or unspecified. The bearerTypeName() - function may return additional information. - \value BearerEthernet The configuration is for an Ethernet interfaces. - \value BearerWLAN The configuration is for a Wireless LAN interface. - \value Bearer2G The configuration is for a CSD, GPRS, HSCSD, EDGE or cdmaOne interface. - \value Bearer3G The configuration is for a 3G interface. - \value Bearer4G The configuration is for a 4G interface. - \value BearerCDMA2000 The configuration is for CDMA interface. - \value BearerWCDMA The configuration is for W-CDMA/UMTS interface. - \value BearerHSPA The configuration is for High Speed Packet Access (HSPA) interface. - \value BearerBluetooth The configuration is for a Bluetooth interface. - \value BearerWiMAX The configuration is for a WiMAX interface. - \value BearerEVDO The configuration is for an EVDO (3G) interface. - \value BearerLTE The configuration is for a LTE (4G) interface. -*/ - -/*! - Constructs an invalid configuration object. - - \sa isValid() -*/ -QNetworkConfiguration::QNetworkConfiguration() - : d(nullptr) -{ -} - -/*! - Creates a copy of the QNetworkConfiguration object contained in \a other. -*/ -QNetworkConfiguration::QNetworkConfiguration(const QNetworkConfiguration &other) - : d(other.d) -{ -} - -/*! - Frees the resources associated with the QNetworkConfiguration object. -*/ -QNetworkConfiguration::~QNetworkConfiguration() -{ -} - -/*! - Copies the content of the QNetworkConfiguration object contained in \a other into this one. -*/ -QNetworkConfiguration &QNetworkConfiguration::operator=(const QNetworkConfiguration &other) -{ - d = other.d; - return *this; -} - -/*! - \fn void QNetworkConfiguration::swap(QNetworkConfiguration &other) - \since 5.0 - - Swaps this network configuration with \a other. This function is - very fast and never fails. -*/ - -/*! - Returns \c true, if this configuration is the same as the \a other - configuration given; otherwise returns \c false. -*/ -bool QNetworkConfiguration::operator==(const QNetworkConfiguration &other) const -{ - return (d == other.d); -} - -/*! - \fn bool QNetworkConfiguration::operator!=(const QNetworkConfiguration &other) const - - Returns \c true if this configuration is not the same as the \a other - configuration given; otherwise returns \c false. -*/ - -/*! - Returns the user visible name of this configuration. - - The name may either be the name of the underlying access point or the - name for service network that this configuration represents. -*/ -QString QNetworkConfiguration::name() const -{ - if (!d) - return QString(); - - QMutexLocker locker(&d->mutex); - return d->name; -} - -/*! - Returns the unique and platform specific identifier for this network configuration; - otherwise an empty string. -*/ -QString QNetworkConfiguration::identifier() const -{ - if (!d) - return QString(); - - QMutexLocker locker(&d->mutex); - return d->id; -} - -/*! - Returns the type of the configuration. - - A configuration can represent a single access point configuration or - a set of access point configurations. Such a set is called service network. - A configuration that is based on a service network can potentially support - roaming of network sessions. -*/ -QNetworkConfiguration::Type QNetworkConfiguration::type() const -{ - if (!d) - return QNetworkConfiguration::Invalid; - - QMutexLocker locker(&d->mutex); - return d->type; -} - -/*! - Returns \c true if this QNetworkConfiguration object is valid. - A configuration may become invalid if the user deletes the configuration or - the configuration was default-constructed. - - The addition and removal of configurations can be monitored via the - QNetworkConfigurationManager. - - \sa QNetworkConfigurationManager -*/ -bool QNetworkConfiguration::isValid() const -{ - if (!d) - return false; - - QMutexLocker locker(&d->mutex); - return d->isValid; -} - -/*! - \since 5.9 - - Returns the connect timeout of this configuration. - - \sa setConnectTimeout -*/ -int QNetworkConfiguration::connectTimeout() const -{ - if (!d) - return QNetworkConfigurationPrivate::DefaultTimeout; - QMutexLocker locker(&d->mutex); - return d->timeout; -} - -/*! - \since 5.9 - - Sets the connect timeout of this configuration to \a timeout. - This allows control of the timeout used by \c QAbstractSocket - to establish a connection. - - \note \a timeout is in millisecond. - - \warning This will have no effect if the bearer plugin doesn't have - the CanStartAndStopInterfaces capability. - - Returns true if succeeded. - - \sa connectTimeout -*/ -bool QNetworkConfiguration::setConnectTimeout(int timeout) -{ - if (!d) - return false; - QMutexLocker locker(&d->mutex); - d->timeout = timeout; - return true; -} - -/*! - Returns the current state of the configuration. -*/ -QNetworkConfiguration::StateFlags QNetworkConfiguration::state() const -{ - if (!d) - return QNetworkConfiguration::Undefined; - - QMutexLocker locker(&d->mutex); - return d->state; -} - -/*! - Returns the purpose of this configuration. - - The purpose field may be used to programmatically determine the - purpose of a configuration. Such information is usually part of the - access point or service network meta data. -*/ -QNetworkConfiguration::Purpose QNetworkConfiguration::purpose() const -{ - if (!d) - return QNetworkConfiguration::UnknownPurpose; - - QMutexLocker locker(&d->mutex); - return d->purpose; -} - -/*! - Returns \c true if this configuration supports roaming; otherwise false. -*/ -bool QNetworkConfiguration::isRoamingAvailable() const -{ - if (!d) - return false; - - QMutexLocker locker(&d->mutex); - return d->roamingSupported; -} - -/*! - Returns all sub configurations of this network configuration in priority order. The first sub - configuration in the list has the highest priority. - - Only network configurations of type \l ServiceNetwork can have children. Otherwise this - function returns an empty list. -*/ -QList<QNetworkConfiguration> QNetworkConfiguration::children() const -{ - return {}; -} - -/*! - Returns the type of bearer used by this network configuration. - - If the bearer type is \l {QNetworkConfiguration::BearerUnknown}{unknown} the bearerTypeName() - function can be used to retrieve a textural type name for the bearer. - - An invalid network configuration always returns the BearerUnknown value. - - \sa bearerTypeName(), bearerTypeFamily() -*/ -QNetworkConfiguration::BearerType QNetworkConfiguration::bearerType() const -{ - if (!isValid()) - return BearerUnknown; - - QMutexLocker locker(&d->mutex); - return d->bearerType; -} - -/*! - \since 5.2 - - Returns the bearer type family used by this network configuration. - The following table lists how bearerType() values map to - bearerTypeFamily() values: - - \table - \header - \li bearer type - \li bearer type family - \row - \li BearerUnknown, Bearer2G, BearerEthernet, BearerWLAN, - BearerBluetooth - \li (same type) - \row - \li BearerCDMA2000, BearerEVDO, BearerWCDMA, BearerHSPA, Bearer3G - \li Bearer3G - \row - \li BearerWiMAX, BearerLTE, Bearer4G - \li Bearer4G - \endtable - - An invalid network configuration always returns the BearerUnknown value. - - \sa bearerType(), bearerTypeName() -*/ -QNetworkConfiguration::BearerType QNetworkConfiguration::bearerTypeFamily() const -{ - QNetworkConfiguration::BearerType type = bearerType(); - switch (type) { - case QNetworkConfiguration::BearerUnknown: // fallthrough - case QNetworkConfiguration::Bearer2G: // fallthrough - case QNetworkConfiguration::BearerEthernet: // fallthrough - case QNetworkConfiguration::BearerWLAN: // fallthrough - case QNetworkConfiguration::BearerBluetooth: - return type; - case QNetworkConfiguration::BearerCDMA2000: // fallthrough - case QNetworkConfiguration::BearerEVDO: // fallthrough - case QNetworkConfiguration::BearerWCDMA: // fallthrough - case QNetworkConfiguration::BearerHSPA: // fallthrough - case QNetworkConfiguration::Bearer3G: - return QNetworkConfiguration::Bearer3G; - case QNetworkConfiguration::BearerWiMAX: // fallthrough - case QNetworkConfiguration::BearerLTE: // fallthrough - case QNetworkConfiguration::Bearer4G: - return QNetworkConfiguration::Bearer4G; - default: - qWarning() << "unknown bearer type" << type; - return QNetworkConfiguration::BearerUnknown; - } -} -/*! - Returns the type of bearer used by this network configuration as a string. - - The string is not translated and therefore cannot be shown to the user. The subsequent table - shows the fixed mappings between BearerType and the bearer type name for known types. If the - BearerType is unknown this function may return additional information if it is available; - otherwise an empty string will be returned. - - \table - \header - \li BearerType - \li Value - \row - \li BearerUnknown - \li The session is based on an unknown or unspecified bearer type. The value of the - string returned describes the bearer type. - \row - \li BearerEthernet - \li Ethernet - \row - \li BearerWLAN - \li WLAN - \row - \li Bearer2G - \li 2G - \row - \li Bearer3G - \li 3G - \row - \li Bearer4G - \li 4G - \row - \li BearerCDMA2000 - \li CDMA2000 - \row - \li BearerWCDMA - \li WCDMA - \row - \li BearerHSPA - \li HSPA - \row - \li BearerBluetooth - \li Bluetooth - \row - \li BearerWiMAX - \li WiMAX - \row - \li BearerEVDO - \li EVDO - \row - \li BearerLTE - \li LTE - \endtable - - This function returns an empty string if this is an invalid configuration, a network - configuration of type \l QNetworkConfiguration::ServiceNetwork or - \l QNetworkConfiguration::UserChoice. - - \sa bearerType(), bearerTypeFamily() -*/ -QString QNetworkConfiguration::bearerTypeName() const -{ - if (!isValid()) - return QString(); - - QMutexLocker locker(&d->mutex); - - if (d->type == QNetworkConfiguration::ServiceNetwork || - d->type == QNetworkConfiguration::UserChoice) - return QString(); - - switch (d->bearerType) { - case BearerEthernet: - return QStringLiteral("Ethernet"); - case BearerWLAN: - return QStringLiteral("WLAN"); - case Bearer2G: - return QStringLiteral("2G"); - case Bearer3G: - return QStringLiteral("3G"); - case Bearer4G: - return QStringLiteral("4G"); - case BearerCDMA2000: - return QStringLiteral("CDMA2000"); - case BearerWCDMA: - return QStringLiteral("WCDMA"); - case BearerHSPA: - return QStringLiteral("HSPA"); - case BearerBluetooth: - return QStringLiteral("Bluetooth"); - case BearerWiMAX: - return QStringLiteral("WiMAX"); - case BearerEVDO: - return QStringLiteral("EVDO"); - case BearerLTE: - return QStringLiteral("LTE"); - case BearerUnknown: - break; - } - return QStringLiteral("Unknown"); -} - -QT_END_NAMESPACE diff --git a/src/network/bearer/qnetworkconfiguration.h b/src/network/bearer/qnetworkconfiguration.h deleted file mode 100644 index 69864a3165..0000000000 --- a/src/network/bearer/qnetworkconfiguration.h +++ /dev/null @@ -1,147 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QNETWORKCONFIGURATION_H -#define QNETWORKCONFIGURATION_H - -#if 0 -#pragma qt_class(QNetworkConfiguration) -#endif - -#include <QtNetwork/qtnetworkglobal.h> - -#include <QtCore/qshareddata.h> -#include <QtCore/qstring.h> -#include <QtCore/qlist.h> -#include <QtCore/qmetatype.h> - -QT_WARNING_PUSH -QT_WARNING_DISABLE_DEPRECATED - -QT_BEGIN_NAMESPACE - -class QNetworkConfigurationPrivate; -class QT_DEPRECATED_BEARER_MANAGEMENT Q_NETWORK_EXPORT QNetworkConfiguration -{ -public: - QNetworkConfiguration(); - QNetworkConfiguration(const QNetworkConfiguration& other); - QNetworkConfiguration &operator=(QNetworkConfiguration &&other) noexcept { swap(other); return *this; } - QNetworkConfiguration &operator=(const QNetworkConfiguration &other); - ~QNetworkConfiguration(); - - void swap(QNetworkConfiguration &other) noexcept { qSwap(d, other.d); } - - bool operator==(const QNetworkConfiguration &other) const; - inline bool operator!=(const QNetworkConfiguration &other) const - { return !operator==(other); } - - enum Type { - InternetAccessPoint = 0, - ServiceNetwork, - UserChoice, - Invalid - }; - - enum Purpose { - UnknownPurpose = 0, - PublicPurpose, - PrivatePurpose, - ServiceSpecificPurpose - }; - - enum StateFlag { - Undefined = 0x0000001, - Defined = 0x0000002, - Discovered = 0x0000006, - Active = 0x000000e - }; - Q_DECLARE_FLAGS(StateFlags, StateFlag) - - enum BearerType { - BearerUnknown, - BearerEthernet, - BearerWLAN, - Bearer2G, - BearerCDMA2000, - BearerWCDMA, - BearerHSPA, - BearerBluetooth, - BearerWiMAX, - BearerEVDO, - BearerLTE, - Bearer3G, - Bearer4G - }; - - StateFlags state() const; - Type type() const; - Purpose purpose() const; - - BearerType bearerType() const; - BearerType bearerTypeFamily() const; - QString bearerTypeName() const; - - QString identifier() const; - bool isRoamingAvailable() const; - QList<QNetworkConfiguration> children() const; - - QString name() const; - bool isValid() const; - - int connectTimeout() const; - bool setConnectTimeout(int timeout); - -private: - friend class QNetworkConfigurationPrivate; - friend class QNetworkConfigurationManager; - friend class QNetworkConfigurationManagerPrivate; - friend class QNetworkSessionPrivate; - QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> d; -}; - -Q_DECLARE_SHARED(QNetworkConfiguration) - -QT_END_NAMESPACE - -Q_DECLARE_METATYPE(QNetworkConfiguration) - -QT_WARNING_POP - -#endif // QNETWORKCONFIGURATION_H diff --git a/src/network/bearer/qnetworkconfiguration_p.h b/src/network/bearer/qnetworkconfiguration_p.h deleted file mode 100644 index 96854fe831..0000000000 --- a/src/network/bearer/qnetworkconfiguration_p.h +++ /dev/null @@ -1,99 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QNETWORKCONFIGURATIONPRIVATE_H -#define QNETWORKCONFIGURATIONPRIVATE_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtNetwork/private/qtnetworkglobal_p.h> -#include "qnetworkconfiguration.h" - -#include <QtCore/qshareddata.h> -#include <QtCore/qmutex.h> -#include <QtCore/qmap.h> - -QT_BEGIN_NAMESPACE - -typedef QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> QNetworkConfigurationPrivatePointer; -class QNetworkConfigurationPrivate : public QSharedData -{ -public: - QNetworkConfigurationPrivate() : - type(QNetworkConfiguration::Invalid), - purpose(QNetworkConfiguration::UnknownPurpose), - bearerType(QNetworkConfiguration::BearerUnknown), - isValid(false), roamingSupported(false), - timeout(DefaultTimeout) - {} - - mutable QRecursiveMutex mutex; - - QString name; - QString id; - - QNetworkConfiguration::StateFlags state; - QNetworkConfiguration::Type type; - QNetworkConfiguration::Purpose purpose; - QNetworkConfiguration::BearerType bearerType; - - bool isValid; - bool roamingSupported; - int timeout; - - static Q_CONSTEXPR int DefaultTimeout = 30000; - -private: - Q_DISABLE_COPY_MOVE(QNetworkConfigurationPrivate) -}; - -QT_END_NAMESPACE - -Q_DECLARE_METATYPE(QNetworkConfigurationPrivatePointer) - -#endif // QNETWORKCONFIGURATIONPRIVATE_H diff --git a/src/network/bearer/qnetworksession.cpp b/src/network/bearer/qnetworksession.cpp deleted file mode 100644 index 4e8ed1619b..0000000000 --- a/src/network/bearer/qnetworksession.cpp +++ /dev/null @@ -1,743 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtNetwork/private/qtnetworkglobal_p.h> - -#include "qnetworksession.h" -#include "qnetworksession_p.h" -#include "qbearerengine_p.h" - -#include <QEventLoop> -#include <QMetaMethod> -#include <QTimer> -#include <QThread> - -#include "qnetworkconfigmanager_p.h" - -// for QNetworkSession::interface -#ifdef interface -# undef interface -#endif - -#ifndef QT_NO_BEARERMANAGEMENT - -QT_BEGIN_NAMESPACE - -/*! - \class QNetworkSession - \obsolete - - \brief The QNetworkSession class provides control over the system's access points - and enables session management for cases when multiple clients access the same access point. - - \since 4.7 - - \inmodule QtNetwork - \ingroup network - - A QNetworkSession enables control over the system's network interfaces. The session's configuration - parameter are determined via the QNetworkConfiguration object to which it is bound. Depending on the - type of the session (single access point or service network) a session may be linked to one or more - network interfaces. By means of \l{open()}{opening} and \l{close()}{closing} of network sessions - a developer can start and stop the systems network interfaces. If the configuration represents - multiple access points (see \l QNetworkConfiguration::ServiceNetwork) more advanced features such as roaming may be supported. - - QNetworkSession supports session management within the same process and depending on the platform's - capabilities may support out-of-process sessions. If the same - network configuration is used by multiple open sessions the underlying network interface is only terminated once - the last session has been closed. - - \section1 Roaming - - Applications may connect to the preferredConfigurationChanged() signal in order to - receive notifications when a more suitable access point becomes available. - In response to this signal the application must either initiate the roaming via migrate() - or ignore() the new access point. Once the session has roamed the - newConfigurationActivated() signal is emitted. The application may now test the - carrier and must either accept() or reject() it. The session will return to the previous - access point if the roaming was rejected. The subsequent state diagram depicts the required - state transitions. - - \image roaming-states.png - - Some platforms may distinguish forced roaming and application level roaming (ALR). - ALR implies that the application controls (via migrate(), ignore(), accept() and reject()) - whether a network session can roam from one access point to the next. Such control is useful - if the application maintains stateful socket connections and wants to control the transition from - one interface to the next. Forced roaming implies that the system automatically roams to the next network without - consulting the application. This has the advantage that the application can make use of roaming features - without actually being aware of it. It is expected that the application detects that the underlying - socket is broken and automatically reconnects via the new network link. - - If the platform supports both modes of roaming, an application indicates its preference - by connecting to the preferredConfigurationChanged() signal. Connecting to this signal means that - the application wants to take control over the roaming behavior and therefore implies application - level roaming. If the client does not connect to the preferredConfigurationChanged(), forced roaming - is used. If forced roaming is not supported the network session will not roam by default. - - Some applications may want to suppress any form of roaming altogether. Possible use cases may be - high priority downloads or remote services which cannot handle a roaming enabled client. Clients - can suppress roaming by connecting to the preferredConfigurationChanged() signal and answer each - signal emission with ignore(). - - \sa QNetworkConfiguration, QNetworkConfigurationManager -*/ - -/*! - \enum QNetworkSession::State - - This enum describes the connectivity state of the session. If the session is based on a - single access point configuration the state of the session is the same as the state of the - associated network interface. - - \value Invalid The session is invalid due to an invalid configuration. This may - happen due to a removed access point or a configuration that was - invalid to begin with. - \value NotAvailable The session is based on a defined but not yet discovered QNetworkConfiguration - (see \l QNetworkConfiguration::StateFlag). - \value Connecting The network session is being established. - \value Connected The network session is connected. If the current process wishes to use this session - it has to register its interest by calling open(). A network session - is considered to be ready for socket operations if it isOpen() and connected. - \value Closing The network session is in the process of being shut down. - \value Disconnected The network session is not connected. The associated QNetworkConfiguration - has the state QNetworkConfiguration::Discovered. - \value Roaming The network session is roaming from one access point to another - access point. -*/ - -/*! - \enum QNetworkSession::SessionError - - This enum describes the session errors that can occur. - - \value UnknownSessionError An unidentified error occurred. - \value SessionAbortedError The session was aborted by the user or system. - \value RoamingError The session cannot roam to a new configuration. - \value OperationNotSupportedError The operation is not supported for current configuration. - \value InvalidConfigurationError The operation cannot currently be performed for the - current configuration. -*/ - -/*! - \enum QNetworkSession::UsagePolicy - \since 5.0 - - These flags allow the system to inform the application of network usage restrictions that - may be in place. - - \value NoPolicy No policy in force, usage is unrestricted. - \value NoBackgroundTrafficPolicy Background network traffic (not user initiated) should be avoided - for example to save battery or data charges -*/ - -/*! - \fn void QNetworkSession::stateChanged(QNetworkSession::State state) - - This signal is emitted whenever the state of the network session changes. - The \a state parameter is the new state. - - \sa state() -*/ - -/*! - \fn void QNetworkSession::error(QNetworkSession::SessionError error) - - This signal is emitted after an error occurred. The \a error parameter - describes the error that occurred. - - \sa error(), errorString() -*/ - -/*! - \fn void QNetworkSession::preferredConfigurationChanged(const QNetworkConfiguration &config, bool isSeamless) - - This signal is emitted when the preferred configuration/access point for the - session changes. Only sessions which are based on service network configurations - may emit this signal. \a config can be used to determine access point specific - details such as proxy settings and \a isSeamless indicates whether roaming will - break the sessions IP address. - - As a consequence to this signal the application must either start the roaming process - by calling migrate() or choose to ignore() the new access point. - - If the roaming process is non-seamless the IP address will change which means that - a socket becomes invalid. However seamless mobility can ensure that the local IP address - does not change. This is achieved by using a virtual IP address which is bound to the actual - link address. During the roaming process the virtual address is attached to the new link - address. - - Some platforms may support the concept of Forced Roaming and Application Level Roaming (ALR). - Forced roaming implies that the platform may simply roam to a new configuration without - consulting applications. It is up to the application to detect the link layer loss and reestablish - its sockets. In contrast ALR provides the opportunity to prevent the system from roaming. - If this session is based on a configuration that supports roaming the application can choose - whether it wants to be consulted (ALR use case) by connecting to this signal. For as long as this signal - connection remains the session remains registered as a roaming stakeholder; otherwise roaming will - be enforced by the platform. - - \sa migrate(), ignore(), QNetworkConfiguration::isRoamingAvailable() -*/ - -/*! - \fn void QNetworkSession::newConfigurationActivated() - - This signal is emitted once the session has roamed to the new access point. - The application may reopen its socket and test the suitability of the new network link. - Subsequently it must either accept() or reject() the new access point. - - \sa accept(), reject() -*/ - -/*! - \fn void QNetworkSession::opened() - - This signal is emitted when the network session has been opened. - - The underlying network interface will not be shut down as long as the session remains open. - Note that this feature is dependent on \l{QNetworkConfigurationManager::SystemSessionSupport}{system wide session support}. -*/ - -/*! - \fn void QNetworkSession::closed() - - This signal is emitted when the network session has been closed. -*/ - -/*! - \fn void QNetworkSession::usagePoliciesChanged(QNetworkSession::UsagePolicies usagePolicies) - \since 5.0 - - This signal is emitted when the \a usagePolicies in force are changed by the system. -*/ - -/*! - Constructs a session based on \a connectionConfig with the given \a parent. - - \sa QNetworkConfiguration -*/ -QNetworkSession::QNetworkSession(const QNetworkConfiguration &connectionConfig, QObject *parent) - : QObject(parent), d(nullptr) -{ - qRegisterMetaType<QNetworkSession::State>(); - qRegisterMetaType<QNetworkSession::SessionError>(); - qRegisterMetaType<QNetworkSession::UsagePolicies>(); - - // invalid configuration - if (!connectionConfig.identifier().isEmpty()) { - auto priv = qNetworkConfigurationManagerPrivate(); - const auto engines = priv ? priv->engines() : QList<QBearerEngine *>(); - for (QBearerEngine *engine : engines) { - if (engine->hasIdentifier(connectionConfig.identifier())) { - d = engine->createSessionBackend(); - d->q = this; - d->publicConfig = connectionConfig; - d->syncStateWithInterface(); - connect(d, SIGNAL(quitPendingWaitsForOpened()), this, SIGNAL(opened())); - connect(d, SIGNAL(error(QNetworkSession::SessionError)), - this, SIGNAL(error(QNetworkSession::SessionError))); - connect(d, SIGNAL(stateChanged(QNetworkSession::State)), - this, SIGNAL(stateChanged(QNetworkSession::State))); - connect(d, SIGNAL(closed()), this, SIGNAL(closed())); - connect(d, SIGNAL(preferredConfigurationChanged(QNetworkConfiguration,bool)), - this, SIGNAL(preferredConfigurationChanged(QNetworkConfiguration,bool))); - connect(d, SIGNAL(newConfigurationActivated()), - this, SIGNAL(newConfigurationActivated())); - connect(d, SIGNAL(usagePoliciesChanged(QNetworkSession::UsagePolicies)), - this, SIGNAL(usagePoliciesChanged(QNetworkSession::UsagePolicies))); - break; - } - } - } -} - -/*! - Frees the resources associated with the QNetworkSession object. -*/ -QNetworkSession::~QNetworkSession() -{ - delete d; -} - -/*! - Creates an open session which increases the session counter on the underlying network interface. - The system will not terminate a network interface until the session reference counter reaches zero. - Therefore an open session allows an application to register its use of the interface. - - As a result of calling open() the interface will be started if it is not connected/up yet. - Some platforms may not provide support for out-of-process sessions. On such platforms the session - counter ignores any sessions held by another process. The platform capabilities can be - detected via QNetworkConfigurationManager::capabilities(). - - Note that this call is asynchronous. Depending on the outcome of this call the results can be enquired - by connecting to the stateChanged(), opened() or error() signals. - - It is not a requirement to open a session in order to monitor the underlying network interface. - - \sa close(), stop(), isOpen() -*/ -void QNetworkSession::open() -{ - if (d) - d->open(); - else - emit error(InvalidConfigurationError); -} - -/*! - Waits until the session has been opened, up to \a msecs milliseconds. If the session has been opened, this - function returns \c true; otherwise it returns \c false. In the case where it returns \c false, you can call error() - to determine the cause of the error. - - The following example waits up to one second for the session to be opened: - - \snippet code/src_network_bearer_qnetworksession.cpp 0 - - If \a msecs is -1, this function will not time out. - - \sa open(), error() -*/ -bool QNetworkSession::waitForOpened(int msecs) -{ - if (!d) - return false; - - if (d->isOpen) - return true; - - if (!(d->state == Connecting || d->state == Connected)) { - return false; - } - - QEventLoop loop; - QObject::connect(d, SIGNAL(quitPendingWaitsForOpened()), &loop, SLOT(quit())); - QObject::connect(this, SIGNAL(error(QNetworkSession::SessionError)), &loop, SLOT(quit())); - - //final call - if (msecs >= 0) - QTimer::singleShot(msecs, &loop, SLOT(quit())); - - // enter the event loop and wait for opened/error/timeout - loop.exec(QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents); - - return d->isOpen; -} - -/*! - Decreases the session counter on the associated network configuration. If the session counter reaches zero - the active network interface is shut down. This also means that state() will only change from \l Connected to - \l Disconnected if the current session was the last open session. - - If the platform does not support out-of-process sessions calling this function does not stop the - interface. In this case \l{stop()} has to be used to force a shut down. - The platform capabilities can be detected via QNetworkConfigurationManager::capabilities(). - - Note that this call is asynchronous. Depending on the outcome of this call the results can be enquired - by connecting to the stateChanged(), opened() or error() signals. - - \sa open(), stop(), isOpen() -*/ -void QNetworkSession::close() -{ - if (d) - d->close(); -} - -/*! - Invalidates all open sessions against the network interface and therefore stops the - underlying network interface. This function always changes the session's state() flag to - \l Disconnected. - - \sa open(), close() -*/ -void QNetworkSession::stop() -{ - if (d) - d->stop(); -} - -/*! - Returns the QNetworkConfiguration that this network session object is based on. - - \sa QNetworkConfiguration -*/ -QNetworkConfiguration QNetworkSession::configuration() const -{ - return d ? d->publicConfig : QNetworkConfiguration(); -} - -#ifndef QT_NO_NETWORKINTERFACE -/*! - Returns the network interface that is used by this session. - - This function only returns a valid QNetworkInterface when this session is \l Connected. - - The returned interface may change as a result of a roaming process. - - \sa state() -*/ -QNetworkInterface QNetworkSession::interface() const -{ - return d ? d->currentInterface() : QNetworkInterface(); -} -#endif - -/*! - Returns \c true if this session is open. If the number of all open sessions is greater than - zero the underlying network interface will remain connected/up. - - The session can be controlled via open() and close(). -*/ -bool QNetworkSession::isOpen() const -{ - return d ? d->isOpen : false; -} - -/*! - Returns the state of the session. - - If the session is based on a single access point configuration the state of the - session is the same as the state of the associated network interface. Therefore - a network session object can be used to monitor network interfaces. - - A \l QNetworkConfiguration::ServiceNetwork based session summarizes the state of all its children - and therefore returns the \l Connected state if at least one of the service network's - \l {QNetworkConfiguration::children()}{children()} configurations is active. - - Note that it is not required to hold an open session in order to obtain the network interface state. - A connected but closed session may be used to monitor network interfaces whereas an open and connected - session object may prevent the network interface from being shut down. - - \sa error(), stateChanged() -*/ -QNetworkSession::State QNetworkSession::state() const -{ - return d ? d->state : QNetworkSession::Invalid; -} - -/*! - Returns the type of error that last occurred. - - \sa state(), errorString() -*/ -QNetworkSession::SessionError QNetworkSession::error() const -{ - return d ? d->error() : InvalidConfigurationError; -} - -/*! - Returns a human-readable description of the last device error that - occurred. - - \sa error() -*/ -QString QNetworkSession::errorString() const -{ - return d ? d->errorString() : tr("Invalid configuration."); -} - -/*! - Returns the value for property \a key. - - A network session can have properties attached which may describe the session in more details. - This function can be used to gain access to those properties. - - The following property keys are guaranteed to be specified on all platforms: - - \table 80% - \header - \li Key \li Description - \row - \li ActiveConfiguration - \li If the session \l isOpen() this property returns the identifier of the - QNetworkConfiguration that is used by this session; otherwise an empty string. - - The main purpose of this key is to determine which Internet access point is used - if the session is based on a \l{QNetworkConfiguration::ServiceNetwork}{ServiceNetwork}. - The following code snippet highlights the difference: - \snippet code/src_network_bearer_qnetworksession.cpp 1 - \row - \li UserChoiceConfiguration - \li If the session \l isOpen() and is bound to a QNetworkConfiguration of type - UserChoice, this property returns the identifier of the QNetworkConfiguration that the - configuration resolved to when \l open() was called; otherwise an empty string. - - The purpose of this key is to determine the real QNetworkConfiguration that the - session is using. This key is different from \e ActiveConfiguration in that - this key may return an identifier for either a - \l {QNetworkConfiguration::ServiceNetwork}{service network} or a - \l {QNetworkConfiguration::InternetAccessPoint}{Internet access points} configurations, - whereas \e ActiveConfiguration always returns identifiers to - \l {QNetworkConfiguration::InternetAccessPoint}{Internet access points} configurations. - \row - \li ConnectInBackground - \li Setting this property to \e true before calling \l open() implies that the connection attempt - is made but if no connection can be established, the user is not connsulted and asked to select - a suitable connection. This property is not set by default and support for it depends on the platform. - - \row - \li AutoCloseSessionTimeout - \li If the session requires polling to keep its state up to date, this property holds - the timeout in milliseconds before the session will automatically close. If the - value of this property is -1 the session will not automatically close. This property - is set to -1 by default. - - The purpose of this property is to minimize resource use on platforms that use - polling to update the state of the session. Applications can set the value of this - property to the desired timeout before the session is closed. In response to the - closed() signal the network session should be deleted to ensure that all polling is - stopped. The session can then be recreated once it is required again. This property - has no effect for sessions that do not require polling. - \endtable -*/ -QVariant QNetworkSession::sessionProperty(const QString &key) const -{ - if (!d || !d->publicConfig.isValid()) - return QVariant(); - - if (key == QLatin1String("ActiveConfiguration")) - return d->isOpen ? d->activeConfig.identifier() : QString(); - - if (key == QLatin1String("UserChoiceConfiguration")) { - if (!d->isOpen || d->publicConfig.type() != QNetworkConfiguration::UserChoice) - return QString(); - - if (d->serviceConfig.isValid()) - return d->serviceConfig.identifier(); - else - return d->activeConfig.identifier(); - } - - return d->sessionProperty(key); -} - -/*! - Sets the property \a value on the session. The property is identified using - \a key. Removing an already set property can be achieved by passing an - invalid QVariant. - - Note that the \e UserChoiceConfiguration and \e ActiveConfiguration - properties are read only and cannot be changed using this method. -*/ -void QNetworkSession::setSessionProperty(const QString &key, const QVariant &value) -{ - if (!d) - return; - - if (key == QLatin1String("ActiveConfiguration") || - key == QLatin1String("UserChoiceConfiguration")) { - return; - } - - d->setSessionProperty(key, value); -} - -/*! - Instructs the session to roam to the new access point. The old access point remains active - until the application calls accept(). - - The newConfigurationActivated() signal is emitted once roaming has been completed. - - \sa accept() -*/ -void QNetworkSession::migrate() -{ - if (d) - d->migrate(); -} - -/*! - This function indicates that the application does not wish to roam the session. - - \sa migrate() -*/ -void QNetworkSession::ignore() -{ - if (d) - d->ignore(); -} - -/*! - Instructs the session to permanently accept the new access point. Once this function - has been called the session may not return to the old access point. - - The old access point may be closed in the process if there are no other network sessions for it. - Therefore any open socket that still uses the old access point - may become unusable and should be closed before completing the migration. -*/ -void QNetworkSession::accept() -{ - if (d) - d->accept(); -} - -/*! - The new access point is not suitable for the application. By calling this function the - session returns to the previous access point/configuration. This action may invalidate - any socket that has been created via the not desired access point. - - \sa accept() -*/ -void QNetworkSession::reject() -{ - if (d) - d->reject(); -} - - -/*! - Returns the amount of data sent in bytes; otherwise 0. - - This field value includes the usage across all open network - sessions which use the same network interface. - - If the session is based on a service network configuration the number of - sent bytes across all active member configurations are returned. - - This function may not always be supported on all platforms and returns 0. - The platform capability can be detected via QNetworkConfigurationManager::DataStatistics. - - \note On some platforms this function may run the main event loop. -*/ -quint64 QNetworkSession::bytesWritten() const -{ - return d ? d->bytesWritten() : Q_UINT64_C(0); -} - -/*! - Returns the amount of data received in bytes; otherwise 0. - - This field value includes the usage across all open network - sessions which use the same network interface. - - If the session is based on a service network configuration the number of - sent bytes across all active member configurations are returned. - - This function may not always be supported on all platforms and returns 0. - The platform capability can be detected via QNetworkConfigurationManager::DataStatistics. - - \note On some platforms this function may run the main event loop. -*/ -quint64 QNetworkSession::bytesReceived() const -{ - return d ? d->bytesReceived() : Q_UINT64_C(0); -} - -/*! - Returns the number of seconds that the session has been active. -*/ -quint64 QNetworkSession::activeTime() const -{ - return d ? d->activeTime() : Q_UINT64_C(0); -} - -/*! - Returns the network usage policies currently in force by the system. -*/ -QNetworkSession::UsagePolicies QNetworkSession::usagePolicies() const -{ - return d ? d->usagePolicies() : QNetworkSession::NoPolicy; -} - -/*! - \internal - Change usage policies for unit testing. - In normal use, the policies are published by the bearer plugin -*/ -void QNetworkSessionPrivate::setUsagePolicies(QNetworkSession &session, QNetworkSession::UsagePolicies policies) -{ - if (!session.d) - return; - session.d->setUsagePolicies(policies); -} - -/*! - \internal - - This function is required to detect whether the client wants to control - the roaming process. If he connects to preferredConfigurationChanged() signal - he intends to influence it. Otherwise QNetworkSession always roams - without registering this session as a stakeholder in the roaming process. - - For more details check the Forced vs ALR roaming section in the QNetworkSession - class description. -*/ -void QNetworkSession::connectNotify(const QMetaMethod &signal) -{ - QObject::connectNotify(signal); - - if (!d) - return; - - //check for preferredConfigurationChanged() signal connect notification - //This is not required on all platforms - static const QMetaMethod preferredConfigurationChangedSignal = - QMetaMethod::fromSignal(&QNetworkSession::preferredConfigurationChanged); - if (signal == preferredConfigurationChangedSignal) - d->setALREnabled(true); -} - -/*! - \internal - - This function is called when the client disconnects from the - preferredConfigurationChanged() signal. - - \sa connectNotify() -*/ -void QNetworkSession::disconnectNotify(const QMetaMethod &signal) -{ - QObject::disconnectNotify(signal); - - if (!d) - return; - - //check for preferredConfigurationChanged() signal disconnect notification - //This is not required on all platforms - static const QMetaMethod preferredConfigurationChangedSignal = - QMetaMethod::fromSignal(&QNetworkSession::preferredConfigurationChanged); - if (signal == preferredConfigurationChangedSignal) - d->setALREnabled(false); -} - -QT_END_NAMESPACE - -#include "moc_qnetworksession.cpp" - -#endif // QT_NO_BEARERMANAGEMENT diff --git a/src/network/bearer/qnetworksession.h b/src/network/bearer/qnetworksession.h deleted file mode 100644 index 65d90b0a82..0000000000 --- a/src/network/bearer/qnetworksession.h +++ /dev/null @@ -1,159 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QNETWORKSESSION_H -#define QNETWORKSESSION_H - -#if 0 -#pragma qt_class(QNetworkSession) -#endif - -#include <QtNetwork/qtnetworkglobal.h> -#include <QtCore/qobject.h> -#include <QtCore/qstring.h> -#include <QtNetwork/qnetworkinterface.h> -#include <QtCore/qvariant.h> -#include <QtNetwork/qnetworkconfiguration.h> - -QT_WARNING_PUSH -QT_WARNING_DISABLE_DEPRECATED - -#ifndef QT_NO_BEARERMANAGEMENT - -#if defined(Q_OS_WIN) && defined(interface) -#undef interface -#endif - -#include <QtCore/qshareddata.h> -QT_BEGIN_NAMESPACE - -class QNetworkSessionPrivate; -class QT_DEPRECATED_BEARER_MANAGEMENT Q_NETWORK_EXPORT QNetworkSession : public QObject -{ - Q_OBJECT - -public: - enum State { - Invalid = 0, - NotAvailable, - Connecting, - Connected, - Closing, - Disconnected, - Roaming - }; - - enum SessionError { - UnknownSessionError = 0, - SessionAbortedError, - RoamingError, - OperationNotSupportedError, - InvalidConfigurationError - }; - - enum UsagePolicy { - NoPolicy = 0, - NoBackgroundTrafficPolicy = 1 - }; - - Q_DECLARE_FLAGS(UsagePolicies, UsagePolicy) - - explicit QNetworkSession(const QNetworkConfiguration &connConfig, QObject *parent = nullptr); - virtual ~QNetworkSession(); - - bool isOpen() const; - QNetworkConfiguration configuration() const; -#ifndef QT_NO_NETWORKINTERFACE - QNetworkInterface interface() const; -#endif - - State state() const; - SessionError error() const; - QString errorString() const; - QVariant sessionProperty(const QString &key) const; - void setSessionProperty(const QString &key, const QVariant &value); - - quint64 bytesWritten() const; - quint64 bytesReceived() const; - quint64 activeTime() const; - - QNetworkSession::UsagePolicies usagePolicies() const; - - bool waitForOpened(int msecs = 30000); - -public Q_SLOTS: - void open(); - void close(); - void stop(); - - //roaming related slots - void migrate(); - void ignore(); - void accept(); - void reject(); - -Q_SIGNALS: - void stateChanged(QNetworkSession::State); - void opened(); - void closed(); - void error(QNetworkSession::SessionError); - void preferredConfigurationChanged(const QNetworkConfiguration &config, bool isSeamless); - void newConfigurationActivated(); - void usagePoliciesChanged(QNetworkSession::UsagePolicies usagePolicies); - -protected: - virtual void connectNotify(const QMetaMethod &signal) override; - virtual void disconnectNotify(const QMetaMethod &signal) override; - -private: - Q_DISABLE_COPY(QNetworkSession) - friend class QNetworkSessionPrivate; - QNetworkSessionPrivate *d; -}; - -QT_END_NAMESPACE -Q_DECLARE_METATYPE(QNetworkSession::State) -Q_DECLARE_METATYPE(QNetworkSession::SessionError) -Q_DECLARE_METATYPE(QNetworkSession::UsagePolicies) - -#endif // QT_NO_BEARERMANAGEMENT - -QT_WARNING_POP - -#endif // QNETWORKSESSION_H diff --git a/src/network/bearer/qnetworksession_p.h b/src/network/bearer/qnetworksession_p.h deleted file mode 100644 index 7c1ff63b68..0000000000 --- a/src/network/bearer/qnetworksession_p.h +++ /dev/null @@ -1,157 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QNETWORKSESSIONPRIVATE_H -#define QNETWORKSESSIONPRIVATE_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtNetwork/private/qtnetworkglobal_p.h> -#include "qnetworksession.h" -#include "qnetworkconfiguration_p.h" -#include "QtCore/qsharedpointer.h" - -#ifndef QT_NO_BEARERMANAGEMENT - -QT_BEGIN_NAMESPACE - -class Q_NETWORK_EXPORT QNetworkSessionPrivate : public QObject -{ - Q_OBJECT - - friend class QNetworkSession; - -public: - QNetworkSessionPrivate() : QObject(), - state(QNetworkSession::Invalid), isOpen(false) - {} - virtual ~QNetworkSessionPrivate() - {} - - //called by QNetworkSession constructor and ensures - //that the state is immediately updated (w/o actually opening - //a session). Also this function should take care of - //notification hooks to discover future state changes. - virtual void syncStateWithInterface() = 0; - -#ifndef QT_NO_NETWORKINTERFACE - virtual QNetworkInterface currentInterface() const = 0; -#endif - virtual QVariant sessionProperty(const QString &key) const = 0; - virtual void setSessionProperty(const QString &key, const QVariant &value) = 0; - - virtual void open() = 0; - virtual void close() = 0; - virtual void stop() = 0; - - virtual void setALREnabled(bool /*enabled*/) {} - virtual void migrate() = 0; - virtual void accept() = 0; - virtual void ignore() = 0; - virtual void reject() = 0; - - virtual QString errorString() const = 0; //must return translated string - virtual QNetworkSession::SessionError error() const = 0; - - virtual quint64 bytesWritten() const = 0; - virtual quint64 bytesReceived() const = 0; - virtual quint64 activeTime() const = 0; - - virtual QNetworkSession::UsagePolicies usagePolicies() const = 0; - virtual void setUsagePolicies(QNetworkSession::UsagePolicies) = 0; - - static void setUsagePolicies(QNetworkSession&, QNetworkSession::UsagePolicies); //for unit testing -protected: - inline QNetworkConfigurationPrivatePointer privateConfiguration(const QNetworkConfiguration &config) const - { - return config.d; - } - - inline void setPrivateConfiguration(QNetworkConfiguration &config, - const QNetworkConfigurationPrivatePointer &ptr) const - { - config.d = ptr; - } - -Q_SIGNALS: - //releases any pending waitForOpened() calls - void quitPendingWaitsForOpened(); - - void error(QNetworkSession::SessionError error); - void stateChanged(QNetworkSession::State state); - void closed(); - void newConfigurationActivated(); - void preferredConfigurationChanged(const QNetworkConfiguration &config, bool isSeamless); - void usagePoliciesChanged(QNetworkSession::UsagePolicies); - -protected: - QNetworkSession *q; - - // The config set on QNetworkSession. - QNetworkConfiguration publicConfig; - - // If publicConfig is a ServiceNetwork this is a copy of publicConfig. - // If publicConfig is an UserChoice that is resolved to a ServiceNetwork this is the actual - // ServiceNetwork configuration. - QNetworkConfiguration serviceConfig; - - // This is the actual active configuration currently in use by the session. - // Either a copy of publicConfig or one of serviceConfig.children(). - QNetworkConfiguration activeConfig; - - QNetworkSession::State state; - bool isOpen; - - QRecursiveMutex mutex; -}; - -QT_END_NAMESPACE - -#endif // QT_NO_BEARERMANAGEMENT - -#endif // QNETWORKSESSIONPRIVATE_H diff --git a/src/network/bearer/qsharednetworksession.cpp b/src/network/bearer/qsharednetworksession.cpp deleted file mode 100644 index b3e9892f4b..0000000000 --- a/src/network/bearer/qsharednetworksession.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsharednetworksession_p.h" -#include "qbearerengine_p.h" -#include <QThreadStorage> - -#ifndef QT_NO_BEARERMANAGEMENT - -QT_BEGIN_NAMESPACE - -QThreadStorage<QSharedNetworkSessionManager *> tls; - -inline QSharedNetworkSessionManager* sharedNetworkSessionManager() -{ - QSharedNetworkSessionManager* rv = tls.localData(); - if (!rv) { - rv = new QSharedNetworkSessionManager; - tls.setLocalData(rv); - } - return rv; -} - -struct DeleteLater { - void operator()(QObject* obj) const - { - obj->deleteLater(); - } -}; - -template <typename Container> -static void maybe_prune_expired(Container &c) -{ - if (c.size() > 16) { - for (auto it = c.cbegin(), end = c.cend(); it != end; /*erasing*/) { - if (!it->second.lock()) - it = c.erase(it); - else - ++it; - } - } -} - -QSharedPointer<QNetworkSession> QSharedNetworkSessionManager::getSession(const QNetworkConfiguration &config) -{ - QSharedNetworkSessionManager *m = sharedNetworkSessionManager(); - maybe_prune_expired(m->sessions); - auto &entry = m->sessions[config]; - //if already have a session, return it - if (auto p = entry.toStrongRef()) - return p; - //otherwise make one - QSharedPointer<QNetworkSession> session(new QNetworkSession(config), DeleteLater{}); - entry = session; - return session; -} - -void QSharedNetworkSessionManager::setSession(const QNetworkConfiguration &config, QSharedPointer<QNetworkSession> session) -{ - QSharedNetworkSessionManager *m = sharedNetworkSessionManager(); - m->sessions[config] = std::move(session); -} - -QT_END_NAMESPACE - -#endif // QT_NO_BEARERMANAGEMENT diff --git a/src/network/bearer/qsharednetworksession_p.h b/src/network/bearer/qsharednetworksession_p.h deleted file mode 100644 index f22f9eeacb..0000000000 --- a/src/network/bearer/qsharednetworksession_p.h +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSHAREDNETWORKSESSIONPRIVATE_H -#define QSHAREDNETWORKSESSIONPRIVATE_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtNetwork/private/qtnetworkglobal_p.h> -#include "qnetworksession.h" -#include "qnetworkconfiguration.h" -#include <QSharedPointer> -#include <QWeakPointer> -#include <QMutex> - -#include <unordered_map> - -#ifndef QT_NO_BEARERMANAGEMENT - -QT_BEGIN_NAMESPACE - -namespace QtPrivate { -struct NetworkConfigurationHash { - using result_type = size_t; - using argument_type = QNetworkConfiguration; - size_t operator()(const QNetworkConfiguration &config) const noexcept - { - return std::hash<size_t>{}(size_t(config.type()) | (size_t(config.bearerType()) << 8) | (size_t(config.purpose()) << 16)); - } -}; -} - -class QSharedNetworkSessionManager -{ -public: - static QSharedPointer<QNetworkSession> getSession(const QNetworkConfiguration &config); - static void setSession(const QNetworkConfiguration &config, QSharedPointer<QNetworkSession> session); -private: - std::unordered_map<QNetworkConfiguration, QWeakPointer<QNetworkSession>, QtPrivate::NetworkConfigurationHash> sessions; -}; - -QT_END_NAMESPACE - -#endif // QT_NO_BEARERMANAGEMENT - -#endif //QSHAREDNETWORKSESSIONPRIVATE_H - diff --git a/src/network/configure.cmake b/src/network/configure.cmake new file mode 100644 index 0000000000..ae9deb79ed --- /dev/null +++ b/src/network/configure.cmake @@ -0,0 +1,445 @@ + + +#### Inputs + + + +#### Libraries + +qt_find_package(Libproxy PROVIDED_TARGETS PkgConfig::Libproxy) +qt_find_package(WrapOpenSSLHeaders PROVIDED_TARGETS WrapOpenSSLHeaders::WrapOpenSSLHeaders) +# openssl_headers +qt_config_compile_test(openssl_headers + LIBRARIES + WrapOpenSSLHeaders::WrapOpenSSLHeaders + CODE +" +#include <openssl/ssl.h> +#include <openssl/opensslv.h> +#if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER-0 < 0x10100000L +# error OpenSSL >= 1.1.0 is required +#endif +#if !defined(OPENSSL_NO_EC) && !defined(SSL_CTRL_SET_CURVES) +# error OpenSSL was reported as >= 1.1.0 but is missing required features, possibly it's libressl which is unsupported +#endif +int main(int argc, char **argv) +{ + (void)argc; (void)argv; + /* BEGIN TEST: */ + + /* END TEST: */ + return 0; +} +") + +qt_find_package(WrapOpenSSL PROVIDED_TARGETS WrapOpenSSL::WrapOpenSSL) +# openssl +qt_config_compile_test(openssl + LIBRARIES + WrapOpenSSL::WrapOpenSSL + CODE +" +#include <openssl/ssl.h> +#include <openssl/opensslv.h> +#if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER-0 < 0x10100000L +# error OpenSSL >= 1.1.0 is required +#endif +#if !defined(OPENSSL_NO_EC) && !defined(SSL_CTRL_SET_CURVES) +# error OpenSSL was reported as >= 1.1.0 but is missing required features, possibly it's libressl which is unsupported +#endif +int main(int argc, char **argv) +{ + (void)argc; (void)argv; + /* BEGIN TEST: */ +SSL_free(SSL_new(0)); + /* END TEST: */ + return 0; +} +") + +qt_find_package(GSSAPI PROVIDED_TARGETS GSSAPI::GSSAPI) + + +#### Tests + +# getifaddrs +qt_config_compile_test(getifaddrs + LABEL "getifaddrs()" + CODE +" +#include <sys/types.h> +#include <sys/socket.h> +#include <net/if.h> +#include <ifaddrs.h> + +int main(int argc, char **argv) +{ + (void)argc; (void)argv; + /* BEGIN TEST: */ +ifaddrs *list; +getifaddrs(&list); +freeifaddrs(list); + /* END TEST: */ + return 0; +} +"# FIXME: use: unmapped library: network +) + +# ipv6ifname +qt_config_compile_test(ipv6ifname + LABEL "IPv6 ifname" + CODE +" +#include <sys/types.h> +#include <sys/socket.h> +#include <net/if.h> + +int main(int argc, char **argv) +{ + (void)argc; (void)argv; + /* BEGIN TEST: */ +char buf[IFNAMSIZ]; +if_nametoindex(\"eth0\"); +if_indextoname(1, buf); +if_freenameindex(if_nameindex()); + /* END TEST: */ + return 0; +} +"# FIXME: use: unmapped library: network +) + +# linux-netlink +qt_config_compile_test(linux_netlink + LABEL "Linux AF_NETLINK sockets" + CODE +" +#include <asm/types.h> +#include <linux/netlink.h> +#include <linux/rtnetlink.h> +#include <sys/socket.h> + +int main(int argc, char **argv) +{ + (void)argc; (void)argv; + /* BEGIN TEST: */ +struct rtattr rta = { }; +struct ifinfomsg ifi = {}; +struct ifaddrmsg ifa = {}; +struct ifa_cacheinfo ci; +ci.ifa_prefered = ci.ifa_valid = 0; +(void)RTM_NEWLINK; (void)RTM_NEWADDR; +(void)IFLA_ADDRESS; (void)IFLA_IFNAME; +(void)IFA_ADDRESS; (void)IFA_LABEL; (void)IFA_CACHEINFO; +(void)(IFA_F_SECONDARY | IFA_F_DEPRECATED | IFA_F_PERMANENT | IFA_F_MANAGETEMPADDR); + /* END TEST: */ + return 0; +} +") + +# sctp +qt_config_compile_test(sctp + LABEL "SCTP support" + CODE +" +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netinet/sctp.h> + +int main(int argc, char **argv) +{ + (void)argc; (void)argv; + /* BEGIN TEST: */ +sctp_initmsg sctpInitMsg; +socklen_t sctpInitMsgSize = sizeof(sctpInitMsg); +(void) socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP); +(void) getsockopt(-1, SOL_SCTP, SCTP_INITMSG, &sctpInitMsg, &sctpInitMsgSize); + /* END TEST: */ + return 0; +} +"# FIXME: use: unmapped library: network +) + +# dtls +qt_config_compile_test(dtls + LABEL "DTLS support in OpenSSL" + LIBRARIES + WrapOpenSSLHeaders::WrapOpenSSLHeaders + CODE +" +#include <openssl/ssl.h> +#if defined(OPENSSL_NO_DTLS) || !defined(DTLS1_2_VERSION) +# error OpenSSL without DTLS support +#endif +int main(int argc, char **argv) +{ + (void)argc; (void)argv; + /* BEGIN TEST: */ + + /* END TEST: */ + return 0; +} +") + +# ocsp +qt_config_compile_test(ocsp + LABEL "OCSP stapling support in OpenSSL" + LIBRARIES + WrapOpenSSLHeaders::WrapOpenSSLHeaders + CODE +" +#include <openssl/ssl.h> +#include <openssl/ocsp.h> +#if defined(OPENSSL_NO_OCSP) || defined(OPENSSL_NO_TLSEXT) +# error OpenSSL without OCSP stapling +#endif +int main(int argc, char **argv) +{ + (void)argc; (void)argv; + /* BEGIN TEST: */ + + /* END TEST: */ + return 0; +} +") + +# netlistmgr +qt_config_compile_test(netlistmgr + LABEL "Network List Manager" + CODE +" +#include <netlistmgr.h> +#include <wrl/client.h> + +int main(int argc, char **argv) +{ + (void)argc; (void)argv; + /* BEGIN TEST: */ +using namespace Microsoft::WRL; +ComPtr<INetworkListManager> networkListManager; +ComPtr<IConnectionPoint> connectionPoint; +ComPtr<IConnectionPointContainer> connectionPointContainer; +networkListManager.As(&connectionPointContainer); +connectionPointContainer->FindConnectionPoint(IID_INetworkConnectionEvents, &connectionPoint); + /* END TEST: */ + return 0; +} +"# FIXME: qmake: LIBS += -lOle32 +) + + + +#### Features + +qt_feature("corewlan" PUBLIC PRIVATE + LABEL "CoreWLan" + CONDITION libs.corewlan OR FIXME + EMIT_IF APPLE +) +qt_feature_definition("corewlan" "QT_NO_COREWLAN" NEGATE VALUE "1") +qt_feature("getifaddrs" PUBLIC + LABEL "getifaddrs()" + CONDITION TEST_getifaddrs +) +qt_feature_definition("getifaddrs" "QT_NO_GETIFADDRS" NEGATE VALUE "1") +qt_feature("ipv6ifname" PUBLIC + LABEL "IPv6 ifname" + CONDITION TEST_ipv6ifname +) +qt_feature_definition("ipv6ifname" "QT_NO_IPV6IFNAME" NEGATE VALUE "1") +qt_feature("libproxy" PRIVATE + LABEL "libproxy" + AUTODETECT OFF + CONDITION Libproxy_FOUND +) +qt_feature("linux-netlink" PRIVATE + LABEL "Linux AF_NETLINK" + CONDITION LINUX AND TEST_linux_netlink +) +qt_feature("openssl" PRIVATE + LABEL "OpenSSL" + CONDITION QT_FEATURE_openssl_runtime OR QT_FEATURE_openssl_linked + ENABLE false +) +qt_feature_definition("openssl" "QT_NO_OPENSSL" NEGATE) +qt_feature_config("openssl" QMAKE_PUBLIC_QT_CONFIG) +qt_feature("openssl-runtime" + AUTODETECT NOT WINRT AND NOT WASM + CONDITION NOT QT_FEATURE_securetransport AND NOT QT_FEATURE_schannel AND TEST_openssl_headers + ENABLE INPUT_openssl STREQUAL 'yes' OR INPUT_openssl STREQUAL 'runtime' + DISABLE INPUT_openssl STREQUAL 'no' OR INPUT_openssl STREQUAL 'linked' OR INPUT_ssl STREQUAL 'no' +) +qt_feature("openssl-linked" PRIVATE + LABEL " Qt directly linked to OpenSSL" + AUTODETECT OFF + CONDITION NOT QT_FEATURE_securetransport AND NOT QT_FEATURE_schannel AND TEST_openssl + ENABLE INPUT_openssl STREQUAL 'linked' +) +qt_feature_definition("openssl-linked" "QT_LINKED_OPENSSL") +qt_feature("securetransport" PUBLIC + LABEL "SecureTransport" + CONDITION APPLE AND ( INPUT_openssl STREQUAL '' OR INPUT_openssl STREQUAL 'no' ) + DISABLE INPUT_securetransport STREQUAL 'no' OR INPUT_ssl STREQUAL 'no' +) +qt_feature_definition("securetransport" "QT_SECURETRANSPORT") +qt_feature("schannel" PUBLIC + LABEL "Schannel" + CONDITION INPUT_schannel STREQUAL 'yes' AND WIN32 AND NOT WINRT AND ( INPUT_openssl STREQUAL '' OR INPUT_openssl STREQUAL 'no' ) + DISABLE INPUT_schannel STREQUAL 'no' OR INPUT_ssl STREQUAL 'no' +) +qt_feature_definition("schannel" "QT_SCHANNEL") +qt_feature("ssl" PUBLIC + LABEL "SSL" + CONDITION WINRT OR QT_FEATURE_securetransport OR QT_FEATURE_openssl OR QT_FEATURE_schannel +) +qt_feature_definition("ssl" "QT_NO_SSL" NEGATE VALUE "1") +qt_feature("dtls" PUBLIC + SECTION "Networking" + LABEL "DTLS" + PURPOSE "Provides a DTLS implementation" + CONDITION QT_FEATURE_openssl AND QT_FEATURE_udpsocket AND TEST_dtls +) +qt_feature("ocsp" PUBLIC + SECTION "Networking" + LABEL "OCSP-stapling" + PURPOSE "Provides OCSP stapling support" + CONDITION QT_FEATURE_opensslv11 AND TEST_ocsp +) +qt_feature("opensslv11" PUBLIC + LABEL "OpenSSL 1.1" + CONDITION QT_FEATURE_openssl +) +qt_feature("sctp" PUBLIC + LABEL "SCTP" + AUTODETECT OFF + CONDITION TEST_sctp +) +qt_feature_definition("sctp" "QT_NO_SCTP" NEGATE VALUE "1") +qt_feature("system-proxies" PRIVATE + LABEL "Use system proxies" +) +qt_feature("ftp" PUBLIC + SECTION "Networking" + LABEL "FTP" + PURPOSE "Provides support for the File Transfer Protocol in QNetworkAccessManager." + AUTODETECT OFF + CONDITION QT_FEATURE_textdate AND QT_FEATURE_regularexpression +) +qt_feature_definition("ftp" "QT_NO_FTP" NEGATE VALUE "1") +qt_feature("http" PUBLIC + SECTION "Networking" + LABEL "HTTP" + PURPOSE "Provides support for the Hypertext Transfer Protocol in QNetworkAccessManager." + CONDITION QT_FEATURE_thread +) +qt_feature_definition("http" "QT_NO_HTTP" NEGATE VALUE "1") +qt_feature("udpsocket" PUBLIC + SECTION "Networking" + LABEL "QUdpSocket" + PURPOSE "Provides access to UDP sockets." +) +qt_feature_definition("udpsocket" "QT_NO_UDPSOCKET" NEGATE VALUE "1") +qt_feature("networkproxy" PUBLIC + SECTION "Networking" + LABEL "QNetworkProxy" + PURPOSE "Provides network proxy support." +) +qt_feature_definition("networkproxy" "QT_NO_NETWORKPROXY" NEGATE VALUE "1") +qt_feature("socks5" PUBLIC + SECTION "Networking" + LABEL "SOCKS5" + PURPOSE "Provides SOCKS5 support in QNetworkProxy." + CONDITION QT_FEATURE_networkproxy +) +qt_feature_definition("socks5" "QT_NO_SOCKS5" NEGATE VALUE "1") +qt_feature("networkinterface" PUBLIC + SECTION "Networking" + LABEL "QNetworkInterface" + PURPOSE "Supports enumerating a host's IP addresses and network interfaces." + CONDITION NOT WASM +) +qt_feature_definition("networkinterface" "QT_NO_NETWORKINTERFACE" NEGATE VALUE "1") +qt_feature("networkdiskcache" PUBLIC + SECTION "Networking" + LABEL "QNetworkDiskCache" + PURPOSE "Provides a disk cache for network resources." + CONDITION QT_FEATURE_temporaryfile +) +qt_feature_definition("networkdiskcache" "QT_NO_NETWORKDISKCACHE" NEGATE VALUE "1") +qt_feature("localserver" PUBLIC + SECTION "Networking" + LABEL "QLocalServer" + PURPOSE "Provides a local socket based server." + CONDITION QT_FEATURE_temporaryfile +) +qt_feature_definition("localserver" "QT_NO_LOCALSERVER" NEGATE VALUE "1") +qt_feature("dnslookup" PUBLIC + SECTION "Networking" + LABEL "QDnsLookup" + PURPOSE "Provides API for DNS lookups." +) +qt_feature("gssapi" PUBLIC + SECTION "Networking" + LABEL "GSSAPI" + PURPOSE "Enable SPNEGO authentication through GSSAPI" + CONDITION NOT WIN32 AND GSSAPI_FOUND +) +qt_feature_definition("gssapi" "QT_NO_GSSAPI" NEGATE VALUE "1") +qt_feature("sspi" PUBLIC + SECTION "Networking" + LABEL "SSPI" + PURPOSE "Enable NTLM/SPNEGO authentication through SSPI" + CONDITION WIN32 AND NOT WINRT +) +qt_feature_definition("sspi" "QT_NO_SSPI" NEGATE VALUE "1") +qt_feature("netlistmgr" PRIVATE + SECTION "Networking" + LABEL "Network List Manager" + PURPOSE "Use Network List Manager to keep track of network connectivity" + CONDITION WIN32 AND TEST_netlistmgr +) +qt_feature("topleveldomain" PUBLIC + SECTION "Networking" + LABEL "qTopLevelDomain()" + PURPOSE "Provides support for extracting the top level domain from URLs. If enabled, a binary dump of the Public Suffix List (http://www.publicsuffix.org, Mozilla License) is included. The data is then also used in QNetworkCookieJar::validateCookie." +) +qt_configure_add_summary_section(NAME "Qt Network") +qt_configure_add_summary_entry( + ARGS "corewlan" + CONDITION APPLE +) +qt_configure_add_summary_entry(ARGS "getifaddrs") +qt_configure_add_summary_entry(ARGS "ipv6ifname") +qt_configure_add_summary_entry(ARGS "libproxy") +qt_configure_add_summary_entry( + ARGS "linux-netlink" + CONDITION LINUX +) +qt_configure_add_summary_entry( + ARGS "securetransport" + CONDITION APPLE +) +qt_configure_add_summary_entry( + ARGS "schannel" + CONDITION WIN32 AND NOT WINRT +) +qt_configure_add_summary_entry(ARGS "openssl") +qt_configure_add_summary_entry(ARGS "openssl-linked") +qt_configure_add_summary_entry(ARGS "opensslv11") +qt_configure_add_summary_entry(ARGS "dtls") +qt_configure_add_summary_entry(ARGS "ocsp") +qt_configure_add_summary_entry(ARGS "ftp") +qt_configure_add_summary_entry(ARGS "sctp") +qt_configure_add_summary_entry(ARGS "system-proxies") +qt_configure_add_summary_entry(ARGS "gssapi") +qt_configure_end_summary_section() # end of "Qt Network" section +qt_configure_add_report_entry( + TYPE NOTE + MESSAGE "When linking against OpenSSL, you can override the default library names through OPENSSL_LIBS. For example: OPENSSL_LIBS='-L/opt/ssl/lib -lssl -lcrypto' ./configure -openssl-linked" + CONDITION NOT ANDROID AND QT_FEATURE_openssl_linked AND TEST_openssl.source NOT = 0 AND INPUT_openssl.prefix STREQUAL '' AND INPUT_openssl.libs STREQUAL '' AND INPUT_openssl.libs.debug STREQUAL '' OR FIXME +) +qt_configure_add_report_entry( + TYPE WARNING + MESSAGE "Some of libproxy's plugins may use incompatible Qt versions. Some platforms and distributions ship libproxy with plugins, such as config_kde4.so, that are linked against old versions of Qt, and libproxy loads these plugins automatically when initialized. If Qt is not in a namespace, that loading causes a crash. Even if the systems on which you build and test have no such plugins, your users' systems may have them. We therefore recommend that you combine -libproxy with -qtnamespace when configuring Qt." + CONDITION QT_FEATURE_libproxy AND INPUT_qt_namespace STREQUAL '' +) diff --git a/src/network/configure.json b/src/network/configure.json index 289d84fbb4..254a36d725 100644 --- a/src/network/configure.json +++ b/src/network/configure.json @@ -343,7 +343,8 @@ "label": "FTP", "purpose": "Provides support for the File Transfer Protocol in QNetworkAccessManager.", "section": "Networking", - "condition": "features.textdate", + "autoDetect": false, + "condition": "features.textdate && features.regularexpression", "output": [ "publicFeature", "feature" ] }, "http": { @@ -386,17 +387,6 @@ "condition": "features.temporaryfile", "output": [ "publicFeature", "feature" ] }, - "bearermanagement": { - "label": "Bearer management (deprecated)", - "purpose": "Provides bearer management for the network stack.", - "section": "Networking", - "condition": "features.thread && features.library && features.networkinterface && features.properties", - "output": [ - "publicFeature", - "feature", - { "type": "define", "negative": true, "name": "QT_NO_BEARERMANAGEMENT" } - ] - }, "localserver": { "label": "QLocalServer", "purpose": "Provides a local socket based server.", @@ -430,6 +420,12 @@ "section": "Networking", "condition": "config.win32 && tests.netlistmgr", "output": [ "privateFeature" ] + }, + "topleveldomain": { + "label": "qTopLevelDomain()", + "purpose": "Provides support for extracting the top level domain from URLs. If enabled, a binary dump of the Public Suffix List (http://www.publicsuffix.org, Mozilla License) is included. The data is then also used in QNetworkCookieJar::validateCookie.", + "section": "Networking", + "output": [ "publicFeature" ] } }, @@ -446,15 +442,7 @@ For example: { "type": "warning", "condition": "features.libproxy && input.qt_namespace == ''", - "message": "Some of libproxy's plugins may use incompatible Qt versions. - - Some platforms and distributions ship libproxy with plugins, such - as config_kde4.so, that are linked against old versions of Qt; and - libproxy loads these plugins automatically when initialized. If Qt - is not in a namespace, that loading causes a crash. Even if the - systems on which you build and test have no such plugins, your - users' systems may have them. We therefore recommend that you - combine -libproxy with -qtnamespace when configuring Qt." + "message": "Some of libproxy's plugins may use incompatible Qt versions. Some platforms and distributions ship libproxy with plugins, such as config_kde4.so, that are linked against old versions of Qt; and libproxy loads these plugins automatically when initialized. If Qt is not in a namespace, that loading causes a crash. Even if the systems on which you build and test have no such plugins, your users' systems may have them. We therefore recommend that you combine -libproxy with -qtnamespace when configuring Qt." } ], @@ -488,6 +476,7 @@ For example: "opensslv11", "dtls", "ocsp", + "ftp", "sctp", "system-proxies", "gssapi" diff --git a/src/network/doc/snippets/code/src_network_access_qnetworkaccessmanager.cpp b/src/network/doc/snippets/code/src_network_access_qnetworkaccessmanager.cpp index d317137dad..39a3199bf7 100644 --- a/src/network/doc/snippets/code/src_network_access_qnetworkaccessmanager.cpp +++ b/src/network/doc/snippets/code/src_network_access_qnetworkaccessmanager.cpp @@ -70,15 +70,6 @@ connect(reply, &QNetworkReply::sslErrors, this, &MyClass::slotSslErrors); //! [1] -//! [2] -QNetworkConfigurationManager manager; -networkAccessManager->setConfiguration(manager.defaultConfiguration()); -//! [2] - -//! [3] -networkAccessManager->setConfiguration(QNetworkConfiguration()); -//! [3] - //! [4] networkAccessManager->setNetworkAccessible(QNetworkAccessManager::NotAccessible); //! [4] diff --git a/src/network/doc/snippets/code/src_network_bearer_qnetworkconfigmanager.cpp b/src/network/doc/snippets/code/src_network_bearer_qnetworkconfigmanager.cpp deleted file mode 100644 index 42992f08d9..0000000000 --- a/src/network/doc/snippets/code/src_network_bearer_qnetworkconfigmanager.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//! [0] -QNetworkConfigurationManager mgr; -QList<QNetworkConfiguration> activeConfigs = mgr.allConfigurations(QNetworkConfiguration::Active); -if (activeConfigs.count() > 0) - Q_ASSERT(mgr.isOnline()); -else - Q_ASSERT(!mgr.isOnline()); -//! [0] diff --git a/src/network/doc/snippets/code/src_network_bearer_qnetworksession.cpp b/src/network/doc/snippets/code/src_network_bearer_qnetworksession.cpp deleted file mode 100644 index b88b6d1768..0000000000 --- a/src/network/doc/snippets/code/src_network_bearer_qnetworksession.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//! [0] - session->open(); - if (session->waitForOpened(1000)) - qDebug("Open!"); -//! [0] - -//! [1] - QNetworkConfigurationManager mgr; - QNetworkConfiguration ap = mgr.defaultConfiguration(); - QNetworkSession *session = new QNetworkSession(ap); - ... //code activates session - - QString ident = session->sessionProperty("ActiveConfiguration").toString(); - if ( ap.type() == QNetworkConfiguration::ServiceNetwork ) { - Q_ASSERT( ap.identifier() != ident ); - Q_ASSERT( ap.children().contains( mgr.configurationFromIdentifier(ident) ) ); - } else if ( ap.type() == QNetworkConfiguration::InternetAccessPoint ) { - Q_ASSERT( ap.identifier() == ident ); - } - \endcode -//! [1] diff --git a/src/network/doc/snippets/code/src_network_ssl_qsslcertificate.cpp b/src/network/doc/snippets/code/src_network_ssl_qsslcertificate.cpp index b381ae7b6e..62502afe61 100644 --- a/src/network/doc/snippets/code/src_network_ssl_qsslcertificate.cpp +++ b/src/network/doc/snippets/code/src_network_ssl_qsslcertificate.cpp @@ -48,14 +48,6 @@ ** ****************************************************************************/ -//! [0] -const auto certs = QSslCertificate::fromPath("C:/ssl/certificate.*.pem", - QSsl::Pem, QRegExp::Wildcard); -for (const QSslCertificate &cert : certs) { - qDebug() << cert.issuerInfo(QSslCertificate::Organization); -} -//! [0] - //! [1] const auto certs = QSslCertificate::fromPath("C:/ssl/certificate.*.pem", QSsl::Pem, QSslCertificate::Wildcard); diff --git a/src/network/doc/src/bearermanagement.qdoc b/src/network/doc/src/bearermanagement.qdoc deleted file mode 100644 index 8aec894269..0000000000 --- a/src/network/doc/src/bearermanagement.qdoc +++ /dev/null @@ -1,242 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: https://www.gnu.org/licenses/fdl-1.3.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! -\page bearer-management.html - -\title Bearer Management -\brief An API to control the system's connectivity state. - -\warning Bearer management is deprecated and will be removed in Qt 6.0. - -Bearer Management controls the connectivity state of the system so that -the user can start or stop interfaces or roam transparently between -access points. - -\tableofcontents - - -\section1 Overview - -The Bearer Management API controls the system's connectivity state. This -incorporates simple information such as whether the device is online and -how many interfaces there are as well as enables the application developer -to start, stop network interfaces and influences other connection specific -details. Depending on the platform's capabilities it may even provide -session management so that a network interface remains up for as long as -clients have a registered interest in them while at the same time -optimizes the interface's uptime. - -This API does not provide support for management of network configurations -themselves. It is up to the platform to provide infrastructure which -enables to user to create, edit or delete network configurations. - -\section2 The API in Detail - -Computer systems manage their network interfaces via a set of configurations. -Each configuration describes a set of parameters which instruct the system -how a particular network interface is started. One of the most simplistic -examples might be an Ethernet configuration that links a network card to a -DHCP server. A more complex example might be a Wireless LAN configuration -which may comprise of hardware details such as the WLAN card address, -WLAN access point details (e.g ESSID, encryption details) and user specific -information (for example username and password). Once the network interface -was configured and started according to the configuration blue print, -multiple applications are free to use this link layer connection/session -for their own socket operations. Note that the QNetworkConfiguration object -only provides limited information about the configuration details themselves. -It's main purpose is to act as a configuration identifier through which link -layer connections can be created, destroyed and monitored. - -QNetworkSession provides two types of use cases. It enables the monitoring of -physical network interfaces and management of network sessions. Network sessions -are a common feature on mobile devices where multiple applications -can request network sessions as they see fit. The system consolidates and tracks -active network sessions for the same network interface by maintaining the link -layer connections until the last session has been closed. The subsequent table -lists the major QNetworkSession functions and how they fit into the session and -hardware management categories: - -\table 60% -\header \li Interface management \li Session management -\row \li QNetworkSession::stop() \li QNetworkSession::open() -\row \li QNetworkSession::interface() \li QNetworkSession::close() -\row \li QNetworkSession::state() \li QNetworkSession::isOpen() -\row \li QNetworkSession::bytesWritten() \li QNetworkSession::migrate() -\row \li QNetworkSession::bytesReceived() \li QNetworkSession::ignore() -\row \li QNetworkSession::activeTime() \li QNetworkSession::accept() -\row \li QNetworkSession::stateChanged() \li QNetworkSession::reject() -\row \li \li QNetworkSession::opened() -\row \li \li QNetworkSession::closed() -\endtable - -The state of the session represents the state of the underlying access point -whereas the session's openness implies the networking/connectivity state available -to the current process. - -Possible use cases for interface management are network management related -applications which intend to monitor the connectivity state but do not engage -in network communication themselves. Any application wanting to open a socket -to a remote address will typically use session management related functionality. - -\section3 Service networks - -Some mobile platforms use the concept of grouped access points (also -called SNAP or Service Network Access Point). In principle multiple -configurations are grouped together and possibly even prioritized when -compared to each other. This is useful for use cases where all -configurations serve a similar purpose or context. A common context could -be that they provide access to the public Internet or possibly only to the -office Intranet. By providing a pool of configurations the system can make -a decision based on given priorities which usually map to factors such as -speed, availability and cost. Furthermore the system can automatically -roam from one access point to the next one while ensuring minimal impact on -the user experience. - -The \l{QNetworkConfiguration::Type} flag specifies to what category a -configuration belongs. The \l{QNetworkConfiguration::InternetAccessPoint} -type is the most common example. It represents a configuration that can be -used to create a session. The above mentioned grouping behavior is provided -by \l {QNetworkConfiguration::ServiceNetwork} configurations. Service -networks are place holders until such time when the user attempts to -\l {QNetworkSession::open()}{open()} a new session. At that point in time -the system determines which of the configurations \l{QNetworkConfiguration::children()} -is best to use. The selection algorithm is provided by the platform and is usually managed -by network settings applications. A service network can only have one level of indirection -which implies children can only be of type \l {QNetworkConfiguration::InternetAccessPoint}. - -Most systems allow the user to define the systems default configuration. -Usually the default behavior is either a service network, a particular -Internet access point or the user instructs the platform to ask the user -once an application requests the network. User interaction is generally -implemented by some sort of system dialog which shows up at the appropriate -point in time. The application does not have to handle the user input. This -API provides the \l QNetworkConfigurationManager::defaultConfiguration() -call which serves a similar purpose. The subsequent code snippet provides -a quick way how an application can quickly create a new network session -without (or only minimal) user interaction: - -\code - // Set Internet Access Point - QNetworkConfigurationManager manager; - const bool canStartIAP = (manager.capabilities() - & QNetworkConfigurationManager::CanStartAndStopInterfaces); - // Is there default access point, use it - QNetworkConfiguration cfg = manager.defaultConfiguration(); - if (!cfg.isValid() || (!canStartIAP && cfg.state() != QNetworkConfiguration::Active)) { - QMessageBox::information(this, tr("Network"), tr( - "No Access Point found.")); - return; - } - - session = new QNetworkSession(cfg, this); - session->open(); - session->waitForOpened(-1); -\endcode - -To accommodate the "Ask user" use case the default configuration can be of -type QNetworkConfiguration::UserChoice. A user choice configuration is -resolved as part of the \l {QNetworkSession::open()} call. Note that a -\l{QNetworkConfiguration::UserChoice}{UserChoice} configuration is only -ever returned via \l {QNetworkConfigurationManager::defaultConfiguration()} -and not \l QNetworkConfigurationManager::allConfigurations(). - -On systems which do not maintain a list of -\l {QNetworkConfigurationManager::defaultConfiguration()}{defaultConfiguration()} -an invalid configuration is returned. A possible workaround could be to -implement a custom dialog which is populated based on what -\l QNetworkConfigurationManager::allConfigurations() returns. - -\section3 Managing network sessions - -A QNetworkSession object separates a \l {QNetworkSession::state()}{state()} -and an \l{QNetworkSession::isOpen()}{isOpen()} condition. - -The state() attribute enables developers to detect whether the system -currently maintains a global network session for the given -QNetworkConfiguration. If \l {QNetworkSession::isOpen()}{isOpen()} -returns \c true the QNetworkSession instance at hand was at least one of the -entities requesting the global network session. This distinction is -required to support the notion of session registrations. For as long as -there are one or more open QNetworkSession instances the underlying -network interface is not shut down. Therefore the session -\l{QNetworkSession::state()}{state()} can be used to monitor the state of -network interfaces. - -An open session is created by calling \l {QNetworkSession::open()} and -closed via \l{QNetworkSession::close()}, respectively. If the session -is \l{QNetworkSession::Disconnected}{disconnected} at the time of the -\l{QNetworkSession::open()}{open()} call the underlying interface is started; -otherwise only the reference counter against the global session is -incremented. The opposite behavior can be observed when using -\l{QNetworkSession::close()}{close()}. - -In some use cases it may be necessary to turn the interface off despite of -open sessions. This can be achieved by calling -\l{QNetworkSession::stop()}{stop()}. An example use case could be a -network manager type of application allowing the user to control the -overall state of the devices connectivity. - -Global (inter-process) session support is platform dependent and can be -detected via \l {QNetworkConfigurationManager::SystemSessionSupport}. -If the system does not support global session calling -\l{QNetworkSession::close()}{close()} never stops the interface. - -\section3 Roaming - -Roaming is the process of reconnecting a device from one network to another -while minimizing the impact on the application. The system notifies the application -about link layer changes so that the required preparation can be taken. -The most common reaction would be to reinitialize sockets and to renegotiate -stateful connections with other parties. In the most extreme cases applications -may even prevent the roaming altogether. - -Roaming is initiated when the system determines that a more appropriate access point -becomes available to the user. In general such a decision is based on cost, network speed -or network type (access to certain private networks may only be provided via certain access points). -Almost all devices providing roaming support have some form of global configuration application -enabling the user to define such groups of access points (service networks) and priorities. - -This API supports two types of roaming. Application level roaming (ALR) -provides the most control over the process. Applications will be notified about upcoming -link layer changes and get the opportunity to test the new access point. Eventually they can -reject or accept the link layer change. The second form of roaming is referred to as Forced Roaming. -The system simply changes the link layer without consulting the application. It is up to -the application to detect that some of its internal socket may have become invalid. As a consequence -it has to reinitialize those sockets and reestablish the previous user session without -any interruption. Forced roaming has the advantage that applications don't have to -manage the entire roaming process by themselves. - -QNetworkSession is the central class for managing roaming related issues. - -\section3 Platform capabilities - -Some API features are not available on all platforms. The -\l QNetworkConfigurationManager::Capability should be used to detect -platform features at runtime. - -*/ diff --git a/src/network/doc/src/network-programming.qdoc b/src/network/doc/src/network-programming.qdoc index 654227f971..96bbd8d38b 100644 --- a/src/network/doc/src/network-programming.qdoc +++ b/src/network/doc/src/network-programming.qdoc @@ -43,9 +43,6 @@ QTcpServer and QUdpSocket that represent low level network concepts, and high level classes such as QNetworkRequest, QNetworkReply and QNetworkAccessManager to perform network operations using common protocols. - It also offers classes such as QNetworkConfiguration, - QNetworkConfigurationManager and QNetworkSession that implement bearer - management. \tableofcontents diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri index 110d9f56bf..7dd5b1d97e 100644 --- a/src/network/kernel/kernel.pri +++ b/src/network/kernel/kernel.pri @@ -26,6 +26,13 @@ SOURCES += kernel/qauthenticator.cpp \ kernel/qnetworkinterface.cpp \ kernel/qnetworkproxy.cpp + +qtConfig(topleveldomain) { + HEADERS += kernel/qurltlds_p.h \ + kernel/qtldurl_p.h + SOURCES += kernel/qtldurl.cpp +} + qtConfig(ftp) { HEADERS += kernel/qurlinfo_p.h SOURCES += kernel/qurlinfo.cpp diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp index ed1c23ed6e..b9fc129685 100644 --- a/src/network/kernel/qhostaddress.cpp +++ b/src/network/kernel/qhostaddress.cpp @@ -1333,7 +1333,7 @@ QDebug operator<<(QDebug d, const QHostAddress &address) \relates QHostAddress Returns a hash of the host address \a key, using \a seed to seed the calculation. */ -uint qHash(const QHostAddress &key, uint seed) noexcept +size_t qHash(const QHostAddress &key, size_t seed) noexcept { return qHashBits(key.d->a6.c, 16, seed); } diff --git a/src/network/kernel/qhostaddress.h b/src/network/kernel/qhostaddress.h index 799247695e..ffa08aca30 100644 --- a/src/network/kernel/qhostaddress.h +++ b/src/network/kernel/qhostaddress.h @@ -66,7 +66,7 @@ typedef QIPv6Address Q_IPV6ADDR; class QHostAddress; // qHash is a friend, but we can't use default arguments for friends (§8.3.6.4) -Q_NETWORK_EXPORT uint qHash(const QHostAddress &key, uint seed = 0) noexcept; +Q_NETWORK_EXPORT size_t qHash(const QHostAddress &key, size_t seed = 0) noexcept; class Q_NETWORK_EXPORT QHostAddress { @@ -154,7 +154,7 @@ public: static QPair<QHostAddress, int> parseSubnet(const QString &subnet); - friend Q_NETWORK_EXPORT uint qHash(const QHostAddress &key, uint seed) noexcept; + friend Q_NETWORK_EXPORT size_t qHash(const QHostAddress &key, size_t seed) noexcept; protected: friend class QHostAddressPrivate; QExplicitlySharedDataPointer<QHostAddressPrivate> d; diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp index 93be053ef3..115f3445b9 100644 --- a/src/network/kernel/qhostinfo.cpp +++ b/src/network/kernel/qhostinfo.cpp @@ -51,7 +51,6 @@ #include <qstringlist.h> #include <qthread.h> #include <qurl.h> -#include <private/qnetworksession_p.h> #include <algorithm> diff --git a/src/network/kernel/qhostinfo_p.h b/src/network/kernel/qhostinfo_p.h index d7875a0673..cc34d575b2 100644 --- a/src/network/kernel/qhostinfo_p.h +++ b/src/network/kernel/qhostinfo_p.h @@ -70,7 +70,6 @@ #include <QElapsedTimer> #include <QCache> -#include <QNetworkSession> #include <QSharedPointer> #include <atomic> diff --git a/src/network/kernel/qnetworkinterface.h b/src/network/kernel/qnetworkinterface.h index 4caedaa38f..c65ea58860 100644 --- a/src/network/kernel/qnetworkinterface.h +++ b/src/network/kernel/qnetworkinterface.h @@ -50,7 +50,6 @@ QT_BEGIN_NAMESPACE class QDeadlineTimer; -template<typename T> class QList; class QNetworkAddressEntryPrivate; class Q_NETWORK_EXPORT QNetworkAddressEntry diff --git a/src/network/kernel/qnetworkproxy.cpp b/src/network/kernel/qnetworkproxy.cpp index 3cabdd0bd5..75f81a0037 100644 --- a/src/network/kernel/qnetworkproxy.cpp +++ b/src/network/kernel/qnetworkproxy.cpp @@ -241,10 +241,6 @@ #include "qstringlist.h" #include "qurl.h" -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section -#include <QtNetwork/QNetworkConfiguration> -#endif - QT_BEGIN_NAMESPACE class QSocks5SocketEngineHandler; @@ -1128,73 +1124,6 @@ QNetworkProxyQuery::QNetworkProxyQuery(quint16 bindPort, const QString &protocol d->type = queryType; } -#if !defined(QT_NO_BEARERMANAGEMENT) && QT_DEPRECATED_SINCE(5, 10) -/*! - \deprecated - - Constructs a QNetworkProxyQuery with the URL \a requestUrl and - sets the query type to \a queryType. The specified \a networkConfiguration - parameter is ignored. - - \sa protocolTag(), peerHostName(), peerPort(), networkConfiguration() -*/ -QNetworkProxyQuery::QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration, - const QUrl &requestUrl, QueryType queryType) -{ - Q_UNUSED(networkConfiguration) - d->remote = requestUrl; - d->type = queryType; -} - -/*! - \deprecated - - Constructs a QNetworkProxyQuery of type \a queryType and sets the - protocol tag to be \a protocolTag. This constructor is suitable - for QNetworkProxyQuery::TcpSocket queries, because it sets the - peer hostname to \a hostname and the peer's port number to \a - port. The specified \a networkConfiguration parameter is ignored. - - \sa networkConfiguration() -*/ -QNetworkProxyQuery::QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration, - const QString &hostname, int port, - const QString &protocolTag, - QueryType queryType) -{ - Q_UNUSED(networkConfiguration); - d->remote.setScheme(protocolTag); - d->remote.setHost(hostname); - d->remote.setPort(port); - d->type = queryType; -} - -/*! - \deprecated - - Constructs a QNetworkProxyQuery of type \a queryType and sets the - protocol tag to be \a protocolTag. This constructor is suitable - for QNetworkProxyQuery::TcpSocket queries because it sets the - local port number to \a bindPort. The specified \a networkConfiguration - parameter is ignored. - - Note that \a bindPort is of type quint16 to indicate the exact - port number that is requested. The value of -1 (unknown) is not - allowed in this context. - - \sa localPort(), networkConfiguration() -*/ -QNetworkProxyQuery::QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration, - quint16 bindPort, const QString &protocolTag, - QueryType queryType) -{ - Q_UNUSED(networkConfiguration); - d->remote.setScheme(protocolTag); - d->localPort = bindPort; - d->type = queryType; -} -#endif // !defined(QT_NO_BEARERMANAGEMENT) && QT_DEPRECATED_SINCE(5, 10) - /*! Constructs a QNetworkProxyQuery object that is a copy of \a other. */ @@ -1417,33 +1346,6 @@ void QNetworkProxyQuery::setUrl(const QUrl &url) d->remote = url; } -#if !defined(QT_NO_BEARERMANAGEMENT) && QT_DEPRECATED_SINCE(5, 10) -/*! - \deprecated - - Returns QNetworkConfiguration(). - - \sa setNetworkConfiguration() -*/ -QNetworkConfiguration QNetworkProxyQuery::networkConfiguration() const -{ - return QNetworkConfiguration(); -} - -/*! - \deprecated - - This function does nothing. The specified \a networkConfiguration parameter - is ignored. - - \sa networkConfiguration() -*/ -void QNetworkProxyQuery::setNetworkConfiguration(const QNetworkConfiguration &networkConfiguration) -{ - Q_UNUSED(networkConfiguration); -} -#endif // !defined(QT_NO_BEARERMANAGEMENT) && QT_DEPRECATED_SINCE(5, 10) - /*! \class QNetworkProxyFactory \brief The QNetworkProxyFactory class provides fine-grained proxy selection. diff --git a/src/network/kernel/qnetworkproxy.h b/src/network/kernel/qnetworkproxy.h index d267e744e3..1f0409e8ab 100644 --- a/src/network/kernel/qnetworkproxy.h +++ b/src/network/kernel/qnetworkproxy.h @@ -51,7 +51,6 @@ QT_BEGIN_NAMESPACE class QUrl; -class QNetworkConfiguration; class QNetworkProxyQueryPrivate; class Q_NETWORK_EXPORT QNetworkProxyQuery @@ -75,22 +74,6 @@ public: QueryType queryType = TcpSocket); explicit QNetworkProxyQuery(quint16 bindPort, const QString &protocolTag = QString(), QueryType queryType = TcpServer); -#if !defined(QT_NO_BEARERMANAGEMENT) && QT_DEPRECATED_SINCE(5, 10) -QT_WARNING_PUSH -QT_WARNING_DISABLE_DEPRECATED - Q_DECL_DEPRECATED_X("QNetworkConfiguration support in QNetworkProxy is deprecated") - QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration, - const QUrl &requestUrl, QueryType queryType = UrlRequest); - Q_DECL_DEPRECATED_X("QNetworkConfiguration support in QNetworkProxy is deprecated") - QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration, - const QString &hostname, int port, const QString &protocolTag = QString(), - QueryType queryType = TcpSocket); - Q_DECL_DEPRECATED_X("QNetworkConfiguration support in QNetworkProxy is deprecated") - QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration, - quint16 bindPort, const QString &protocolTag = QString(), - QueryType queryType = TcpServer); -QT_WARNING_POP -#endif QNetworkProxyQuery(const QNetworkProxyQuery &other); QNetworkProxyQuery &operator=(QNetworkProxyQuery &&other) noexcept { swap(other); return *this; } QNetworkProxyQuery &operator=(const QNetworkProxyQuery &other); @@ -120,16 +103,6 @@ QT_WARNING_POP QUrl url() const; void setUrl(const QUrl &url); -#if !defined(QT_NO_BEARERMANAGEMENT) && QT_DEPRECATED_SINCE(5, 10) -QT_WARNING_PUSH -QT_WARNING_DISABLE_DEPRECATED - Q_DECL_DEPRECATED_X("QNetworkConfiguration support in QNetworkProxy is deprecated") - QNetworkConfiguration networkConfiguration() const; - Q_DECL_DEPRECATED_X("QNetworkConfiguration support in QNetworkProxy is deprecated") - void setNetworkConfiguration(const QNetworkConfiguration &networkConfiguration); -QT_WARNING_POP -#endif - private: QSharedDataPointer<QNetworkProxyQueryPrivate> d; }; diff --git a/src/network/kernel/qnetworkproxy_mac.cpp b/src/network/kernel/qnetworkproxy_mac.cpp index 67fda24ea6..4c582bfa71 100644 --- a/src/network/kernel/qnetworkproxy_mac.cpp +++ b/src/network/kernel/qnetworkproxy_mac.cpp @@ -45,7 +45,7 @@ #include <CoreFoundation/CoreFoundation.h> #include <SystemConfiguration/SystemConfiguration.h> -#include <QtCore/QRegExp> +#include <QtCore/QRegularExpression> #include <QtCore/QStringList> #include <QtCore/QUrl> #include <QtCore/qendian.h> @@ -110,8 +110,9 @@ static bool isHostExcluded(CFDictionaryRef dict, const QString &host) return true; // excluded } else { // do wildcard matching - QRegExp rx(entry, Qt::CaseInsensitive, QRegExp::Wildcard); - if (rx.exactMatch(host)) + QRegularExpression rx(QRegularExpression::wildcardToRegularExpression(entry), + QRegularExpression::CaseInsensitiveOption); + if (rx.match(host).hasMatch()) return true; } } diff --git a/src/network/kernel/qnetworkproxy_win.cpp b/src/network/kernel/qnetworkproxy_win.cpp index 56397814b0..dffc0adf8f 100644 --- a/src/network/kernel/qnetworkproxy_win.cpp +++ b/src/network/kernel/qnetworkproxy_win.cpp @@ -43,7 +43,7 @@ #include <qmutex.h> #include <qstringlist.h> -#include <qregexp.h> +#include <qregularexpression.h> #include <qurl.h> #include <private/qsystemlibrary_p.h> #include <qnetworkinterface.h> @@ -212,8 +212,9 @@ static bool isBypassed(const QString &host, const QStringList &bypassList) return true; // excluded } else { // do wildcard matching - QRegExp rx(entry, Qt::CaseInsensitive, QRegExp::Wildcard); - if (rx.exactMatch(host)) + QRegularExpression rx(QRegularExpression::wildcardToRegularExpression(entry), + QRegularExpression::CaseInsensitiveOption); + if (rx.match(host).hasMatch()) return true; } } diff --git a/src/network/kernel/qtldurl.cpp b/src/network/kernel/qtldurl.cpp new file mode 100644 index 0000000000..c2f7d1de26 --- /dev/null +++ b/src/network/kernel/qtldurl.cpp @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore 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 The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qglobal.h> + +#include <QtNetwork/private/qtnetworkglobal_p.h> + +#if QT_CONFIG(topleveldomain) + +#include "qplatformdefs.h" +#include "qurl.h" +#include "private/qurltlds_p.h" +#include "private/qtldurl_p.h" +#include "QtCore/qstring.h" +#include "QtCore/qvector.h" + +QT_BEGIN_NAMESPACE + +enum TLDMatchType { + ExactMatch, + SuffixMatch, + ExceptionMatch, +}; + +static bool containsTLDEntry(QStringView entry, TLDMatchType match) +{ + const QStringView matchSymbols[] = { + u"", + u"*", + u"!", + }; + const auto symbol = matchSymbols[match]; + int index = qt_hash(entry, qt_hash(symbol)) % tldCount; + + // select the right chunk from the big table + short chunk = 0; + uint chunkIndex = tldIndices[index], offset = 0; + while (chunk < tldChunkCount && tldIndices[index] >= tldChunks[chunk]) { + chunkIndex -= tldChunks[chunk]; + offset += tldChunks[chunk]; + chunk++; + } + + // check all the entries from the given index + while (chunkIndex < tldIndices[index+1] - offset) { + const auto utf8 = tldData[chunk] + chunkIndex; + if ((symbol.isEmpty() || QLatin1Char(*utf8) == symbol) && entry == QString::fromUtf8(utf8 + symbol.size())) + return true; + chunkIndex += qstrlen(utf8) + 1; // +1 for the ending \0 + } + return false; +} + +/*! + \internal + + Return the top-level-domain per Qt's copy of the Mozilla public suffix list of + \a domain. +*/ + +Q_NETWORK_EXPORT QString qTopLevelDomain(const QString &domain) +{ + const QString domainLower = domain.toLower(); + QVector<QStringRef> sections = domainLower.splitRef(QLatin1Char('.'), Qt::SkipEmptyParts); + if (sections.isEmpty()) + return QString(); + + QString level, tld; + for (int j = sections.count() - 1; j >= 0; --j) { + level.prepend(QLatin1Char('.') + sections.at(j)); + if (qIsEffectiveTLD(level.rightRef(level.size() - 1))) + tld = level; + } + return tld; +} + +/*! + \internal + + Return true if \a domain is a top-level-domain per Qt's copy of the Mozilla public suffix list. +*/ + +Q_NETWORK_EXPORT bool qIsEffectiveTLD(const QStringRef &domain) +{ + // for domain 'foo.bar.com': + // 1. return if TLD table contains 'foo.bar.com' + // 2. else if table contains '*.bar.com', + // 3. test that table does not contain '!foo.bar.com' + + if (containsTLDEntry(domain, ExactMatch)) // 1 + return true; + + const int dot = domain.indexOf(QLatin1Char('.')); + if (dot < 0) // Actual TLD: may be effective if the subject of a wildcard rule: + return containsTLDEntry(QString(QLatin1Char('.') + domain), SuffixMatch); + if (containsTLDEntry(domain.mid(dot), SuffixMatch)) // 2 + return !containsTLDEntry(domain, ExceptionMatch); // 3 + return false; +} + +QT_END_NAMESPACE + +#endif diff --git a/src/network/bearer/qbearerplugin_p.h b/src/network/kernel/qtldurl_p.h index ac787d0541..a6948cfd48 100644 --- a/src/network/bearer/qbearerplugin_p.h +++ b/src/network/kernel/qtldurl_p.h @@ -37,45 +37,35 @@ ** ****************************************************************************/ -#ifndef QBEARERPLUGIN_P_H -#define QBEARERPLUGIN_P_H +#ifndef QTLDURL_P_H +#define QTLDURL_P_H // // W A R N I N G // ------------- // -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to +// This file is not part of the Qt API. It exists for the convenience +// of qDecodeDataUrl. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include <QtNetwork/private/qtnetworkglobal_p.h> -#include "qbearerengine_p.h" +#include "QtCore/qurl.h" +#include "QtCore/qstring.h" -#include <QtCore/qplugin.h> -#include <QtCore/qfactoryinterface.h> - -#ifndef QT_NO_BEARERMANAGEMENT +QT_REQUIRE_CONFIG(topleveldomain); QT_BEGIN_NAMESPACE - -#define QBearerEngineFactoryInterface_iid "org.qt-project.Qt.QBearerEngineFactoryInterface" - -class Q_NETWORK_EXPORT QBearerEnginePlugin : public QObject +Q_NETWORK_EXPORT QString qTopLevelDomain(const QString &domain); +Q_NETWORK_EXPORT bool qIsEffectiveTLD(const QStringRef &domain); +inline bool qIsEffectiveTLD(const QString &domain) { - Q_OBJECT -public: - explicit QBearerEnginePlugin(QObject *parent = nullptr); - virtual ~QBearerEnginePlugin(); - - virtual QBearerEngine *create(const QString &key) const = 0; -}; + return qIsEffectiveTLD(QStringRef(&domain)); +} QT_END_NAMESPACE -#endif // QT_NO_BEARERMANAGEMENT - -#endif // QBEARERPLUGIN_P_H +#endif // QDATAURL_P_H diff --git a/src/network/kernel/qurltlds_p.h b/src/network/kernel/qurltlds_p.h new file mode 100644 index 0000000000..1257c0e6e1 --- /dev/null +++ b/src/network/kernel/qurltlds_p.h @@ -0,0 +1,14467 @@ +// License: MPL 2.0/GPL 2.0/LGPL 3 +// +// The contents of this file are subject to the Mozilla Public License Version +// 2.0 (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// http://www.mozilla.org/MPL/ +// +// Software distributed under the License is distributed on an "AS IS" basis, +// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +// for the specific language governing rights and limitations under the +// License. +// +// The Original Code is the Public Suffix List. +// +// The Initial Developer of the Original Code is +// Jo Hermans <jo.hermans@gmail.com>. +// Portions created by the Initial Developer are Copyright (C) 2007 +// the Initial Developer. All Rights Reserved. +// +// Contributor(s): +// Ruben Arakelyan <ruben@wackomenace.co.uk> +// Gervase Markham <gerv@gerv.net> +// Pamela Greene <pamg.bugs@gmail.com> +// David Triendl <david@triendl.name> +// Jothan Frakes <jothan@gmail.com> +// The kind representatives of many TLD registries +// +// Alternatively, the contents of this file may be used under the terms of +// either the GNU General Public License Version 2 or later (the "GPL"), or +// the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +// in which case the provisions of the GPL or the LGPL are applicable instead +// of those above. If you wish to allow use of your version of this file only +// under the terms of either the GPL or the LGPL, and not to allow others to +// use your version of this file under the terms of the MPL, indicate your +// decision by deleting the provisions above and replace them with the notice +// and other provisions required by the GPL or the LGPL. If you do not delete +// the provisions above, a recipient may use your version of this file under +// the terms of any one of the MPL, the GPL or the LGPL. +// + +#ifndef QURLTLD_P_H +#define QURLTLD_P_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 and Core framework. This header file may change from +// version to version without notice, or even be removed. +// +// We mean it. +// + +#include <QtNetwork/private/qtnetworkglobal_p.h> + +QT_BEGIN_NAMESPACE + +// note to maintainer: +// this file should be updated before each release -> +// for instructions see the program at +// util/corelib/qurl-generateTLDs/ + +static const quint16 tldCount = 8830; +static const quint32 tldIndices[] = { +0, +16, +28, +45, +45, +45, +78, +78, +106, +128, +169, +202, +220, +237, +237, +260, +260, +270, +270, +281, +302, +302, +302, +302, +328, +337, +369, +369, +382, +382, +396, +409, +422, +422, +422, +422, +439, +454, +472, +506, +506, +506, +506, +552, +552, +565, +565, +570, +604, +604, +604, +604, +618, +636, +641, +656, +656, +656, +660, +670, +670, +670, +674, +674, +707, +714, +768, +792, +815, +821, +873, +873, +883, +883, +893, +893, +893, +893, +899, +899, +909, +917, +925, +949, +949, +962, +962, +962, +975, +1011, +1011, +1048, +1064, +1064, +1064, +1071, +1085, +1085, +1113, +1149, +1157, +1157, +1157, +1176, +1176, +1176, +1176, +1191, +1212, +1217, +1228, +1256, +1256, +1256, +1274, +1274, +1301, +1354, +1386, +1386, +1430, +1450, +1450, +1450, +1450, +1450, +1472, +1472, +1491, +1491, +1500, +1500, +1531, +1531, +1539, +1551, +1561, +1588, +1588, +1603, +1620, +1640, +1640, +1650, +1650, +1680, +1680, +1680, +1680, +1680, +1685, +1704, +1704, +1704, +1710, +1722, +1722, +1722, +1732, +1732, +1754, +1754, +1769, +1791, +1803, +1803, +1803, +1809, +1809, +1845, +1866, +1900, +1912, +1912, +1919, +1935, +1935, +1944, +1944, +1944, +1944, +1951, +1970, +1970, +1998, +1998, +2012, +2017, +2017, +2017, +2022, +2030, +2030, +2036, +2060, +2065, +2065, +2088, +2118, +2157, +2177, +2177, +2177, +2193, +2202, +2219, +2219, +2219, +2219, +2219, +2229, +2229, +2229, +2229, +2229, +2229, +2238, +2238, +2238, +2238, +2238, +2238, +2238, +2252, +2273, +2291, +2291, +2295, +2295, +2308, +2308, +2308, +2313, +2353, +2353, +2353, +2353, +2378, +2378, +2397, +2397, +2402, +2416, +2434, +2459, +2466, +2473, +2491, +2513, +2513, +2513, +2518, +2526, +2526, +2541, +2557, +2566, +2566, +2583, +2599, +2610, +2610, +2625, +2643, +2643, +2676, +2711, +2711, +2728, +2728, +2738, +2738, +2746, +2746, +2759, +2792, +2792, +2812, +2812, +2820, +2831, +2831, +2837, +2864, +2884, +2915, +2919, +2919, +2919, +2925, +2932, +2960, +2960, +2964, +2983, +3007, +3037, +3046, +3046, +3062, +3071, +3092, +3100, +3100, +3143, +3143, +3143, +3167, +3167, +3167, +3167, +3167, +3174, +3183, +3192, +3201, +3221, +3221, +3253, +3269, +3286, +3310, +3310, +3324, +3336, +3336, +3336, +3336, +3352, +3391, +3391, +3420, +3426, +3441, +3441, +3441, +3448, +3466, +3466, +3481, +3493, +3526, +3526, +3551, +3558, +3558, +3583, +3583, +3583, +3583, +3620, +3620, +3620, +3626, +3646, +3646, +3690, +3729, +3736, +3736, +3776, +3798, +3818, +3836, +3857, +3857, +3880, +3880, +3890, +3908, +3908, +3908, +3917, +3933, +3933, +3933, +3955, +3955, +3968, +3982, +3999, +3999, +4006, +4024, +4059, +4059, +4059, +4075, +4092, +4092, +4108, +4138, +4138, +4138, +4138, +4138, +4165, +4171, +4177, +4184, +4202, +4222, +4222, +4238, +4261, +4268, +4268, +4287, +4293, +4306, +4312, +4326, +4383, +4401, +4413, +4448, +4453, +4476, +4512, +4522, +4559, +4575, +4575, +4575, +4575, +4575, +4593, +4652, +4652, +4652, +4652, +4675, +4685, +4685, +4696, +4727, +4739, +4739, +4746, +4746, +4767, +4779, +4799, +4799, +4805, +4805, +4812, +4812, +4826, +4846, +4846, +4862, +4868, +4887, +4887, +4887, +4887, +4887, +4915, +4933, +4950, +4968, +4972, +4985, +4985, +4985, +4985, +4997, +5003, +5003, +5019, +5019, +5028, +5053, +5059, +5059, +5059, +5059, +5078, +5078, +5091, +5124, +5151, +5180, +5220, +5220, +5239, +5263, +5274, +5274, +5288, +5303, +5313, +5330, +5347, +5384, +5384, +5401, +5407, +5423, +5423, +5423, +5429, +5451, +5474, +5496, +5518, +5530, +5540, +5540, +5562, +5591, +5597, +5597, +5614, +5618, +5647, +5657, +5657, +5657, +5679, +5696, +5696, +5705, +5712, +5735, +5735, +5764, +5764, +5764, +5764, +5764, +5772, +5776, +5791, +5806, +5812, +5833, +5853, +5873, +5873, +5891, +5903, +5916, +5916, +5916, +5936, +5954, +5964, +5964, +5975, +5975, +5985, +6020, +6043, +6056, +6056, +6056, +6067, +6067, +6077, +6077, +6083, +6092, +6101, +6111, +6132, +6149, +6155, +6159, +6159, +6217, +6226, +6226, +6226, +6286, +6286, +6286, +6298, +6336, +6336, +6336, +6392, +6392, +6401, +6425, +6433, +6444, +6466, +6483, +6493, +6493, +6505, +6516, +6540, +6547, +6547, +6564, +6564, +6604, +6604, +6604, +6612, +6612, +6633, +6633, +6633, +6660, +6681, +6681, +6681, +6681, +6699, +6756, +6768, +6799, +6817, +6817, +6838, +6838, +6838, +6853, +6875, +6875, +6875, +6887, +6887, +6893, +6893, +6893, +6933, +6933, +6940, +6947, +6969, +6983, +6983, +6983, +6983, +7017, +7017, +7024, +7024, +7042, +7051, +7058, +7058, +7066, +7066, +7066, +7092, +7092, +7092, +7092, +7092, +7116, +7132, +7132, +7139, +7172, +7205, +7205, +7217, +7217, +7217, +7225, +7225, +7225, +7236, +7247, +7258, +7258, +7265, +7276, +7317, +7322, +7362, +7382, +7382, +7382, +7387, +7387, +7387, +7387, +7387, +7387, +7415, +7474, +7486, +7486, +7495, +7511, +7524, +7549, +7581, +7591, +7591, +7591, +7591, +7598, +7598, +7634, +7643, +7668, +7668, +7675, +7697, +7697, +7697, +7706, +7773, +7804, +7814, +7814, +7828, +7828, +7828, +7828, +7848, +7848, +7865, +7884, +7899, +7906, +7924, +7924, +7955, +8003, +8020, +8034, +8073, +8073, +8073, +8073, +8073, +8073, +8073, +8083, +8098, +8120, +8137, +8144, +8144, +8175, +8186, +8186, +8210, +8217, +8217, +8217, +8217, +8244, +8249, +8249, +8249, +8249, +8267, +8267, +8267, +8267, +8280, +8280, +8280, +8302, +8330, +8357, +8357, +8388, +8424, +8424, +8444, +8451, +8468, +8484, +8500, +8500, +8500, +8518, +8518, +8518, +8518, +8518, +8544, +8563, +8582, +8592, +8592, +8607, +8627, +8654, +8723, +8723, +8744, +8744, +8763, +8811, +8811, +8811, +8824, +8846, +8891, +8909, +8939, +8939, +8939, +8974, +8984, +8996, +8996, +8996, +9003, +9023, +9035, +9052, +9052, +9052, +9062, +9075, +9075, +9093, +9093, +9106, +9112, +9112, +9142, +9155, +9159, +9159, +9159, +9166, +9173, +9187, +9217, +9239, +9256, +9256, +9277, +9302, +9302, +9322, +9341, +9353, +9353, +9353, +9366, +9370, +9382, +9382, +9382, +9382, +9382, +9401, +9401, +9415, +9427, +9448, +9483, +9500, +9551, +9582, +9582, +9582, +9594, +9625, +9635, +9645, +9674, +9701, +9701, +9701, +9731, +9743, +9753, +9803, +9820, +9820, +9820, +9820, +9846, +9861, +9873, +9873, +9873, +9897, +9904, +9920, +9928, +9928, +9928, +9950, +9950, +9950, +9950, +9950, +9950, +9950, +9965, +9984, +9984, +9991, +9991, +10010, +10054, +10061, +10061, +10061, +10061, +10061, +10061, +10115, +10115, +10122, +10126, +10126, +10126, +10126, +10137, +10137, +10143, +10143, +10170, +10170, +10186, +10186, +10186, +10186, +10186, +10186, +10186, +10193, +10201, +10201, +10201, +10216, +10225, +10225, +10262, +10269, +10284, +10305, +10352, +10370, +10379, +10399, +10399, +10399, +10399, +10399, +10410, +10430, +10436, +10436, +10436, +10464, +10464, +10464, +10475, +10492, +10513, +10513, +10522, +10541, +10551, +10569, +10575, +10599, +10599, +10618, +10618, +10618, +10641, +10641, +10641, +10641, +10641, +10659, +10659, +10677, +10677, +10713, +10713, +10713, +10756, +10771, +10785, +10801, +10819, +10837, +10837, +10837, +10841, +10841, +10863, +10882, +10882, +10898, +10898, +10905, +10905, +10905, +10905, +10915, +10915, +10919, +10928, +10948, +10970, +10980, +10992, +10992, +11002, +11002, +11002, +11018, +11018, +11043, +11043, +11043, +11060, +11067, +11086, +11104, +11109, +11109, +11109, +11147, +11147, +11178, +11185, +11185, +11194, +11194, +11194, +11199, +11199, +11236, +11261, +11261, +11270, +11333, +11343, +11343, +11354, +11354, +11354, +11354, +11366, +11366, +11401, +11401, +11401, +11401, +11422, +11445, +11445, +11445, +11445, +11471, +11478, +11500, +11500, +11500, +11504, +11516, +11524, +11560, +11560, +11566, +11578, +11578, +11578, +11610, +11610, +11632, +11632, +11643, +11643, +11643, +11643, +11652, +11652, +11652, +11697, +11720, +11724, +11745, +11761, +11772, +11808, +11808, +11823, +11863, +11883, +11883, +11896, +11896, +11908, +11930, +11936, +11942, +11942, +11987, +12003, +12029, +12029, +12049, +12068, +12083, +12083, +12121, +12121, +12121, +12132, +12136, +12136, +12136, +12136, +12136, +12148, +12148, +12163, +12170, +12170, +12188, +12202, +12208, +12208, +12213, +12225, +12242, +12242, +12242, +12264, +12264, +12297, +12312, +12335, +12335, +12344, +12375, +12375, +12384, +12406, +12406, +12406, +12406, +12406, +12406, +12406, +12406, +12412, +12424, +12424, +12424, +12424, +12434, +12440, +12440, +12479, +12494, +12505, +12505, +12520, +12526, +12526, +12526, +12526, +12570, +12588, +12600, +12612, +12631, +12631, +12631, +12631, +12631, +12631, +12647, +12659, +12659, +12668, +12708, +12736, +12741, +12741, +12741, +12753, +12753, +12753, +12759, +12767, +12786, +12794, +12810, +12836, +12836, +12848, +12888, +12899, +12914, +12914, +12914, +12921, +12943, +12953, +12978, +12989, +12989, +12989, +13006, +13006, +13022, +13035, +13073, +13097, +13118, +13168, +13177, +13191, +13200, +13200, +13214, +13234, +13234, +13234, +13234, +13276, +13282, +13311, +13321, +13321, +13321, +13327, +13334, +13361, +13378, +13397, +13412, +13420, +13426, +13444, +13444, +13444, +13467, +13467, +13467, +13467, +13479, +13479, +13502, +13502, +13502, +13514, +13535, +13543, +13596, +13596, +13596, +13596, +13596, +13596, +13603, +13603, +13603, +13636, +13647, +13647, +13647, +13657, +13698, +13698, +13698, +13716, +13716, +13723, +13741, +13751, +13751, +13762, +13762, +13762, +13762, +13762, +13762, +13770, +13803, +13812, +13812, +13838, +13855, +13866, +13866, +13866, +13900, +13900, +13947, +13960, +13960, +13972, +13990, +13990, +14040, +14054, +14073, +14073, +14073, +14082, +14131, +14145, +14166, +14166, +14166, +14203, +14210, +14234, +14250, +14261, +14286, +14286, +14286, +14290, +14336, +14367, +14367, +14383, +14409, +14409, +14409, +14415, +14441, +14441, +14457, +14465, +14484, +14484, +14484, +14484, +14495, +14514, +14521, +14521, +14521, +14521, +14539, +14549, +14568, +14568, +14593, +14606, +14613, +14649, +14676, +14708, +14708, +14712, +14734, +14752, +14765, +14782, +14830, +14830, +14830, +14838, +14838, +14855, +14898, +14898, +14920, +14967, +14967, +14967, +14999, +15009, +15009, +15009, +15018, +15047, +15047, +15047, +15070, +15083, +15093, +15099, +15139, +15139, +15146, +15165, +15165, +15187, +15217, +15222, +15244, +15244, +15268, +15296, +15302, +15308, +15308, +15308, +15308, +15308, +15308, +15317, +15324, +15336, +15355, +15355, +15355, +15355, +15355, +15372, +15372, +15391, +15403, +15414, +15446, +15446, +15453, +15459, +15463, +15500, +15500, +15513, +15513, +15522, +15542, +15599, +15617, +15624, +15654, +15668, +15688, +15688, +15718, +15718, +15718, +15725, +15725, +15741, +15756, +15756, +15817, +15817, +15856, +15856, +15874, +15884, +15884, +15893, +15922, +15940, +15958, +15967, +15967, +15967, +15967, +15967, +15967, +15967, +15967, +15967, +15980, +15980, +15980, +16017, +16051, +16051, +16051, +16062, +16062, +16062, +16069, +16073, +16073, +16087, +16103, +16103, +16103, +16128, +16128, +16152, +16201, +16228, +16228, +16228, +16268, +16277, +16296, +16337, +16357, +16397, +16397, +16397, +16397, +16419, +16462, +16462, +16469, +16493, +16493, +16493, +16493, +16502, +16502, +16502, +16536, +16544, +16575, +16575, +16575, +16649, +16649, +16674, +16674, +16674, +16674, +16686, +16686, +16731, +16754, +16768, +16768, +16776, +16783, +16783, +16783, +16799, +16819, +16838, +16838, +16863, +16884, +16893, +16915, +16915, +16931, +16931, +16946, +16971, +16975, +17003, +17013, +17026, +17041, +17041, +17041, +17041, +17069, +17115, +17151, +17151, +17151, +17155, +17155, +17155, +17177, +17230, +17237, +17244, +17258, +17258, +17299, +17304, +17304, +17331, +17370, +17383, +17389, +17397, +17417, +17417, +17438, +17443, +17443, +17443, +17453, +17486, +17486, +17504, +17522, +17522, +17539, +17556, +17556, +17576, +17596, +17596, +17596, +17606, +17610, +17617, +17617, +17621, +17625, +17630, +17660, +17676, +17691, +17701, +17754, +17781, +17804, +17804, +17824, +17839, +17850, +17850, +17850, +17850, +17856, +17856, +17856, +17879, +17879, +17929, +17929, +17934, +17956, +17956, +17956, +17956, +17956, +17962, +17984, +18008, +18008, +18008, +18008, +18019, +18019, +18030, +18030, +18051, +18070, +18070, +18082, +18082, +18123, +18123, +18130, +18144, +18181, +18257, +18257, +18267, +18267, +18267, +18267, +18281, +18320, +18327, +18345, +18348, +18351, +18377, +18380, +18396, +18396, +18404, +18404, +18409, +18424, +18427, +18444, +18465, +18497, +18518, +18524, +18527, +18555, +18573, +18576, +18582, +18594, +18597, +18603, +18635, +18635, +18638, +18674, +18694, +18738, +18761, +18764, +18770, +18776, +18776, +18782, +18788, +18791, +18809, +18822, +18850, +18853, +18856, +18859, +18862, +18862, +18885, +18919, +18919, +18938, +18944, +18958, +18961, +18974, +18991, +19004, +19026, +19033, +19047, +19098, +19161, +19161, +19174, +19194, +19211, +19211, +19214, +19221, +19231, +19261, +19270, +19273, +19306, +19306, +19320, +19320, +19357, +19357, +19357, +19363, +19377, +19418, +19425, +19437, +19437, +19437, +19466, +19485, +19485, +19485, +19502, +19506, +19509, +19509, +19512, +19518, +19518, +19521, +19524, +19535, +19558, +19561, +19564, +19564, +19582, +19628, +19638, +19680, +19680, +19700, +19703, +19706, +19709, +19712, +19734, +19738, +19761, +19761, +19794, +19798, +19801, +19805, +19808, +19811, +19811, +19811, +19858, +19861, +19861, +19867, +19873, +19902, +19912, +19930, +19930, +19930, +19951, +19954, +19957, +19960, +19963, +19963, +19973, +20023, +20026, +20029, +20052, +20052, +20052, +20065, +20076, +20091, +20135, +20140, +20152, +20152, +20155, +20175, +20185, +20193, +20215, +20221, +20243, +20283, +20304, +20304, +20336, +20345, +20367, +20367, +20382, +20385, +20385, +20388, +20418, +20424, +20436, +20459, +20459, +20459, +20462, +20481, +20512, +20523, +20526, +20564, +20564, +20600, +20600, +20641, +20644, +20663, +20669, +20675, +20686, +20689, +20699, +20715, +20729, +20729, +20732, +20759, +20764, +20785, +20794, +20824, +20839, +20842, +20906, +20927, +20942, +20948, +20991, +21000, +21030, +21051, +21051, +21054, +21094, +21094, +21097, +21129, +21136, +21158, +21223, +21234, +21237, +21252, +21272, +21291, +21306, +21318, +21335, +21342, +21359, +21359, +21367, +21367, +21376, +21395, +21445, +21445, +21470, +21505, +21505, +21552, +21571, +21579, +21582, +21585, +21625, +21670, +21684, +21704, +21707, +21731, +21734, +21764, +21772, +21779, +21815, +21839, +21842, +21873, +21885, +21885, +21885, +21885, +21885, +21885, +21885, +21897, +21920, +21940, +21943, +21961, +21972, +21991, +21999, +21999, +22012, +22025, +22034, +22056, +22059, +22059, +22062, +22065, +22081, +22084, +22096, +22163, +22193, +22206, +22209, +22224, +22249, +22271, +22274, +22277, +22317, +22325, +22325, +22328, +22334, +22340, +22351, +22374, +22383, +22410, +22436, +22446, +22469, +22480, +22483, +22523, +22540, +22547, +22563, +22566, +22591, +22594, +22594, +22616, +22622, +22622, +22656, +22659, +22667, +22667, +22681, +22698, +22705, +22705, +22721, +22754, +22770, +22770, +22795, +22837, +22854, +22854, +22884, +22894, +22894, +22946, +22946, +22981, +22989, +22989, +23005, +23005, +23034, +23040, +23058, +23082, +23097, +23108, +23108, +23108, +23108, +23108, +23119, +23146, +23154, +23175, +23175, +23192, +23215, +23232, +23270, +23270, +23270, +23270, +23297, +23312, +23330, +23350, +23354, +23354, +23361, +23361, +23361, +23361, +23361, +23382, +23382, +23382, +23392, +23405, +23405, +23420, +23420, +23438, +23438, +23438, +23450, +23471, +23483, +23493, +23493, +23496, +23496, +23496, +23510, +23518, +23537, +23557, +23564, +23599, +23618, +23652, +23659, +23676, +23676, +23676, +23690, +23709, +23737, +23737, +23755, +23765, +23765, +23788, +23792, +23792, +23792, +23803, +23821, +23863, +23863, +23863, +23879, +23886, +23911, +23931, +23944, +23955, +23955, +23970, +23974, +23980, +24006, +24038, +24044, +24044, +24044, +24052, +24052, +24063, +24063, +24116, +24135, +24152, +24193, +24199, +24223, +24245, +24245, +24251, +24272, +24288, +24288, +24303, +24323, +24354, +24360, +24360, +24391, +24391, +24391, +24406, +24406, +24406, +24415, +24415, +24433, +24464, +24464, +24489, +24506, +24514, +24524, +24524, +24545, +24574, +24587, +24587, +24593, +24599, +24626, +24664, +24664, +24679, +24688, +24688, +24688, +24694, +24712, +24712, +24724, +24756, +24794, +24836, +24836, +24850, +24880, +24893, +24902, +24902, +24943, +24943, +24965, +24991, +25023, +25034, +25034, +25034, +25051, +25059, +25059, +25079, +25089, +25095, +25102, +25102, +25102, +25121, +25121, +25121, +25128, +25156, +25166, +25194, +25201, +25246, +25246, +25274, +25274, +25281, +25302, +25318, +25326, +25334, +25356, +25369, +25369, +25385, +25385, +25385, +25385, +25385, +25385, +25385, +25385, +25397, +25430, +25437, +25480, +25501, +25501, +25508, +25573, +25602, +25621, +25641, +25665, +25729, +25734, +25752, +25783, +25783, +25783, +25806, +25821, +25821, +25838, +25838, +25856, +25856, +25861, +25861, +25867, +25895, +25895, +25895, +25902, +25902, +25910, +25910, +25917, +25928, +25944, +25951, +25965, +25965, +25972, +25980, +25984, +25984, +25984, +26007, +26042, +26060, +26070, +26091, +26102, +26102, +26124, +26124, +26144, +26161, +26161, +26161, +26176, +26201, +26232, +26250, +26287, +26293, +26316, +26364, +26371, +26409, +26409, +26409, +26409, +26422, +26422, +26427, +26427, +26449, +26449, +26455, +26460, +26466, +26483, +26483, +26502, +26517, +26529, +26529, +26548, +26548, +26590, +26610, +26645, +26645, +26658, +26658, +26694, +26700, +26715, +26715, +26715, +26722, +26730, +26730, +26730, +26755, +26755, +26772, +26772, +26772, +26792, +26823, +26823, +26846, +26846, +26846, +26846, +26846, +26846, +26872, +26920, +26920, +26920, +26954, +26954, +26961, +26970, +26970, +26976, +26976, +27005, +27005, +27049, +27068, +27068, +27098, +27112, +27116, +27116, +27116, +27116, +27120, +27139, +27139, +27139, +27149, +27170, +27177, +27198, +27198, +27234, +27261, +27261, +27311, +27311, +27317, +27317, +27317, +27351, +27355, +27355, +27355, +27355, +27376, +27376, +27398, +27398, +27398, +27427, +27444, +27444, +27444, +27454, +27490, +27503, +27503, +27517, +27517, +27527, +27527, +27545, +27560, +27566, +27566, +27566, +27574, +27574, +27660, +27667, +27667, +27720, +27720, +27732, +27751, +27751, +27773, +27782, +27791, +27791, +27803, +27815, +27815, +27828, +27828, +27868, +27868, +27868, +27868, +27868, +27868, +27868, +27884, +27884, +27884, +27895, +27895, +27914, +27914, +27919, +27919, +27962, +27962, +27962, +28010, +28017, +28032, +28058, +28058, +28063, +28063, +28063, +28094, +28106, +28106, +28156, +28165, +28175, +28210, +28263, +28285, +28285, +28303, +28323, +28323, +28323, +28329, +28350, +28388, +28413, +28461, +28461, +28474, +28497, +28512, +28522, +28522, +28551, +28551, +28581, +28597, +28597, +28597, +28597, +28612, +28624, +28624, +28652, +28652, +28657, +28657, +28685, +28685, +28685, +28685, +28685, +28699, +28720, +28742, +28742, +28742, +28742, +28742, +28755, +28767, +28767, +28767, +28767, +28779, +28779, +28797, +28819, +28861, +28868, +28868, +28902, +28902, +28902, +28906, +28925, +28925, +28941, +28959, +28959, +28959, +28981, +28981, +28994, +28998, +28998, +29004, +29004, +29004, +29016, +29016, +29016, +29016, +29016, +29030, +29047, +29047, +29047, +29065, +29080, +29080, +29093, +29127, +29157, +29171, +29191, +29191, +29202, +29224, +29224, +29247, +29247, +29264, +29277, +29277, +29281, +29281, +29281, +29281, +29296, +29337, +29350, +29350, +29357, +29364, +29373, +29373, +29383, +29383, +29383, +29392, +29402, +29448, +29448, +29466, +29466, +29492, +29492, +29500, +29544, +29544, +29564, +29599, +29612, +29612, +29625, +29639, +29648, +29676, +29689, +29701, +29701, +29701, +29701, +29743, +29750, +29750, +29750, +29761, +29797, +29812, +29812, +29812, +29812, +29812, +29839, +29839, +29845, +29845, +29851, +29851, +29887, +29908, +29908, +29908, +29926, +29938, +29938, +29949, +29949, +29972, +29972, +29972, +29991, +29997, +29997, +29997, +29997, +30004, +30004, +30004, +30017, +30025, +30025, +30025, +30032, +30032, +30032, +30032, +30032, +30032, +30032, +30032, +30054, +30054, +30072, +30088, +30102, +30102, +30102, +30106, +30106, +30122, +30122, +30141, +30141, +30141, +30165, +30187, +30187, +30187, +30193, +30193, +30203, +30203, +30214, +30221, +30235, +30235, +30235, +30242, +30268, +30268, +30277, +30277, +30307, +30314, +30319, +30336, +30336, +30363, +30363, +30363, +30363, +30363, +30395, +30401, +30401, +30401, +30410, +30431, +30446, +30446, +30484, +30484, +30484, +30484, +30527, +30546, +30546, +30560, +30571, +30612, +30635, +30646, +30657, +30657, +30688, +30703, +30703, +30735, +30735, +30752, +30760, +30786, +30786, +30786, +30805, +30805, +30815, +30836, +30836, +30836, +30836, +30861, +30869, +30876, +30876, +30915, +30937, +30943, +30958, +30979, +30979, +30979, +30979, +30979, +30994, +31023, +31023, +31040, +31065, +31075, +31109, +31116, +31116, +31157, +31178, +31227, +31255, +31255, +31262, +31287, +31287, +31306, +31313, +31313, +31333, +31333, +31333, +31333, +31333, +31348, +31348, +31364, +31364, +31364, +31364, +31364, +31364, +31383, +31402, +31418, +31433, +31445, +31467, +31474, +31505, +31549, +31549, +31556, +31586, +31586, +31621, +31631, +31631, +31665, +31678, +31678, +31721, +31721, +31760, +31786, +31786, +31796, +31811, +31854, +31854, +31871, +31871, +31871, +31881, +31918, +31918, +31928, +31928, +31928, +31937, +31937, +31937, +31937, +31937, +31937, +31937, +31945, +31958, +31972, +31984, +31991, +31991, +32000, +32000, +32008, +32008, +32008, +32032, +32062, +32062, +32104, +32120, +32147, +32158, +32158, +32174, +32212, +32222, +32241, +32252, +32260, +32282, +32282, +32286, +32327, +32346, +32384, +32384, +32396, +32396, +32415, +32415, +32415, +32415, +32432, +32432, +32442, +32452, +32489, +32506, +32519, +32573, +32573, +32590, +32597, +32604, +32604, +32620, +32643, +32650, +32660, +32680, +32713, +32750, +32773, +32780, +32780, +32780, +32813, +32833, +32864, +32874, +32874, +32893, +32903, +32910, +32923, +32969, +32994, +32994, +33001, +33008, +33015, +33022, +33032, +33045, +33052, +33113, +33139, +33150, +33171, +33183, +33206, +33264, +33307, +33319, +33319, +33338, +33345, +33364, +33388, +33388, +33400, +33400, +33400, +33414, +33457, +33464, +33476, +33503, +33550, +33550, +33560, +33573, +33573, +33580, +33585, +33585, +33585, +33607, +33607, +33614, +33622, +33669, +33710, +33710, +33736, +33760, +33760, +33771, +33792, +33804, +33823, +33823, +33823, +33830, +33867, +33872, +33889, +33894, +33900, +33900, +33924, +33924, +33953, +33978, +33997, +34005, +34017, +34024, +34048, +34087, +34093, +34118, +34130, +34139, +34146, +34161, +34180, +34197, +34204, +34214, +34221, +34221, +34238, +34254, +34261, +34261, +34268, +34275, +34280, +34310, +34326, +34350, +34419, +34426, +34466, +34476, +34506, +34506, +34520, +34520, +34527, +34527, +34534, +34546, +34546, +34560, +34590, +34599, +34612, +34612, +34612, +34628, +34647, +34659, +34702, +34751, +34772, +34799, +34815, +34815, +34860, +34903, +34915, +34915, +34932, +34947, +34947, +34953, +34953, +34967, +34983, +34993, +35016, +35033, +35077, +35086, +35103, +35125, +35143, +35150, +35150, +35150, +35150, +35177, +35177, +35177, +35204, +35239, +35246, +35253, +35253, +35265, +35277, +35328, +35328, +35348, +35355, +35385, +35385, +35397, +35397, +35397, +35397, +35408, +35463, +35463, +35463, +35463, +35480, +35487, +35511, +35553, +35553, +35560, +35591, +35591, +35606, +35625, +35645, +35657, +35696, +35703, +35710, +35717, +35744, +35764, +35771, +35785, +35785, +35785, +35827, +35852, +35892, +35918, +35918, +35924, +35954, +35976, +35986, +35986, +36029, +36042, +36047, +36047, +36092, +36132, +36132, +36153, +36163, +36174, +36180, +36203, +36203, +36218, +36218, +36225, +36255, +36255, +36262, +36285, +36307, +36333, +36356, +36396, +36410, +36433, +36433, +36473, +36480, +36528, +36535, +36551, +36563, +36577, +36602, +36638, +36648, +36663, +36679, +36679, +36707, +36707, +36721, +36721, +36733, +36757, +36773, +36802, +36839, +36883, +36899, +36911, +36931, +36954, +36954, +36969, +37016, +37034, +37034, +37053, +37065, +37080, +37104, +37136, +37136, +37152, +37159, +37177, +37223, +37254, +37280, +37298, +37312, +37319, +37355, +37380, +37380, +37406, +37431, +37455, +37470, +37476, +37503, +37542, +37561, +37561, +37573, +37596, +37615, +37634, +37634, +37653, +37660, +37660, +37713, +37738, +37751, +37794, +37824, +37837, +37837, +37853, +37853, +37859, +37859, +37888, +37895, +37895, +37911, +37933, +37940, +37959, +37976, +37988, +38000, +38033, +38040, +38040, +38040, +38046, +38075, +38075, +38089, +38098, +38102, +38145, +38158, +38165, +38193, +38193, +38228, +38275, +38279, +38290, +38300, +38300, +38320, +38320, +38340, +38363, +38363, +38370, +38381, +38386, +38397, +38412, +38412, +38422, +38422, +38464, +38491, +38491, +38491, +38491, +38510, +38510, +38519, +38519, +38519, +38519, +38526, +38552, +38573, +38612, +38618, +38618, +38636, +38641, +38641, +38646, +38658, +38670, +38688, +38695, +38719, +38746, +38746, +38774, +38774, +38778, +38790, +38795, +38795, +38838, +38838, +38849, +38849, +38849, +38849, +38862, +38862, +38862, +38862, +38878, +38918, +38926, +38941, +38941, +38951, +38976, +38993, +38999, +39017, +39033, +39051, +39051, +39051, +39051, +39065, +39107, +39107, +39107, +39112, +39125, +39143, +39160, +39181, +39199, +39210, +39224, +39224, +39228, +39247, +39255, +39255, +39297, +39297, +39297, +39311, +39320, +39337, +39337, +39361, +39370, +39370, +39376, +39385, +39391, +39391, +39397, +39403, +39423, +39427, +39437, +39463, +39463, +39487, +39487, +39487, +39487, +39501, +39501, +39514, +39520, +39527, +39527, +39527, +39531, +39531, +39560, +39560, +39593, +39593, +39593, +39617, +39630, +39647, +39660, +39660, +39676, +39686, +39699, +39737, +39761, +39761, +39769, +39792, +39810, +39845, +39854, +39878, +39900, +39906, +39906, +39951, +39951, +39951, +39951, +39975, +40011, +40011, +40044, +40062, +40062, +40062, +40062, +40090, +40100, +40115, +40115, +40115, +40115, +40119, +40124, +40154, +40174, +40178, +40182, +40182, +40182, +40182, +40182, +40216, +40216, +40216, +40216, +40216, +40216, +40231, +40242, +40261, +40267, +40290, +40302, +40327, +40353, +40353, +40357, +40374, +40408, +40408, +40408, +40412, +40412, +40443, +40464, +40464, +40464, +40464, +40474, +40474, +40493, +40514, +40514, +40514, +40532, +40568, +40593, +40593, +40593, +40610, +40624, +40645, +40655, +40655, +40675, +40694, +40699, +40699, +40699, +40738, +40738, +40758, +40770, +40776, +40776, +40793, +40817, +40823, +40828, +40866, +40891, +40904, +40933, +40944, +40953, +40953, +40963, +40969, +40969, +40969, +40976, +40976, +40976, +40976, +40983, +40983, +40998, +40998, +41016, +41016, +41026, +41044, +41070, +41105, +41116, +41162, +41177, +41223, +41223, +41223, +41223, +41231, +41231, +41231, +41231, +41257, +41273, +41273, +41292, +41308, +41308, +41331, +41346, +41364, +41364, +41364, +41376, +41376, +41382, +41388, +41388, +41388, +41388, +41388, +41401, +41417, +41433, +41446, +41466, +41488, +41488, +41521, +41534, +41577, +41577, +41593, +41604, +41625, +41665, +41665, +41678, +41678, +41678, +41696, +41720, +41737, +41755, +41771, +41805, +41811, +41811, +41830, +41891, +41891, +41920, +41920, +41926, +41947, +41999, +41999, +41999, +41999, +42010, +42042, +42042, +42048, +42059, +42076, +42076, +42093, +42100, +42100, +42120, +42120, +42128, +42151, +42168, +42181, +42215, +42233, +42233, +42233, +42233, +42233, +42233, +42239, +42268, +42297, +42312, +42318, +42326, +42326, +42331, +42345, +42356, +42356, +42356, +42374, +42382, +42400, +42409, +42409, +42423, +42423, +42441, +42470, +42470, +42482, +42495, +42513, +42513, +42520, +42524, +42541, +42541, +42596, +42609, +42609, +42616, +42635, +42651, +42681, +42725, +42744, +42767, +42767, +42773, +42805, +42805, +42805, +42805, +42805, +42805, +42830, +42841, +42852, +42866, +42883, +42883, +42883, +42883, +42883, +42894, +42932, +42932, +42975, +42975, +43001, +43009, +43009, +43009, +43009, +43019, +43035, +43035, +43055, +43055, +43055, +43061, +43061, +43061, +43067, +43073, +43096, +43120, +43136, +43136, +43160, +43160, +43160, +43160, +43160, +43169, +43169, +43169, +43181, +43195, +43204, +43216, +43240, +43261, +43290, +43290, +43307, +43324, +43337, +43337, +43337, +43337, +43346, +43357, +43398, +43409, +43417, +43428, +43467, +43467, +43467, +43467, +43488, +43497, +43538, +43550, +43571, +43571, +43586, +43606, +43606, +43606, +43606, +43634, +43634, +43668, +43668, +43668, +43668, +43682, +43713, +43733, +43733, +43740, +43760, +43760, +43780, +43815, +43833, +43879, +43904, +43904, +43904, +43920, +43927, +43933, +43933, +43933, +43951, +43956, +43978, +43978, +43978, +44003, +44003, +44023, +44034, +44054, +44054, +44060, +44075, +44075, +44089, +44089, +44089, +44110, +44128, +44134, +44155, +44162, +44189, +44189, +44189, +44189, +44212, +44240, +44240, +44240, +44255, +44255, +44255, +44265, +44297, +44297, +44297, +44304, +44304, +44304, +44304, +44304, +44304, +44332, +44332, +44347, +44347, +44347, +44368, +44389, +44407, +44407, +44451, +44467, +44486, +44486, +44486, +44486, +44503, +44503, +44547, +44559, +44570, +44570, +44570, +44582, +44610, +44610, +44610, +44620, +44620, +44620, +44620, +44632, +44632, +44636, +44642, +44649, +44699, +44699, +44720, +44733, +44738, +44750, +44750, +44750, +44750, +44750, +44750, +44750, +44765, +44765, +44765, +44774, +44774, +44774, +44774, +44774, +44787, +44798, +44798, +44798, +44813, +44846, +44846, +44867, +44867, +44867, +44867, +44867, +44867, +44877, +44889, +44896, +44896, +44896, +44896, +44896, +44896, +44896, +44896, +44907, +44920, +44931, +44944, +44944, +44951, +44956, +44956, +44975, +44975, +44999, +45017, +45017, +45017, +45034, +45034, +45034, +45034, +45038, +45044, +45048, +45048, +45060, +45093, +45093, +45112, +45121, +45121, +45121, +45128, +45128, +45157, +45157, +45157, +45178, +45190, +45190, +45190, +45190, +45204, +45220, +45239, +45239, +45260, +45283, +45295, +45309, +45345, +45352, +45352, +45352, +45352, +45352, +45352, +45352, +45357, +45357, +45357, +45357, +45371, +45371, +45371, +45371, +45438, +45449, +45467, +45497, +45522, +45530, +45535, +45544, +45544, +45554, +45574, +45574, +45590, +45614, +45614, +45614, +45618, +45638, +45653, +45671, +45687, +45687, +45687, +45709, +45739, +45746, +45746, +45752, +45763, +45781, +45803, +45803, +45821, +45821, +45843, +45867, +45867, +45867, +45885, +45885, +45885, +45912, +45912, +45917, +45934, +45944, +45944, +45953, +45996, +46009, +46016, +46031, +46051, +46051, +46070, +46086, +46086, +46096, +46109, +46115, +46115, +46115, +46115, +46115, +46119, +46119, +46119, +46127, +46140, +46150, +46159, +46169, +46190, +46190, +46194, +46203, +46211, +46226, +46226, +46226, +46240, +46279, +46290, +46302, +46324, +46331, +46350, +46368, +46390, +46390, +46434, +46434, +46457, +46473, +46484, +46484, +46484, +46484, +46534, +46534, +46540, +46553, +46596, +46596, +46596, +46596, +46625, +46625, +46661, +46661, +46661, +46669, +46704, +46704, +46721, +46731, +46731, +46731, +46731, +46731, +46799, +46805, +46834, +46845, +46845, +46858, +46868, +46885, +46924, +46946, +46946, +46965, +46981, +46981, +46992, +46992, +46992, +46992, +46992, +47006, +47006, +47015, +47015, +47019, +47019, +47031, +47031, +47031, +47058, +47058, +47078, +47078, +47106, +47142, +47142, +47142, +47142, +47142, +47184, +47208, +47247, +47254, +47269, +47279, +47286, +47298, +47298, +47298, +47298, +47322, +47336, +47350, +47367, +47367, +47388, +47406, +47445, +47472, +47472, +47484, +47522, +47530, +47537, +47547, +47547, +47547, +47582, +47582, +47592, +47608, +47627, +47642, +47642, +47642, +47649, +47649, +47649, +47694, +47714, +47733, +47747, +47761, +47779, +47779, +47790, +47798, +47798, +47798, +47809, +47809, +47809, +47814, +47814, +47822, +47839, +47864, +47882, +47889, +47924, +47935, +47935, +47946, +47946, +47963, +47963, +47967, +47967, +47967, +47989, +47989, +48024, +48024, +48024, +48024, +48035, +48047, +48053, +48065, +48065, +48094, +48113, +48118, +48118, +48118, +48118, +48137, +48173, +48196, +48196, +48196, +48217, +48226, +48244, +48251, +48280, +48290, +48290, +48305, +48337, +48358, +48369, +48378, +48378, +48393, +48398, +48398, +48403, +48424, +48431, +48431, +48431, +48431, +48431, +48437, +48437, +48455, +48461, +48470, +48470, +48470, +48486, +48496, +48514, +48514, +48528, +48556, +48611, +48615, +48624, +48656, +48656, +48667, +48667, +48667, +48684, +48697, +48732, +48760, +48773, +48796, +48812, +48836, +48836, +48870, +48892, +48899, +48899, +48899, +48927, +48943, +48943, +48948, +48948, +48953, +48969, +48982, +49001, +49015, +49033, +49033, +49048, +49054, +49070, +49070, +49106, +49117, +49134, +49148, +49148, +49148, +49154, +49164, +49164, +49199, +49199, +49199, +49230, +49230, +49230, +49245, +49255, +49272, +49282, +49282, +49316, +49328, +49328, +49342, +49355, +49423, +49450, +49450, +49476, +49476, +49476, +49476, +49476, +49502, +49502, +49514, +49514, +49514, +49519, +49525, +49549, +49559, +49559, +49606, +49615, +49630, +49642, +49648, +49648, +49689, +49689, +49700, +49707, +49720, +49727, +49727, +49744, +49744, +49744, +49757, +49775, +49789, +49789, +49803, +49823, +49831, +49831, +49831, +49831, +49831, +49855, +49866, +49866, +49875, +49888, +49888, +49896, +49896, +49896, +49896, +49896, +49896, +49917, +49917, +49922, +49942, +49942, +49956, +49962, +49962, +49988, +50007, +50007, +50040, +50040, +50040, +50071, +50071, +50071, +50071, +50071, +50071, +50079, +50115, +50145, +50168, +50168, +50168, +50188, +50204, +50204, +50204, +50204, +50211, +50211, +50231, +50237, +50247, +50247, +50283, +50283, +50289, +50289, +50311, +50328, +50344, +50344, +50355, +50366, +50366, +50372, +50399, +50399, +50399, +50405, +50405, +50405, +50440, +50440, +50461, +50461, +50461, +50486, +50486, +50486, +50493, +50511, +50526, +50554, +50554, +50554, +50554, +50554, +50554, +50554, +50581, +50581, +50606, +50635, +50635, +50641, +50677, +50700, +50700, +50721, +50731, +50731, +50731, +50731, +50761, +50769, +50769, +50791, +50807, +50845, +50845, +50845, +50857, +50876, +50876, +50887, +50887, +50912, +50912, +50912, +50932, +50969, +50969, +51000, +51010, +51010, +51015, +51015, +51015, +51015, +51032, +51032, +51032, +51065, +51080, +51116, +51116, +51116, +51132, +51132, +51158, +51164, +51171, +51171, +51171, +51190, +51190, +51201, +51226, +51226, +51241, +51254, +51254, +51273, +51279, +51279, +51288, +51307, +51307, +51312, +51312, +51326, +51333, +51355, +51378, +51425, +51448, +51460, +51474, +51479, +51499, +51528, +51528, +51528, +51541, +51541, +51548, +51596, +51616, +51616, +51623, +51651, +51651, +51658, +51658, +51677, +51677, +51695, +51702, +51718, +51733, +51733, +51769, +51791, +51798, +51816, +51839, +51855, +51884, +51888, +51895, +51908, +51936, +51949, +51956, +51975, +51982, +51992, +51992, +51992, +51992, +51992, +52016, +52016, +52049, +52063, +52070, +52070, +52082, +52099, +52118, +52144, +52158, +52167, +52183, +52183, +52216, +52216, +52238, +52283, +52290, +52303, +52312, +52337, +52354, +52370, +52384, +52427, +52427, +52448, +52458, +52458, +52511, +52518, +52518, +52533, +52549, +52557, +52568, +52615, +52656, +52719, +52719, +52735, +52748, +52773, +52785, +52785, +52790, +52790, +52805, +52805, +52814, +52838, +52867, +52867, +52873, +52931, +52931, +52968, +52976, +52976, +52976, +52983, +52983, +53001, +53024, +53024, +53024, +53038, +53074, +53084, +53091, +53114, +53114, +53136, +53143, +53173, +53196, +53196, +53213, +53225, +53263, +53281, +53281, +53281, +53309, +53330, +53330, +53348, +53348, +53355, +53368, +53368, +53385, +53410, +53417, +53424, +53424, +53439, +53439, +53439, +53462, +53462, +53462, +53462, +53462, +53462, +53480, +53497, +53534, +53556, +53583, +53583, +53602, +53602, +53624, +53628, +53648, +53659, +53663, +53663, +53682, +53689, +53704, +53716, +53727, +53762, +53769, +53769, +53778, +53778, +53785, +53824, +53878, +53889, +53918, +53918, +53918, +53953, +53975, +53975, +53992, +54020, +54042, +54049, +54056, +54078, +54085, +54085, +54113, +54124, +54131, +54138, +54144, +54184, +54211, +54211, +54217, +54224, +54231, +54270, +54277, +54316, +54349, +54349, +54365, +54372, +54393, +54416, +54416, +54464, +54470, +54470, +54484, +54491, +54491, +54501, +54501, +54530, +54530, +54537, +54555, +54568, +54603, +54603, +54624, +54658, +54662, +54675, +54685, +54691, +54696, +54696, +54711, +54711, +54711, +54751, +54778, +54782, +54789, +54796, +54810, +54823, +54823, +54823, +54861, +54868, +54875, +54882, +54882, +54902, +54908, +54946, +54953, +54953, +54953, +54953, +54978, +54978, +54989, +55015, +55015, +55015, +55015, +55029, +55037, +55037, +55093, +55106, +55129, +55129, +55129, +55149, +55172, +55172, +55211, +55220, +55227, +55249, +55263, +55295, +55314, +55321, +55335, +55361, +55361, +55382, +55398, +55405, +55441, +55469, +55484, +55484, +55500, +55500, +55515, +55522, +55532, +55532, +55551, +55558, +55583, +55590, +55590, +55611, +55618, +55649, +55656, +55720, +55740, +55777, +55777, +55802, +55802, +55827, +55873, +55889, +55889, +55889, +55896, +55896, +55896, +55915, +55925, +55925, +55934, +55972, +55979, +55989, +55996, +55996, +55996, +56024, +56039, +56078, +56096, +56111, +56146, +56192, +56202, +56222, +56236, +56277, +56291, +56335, +56376, +56376, +56402, +56402, +56417, +56425, +56435, +56468, +56476, +56488, +56499, +56506, +56506, +56531, +56538, +56561, +56561, +56561, +56561, +56561, +56561, +56561, +56561, +56569, +56569, +56577, +56585, +56594, +56594, +56594, +56617, +56625, +56650, +56660, +56673, +56716, +56740, +56745, +56757, +56769, +56769, +56769, +56797, +56822, +56838, +56838, +56858, +56858, +56867, +56879, +56879, +56911, +56955, +56976, +57002, +57027, +57034, +57054, +57064, +57064, +57064, +57078, +57085, +57085, +57114, +57114, +57121, +57121, +57121, +57121, +57129, +57155, +57155, +57193, +57220, +57224, +57244, +57244, +57272, +57287, +57305, +57348, +57348, +57355, +57366, +57412, +57420, +57455, +57455, +57455, +57455, +57466, +57477, +57477, +57477, +57497, +57508, +57523, +57539, +57566, +57582, +57612, +57616, +57616, +57634, +57634, +57662, +57686, +57686, +57698, +57708, +57745, +57759, +57798, +57798, +57827, +57840, +57840, +57840, +57850, +57876, +57876, +57876, +57918, +57927, +57927, +57940, +57986, +57994, +58009, +58029, +58029, +58045, +58045, +58071, +58071, +58071, +58093, +58114, +58114, +58114, +58150, +58150, +58174, +58174, +58207, +58217, +58225, +58241, +58258, +58281, +58292, +58304, +58319, +58329, +58351, +58407, +58417, +58439, +58439, +58439, +58475, +58483, +58504, +58513, +58523, +58523, +58527, +58558, +58602, +58602, +58625, +58625, +58649, +58692, +58721, +58721, +58721, +58729, +58739, +58739, +58758, +58771, +58802, +58802, +58802, +58819, +58841, +58854, +58872, +58889, +58910, +58921, +58921, +58921, +58921, +58957, +58957, +58965, +58971, +58971, +58979, +58979, +58979, +59003, +59003, +59022, +59032, +59032, +59032, +59057, +59068, +59068, +59068, +59068, +59068, +59068, +59068, +59076, +59080, +59103, +59120, +59120, +59120, +59120, +59126, +59135, +59151, +59158, +59158, +59184, +59216, +59244, +59259, +59265, +59277, +59284, +59306, +59338, +59338, +59363, +59363, +59363, +59377, +59386, +59386, +59386, +59386, +59411, +59433, +59453, +59480, +59489, +59489, +59495, +59513, +59526, +59548, +59548, +59556, +59566, +59566, +59566, +59583, +59594, +59622, +59643, +59643, +59643, +59648, +59648, +59700, +59740, +59740, +59758, +59769, +59774, +59774, +59774, +59774, +59787, +59822, +59837, +59837, +59845, +59850, +59863, +59863, +59863, +59869, +59869, +59928, +59936, +59953, +59966, +59981, +59981, +59997, +60012, +60049, +60049, +60108, +60123, +60123, +60130, +60164, +60171, +60171, +60171, +60171, +60171, +60171, +60176, +60199, +60217, +60229, +60240, +60240, +60240, +60240, +60248, +60262, +60262, +60284, +60309, +60324, +60329, +60412, +60421, +60421, +60436, +60436, +60457, +60481, +60481, +60481, +60517, +60525, +60525, +60541, +60567, +60575, +60613, +60613, +60642, +60663, +60691, +60727, +60727, +60744, +60759, +60778, +60794, +60809, +60824, +60824, +60834, +60834, +60853, +60878, +60878, +60878, +60878, +60907, +60907, +60907, +60907, +60937, +60948, +60990, +60990, +61014, +61041, +61041, +61049, +61049, +61049, +61062, +61062, +61062, +61078, +61078, +61078, +61092, +61098, +61132, +61150, +61150, +61150, +61150, +61156, +61170, +61178, +61187, +61187, +61187, +61187, +61194, +61217, +61234, +61257, +61257, +61257, +61285, +61285, +61292, +61309, +61333, +61371, +61371, +61386, +61393, +61426, +61450, +61450, +61450, +61466, +61466, +61466, +61481, +61481, +61481, +61481, +61481, +61481, +61500, +61538, +61538, +61538, +61584, +61592, +61624, +61651, +61651, +61651, +61685, +61696, +61711, +61711, +61711, +61711, +61761, +61767, +61783, +61817, +61842, +61842, +61842, +61856, +61856, +61896, +61896, +61896, +61959, +61959, +61959, +61968, +61992, +62025, +62025, +62025, +62040, +62072, +62072, +62072, +62072, +62072, +62078, +62078, +62099, +62123, +62131, +62171, +62171, +62171, +62171, +62171, +62171, +62180, +62233, +62233, +62253, +62253, +62284, +62303, +62318, +62318, +62331, +62338, +62378, +62378, +62378, +62378, +62390, +62395, +62395, +62395, +62395, +62395, +62402, +62402, +62423, +62430, +62447, +62454, +62454, +62486, +62486, +62486, +62509, +62522, +62522, +62522, +62522, +62522, +62547, +62547, +62575, +62597, +62644, +62669, +62686, +62692, +62700, +62736, +62782, +62782, +62812, +62812, +62830, +62834, +62834, +62847, +62866, +62878, +62897, +62912, +62928, +62928, +62928, +62928, +62945, +62952, +62987, +62987, +63023, +63023, +63044, +63044, +63044, +63054, +63065, +63081, +63081, +63081, +63095, +63126, +63154, +63154, +63171, +63171, +63185, +63185, +63185, +63231, +63231, +63252, +63252, +63261, +63261, +63261, +63261, +63269, +63269, +63297, +63297, +63321, +63342, +63342, +63377, +63388, +63401, +63414, +63432, +63432, +63432, +63439, +63439, +63444, +63487, +63497, +63516, +63516, +63545, +63567, +63574, +63585, +63599, +63626, +63626, +63650, +63650, +63709, +63709, +63736, +63757, +63787, +63806, +63821, +63838, +63861, +63868, +63875, +63875, +63891, +63940, +63940, +63940, +63959, +63973, +63973, +64013, +64020, +64020, +64049, +64081, +64099, +64099, +64118, +64118, +64143, +64143, +64155, +64155, +64155, +64155, +64173, +64173, +64193, +64214, +64227, +64227, +64234, +64252, +64262, +64297, +64332, +64349, +64356, +64363, +64370, +64380, +64387, +64394, +64412, +64419, +64436, +64447, +64472, +64472, +64501, +64515, +64515, +64515, +64529, +64547, +64556, +64563, +64573, +64580, +64580, +64580, +64659, +64666, +64688, +64688, +64688, +64695, +64709, +64736, +64736, +64736, +64751, +64751, +64758, +64789, +64799, +64799, +64826, +64849, +64856, +64876, +64899, +64910, +64916, +64923, +64947, +64957, +64993, +65010, +65055, +65055, +65066, +65083, +65101, +65105, +65125, +65129, +65167, +65181, +65188, +65188, +65198, +65229, +65264, +65271, +65306, +65333, +65340, +65340, +65395, +65395, +65395, +65411, +65420, +65437, +65448, +65455, +65462, +65479, +65489, +65489, +65489, +65514, +65514, +65514, +65514, +65532, +65532, +65537, +65556, +65567, +65574, +65609, +65623, +65645, +65659, +65659, +65659, +65659, +65687, +65694, +65713, +65720, +65720, +65727, +65727, +65734, +65741, +65748, +65766, +65800, +65800, +65800, +65826, +65826, +65847, +65854, +65854, +65878, +65895, +65916, +65954, +65973, +66014, +66037, +66037, +66037, +66050, +66070, +66084, +66084, +66084, +66091, +66098, +66122, +66129, +66129, +66182, +66189, +66196, +66214, +66221, +66221, +66221, +66249, +66249, +66249, +66270, +66286, +66286, +66286, +66312, +66312, +66352, +66397, +66397, +66403, +66432, +66432, +66439, +66449, +66471, +66493, +66502, +66520, +66530, +66585, +66585, +66595, +66612, +66647, +66654, +66680, +66699, +66724, +66750, +66750, +66777, +66804, +66811, +66839, +66873, +66914, +66914, +66937, +66960, +66979, +67006, +67024, +67031, +67038, +67038, +67045, +67066, +67109, +67116, +67123, +67139, +67160, +67206, +67225, +67225, +67225, +67270, +67297, +67329, +67357, +67371, +67385, +67421, +67455, +67479, +67479, +67495, +67504, +67504, +67527, +67536, +67543, +67553, +67576, +67576, +67576, +67576, +67576, +67576, +67614, +67614, +67621, +67645, +67645, +67645, +67662, +67698, +67698, +67703, +67707, +67742, +67808, +67808, +67815, +67856, +67863, +67880, +67899, +67905, +67912, +67928, +67948, +67960, +67975, +67982, +67996, +68025, +68025, +68045, +68078, +68085, +68085, +68095, +68104, +68116, +68147, +68153, +68170, +68170, +68183, +68183, +68206, +68206, +68206, +68224, +68235, +68241, +68248, +68265, +68286, +68286, +68303, +68315, +68339, +68346, +68353, +68360, +68387, +68418, +68437, +68451, +68463, +68463, +68463, +68475, +68482, +68482, +68509, +68524, +68524, +68534, +68541, +68562, +68574, +68579, +68586, +68596, +68603, +68610, +68641, +68653, +68671, +68678, +68699, +68706, +68724, +68749, +68762, +68779, +68786, +68791, +68791, +68832, +68876, +68876, +68904, +68933, +68964, +68964, +68964, +68964, +68964, +68964, +68964, +68991, +68991, +69046, +69063, +69074, +69074, +69115, +69167, +69183, +69192, +69192, +69209, +69209, +69209, +69209, +69243, +69275, +69275, +69282, +69282, +69302, +69318, +69318, +69318, +69332, +69345, +69368, +69380, +69416, +69453, +69453, +69459, +69482, +69489, +69525, +69525, +69525, +69542, +69542, +69542, +69553, +69560, +69588, +69588, +69588, +69588, +69611, +69634, +69634, +69634, +69645, +69645, +69645, +69677, +69683, +69693, +69700, +69723, +69734, +69744, +69751, +69751, +69773, +69773, +69773, +69773, +69786, +69819, +69819, +69819, +69837, +69848, +69858, +69858, +69877, +69877, +69877, +69877, +69897, +69897, +69897, +69905, +69911, +69911, +69915, +69941, +69941, +69964, +69964, +69964, +69971, +69971, +69987, +70000, +70000, +70000, +70000, +70011, +70011, +70018, +70018, +70028, +70028, +70028, +70028, +70065, +70072, +70086, +70086, +70086, +70086, +70110, +70110, +70110, +70122, +70145, +70160, +70160, +70172, +70193, +70201, +70201, +70241, +70247, +70289, +70289, +70289, +70311, +70311, +70311, +70327, +70334, +70334, +70352, +70366, +70366, +70366, +70366, +70366, +70366, +70366, +70366, +70380, +70380, +70408, +70418, +70434, +70438, +70438, +70438, +70464, +70481, +70496, +70496, +70510, +70510, +70510, +70510, +70530, +70530, +70551, +70551, +70589, +70604, +70617, +70634, +70634, +70634, +70634, +70634, +70645, +70645, +70645, +70662, +70669, +70716, +70738, +70738, +70738, +70738, +70738, +70748, +70748, +70772, +70799, +70813, +70855, +70886, +70895, +70911, +70937, +70937, +70955, +70955, +70965, +70975, +70975, +70986, +71004, +71004, +71031, +71031, +71053, +71068, +71086, +71086, +71086, +71101, +71117, +71117, +71117, +71151, +71165, +71199, +71199, +71199, +71199, +71199, +71199, +71219, +71232, +71255, +71255, +71255, +71255, +71255, +71255, +71255, +71255, +71283, +71307, +71307, +71314, +71332, +71343, +71347, +71384, +71411, +71428, +71428, +71445, +71450, +71450, +71450, +71462, +71462, +71462, +71462, +71462, +71477, +71488, +71488, +71488, +71488, +71488, +71488, +71501, +71530, +71530, +71567, +71586, +71586, +71586, +71603, +71632, +71632, +71632, +71632, +71663, +71672, +71672, +71682, +71707, +71707, +71707, +71714, +71714, +71719, +71727, +71727, +71727, +71727, +71734, +71734, +71734, +71762, +71770, +71770, +71781, +71801, +71812, +71821, +71854, +71871, +71871, +71879, +71896, +71910, +71922, +71959, +71966, +71984, +71990, +72040, +72053, +72087, +72115, +72143, +72169, +72169, +72169, +72179, +72195, +72195, +72195, +72195, +72195, +72195, +72212, +72212, +72212, +72212, +72212, +72222, +72233, +72233, +72233, +72242, +72270, +72277, +72293, +72319, +72360, +72373, +72392, +72409, +72419, +72419, +72440, +72479, +72479, +72489, +72504, +72513, +72530, +72530, +72530, +72530, +72551, +72559, +72559, +72559, +72591, +72615, +72665, +72665, +72672, +72699, +72699, +72709, +72709, +72709, +72709, +72709, +72709, +72753, +72753, +72773, +72780, +72780, +72780, +72805, +72817, +72817, +72830, +72830, +72840, +72866, +72879, +72879, +72888, +72895, +72895, +72895, +72910, +72921, +72921, +72928, +72958, +72986, +72997, +73009, +73024, +73024, +73024, +73024, +73024, +73052, +73062, +73087, +73097, +73097, +73107, +73107, +73122, +73140, +73150, +73159, +73166, +73166, +73166, +73176, +73204, +73234, +73258, +73258, +73258, +73258, +73258, +73258, +73268, +73296, +73319, +73319, +73319, +73319, +73319, +73319, +73319, +73347, +73356, +73365, +73393, +73403, +73403, +73428, +73451, +73451, +73451, +73461, +73471, +73505, +73520, +73520, +73537, +73537, +73550, +73596, +73629, +73629, +73629, +73629, +73641, +73641, +73658, +73658, +73665, +73665, +73665, +73665, +73677, +73690, +73710, +73727, +73764, +73778, +73791, +73811, +73831, +73868, +73876, +73876, +73876, +73876, +73887, +73907, +73928, +73928, +73928, +73928, +73954, +73961, +73961, +73961, +73988, +73992, +74006, +74049, +74049, +74079, +74079, +74098, +74098, +74098, +74098, +74140, +74140, +74140, +74140, +74192, +74216, +74232, +74232, +74260, +74281, +74281, +74287, +74310, +74310, +74326, +74326, +74326, +74326, +74326, +74351, +74370, +74382, +74408, +74408, +74408, +74408, +74450, +74450, +74450, +74450, +74466, +74495, +74534, +74544, +74560, +74576, +74576, +74588, +74588, +74588, +74606, +74626, +74626, +74647, +74691, +74706, +74724, +74729, +74737, +74744, +74750, +74779, +74833, +74833, +74851, +74851, +74851, +74851, +74851, +74851, +74871, +74909, +74932, +74940, +74971, +74971, +74990, +74990, +75008, +75008, +75021, +75036, +75054, +75060, +75060, +75060, +75060, +75060, +75079, +75079, +75079, +75085, +75085, +75119, +75124, +75133, +75133, +75133, +75139, +75153, +75162, +75175, +75175, +75182, +75182, +75188, +75212, +75229, +75229, +75254, +75260, +75260, +75260, +75271, +75271, +75291, +75291, +75291, +75291, +75304, +75304, +75334, +75351, +75364, +75364, +75374, +75374, +75386, +75386, +75413, +75447, +75454, +75472, +75483, +75483, +75483, +75488, +75488, +75488, +75501, +75539, +75539, +75571, +75571, +75599, +75599, +75637, +75656, +75656, +75656, +75656, +75656, +75676, +75692, +75710, +75732, +75766, +75788, +75799, +75799, +75818, +75848, +75860, +75886, +75902, +75902, +75912, +75912, +75919, +75919, +75919, +75941, +75941, +75941, +75976, +75993, +75993, +76007, +76022, +76022, +76022, +76051, +76077, +76103, +76103, +76125, +76136, +76136, +76146, +76146, +76167, +76174, +76174, +76174, +76181, +76181, +76200, +76209, +76237, +76237, +76254, +76285, +76300, +76300, +76318, +76354, +76363, +76376, +76403, +76403, +76403, +76403, +76403, +76403, +76421, +76421, +76421, +76421, +76459, +76459, +76466, +76476, +76484, +76484, +76484, +76484, +76484, +76484, +76484, +76500, +76500, +76513, +76521, +76563, +76570, +76580, +76587, +76587, +76613, +76628, +76628, +76628, +76628, +76639, +76655, +76655, +76655, +76669, +76696, +76696, +76696, +76702, +76717, +76717, +76717, +76728, +76728, +76728, +76768, +76768, +76768, +76768, +76768, +76773, +76793, +76793, +76813, +76841, +76841, +76885, +76913, +76913, +76920, +76920, +76920, +76938, +76938, +76952, +76952, +76982, +76989, +76989, +76989, +76998, +77032, +77049, +77049, +77068, +77085, +77093, +77093, +77102, +77102, +77115, +77135, +77161, +77161, +77173, +77189, +77202, +77202, +77202, +77202, +77202, +77215, +77215, +77215, +77226, +77247, +77270, +77270, +77270, +77270, +77292, +77316, +77316, +77316, +77326, +77375, +77375, +77375, +77375, +77375, +77408, +77431, +77442, +77442, +77449, +77467, +77516, +77528, +77555, +77574, +77574, +77588, +77588, +77603, +77603, +77603, +77624, +77624, +77643, +77643, +77651, +77662, +77662, +77662, +77677, +77677, +77684, +77765, +77783, +77819, +77838, +77838, +77838, +77851, +77851, +77863, +77863, +77863, +77875, +77899, +77899, +77915, +77915, +77915, +77946, +77946, +77946, +77946, +77946, +77956, +77956, +77978, +77978, +77978, +77994, +77994, +77994, +78010, +78023, +78054, +78076, +78096, +78096, +78096, +78096, +78128, +78128, +78128, +78160, +78182, +78195, +78195, +78223, +78223, +78223, +78223, +78223, +78233, +78267, +78279, +78279, +78279, +78279, +78279, +78319, +78350, +78350, +78363, +78363, +78373, +78373, +78373, +78408, +78443, +78456, +78474, +78494, +78494, +78507, +78525, +78541, +78541, +78586, +78598, +78610, +78626, +78632, +78632, +78656, +78698, +78725, +78760, +78760, +78798, +78822, +78847, +78847, +78847, +78865, +78917, +78934, +78934, +78934, +78934, +78962, +78981, +78981, +78981, +78981, +78988, +79001, +79001, +79001, +79009, +79009, +79009, +79009, +79033, +79033, +79055, +79067, +79067, +79067, +79084, +79099, +79099, +79112, +79112, +79112, +79123, +79123, +79123, +79123, +79123, +79144, +79152, +79152, +79165, +79165, +79180, +79186, +79196, +79196, +79196, +79221, +79235, +79235, +79249, +79264, +79274, +79290, +79300, +79346, +79346, +79346, +79346, +79346, +79367, +79383, +79390, +79390, +79447, +79447, +79470, +79470, +79493, +79493, +79493, +79516, +79548, +79548, +79579, +79589, +79603, +79603, +79603, +79609, +79609, +79609, +79609, +79609, +79609, +79616, +79626, +79626, +79636, +79643, +79688, +79703, +79720, +79739, +79746, +79763, +79778, +79791, +79791, +79805, +79805, +79818, +79818, +79824, +79836, +79856, +79877, +79883, +79900, +79900, +79900, +79918, +79934, +79944, +79982, +79982, +80001, +80014, +80014, +80022, +80022, +80034, +80047, +80047, +80047, +80057, +80064, +80064, +80086, +80115, +80115, +80123, +80123, +80149, +80170, +80182, +80182, +80200, +80226, +80270, +80310, +80344, +80344, +80344, +80344, +80344, +80344, +80359, +80359, +80369, +80369, +80391, +80409, +80409, +80439, +80439, +80439, +80458, +80458, +80469, +80469, +80520, +80520, +80520, +80520, +80520, +80520, +80543, +80593, +80603, +80603, +80603, +80620, +80634, +80669, +80675, +80675, +80675, +80675, +80685, +80704, +80731, +80731, +80741, +80760, +80760, +80760, +80760, +80778, +80778, +80778, +80806, +80826, +80826, +80826, +80826, +80826, +80852, +80852, +80864, +80872, +80878, +80878, +80887, +80887, +80899, +80938, +80955, +80955, +80962, +80979, +80979, +80992, +80999, +81022, +81022, +81022, +81054, +81104, +81163, +81163, +81170, +81170, +81202, +81202, +81249, +81249, +81256, +81256, +81262, +81301, +81307, +81345, +81345, +81345, +81345, +81345, +81367, +81367, +81392, +81392, +81412, +81452, +81462, +81468, +81468, +81477, +81491, +81527, +81547, +81582, +81599, +81599, +81618, +81641, +81646, +81646, +81652, +81658, +81680, +81688, +81724, +81760, +81776, +81783, +81798, +81798, +81798, +81804, +81810, +81810, +81810, +81810, +81810, +81816, +81816, +81816, +81816, +81816, +81816, +81841, +81874, +81880, +81886, +81886, +81908, +81908, +81920, +81933, +81933, +81940, +81940, +81940, +81954, +81972, +81972, +82038, +82053, +82068, +82080, +82080, +82102, +82120, +82129, +82129, +82171, +82191, +82191, +82211, +82211, +82244, +82267, +82267, +82279, +82290, +82290, +82290, +82290, +82318, +82323, +82323, +82350, +82367, +82385, +82395, +82425, +82425, +82471, +82471, +82494, +82494, +82513, +82519, +82539, +82539, +82551, +82551, +82557, +82557, +82569, +82577, +82596, +82596, +82596, +82596, +82602, +82610, +82638, +82655, +82655, +82666, +82676, +82683, +82683, +82683, +82688, +82713, +82719, +82740, +82746, +82752, +82764, +82770, +82795, +82801, +82807, +82813, +82822, +82873, +82881, +82894, +82894, +82900, +82906, +82936, +82936, +82969, +82969, +82997, +82997, +83039, +83085, +83092, +83107, +83129, +83134, +83152, +83152, +83152, +83158, +83174, +83174, +83174, +83174, +83182, +83199, +83199, +83209, +83209, +83209, +83209, +83209, +83253, +83259, +83275, +83284, +83299, +83328, +83328, +83328, +83334, +83334, +83334, +83334, +83339, +83383, +83383, +83400, +83434, +83440, +83456, +83512, +83527, +83533, +83533, +83533, +83540, +83540, +83546, +83563, +83574, +83586, +83593, +83653, +83653, +83653, +83653, +83659, +83679, +83685, +83702, +83734, +83740, +83740, +83774, +83774, +83781, +83837, +83837, +83852, +83852, +83852, +83867, +83867, +83867, +83867, +83867, +83895, +83901, +83901, +83919, +83925, +83925, +83934, +83944, +83944, +83944, +83951, +83969, +83990, +83990, +84000, +84000, +84013, +84013, +84029, +84049, +84049, +84080, +84085, +84085, +84085, +84111, +84128, +84145, +84164, +84176, +84206, +84206, +84244, +84244, +84255, +84276, +84297, +84297, +84297, +84297, +84297, +84310, +84326, +84332, +84348, +84395, +84434, +84459, +84459, +84459, +84459, +84472, +84494, +84494, +84494, +84501, +84521, +84521, +84538, +84538, +84585, +84585, +84610, +84615, +84615, +84615, +84658, +84658, +84668, +84691, +84712, +84726, +84726, +84733, +84733, +84739, +84751, +84751, +84751, +84757, +84772, +84802, +84809, +84835, +84841, +84862, +84883, +84883, +84889, +84918, +84918, +84931, +84942, +84942, +84984, +84993, +85023, +85029, +85073, +85113, +85120, +85137, +85187, +85187, +85187, +85225, +85231, +85248, +85261, +85261, +85282, +85313, +85340, +85369, +85385, +85395, +85412, +85419, +85442, +85471, +85501, +85560, +85576, +85611, +85611, +85611, +85618, +85618, +85618, +85625, +85632, +85686, +85704, +85704, +85711, +85738, +85745, +85795, +85795, +85826, +85833, +85840, +85845, +85845, +85860, +85867, +85874, +85881, +85881, +85881, +85892, +85910, +85960, +85980, +86001, +86001, +86057, +86057, +86064, +86064, +86071, +86071, +86096, +86123, +86123, +86139, +86146, +86146, +86159, +86159, +86159, +86177, +86195, +86202, +86230, +86230, +86250, +86273, +86282, +86289, +86303, +86303, +86303, +86327, +86337, +86355, +86355, +86355, +86362, +86369, +86402, +86402, +86444, +86451, +86451, +86458, +86480, +86480, +86508, +86508, +86530, +86530, +86530, +86551, +86561, +86594, +86614, +86614, +86636, +86651, +86658, +86665, +86678, +86702, +86702, +86709, +86709, +86739, +86759, +86775, +86787, +86855, +86891, +86891, +86904, +86904, +86927, +86935, +86950, +86950, +86950, +86978, +86983, +86983, +86999, +86999, +87008, +87022, +87029, +87039, +87060, +87060, +87076, +87076, +87089, +87116, +87123, +87130, +87130, +87130, +87150, +87157, +87173, +87199, +87217, +87234, +87257, +87257, +87266, +87279, +87289, +87289, +87289, +87289, +87315, +87322, +87332, +87332, +87342, +87342, +87363, +87381, +87450, +87450, +87464, +87511, +87518, +87535, +87557, +87564, +87575, +87589, +87596, +87613, +87620, +87620, +87641, +87648, +87655, +87662, +87669, +87690, +87708, +87708, +87718, +87725, +87725, +87734, +87741, +87748, +87792, +87792, +87799, +87813, +87834, +87834, +87847, +87847, +87854, +87871, +87878, +87893, +87900, +87942, +87971, +88003, +88017, +88045, +88052, +88059, +88073, +88101, +88125, +88132, +88132, +88132, +88132, +88132, +88143, +88143, +88151, +88158, +88175, +88175, +88195, +88212, +88219, +88219, +88237, +88244, +88266, +88266, +88273, +88273, +88296, +88296, +88318, +88318, +88318, +88324, +88344, +88368, +88368, +88375, +88400, +88400, +88407, +88443, +88443, +88466, +88497, +88497, +88504, +88511, +88584, +88591, +88609, +88629, +88629, +88629, +88643, +88660, +88666, +88691, +88691, +88691, +88691, +88691, +88691, +88691, +88704, +88704, +88713, +88726, +88726, +88774, +88789, +88837, +88837, +88837, +88846, +88868, +88881, +88881, +88888, +88937, +88961, +88987, +89030, +89043, +89101, +89150, +89150, +89187, +89203, +89210, +89224, +89260, +89267, +89267, +89267, +89274, +89288, +89295, +89311, +89318, +89330, +89351, +89358, +89388, +89388, +89398, +89405, +89412, +89432, +89474, +89481, +89508, +89523, +89552, +89563, +89584, +89612, +89612, +89629, +89636, +89662, +89681, +89687, +89702, +89711, +89727, +89742, +89754, +89773, +89783, +89849, +89856, +89856, +89863, +89877, +89900, +89907, +89907, +89907, +89921, +89921, +89938, +89938, +89961, +89980, +90000, +90021, +90070, +90070, +90086, +90086, +90146, +90178, +90178, +90187, +90209, +90209, +90209, +90215, +90240, +90247, +90256, +90256, +90290, +90290, +90298, +90298, +90305, +90329, +90329, +90353, +90388, +90403, +90409, +90409, +90409, +90416, +90416, +90416, +90436, +90436, +90436, +90461, +90470, +90475, +90475, +90499, +90540, +90540, +90583, +90590, +90608, +90623, +90623, +90643, +90643, +90651, +90718, +90725, +90731, +90731, +90757, +90780, +90780, +90806, +90829, +90845, +90855, +90891, +90891, +90906, +90926, +90960, +90975, +90975, +90994, +91017, +91017, +91024, +91024, +91024, +91034, +91034, +91034, +91052, +91052, +91067, +91103, +91135, +91172, +91188, +91188, +91202, +91221, +91245, +91245, +91245, +91245, +91245, +91245, +91245, +91245, +91245, +91258, +91258, +91276, +91293, +91293, +91328, +91349, +91363, +91372, +91372, +91393, +91393, +91393, +91393, +91393, +91393, +91393, +91412, +91445, +91445, +91463, +91479, +91497, +91512, +91543, +91549, +91549, +91572, +91572, +91589, +91613, +91629, +91655, +91687, +91703, +91703, +91723, +91741, +91741, +91741, +91767, +91778, +91778, +91778, +91791, +91797, +91797, +91806, +91806, +91820, +91836, +91855, +91855, +91855, +91855, +91862, +91900, +91906, +91948, +91948, +91948, +91956, +91956, +91956, +91966, +91989, +91989, +92007, +92007, +92043, +92049, +92066, +92082, +92088, +92088, +92106, +92106, +92106, +92106, +92121, +92121, +92121, +92121, +92132, +92132, +92141, +92160, +92160, +92160, +92160, +92167, +92183, +92192, +92207, +92227, +92242, +92254, +92254, +92284, +92297, +92318, +92318, +92337, +92346, +92386, +92386, +92386, +92386, +92411, +92439, +92454, +92486, +92486, +92512, +92512, +92529, +92529, +92529, +92534, +92534, +92573, +92601, +92621, +92628, +92648, +92657, +92657, +92657, +92657, +92663, +92675, +92700, +92722, +92736, +92742, +92742, +92762, +92762, +92783, +92783, +92878, +92891, +92891, +92901, +92907, +92922, +92937, +92943, +92979, +92990, +93025, +93043, +93043, +93043, +93043, +93043, +93065, +93078, +93105, +93129, +93140, +93140, +93151, +93170, +93170, +93181, +93181, +93181, +93188, +93198, +93198, +93198, +93231, +93231, +93249, +93258, +93272, +93272, +93295, +93302, +93307, +93307, +93323, +93323, +93333, +93333, +93360, +93369, +93404, +93413, +93430, +93430, +93430, +93447, +93467, +93467, +93521, +93528, +93546, +93546, +93571, +93602, +93628, +93639, +93658, +93689, +93703, +93722, +93729, +93729, +93736, +93794, +93812, +93819, +93819, +93819, +93819, +93844, +93851, +93874, +93874, +93888, +93895, +93922, +93922, +93922, +93930, +93930, +93930, +93937, +93937, +93944, +93966, +93966, +93966, +93966, +93966, +93997, +94011, +94018, +94025, +94043, +94043, +94050, +94067, +94074, +94074, +94081, +94081, +94081, +94088, +94114, +94125, +94125, +94125, +94125, +94162, +94174, +94174, +94206, +94224, +94240, +94283, +94283, +94283, +94283, +94290, +94302, +94302, +94302, +94308, +94308, +94344, +94354, +94369, +94374, +94374, +94441, +94482, +94482, +94508, +94526, +94526, +94532, +94539, +94555, +94562, +94577, +94584, +94584, +94598, +94598, +94620, +94638, +94666, +94672, +94672, +94718, +94718, +94725, +94742, +94742, +94749, +94749, +94771, +94771, +94771, +94780, +94805, +94815, +94815, +94820, +94820, +94841, +94841, +94851, +94851, +94851, +94871, +94902, +94902, +94924, +94935, +94942, +94949, +94966, +94966, +94966, +94973, +94973, +94973, +94987, +94987, +94987, +95007, +95037, +95037, +95037, +95037, +95044, +95044, +95044, +95061, +95084, +95084, +95104, +95126, +95126, +95165, +95187, +95194, +95200, +95216, +95223, +95230, +95237, +95237, +95237, +95260, +95273, +95324, +95331, +95338, +95353, +95377, +95388, +95388, +95388, +95403, +95403, +95410, +95417, +95417, +95434, +95476, +95483, +95493, +95500, +95505, +95512, +95519, +95519, +95554, +95568, +95568, +95592, +95592, +95645, +95668, +95668, +95701, +95727, +95768, +95795, +95829, +95844, +95853, +95862, +95862, +95875, +95882, +95882, +95907, +95907, +95907, +95925, +95925, +95925, +95925, +95925, +95951, +95967, +95967, +96018, +96047, +96069, +96087, +96107, +96107, +96107, +96107, +96114, +96142, +96164, +96205, +96205, +96205, +96212, +96236, +96236, +96243, +96243, +96250, +96286, +96293, +96332, +96339, +96353, +96359, +96375, +96389, +96414, +96436, +96446, +96446, +96454, +96466, +96471, +96499, +96554, +96564, +96586, +96603, +96614, +96614, +96629, +96629, +96640, +96662, +96680, +96680, +96700, +96722, +96742, +96742, +96749, +96756, +96802, +96824, +96831, +96840, +96847, +96874, +96874, +96886, +96893, +96900, +96900, +96907, +96914, +96924, +96931, +96944, +96996, +97024, +97024, +97045, +97062, +97062, +97069, +97096, +97096, +97096, +97134, +97134, +97141, +97141, +97148, +97155, +97155, +97162, +97186, +97205, +97240, +97240, +97240, +97240, +97246, +97251, +97251, +97267, +97267, +97309, +97325, +97341, +97363, +97363, +97377, +97392, +97392, +97392, +97433, +97443, +97443, +97457, +97457, +97479, +97479, +97488, +97500, +97516, +97527, +97527, +97534, +97534, +97534, +97534, +97534, +97534, +97548, +97548, +97548, +97548, +97548, +97583, +97583, +97583, +97604, +97604, +97604, +97604, +97618, +97633, +97633, +97642, +97662, +97662, +97662, +97662, +97662, +97662, +97662, +97662, +97668, +97668, +97702, +97702, +97702, +97719, +97729, +97729, +97729, +97729, +97729, +97729, +97736, +97736, +97768, +97775, +97790, +97790, +97814, +97824, +97849, +97849, +97849, +97849, +97849, +97849, +97878, +97878, +97962, +97974, +97974, +97974, +98020, +98031, +98031, +98031, +98031, +98044, +98059, +98059, +98059, +98059, +98059, +98077, +98087, +98097, +98104, +98104, +98104, +98120, +98126, +98169, +98169, +98190, +98190, +98206, +98206, +98230, +98241, +98241, +98248, +98280, +98280, +98297, +98297, +98312, +98327, +98342, +98380, +98380, +98389, +98408, +98408, +98408, +98432, +98446, +98461, +98520, +98520, +98533, +98553, +98575, +98575, +98575, +98594, +98594, +98625, +98636, +98636, +98636, +98653, +98672, +98672, +98685, +98685, +98691, +98699, +98699, +98707, +98737, +98748, +98748, +98766, +98799, +98799, +98799, +98799, +98799, +98799, +98817, +98817, +98817, +98847, +98847, +98859, +98894, +98894, +98894, +98929, +98947, +98947, +98979, +98988, +99005, +99005, +99037, +99037, +99037, +99037, +99037, +99037, +99062, +99067, +99077, +99097, +99097, +99110, +99110, +99158, +99209, +99224, +99224, +99224, +99224, +99247, +99247, +99271, +99271, +99276, +99281, +99299, +99322, +99322, +99330, +99340, +99356, +99367, +99377, +99388, +99388, +99388, +99388, +99388, +99388, +99388, +99437, +99470, +99503, +99516, +99549, +99549, +99555, +99555, +99555, +99555, +99570, +99570, +99577, +99577, +99597, +99597, +99597, +99627, +99658, +99663, +99663, +99675, +99719, +99719, +99719, +99719, +99737, +99744, +99744, +99776, +99791, +99812, +99837, +99850, +99871, +99871, +99871, +99879, +99889, +99889, +99899, +99899, +99899, +99904, +99925, +99925, +99947, +99960, +99960, +99973, +99973, +100005, +100005, +100026, +100026, +100031, +100062, +100079, +100079, +100084, +100100, +100148, +100148, +100199, +100199, +100207, +100235, +100262, +100296, +100296, +100322, +100328, +100328, +100328, +100351, +100361, +100361, +100367, +100367, +100367, +100377, +100377, +100421, +100421, +100435, +100435, +100481, +100481, +100481, +100489, +100489, +100502, +100509, +100525, +100540, +100540, +100560, +100560, +100611, +100620, +100640, +100653, +100653, +100653, +100685, +100685, +100698, +100712, +100721, +100726, +100726, +100726, +100741, +100741, +100751, +100782, +100792, +100801, +100808, +100813, +100850, +100850, +100863, +100873, +100892, +100892, +100892, +100892, +100892, +100909, +100925, +100936, +100955, +100969, +100978, +100978, +100978, +101008, +101036, +101036, +101071, +101071, +101102, +101127, +101151, +101151, +101158, +101170, +101189, +101205, +101205, +101205, +101234, +101248, +101248, +101248, +101248, +101248, +101275, +101275, +101287, +101314, +101314, +101356, +101366, +101366, +101366, +101374, +101382, +101389, +101408, +101408, +101426, +101426, +101443, +101443, +101459, +101459, +101459, +101459, +101476, +101476, +101504, +101504, +101504, +101529, +101567, +101591, +101638, +101638, +101645, +101673, +101711, +101739, +101787, +101787, +101787, +101797, +101814, +101834, +101834, +101834, +101899, +101907, +101914, +101914, +101914, +101936, +101948, +101948, +101948, +101987, +101987, +101987, +101997, +102027, +102027, +102034, +102034, +102042, +102053, +102068, +102086, +102091, +102099, +102099, +102125, +102138, +102151, +102151, +102151, +102160, +102199, +102199, +102199, +102199, +102216, +102216, +102233, +102255, +102268, +102286, +102302, +102323, +102332, +102339, +102351, +102351, +102351, +102356, +102395, +102395, +102430, +102447, +102447, +102447, +102457, +102457, +102457, +102493, +102493, +102493, +102493, +102502, +102536, +102543, +102543, +102543, +102543, +102566, +102596, +102596, +102625, +102654, +102660, +102678, +102678, +102678, +102678, +102701, +102701, +102701, +102717, +102717, +102723, +102734, +102734, +102750, +102766, +102766, +102766, +102801, +102807, +102807, +102833, +102849, +102849, +102868, +102868, +102881, +102887, +102904, +102924, +102924, +102980, +102980, +103013, +103073, +103073, +103079, +103079, +103085, +103115, +103115, +103115, +103128, +103128, +103128, +103143, +103206, +103231, +103241, +103263, +103263, +103271, +103271, +103309, +103350, +103350, +103379, +103398, +103406, +103425, +103425, +103459, +103468, +103491, +103491, +103491, +103508, +103525, +103525, +103536, +103536, +103536, +103550, +103550, +103573, +103578, +103578, +103578, +103591, +103601, +103612, +103612, +103630, +103630, +103630, +103630, +103659, +103659, +103666, +103684, +103696, +103696, +103719, +103763, +103778, +103778, +103778, +103778, +103834, +103834, +103841, +103868, +103868 +}; + +static const char *tldData[] = { +"sakurai.nara.jp\0" +"filegear.me\0" +"maibara.shiga.jp\0" +"consultant.aero\0mykolaiv.ua\0visa\0" +"usarts.museum\0servebeer.com\0" +"eniwa.hokkaido.jp\0abb\0" +"abc\0s3.dualstack.eu-west-3.amazonaws.com\0" +"ichinomiya.aichi.jp\0lawyer\0za.bz\0" +"beardu.no\0fl\xc3\xa5.no\0" +"nishi.fukuoka.jp\0" +"sanagochi.tokushima.jp\0" +"genova.it\0" +"pescara.it\0" +"naustdal.no\0co.place\0" +"aurland.no\0vipsinaapp.com\0" +"samsclub\0" +"from-ms.com\0from-nc.com\0i234.me\0" +"moto\0origins\0" +"1337.pictures\0" +"iyo.ehime.jp\0" +"ddnsking.com\0" +"*.cns.joyent.com\0" +"veterinaire.fr\0" +"circus.museum\0aco\0" +"monza-brianza.it\0koganei.tokyo.jp\0" +"taranto.it\0chitose.hokkaido.jp\0hara.nagano.jp\0" +"yao.osaka.jp\0" +"*.bd\0" +"act.au\0meland.no\0\xec\x82\xbc\xec\x84\xb1\0\xe4\xb8\xad\xe6\x96\x87\xe7\xbd\x91\0" +"educator.aero\0" +"yahiko.niigata.jp\0" +"viva\0" +"kawagoe.mie.jp\0" +"ads\0" +"veneto.it\0" +"aeg\0" +"static.observableusercontent.com\0" +"\xe3\x82\xb3\xe3\x83\xa0\0" +"grp.lk\0austin.museum\0karasjohka.no\0sc.ug\0barsy.online\0" +"hachioji.tokyo.jp\0xerox\0" +"luster.no\0tinn.no\0vivo\0" +"sc.tz\0" +"*.ck\0m\xc3\xa1latvuopmi.no\0cisco\0app.os.fedoraproject.org\0" +"myjino.ru\0" +"community\0" +"sc.us\0" +"\xe0\xb8\x84\xe0\xb8\xad\xe0\xb8\xa1\0" +"weather\0" +"science\0" +"fukuroi.shizuoka.jp\0afl\0" +"suedtirol.it\0" +"blogsite.org\0" +"kuromatsunai.hokkaido.jp\0of.fashion\0" +"mo.cn\0zentsuji.kagawa.jp\0usa.oita.jp\0" +"frana.no\0\xd5\xb0\xd5\xa1\xd5\xb5\0" +"mormon\0" +"sch.zm\0office\0" +"krodsherad.no\0snillfjord.no\0" +"kamishihoro.hokkaido.jp\0oji.nara.jp\0" +"asso.re\0" +"kaita.hiroshima.jp\0" +"akita.akita.jp\0" +"mt.eu.org\0loginto.me\0" +"*.er\0" +"m\xc3\xa5s\xc3\xb8y.no\0" +"trentin-s\xc3\xbc""dtirol.it\0flickr\0" +"o.bg\0eigersund.no\0" +"research.aero\0b.se\0fhsk.se\0" +"hachirogata.akita.jp\0keisen.fukuoka.jp\0marriott\0reit\0" +"*.fk\0cc.or.us\0dyndns-office.com\0" +"saskatchewan.museum\0uzhgorod.ua\0investments\0" +"kanegasaki.iwate.jp\0" +"aig\0trycloudflare.com\0" +"bugatti\0cupcake.is\0" +"ngrok.io\0" +"int.eu.org\0securitytactics.com\0" +"arte.bo\0" +"ogi.saga.jp\0" +"s\xc3\xa1lat.no\0" +"ginowan.okinawa.jp\0citadel\0" +"usercontent.jp\0" +"hob\xc3\xb8l.no\0hermes\0" +"kitaura.miyazaki.jp\0" +"to.gov.br\0" +"lucca.it\0shintoku.hokkaido.jp\0" +"pccw\0" +"\xeb\x8b\xb7\xec\xbb\xb4\0now-dns.net\0" +"ga.us\0" +"am.br\0sp.it\0" +"raholt.no\0" +"is-an-entertainer.com\0" +"asso.nc\0natura\0" +"monzaedellabrianza.it\0" +"from-in.com\0" +"ci.it\0" +"shitara.aichi.jp\0saigawa.fukuoka.jp\0" +"fastly-terrarium.com\0" +"hashima.gifu.jp\0maniwa.okayama.jp\0" +"*.on-k3s.io\0" +"george\0" +"ninohe.iwate.jp\0" +"sejny.pl\0" +"walter\0" +"oslo.no\0bygland.no\0" +"*.jm\0badajoz.museum\0lanxess\0" +"cleverapps.io\0" +"gift\0" +"zone\0" +"roma.it\0" +"mo.it\0" +"barsy.bg\0dnsupdate.info\0" +"*.kh\0" +"toyosato.shiga.jp\0rent\0" +"nyny.museum\0is-a-musician.com\0" +"ntr.br\0aso.kumamoto.jp\0kouhoku.saga.jp\0" +"preservation.museum\0" +"akashi.hyogo.jp\0" +"barsy.ca\0" +"fastpanel.direct\0" +"utazas.hu\0" +"helsinki\0" +"is-a-chef.net\0" +"myphotos.cc\0barsy.de\0" +"kizu.kyoto.jp\0anz\0" +"aol\0" +"ostrowiec.pl\0" +"*.mm\0" +"rishirifuji.hokkaido.jp\0utazu.kagawa.jp\0" +"omi.niigata.jp\0khplay.nl\0" +"\xe0\xae\x87\xe0\xae\xb2\xe0\xae\x99\xe0\xaf\x8d\xe0\xae\x95\xe0\xaf\x88\0" +"aarp\0" +"quebec.museum\0" +"cloudycluster.net\0" +"s\xc3\xa1l\xc3\xa1t.no\0\xe7\xb5\x84\xe7\xb9\x94.\xe9\xa6\x99\xe6\xb8\xaf\0" +"market\0" +"ltd.cy\0" +"ueno.gunma.jp\0app\0" +"gallery.museum\0yachts\0" +"*.np\0" +"asso.km\0" +"dyn-o-saur.com\0" +"oguchi.aichi.jp\0" +"barsy.eu\0" +"cc.gu.us\0website\0" +"otaki.nagano.jp\0" +"karacol.su\0" +"ontario.museum\0" +"hanamaki.iwate.jp\0" +"\xe0\xb8\xa3\xe0\xb8\xb1\xe0\xb8\x90\xe0\xb8\x9a\xe0\xb8\xb2\xe0\xb8\xa5.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0bar\0" +"commune.am\0bbc\0north-kazakhstan.su\0" +"my.eu.org\0oya.to\0" +"finnoy.no\0" +"surgery\0" +"asso.mc\0*.pg\0" +"morotsuka.miyazaki.jp\0uzs.gov.pl\0" +"aoki.nagano.jp\0rest\0" +"pila.pl\0" +"sunndal.no\0" +"ok.us\0" +"kimino.wakayama.jp\0art\0bbt\0" +"dev-myqnapcloud.com\0" +"fortal.br\0miyashiro.saitama.jp\0" +"bcg\0" +"forex\0" +"zappos\0" +"mantova.it\0yasaka.nagano.jp\0" +"bcn\0" +"ltd.gi\0unj\xc3\xa1rga.no\0" +"lc.it\0iwata.shizuoka.jp\0" +"\xc3\xa1lt\xc3\xa1.no\0melhus.no\0vagsoy.no\0" +"discount\0" +"taira.toyama.jp\0" +"dedyn.io\0" +"omaezaki.shizuoka.jp\0" +"latrobe\0" +"navigation.aero\0web.bo\0vgs.no\0homeunix.org\0" +"adult.ht\0ogata.akita.jp\0" +"ltd.hk\0" +"barsy.in\0" +"barsy.io\0" +"bytom.pl\0" +"*.elb.amazonaws.com\0" +"7.bg\0monticello.museum\0vefsn.no\0" +"perspecta.cloud\0" +"web.co\0verdal.no\0" +"vi.it\0tsuiki.fukuoka.jp\0" +"sango.nara.jp\0" +"author.aero\0" +"dyndns-free.com\0" +"ichikawa.hyogo.jp\0nakanoto.ishikawa.jp\0" +"monza-e-della-brianza.it\0bet\0" +"tm.cy\0" +"knx-server.net\0" +"web.do\0" +"desa.id\0ma.leg.br\0" +"shinjo.nara.jp\0" +"sandcats.io\0" +"olbia-tempio.it\0hamatama.saga.jp\0" +"higashiyodogawa.osaka.jp\0" +"\xe5\x81\xa5\xe5\xba\xb7\0" +"nl.ca\0app.banzaicloud.io\0" +"plaza.museum\0divttasvuotna.no\0za.com\0" +"gmail\0" +"homesecuritymac.com\0" +"furniture.museum\0tiaa\0daplie.me\0shacknet.nu\0" +"minamata.kumamoto.jp\0yokoze.saitama.jp\0" +"camera\0" +"passenger-association.aero\0axa\0property\0" +"wakayama.jp\0\xe5\x9f\xbc\xe7\x8e\x89.jp\0" +"\xc3\xa1k\xc5\x8boluokta.no\0aws\0" +"oseto.nagasaki.jp\0" +"vaksdal.no\0nl.eu.org\0" +"*.ocs.customer-oci.com\0" +"k12.oh.us\0" +"rebun.hokkaido.jp\0" +"volda.no\0" +"tm.fr\0gov.nc.tr\0" +"ltd.lk\0shopitsite.com\0" +"temp-dns.com\0" +"\xe5\xba\x83\xe5\xb3\xb6.jp\0bid\0" +"lib.ri.us\0schule\0" +"cruise\0" +"!city.kawasaki.jp\0" +"cyber.museum\0o.se\0mo.us\0troitsk.su\0" +"forli-cesena.it\0" +"skedsmokorset.no\0" +"web.gu\0able\0bio\0" +"yabu.hyogo.jp\0tanabe.kyoto.jp\0" +"drud.io\0members.linode.com\0" +"hk.cn\0" +"sa.au\0" +"gsm.pl\0" +"homeoffice.gov.uk\0" +"biz\0\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa6\x82\xe0\xa6\xb2\xe0\xa6\xbe\0" +"ascolipiceno.it\0" +"michigan.museum\0ltd.ng\0" +"web.id\0" +"bifuka.hokkaido.jp\0" +"tm.hu\0" +"nara.nara.jp\0" +"citic\0" +"val-daosta.it\0" +"lyngdal.no\0sor-varanger.no\0trana.no\0tynset.no\0""001www.com\0" +"tamamura.gunma.jp\0" +"*.dweb.link\0" +"toride.ibaraki.jp\0nagawa.nagano.jp\0" +"*.ye\0" +"kawaminami.miyazaki.jp\0" +"name\0us-west-2.elasticbeanstalk.com\0" +"mincom.tn\0" +"myasustor.com\0*.ocp.customer-oci.com\0" +"yazu.tottori.jp\0" +"endofinternet.org\0" +"sa.cr\0cesena-forli.it\0nakagawa.hokkaido.jp\0hannan.osaka.jp\0" +"reggio-emilia.it\0poker\0" +"k12.sc.us\0" +"bolivia.bo\0" +"bj.cn\0higashi.okinawa.jp\0hyatt\0" +"glug.org.uk\0" +"eu.org\0" +"is-not-certified.com\0" +"hashbang.sh\0" +"museet.museum\0chase\0" +"tours\0" +"degree\0" +"tm.km\0eng.pro\0" +"ota.gunma.jp\0in.net\0" +"kyuragi.saga.jp\0" +"style\0" +"sakata.yamagata.jp\0" +"nationalheritage.museum\0bms\0" +"joetsu.niigata.jp\0" +"web.lk\0ng.eu.org\0" +"nakama.fukuoka.jp\0" +"bmw\0" +"altoadige.it\0" +"zakopane.pl\0" +"ks.ua\0" +"tm.mc\0k12.md.us\0" +"broadway\0" +"kamisunagawa.hokkaido.jp\0" +"tm.mg\0" +"\xd9\x85\xd9\x88\xd8\xb1\xd9\x8a\xd8\xaa\xd8\xa7\xd9\x86\xd9\x8a\xd8\xa7\0" +"hyllestad.no\0" +"ibigawa.gifu.jp\0misato.miyagi.jp\0" +"kids.museum\0resindevice.io\0" +"semine.miyagi.jp\0pinb.gov.pl\0" +"stjordalshalsen.no\0bom\0is-a-blogger.com\0" +"snasa.no\0ks.us\0boo\0" +"yuu.yamaguchi.jp\0web.nf\0" +"\xc3\xa5""fjord.no\0" +"web.ni\0africa\0" +"bot\0vistaprint\0" +"reklam.hu\0" +"df.gov.br\0church\0" +"hanggliding.aero\0" +"koga.fukuoka.jp\0nanbu.tottori.jp\0box\0" +"nakano.nagano.jp\0" +"tm.no\0" +"nogi.tochigi.jp\0" +"ox.rs\0" +"obanazawa.yamagata.jp\0" +"contemporaryart.museum\0" +"chikuma.nagano.jp\0cab\0" +"diskussionsbereich.de\0" +"brindisi.it\0" +"\xe5\x80\x8b\xe4\xba\xba.hk\0" +"bharti\0forsale\0ltd.ua\0" +"\xe5\xa4\xa7\xe9\x98\xaa.jp\0toba.mie.jp\0virgin\0" +"vi.us\0" +"fantasyleague.cc\0" +"cal\0" +"tecnologia.bo\0drammen.no\0cam\0" +"avocat.fr\0" +"natural.bo\0ltd.uk\0cba\0" +"udono.mie.jp\0car\0" +"cat\0imdb\0" +"web.pk\0" +"sa.it\0ojiya.niigata.jp\0" +"tm.pl\0mazowsze.pl\0republican\0" +"vaga.no\0" +"cbn\0" +"firmdale\0forum\0" +"oki.fukuoka.jp\0" +"nl.no\0" +"\xd9\x81\xd9\x84\xd8\xb3\xd8\xb7\xd9\x8a\xd9\x86\0limited\0" +"cbs\0ferrari\0hs.zone\0" +"itoigawa.niigata.jp\0" +"friulivegiulia.it\0" +"from-mn.com\0" +"oita.oita.jp\0" +"firewall-gateway.de\0" +"futsu.nagasaki.jp\0" +"v\xc3\xa5g\xc3\xa5.no\0" +"unjarga.no\0" +"nt.edu.au\0" +"sumoto.kumamoto.jp\0chino.nagano.jp\0" +"pagespeedmobilizer.com\0" +"feste-ip.net\0" +"press.aero\0" +"meldal.no\0" +"tm.ro\0" +"grainger\0" +"cc.ca.us\0" +"\xe9\x9d\x99\xe5\xb2\xa1.jp\0" +"firewall-gateway.com\0" +"cesena-forl\xc3\xac.it\0" +"tm.se\0" +"ceb\0" +"suzu.ishikawa.jp\0shizuoka.shizuoka.jp\0yoshida.shizuoka.jp\0" +"sport.hu\0" +"showa.gunma.jp\0tomakomai.hokkaido.jp\0rybnik.pl\0myeffect.net\0" +"flakstad.no\0" +"akaiwa.okayama.jp\0wajiki.tokushima.jp\0" +"malatvuopmi.no\0ceo\0navy\0s3.ap-northeast-2.amazonaws.com\0" +"\xd0\xb1\xd0\xb3\0cfa\0" +"minamioguni.kumamoto.jp\0" +"vega.no\0" +"web.tj\0cfd\0" +"kunstunddesign.museum\0" +"pistoia.it\0vv.it\0" +"pueblo.bo\0" +"buy\0drud.us\0" +"messina.it\0" +"public.museum\0r\xc3\xb8ros.no\0" +"web.tr\0" +"satte.saitama.jp\0" +"minami.fukuoka.jp\0teshikaga.hokkaido.jp\0" +"careers\0" +"namsos.no\0ringebu.no\0" +"goto.nagasaki.jp\0pulawy.pl\0" +"cv.ua\0arkhangelsk.su\0" +"deals\0definima.io\0" +"shika.ishikawa.jp\0gushikami.okinawa.jp\0oguni.yamagata.jp\0" +"web.ve\0tips\0" +"cn-north-1.eb.amazonaws.com.cn\0" +"sande.vestfold.no\0" +"communication.museum\0" +"boleslawiec.pl\0" +"decorativearts.museum\0" +"cern\0""2ix.at\0" +"pu.it\0" +"trust.museum\0s3-us-west-2.amazonaws.com\0" +"clinic\0" +"biz.bb\0" +"gs.va.no\0is-slick.com\0" +"qsl.br\0biz.at\0" +"honbetsu.hokkaido.jp\0zachpomor.pl\0" +"biz.az\0" +"katsuragi.nara.jp\0" +"flora.no\0" +"2ix.ch\0" +"aero.tt\0" +"bilbao.museum\0levanger.no\0" +"naruto.tokushima.jp\0bzh\0" +"parti.se\0gratis\0" +"2ix.de\0" +"kushima.miyazaki.jp\0t3l3p0rt.net\0" +"stateofdelaware.museum\0lib.as.us\0" +"tananger.no\0" +"aero.mv\0" +"boxfuse.io\0" +"palermo.it\0" +"meraker.no\0" +"biz.cy\0" +"creditcard\0" +"web.za\0\xe9\xa6\x99\xe6\xa0\xbc\xe9\x87\x8c\xe6\x8b\x89\0biz.dk\0co.technology\0" +"\xd0\xb5\xd1\x8e\0" +"air.museum\0krager\xc3\xb8.no\0skedsmo.no\0tm.za\0" +"ichiba.tokushima.jp\0" +"immo\0" +"baths.museum\0virtuel.museum\0" +"andria-trani-barletta.it\0shiroishi.miyagi.jp\0arita.saga.jp\0" +"from-oh.com\0" +"tokke.no\0" +"sn.cn\0\xe5\xaf\x8c\xe5\xb1\xb1.jp\0" +"is-found.org\0" +"valled-aosta.it\0fbxos.fr\0" +"pasadena.museum\0is-an-actor.com\0" +"mielec.pl\0" +"biz.et\0" +"tawaramoto.nara.jp\0starostwo.gov.pl\0" +"fjell.no\0" +"kimitsu.chiba.jp\0fashion\0" +"biz.fj\0" +"comunica\xc3\xa7\xc3\xb5""es.museum\0" +"lomza.pl\0" +"*.alces.network\0ap-northeast-3.elasticbeanstalk.com\0webspace.rocks\0" +"komono.mie.jp\0hiraya.nagano.jp\0" +"k12.ca.us\0" +"kv\xc3\xa6nangen.no\0" +"donetsk.ua\0cc.va.us\0" +"frankfurt.museum\0" +"kotohira.kagawa.jp\0" +"openair.museum\0" +"biz.gl\0" +"adac\0togliatti.su\0" +"schoenbrunn.museum\0tree.museum\0" +"friuliveneziagiulia.it\0kurotaki.nara.jp\0beep.pl\0" +"az.us\0university\0" +"dontexist.net\0" +"software.aero\0dattoweb.com\0now-dns.org\0" +"edunet.tn\0" +"filegear-gb.me\0" +"sakuragawa.ibaraki.jp\0" +"in-addr.arpa\0com\0" +"eti.br\0" +"chiba.jp\0tanagura.fukushima.jp\0" +"cpa\0juegos\0" +"pagefrontapp.com\0hk.org\0" +"biz.id\0" +"rj.gov.br\0yamada.toyama.jp\0" +"m.bg\0" +"\xc3\xb8ystre-slidre.no\0" +"naval.museum\0" +"hofu.yamaguchi.jp\0dad\0" +"viking.museum\0\xd0\xbe\xd0\xb1\xd1\x80.\xd1\x81\xd1\x80\xd0\xb1\0" +"sarufutsu.hokkaido.jp\0buzz\0" +"hirata.fukushima.jp\0czeladz.pl\0" +"stj\xc3\xb8rdalshalsen.no\0askoy.no\0cbg.ru\0" +"is-a-bookkeeper.com\0" +"leg.br\0" +"\xc3\xb8ksnes.no\0loans\0" +"ito.shizuoka.jp\0" +"khmelnitskiy.ua\0" +"ikeda.hokkaido.jp\0" +"r\xc3\xa5holt.no\0tvedestrand.no\0" +"hidaka.wakayama.jp\0" +"biz.ki\0day\0fujitsu\0" +"mg.leg.br\0" +"handa.aichi.jp\0" +"fishing\0from-ri.com\0" +"ibaraki.ibaraki.jp\0intl.tn\0" +"tydal.no\0s3.dualstack.ap-southeast-1.amazonaws.com\0barsyonline.co.uk\0" +"\xe4\xb8\xaa\xe4\xba\xba.hk\0dr\xc3\xb8""bak.no\0" +"crs\0csc\0obninsk.su\0" +"tachikawa.tokyo.jp\0\xe0\xb8\x98\xe0\xb8\xb8\xe0\xb8\xa3\xe0\xb8\x81\xe0\xb8\xb4\xe0\xb8\x88.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" +"lorenskog.no\0" +"hayakawa.yamanashi.jp\0" +"luxembourg.museum\0holtalen.no\0\xd9\x83\xd8\xa7\xd8\xab\xd9\x88\xd9\x84\xd9\x8a\xd9\x83\0" +"fukaya.saitama.jp\0" +"missoula.museum\0vardo.no\0kpmg\0" +"trentino-suedtirol.it\0siteleaf.net\0" +"police.uk\0" +"ribeirao.br\0" +"biz.ls\0" +"nakatsugawa.gifu.jp\0" +"dsmynas.com\0" +"izumo.shimane.jp\0" +"kl\xc3\xa6""bu.no\0" +"\xe0\xb2\xad\xe0\xb2\xbe\xe0\xb2\xb0\xe0\xb2\xa4\0" +"takata.fukuoka.jp\0" +"\xe0\xac\xad\xe0\xac\xbe\xe0\xac\xb0\xe0\xac\xa4\0" +"macys\0" +"info\0kvinnherad.no\0barsy.mobi\0" +"\xe0\xa6\xad\xe0\xa6\xbe\xe0\xa6\xb0\xe0\xa6\xa4\0" +"dds\0" +"biz.mv\0" +"biz.mw\0" +"santoandre.br\0" +"biz.ni\0vagan.no\0jdevcloud.com\0" +"asahikawa.hokkaido.jp\0" +"giehtavuoatna.no\0" +"southcarolina.museum\0" +"trentinoaadige.it\0dealer\0" +"minami.tokushima.jp\0" +"k12.ks.us\0bargains\0" +"biz.nr\0\xd1\x80\xd1\x84\0" +"ddnsgeek.com\0" +"dev\0" +"dagestan.ru\0" +"tobishima.aichi.jp\0" +"fuso.aichi.jp\0" +"sinaapp.com\0" +"kurashiki.okayama.jp\0" +"groundhandling.aero\0bo.nordland.no\0" +"cloudaccess.host\0" +"beauxarts.museum\0sandnessjoen.no\0cc.mt.us\0cc.nd.us\0" +"oyamazaki.kyoto.jp\0szczecin.pl\0" +"dagestan.su\0" +"kawai.nara.jp\0okutama.tokyo.jp\0" +"mandal.no\0" +"no-ip.biz\0" +"tingvoll.no\0biz.pk\0k12.va.us\0" +"kikonai.hokkaido.jp\0biz.pl\0" +"nature.museum\0myqnapcloud.com\0" +"casacam.net\0" +"fuel.aero\0" +"kasamatsu.gifu.jp\0fujimi.saitama.jp\0biz.pr\0\xe5\xb9\xbf\xe4\xb8\x9c\0" +"fortworth.museum\0" +"hitachi\0cloud.goog\0hzc.io\0" +"motosu.gifu.jp\0" +"sauherad.no\0" +"wassamu.hokkaido.jp\0dhl\0" +"lab.ms\0" +"muroto.kochi.jp\0" +"metlife\0" +"shimabara.nagasaki.jp\0" +"loginline.site\0" +"shimamoto.osaka.jp\0" +"\xe5\x95\x86\xe5\x9f\x8e\0" +"hirado.nagasaki.jp\0" +"eisenbahn.museum\0bplaced.de\0qualifioapp.com\0" +"maison\0" +"kamoenai.hokkaido.jp\0miyoshi.tokushima.jp\0crown\0weber\0" +"lom.it\0" +"diy\0" +"golffan.us\0" +"ws.na\0" +"h\xc3\xb8ylandet.no\0ny.us\0\xe5\x9c\xa8\xe7\xba\xbf\0" +"biz.ss\0cc.ri.us\0" +"biz.tj\0" +"guam.gu\0" +"ustka.pl\0quest\0" +"cc.ar.us\0" +"plc.co.im\0civilization.museum\0biz.ua\0" +"biz.tr\0" +"on-aptible.com\0" +"biz.tt\0barsy.support\0" +"b\xc3\xa1id\xc3\xa1r.no\0s3-website.eu-west-2.amazonaws.com\0" +"tamayu.shimane.jp\0" +"is-by.us\0" +"yamato.fukushima.jp\0" +"tas.gov.au\0" +"shiraoka.saitama.jp\0" +"movie\0" +"omotego.fukushima.jp\0\xe5\xa8\xb1\xe4\xb9\x90\0" +"5.bg\0bible\0" +"kui.hiroshima.jp\0" +"issmarterthanyou.com\0" +"romsa.no\0" +"chikuho.fukuoka.jp\0" +"sa.gov.au\0" +"nagahama.shiga.jp\0" +"click\0" +"otaki.saitama.jp\0biz.vn\0" +"tsukui.kanagawa.jp\0" +"flesberg.no\0nesseby.no\0" +"notogawa.shiga.jp\0" +"usr.cloud.muni.cz\0" +"yamaga.kumamoto.jp\0wakuya.miyagi.jp\0" +"national.museum\0kongsvinger.no\0merseine.nu\0" +"dnp\0cistron.nl\0" +"accesscam.org\0" +"otsuki.kochi.jp\0" +"lom.no\0komforb.se\0" +"kitakami.iwate.jp\0" +"dog\0" +"r\xc3\xb8yrvik.no\0lib.ga.us\0" +"aikawa.kanagawa.jp\0" +"kamo.niigata.jp\0" +"waw.pl\0" +"goldpoint\0" +"dot\0" +"gs.tr.no\0" +"trentino-s-tirol.it\0" +"agents.aero\0k12.nv.us\0" +"rr.gov.br\0" +"my-vigor.de\0" +"hisamitsu\0" +"yahaba.iwate.jp\0" +"la-spezia.it\0oristano.it\0" +"s3.amazonaws.com\0" +"slz.br\0" +"z.bg\0brasil.museum\0" +"sasayama.hyogo.jp\0" +"m.se\0" +"fukuchi.fukuoka.jp\0uchinomi.kagawa.jp\0" +"oshima.yamaguchi.jp\0immobilien\0" +"biz.zm\0" +"skien.no\0" +"rich\0" +"hi.cn\0anpachi.gifu.jp\0ketrzyn.pl\0eat\0" +"berlin.museum\0jolster.no\0" +"dyroy.no\0" +"rs.gov.br\0sc.gov.br\0tajiri.osaka.jp\0arai.shizuoka.jp\0\xe6\x88\x91\xe7\x88\xb1\xe4\xbd\xa0\0" +"flor\xc3\xb8.no\0" +"norddal.no\0" +"ternopil.ua\0" +"castres.museum\0symantec\0barsy.info\0" +"loppa.no\0cherkasy.ua\0" +"oto.fukuoka.jp\0hotmail\0" +"neustar\0scrapper-site.net\0" +"qc.com\0" +"furudono.fukushima.jp\0" +"eco\0" +"stargard.pl\0" +"etne.no\0" +"crotone.it\0reggio-calabria.it\0epson\0" +"smart\0" +"sorreisa.no\0" +"cng.br\0ashikaga.tochigi.jp\0land\0" +"ct.it\0manno.kagawa.jp\0" +"defense.tn\0" +"prato.it\0" +"juedisches.museum\0lib.ut.us\0is-a-teacher.com\0" +"kasugai.aichi.jp\0onion\0" +"edu\0" +"valle-d-aosta.it\0dtv\0" +"wallonie.museum\0" +"gwangju.kr\0" +"artsandcrafts.museum\0vossevangen.no\0" +"chintai\0photos\0" +"rokunohe.aomori.jp\0shimogo.fukushima.jp\0" +"cloudcontrolapp.com\0" +"touch.museum\0" +"time.museum\0" +"tokuyama.yamaguchi.jp\0" +"ak.us\0" +"ln.cn\0" +"ba.gov.br\0azumino.nagano.jp\0koza.wakayama.jp\0" +"egyptian.museum\0" +"hachinohe.aomori.jp\0final\0" +"katsushika.tokyo.jp\0" +"jogasz.hu\0gs.sf.no\0" +"konan.aichi.jp\0" +"kimobetsu.hokkaido.jp\0jelenia-gora.pl\0" +"\xc3\xa5seral.no\0" +"dvr\0" +"dali.museum\0" +"wpdevcloud.com\0" +"health\0" +"hiranai.aomori.jp\0" +"sula.no\0la.us\0" +"fm.br\0" +"chat\0" +"nesodden.no\0" +"toyama.toyama.jp\0" +"lexus\0is-uberleet.com\0" +"botany.museum\0fastvps-server.com\0" +"rn.gov.br\0gmbh\0" +"bjarkoy.no\0skjervoy.no\0" +"belau.pw\0" +"nagano.nagano.jp\0serveblog.net\0" +"busan.kr\0" +"hapmir.no\0from-vt.com\0" +"qc.ca\0" +"trentino.it\0" +"scjohnson\0" +"ro.im\0" +"balsfjord.no\0nes.akershus.no\0github.io\0" +"kanra.gunma.jp\0" +"lavagis.no\0" +"missile.museum\0" +"ro.it\0" +"ro.gov.br\0miura.kanagawa.jp\0osaki.miyagi.jp\0" +"copenhagen.museum\0" +"does-it.net\0" +"karasjok.no\0" +"mimata.miyazaki.jp\0" +"numata.gunma.jp\0" +"j\xc3\xb8lster.no\0" +"masoy.no\0" +"global.prod.fastly.net\0*.ex.ortsinfo.at\0" +"baidar.no\0sortland.no\0azure\0" +"kred\0" +"farm.museum\0" +"cheap\0" +"watches\0" +"ogasawara.tokyo.jp\0" +"nctu.me\0" +"midori.gunma.jp\0" +"tr.eu.org\0*.r.appspot.com\0" +"from-sd.com\0" +"samukawa.kanagawa.jp\0iwafune.tochigi.jp\0" +"lug.org.uk\0" +"himi.toyama.jp\0" +"unicom\0" +"nozawaonsen.nagano.jp\0" +"snaase.no\0" +"kamisu.ibaraki.jp\0\xe5\x98\x89\xe9\x87\x8c\0" +"sand\xc3\xb8y.no\0" +"fujioka.gunma.jp\0" +"takko.aomori.jp\0" +"north.museum\0" +"ikusaka.nagano.jp\0yoshinogari.saga.jp\0" +"*.dev.adobeaemcloud.com\0" +"higashi.fukushima.jp\0" +"lardal.no\0s3.dualstack.eu-central-1.amazonaws.com\0" +"belem.br\0" +"servegame.com\0" +"uni5.net\0" +"noda.chiba.jp\0" +"lib.ms.us\0lib.nc.us\0" +"countryestate.museum\0navuotna.no\0diamonds\0" +"vt.it\0" +"klabu.no\0r\xc3\xb8""d\xc3\xb8y.no\0cc.me.us\0" +"am.gov.br\0" +"edeka\0" +"ong.br\0" +"og.ao\0tula.su\0arvo.network\0" +"aquila.it\0\xe5\x8f\xb0\xe6\xb9\xbe\0" +"m\xc3\xa1tta-v\xc3\xa1rjjat.no\0" +"\xd8\xa7\xd8\xaa\xd8\xb5\xd8\xa7\xd9\x84\xd8\xa7\xd8\xaa\0" +"whoswho\0" +"fm.it\0" +"gos.pk\0africa.com\0" +"makinohara.shizuoka.jp\0" +"verbania.it\0" +"futtsu.chiba.jp\0aid.pl\0" +"sor-fron.no\0" +"aostavalley.it\0earth\0" +"amot.no\0" +"sukagawa.fukushima.jp\0tone.ibaraki.jp\0kami.miyagi.jp\0" +"london\0" +"aero\0flatanger.no\0ct.us\0softbank\0" +"ravenna.it\0" +"oksnes.no\0" +"trentino-s\xc3\xbc""dtirol.it\0nango.fukushima.jp\0" +"manchester.museum\0" +"eid.no\0" +"dell-ogliastra.it\0" +"statefarm\0" +"utwente.io\0" +"2038.io\0" +"psc.br\0fan\0custom.metacentrum.cz\0" +"plumbing\0" +"orsta.no\0\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xd9\x8a\xd9\x87\0" +"maizuru.kyoto.jp\0" +"z.se\0nj.us\0" +"funabashi.chiba.jp\0asago.hyogo.jp\0" +"shoo.okayama.jp\0higashine.yamagata.jp\0turen.tn\0" +"scrapping.cc\0" +"notaires.km\0" +"oguni.kumamoto.jp\0" +"kawaba.gunma.jp\0higashikagawa.kagawa.jp\0kuokgroup\0" +"hagebostad.no\0" +"kitaaiki.nagano.jp\0" +"raisa.no\0" +"miki.hyogo.jp\0mitsue.nara.jp\0higashiomi.shiga.jp\0" +"dontexist.org\0" +"cloud.metacentrum.cz\0" +"journalist.aero\0aknoluokta.no\0dating\0" +"\xe6\xbe\xb3\xe9\x96\x80\0" +"exhibition.museum\0fm.no\0" +"harima.hyogo.jp\0" +"leirvik.no\0" +"sayama.saitama.jp\0gda.pl\0" +"esq\0" +"aizuwakamatsu.fukushima.jp\0ise.mie.jp\0schmidt\0" +"sor-aurdal.no\0\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xd9\x8a\xd8\xa9\0" +"federation.aero\0" +"ap.gov.br\0miyazu.kyoto.jp\0" +"hi.us\0" +"wodzislaw.pl\0\xd8\xa7\xd9\x85\xd8\xa7\xd8\xb1\xd8\xa7\xd8\xaa\0" +"vallee-aoste.it\0" +"fusa.no\0" +"yoshimi.saitama.jp\0" +"sdn.gov.pl\0" +"siellak.no\0hamburg\0" +"cnt.br\0" +"nagai.yamagata.jp\0" +"lerdal.no\0" +"furukawa.miyagi.jp\0" +"hakata.fukuoka.jp\0abbott\0" +"pimienta.org\0" +"\xe8\xb0\xb7\xe6\xad\x8c\0" +"sciencesnaturelles.museum\0lib.wi.us\0" +"esan.hokkaido.jp\0ap.gov.pl\0" +"trysil.no\0airbus\0dattorelay.com\0" +"eus\0" +"tarumizu.kagoshima.jp\0" +"sherbrooke.museum\0" +"fastlylb.net\0" +"b\xc3\xa1hccavuotna.no\0" +"se.gov.br\0kumenan.okayama.jp\0mielno.pl\0ddns.net\0" +"aca.pro\0" +"r\xc3\xa1hkker\xc3\xa1vju.no\0" +"andria-barletta-trani.it\0yasugi.shimane.jp\0" +"og.it\0annaka.gunma.jp\0" +"services.aero\0transport.museum\0training\0\xeb\x8b\xb7\xeb\x84\xb7\0" +"alessandria.it\0fuji.shizuoka.jp\0" +"stockholm\0" +"store.nf\0" +"k12.nm.us\0east-kazakhstan.su\0" +"yamatsuri.fukushima.jp\0" +"alstahaug.no\0" +"landrover\0" +"tires\0" +"isernia.it\0kadena.okinawa.jp\0pup.gov.pl\0" +"mus.br\0" +"midatlantic.museum\0" +"sciencecenters.museum\0" +"yashio.saitama.jp\0playstation\0" +"k.bg\0" +"nakagawa.tokushima.jp\0" +"chippubetsu.hokkaido.jp\0" +"s3.ap-south-1.amazonaws.com\0" +"rehab\0" +"locus\0" +"\xc3\xb8yer.no\0" +"sos.pl\0" +"from-ne.com\0" +"shibukawa.gunma.jp\0" +"jerusalem.museum\0" +"gs.mr.no\0gjovik.no\0" +"kiwa.mie.jp\0" +"healthcare\0" +"bsb.br\0miyada.nagano.jp\0wroc.pl\0" +"\xe6\xbe\xb3\xe9\x97\xa8\0" +"vt.us\0" +"fit\0" +"s3.dualstack.eu-west-1.amazonaws.com\0" +"vevelstad.no\0" +"caa.aero\0" +"matsuda.kanagawa.jp\0" +"medical.museum\0sa-east-1.elasticbeanstalk.com\0dnshome.de\0" +"tanohata.iwate.jp\0" +"latino\0" +"yabuki.fukushima.jp\0museum.tt\0" +"dnsupdater.de\0" +"shikaoi.hokkaido.jp\0" +"musica.ar\0chikusei.ibaraki.jp\0" +"ngo.lk\0" +"maryland.museum\0" +"taketa.oita.jp\0" +"trentin-suedtirol.it\0kahoku.ishikawa.jp\0hayashima.okayama.jp\0" +"ce.it\0gotsu.shimane.jp\0nakano.tokyo.jp\0" +"shingu.fukuoka.jp\0" +"musica.bo\0" +"lighting\0" +"yamamoto.miyagi.jp\0sa.gov.pl\0" +"iveco\0from-wv.com\0" +"azurewebsites.net\0" +"hdfcbank\0" +"ide.kyoto.jp\0" +"civilisation.museum\0ngo.ng\0pgfog.com\0" +"takarazuka.hyogo.jp\0kita.osaka.jp\0" +"leksvik.no\0" +"inf.br\0" +"fly\0" +"nsupdate.info\0" +"oizumi.gunma.jp\0" +"2000.hu\0vik.no\0k12.ky.us\0" +"historyofscience.museum\0" +"kuriyama.hokkaido.jp\0higashimatsuyama.saitama.jp\0" +"chocolate.museum\0uk.eu.org\0" +"saijo.ehime.jp\0fujiyoshida.yamanashi.jp\0" +"delivery\0" +"miyoshi.saitama.jp\0" +"gliding.aero\0koebenhavn.museum\0orland.no\0" +"mashiki.kumamoto.jp\0" +"inf.cu\0balena-devices.com\0test-iserv.de\0" +"archaeological.museum\0" +"buzen.fukuoka.jp\0saka.hiroshima.jp\0android\0" +"ngo.ph\0" +"ulm.museum\0mydobiss.com\0" +"store.ve\0" +"chikujo.fukuoka.jp\0miyake.nara.jp\0" +"corsica\0" +"s3.cn-north-1.amazonaws.com.cn\0" +"tozsde.hu\0school.na\0holmestrand.no\0foo\0s3-website.us-east-2.amazonaws.com\0" +"farmstead.museum\0jewelry\0" +"vanylven.no\0" +"museumvereniging.museum\0phoenix.museum\0bu.no\0" +"nagasu.kumamoto.jp\0fox\0" +"tx.us\0noip.us\0" +"lviv.ua\0" +"target\0" +"g\xc3\xa1\xc5\x8bgaviika.no\0" +"isahaya.nagasaki.jp\0" +"fresenius\0reliance\0" +"berlevag.no\0bjerkreim.no\0" +"bolzano-altoadige.it\0" +"froya.no\0" +"inami.toyama.jp\0canon\0" +"school.nz\0tirol\0" +"tokai.aichi.jp\0" +"frog.museum\0porsgrunn.no\0" +"gal\0" +"fitness\0is-a-linux-user.org\0" +"\xe9\xab\x98\xe7\x9f\xa5.jp\0" +"homeunix.com\0" +"wroclaw.pl\0gap\0" +"res.in\0fukagawa.hokkaido.jp\0" +"certification.aero\0jorpeland.no\0game-host.org\0" +"forl\xc3\xac-cesena.it\0okegawa.saitama.jp\0" +"gay\0" +"akishima.tokyo.jp\0frl\0" +"muncie.museum\0evenassi.no\0vestby.no\0wellbeingzone.eu\0" +"vix.br\0" +"br.com\0" +"zj.cn\0rnrt.tn\0" +"isehara.kanagawa.jp\0takaharu.miyazaki.jp\0" +"vote\0" +"pilot.aero\0presidio.museum\0" +"ashibetsu.hokkaido.jp\0kawakami.nara.jp\0" +"\xc3\xa5krehamn.no\0" +"jetzt\0" +"ferrero\0" +"tabuse.yamaguchi.jp\0" +"wakayama.wakayama.jp\0" +"voto\0" +"museum.mv\0" +"museum.mw\0store.ro\0meteorapp.com\0" +"m\xc3\xa5lselv.no\0if.ua\0" +"tainai.niigata.jp\0" +"hanno.saitama.jp\0" +"dreamhosters.com\0" +"museum.no\0institute\0" +"minamiboso.chiba.jp\0" +"stokke.no\0" +"gdn\0" +"quebec\0" +"gea\0" +"ftr\0" +"3.bg\0" +"gotemba.shizuoka.jp\0warmia.pl\0" +"heritage.museum\0" +"ve.it\0store.st\0" +"museum.om\0" +"moroyama.saitama.jp\0kaneyama.yamagata.jp\0cloudns.biz\0" +"s3.eu-west-2.amazonaws.com\0" +"mat.br\0!city.sendai.jp\0" +"fujimino.saitama.jp\0" +"nordre-land.no\0" +"adm.br\0fun\0" +"en.it\0" +"gb.com\0dyndns-work.com\0" +"sande.m\xc3\xb8re-og-romsdal.no\0\xd0\xb1\xd0\xb5\xd0\xbb\0virtualserver.io\0" +"news\0" +"horokanai.hokkaido.jp\0" +"shoes\0" +"aridagawa.wakayama.jp\0" +"praxi\0dh.bytemark.co.uk\0" +"ybo.review\0" +"\xc3\xb8rland.no\0" +"panasonic\0gotdns.org\0" +"noda.iwate.jp\0next\0" +"ot.it\0pd.it\0" +"trentino-sued-tirol.it\0iizuka.fukuoka.jp\0" +"\xe5\x85\xab\xe5\x8d\xa6\0" +"inf.mk\0moscow\0" +"hekinan.aichi.jp\0yonabaru.okinawa.jp\0" +"chernovtsy.ua\0mk.ua\0from-ia.com\0is-very-evil.org\0ilovecollege.info\0dyn53.io\0" +"frosta.no\0" +"kirovograd.ua\0" +"oga.akita.jp\0\xe0\xb4\xad\xe0\xb4\xbe\xe0\xb4\xb0\xe0\xb4\xa4\xe0\xb4\x82\0\xe4\xba\x9a\xe9\xa9\xac\xe9\x80\x8a\0" +"ngo.za\0" +"uonuma.niigata.jp\0" +"ac\0" +"ad\0" +"ae\0\xe7\xb5\x84\xe7\xbb\x87.hk\0drayddns.com\0" +"af\0" +"ag\0kvanangen.no\0" +"ai\0x.bg\0" +"k.se\0" +"al\0nagasaki.jp\0" +"am\0" +"futurehosting.at\0" +"ao\0namsskogan.no\0fyi\0" +"obama.nagasaki.jp\0saiki.oita.jp\0" +"emergency.aero\0aq\0ba\0" +"ar\0bb\0" +"as\0" +"at\0higashiagatsuma.gunma.jp\0" +"au\0be\0iraq.museum\0" +"bf\0" +"aw\0bg\0" +"ax\0bh\0is.it\0" +"bi\0" +"az\0bj\0" +"intelligence.museum\0citi\0online\0" +"bm\0" +"bn\0valleaosta.it\0tottori.tottori.jp\0" +"bo\0santacruz.museum\0" +"kaisei.kanagawa.jp\0itoman.okinawa.jp\0swatch\0" +"ca\0pics\0diskstation.me\0" +"br\0" +"bs\0cc\0" +"bt\0cd\0" +"bv\0cf\0" +"bw\0cg\0" +"ch\0" +"by\0ci\0stjordal.no\0" +"bz\0matera.it\0" +"lillehammer.no\0lund.no\0city\0" +"cl\0" +"cm\0" +"cn\0" +"co\0" +"noip.me\0diskstation.eu\0" +"cr\0sicilia.it\0balsan-s\xc3\xbc""dtirol.it\0" +"bozen-s\xc3\xbc""dtirol.it\0" +"cu\0de\0" +"cv\0restaurant\0" +"cw\0" +"cx\0\xe7\xa7\x8b\xe7\x94\xb0.jp\0" +"cy\0london.museum\0" +"cz\0dj\0sic.it\0" +"dk\0afamilycompany\0gle\0" +"trd.br\0" +"dm\0capitalone\0" +"cr.it\0shiriuchi.hokkaido.jp\0nyc.mn\0yandexcloud.net\0" +"do\0burghof.museum\0balestrand.no\0lancia\0de.com\0servesarcasm.com\0" +"remotewd.com\0" +"chikuhoku.nagano.jp\0" +"ec\0dallas.museum\0" +"ee\0" +"prd.fr\0" +"eg\0\xe5\x8f\xb0\xe7\x81\xa3\0" +"bizen.okayama.jp\0servebbs.net\0" +"lutsk.ua\0" +"dz\0" +"imageandsound.museum\0jessheim.no\0" +"cloudera.site\0" +"karlsoy.no\0barrell-of-knowledge.info\0" +"email\0" +"es\0fuoisku.no\0" +"et\0kuzumaki.iwate.jp\0odawara.kanagawa.jp\0" +"eu\0gmo\0" +"notaires.fr\0" +"fi\0coldwar.museum\0storj.farm\0" +"fj\0ohda.shimane.jp\0" +"fm\0mining.museum\0" +"gmx\0" +"fo\0" +"ga\0" +"fr\0gb\0" +"gd\0" +"ge\0" +"gf\0bpl.biz\0" +"gg\0bokn.no\0wmflabs.org\0" +"gh\0" +"gi\0" +"v\xc3\xa5ler.hedmark.no\0" +"gl\0barlettatraniandria.it\0hokuryu.hokkaido.jp\0" +"gm\0inf.ua\0" +"gn\0pesaro-urbino.it\0nishihara.kumamoto.jp\0" +"gp\0aomori.aomori.jp\0" +"gq\0" +"gr\0" +"gs\0" +"gt\0" +"skydiving.aero\0gu\0goo\0" +"gop\0" +"gw\0santabarbara.museum\0" +"gy\0fribourg.museum\0herokuapp.com\0" +"got\0" +"hk\0" +"gov\0" +"hm\0" +"hn\0" +"dinosaur.museum\0egersund.no\0osaka\0rackmaze.com\0" +"hr\0" +"ht\0id\0" +"hu\0ie\0" +"umi.fukuoka.jp\0joyo.kyoto.jp\0" +"orkdal.no\0" +"minano.saitama.jp\0" +"newyork.museum\0radio\0" +"il\0" +"im\0" +"in\0" +"io\0" +"iq\0prd.km\0" +"ir\0fujisato.akita.jp\0sukumo.kochi.jp\0gyeongnam.kr\0" +"is\0" +"it\0" +"je\0mx.na\0servehttp.com\0" +"rm.it\0\xe5\x85\xac\xe5\x8f\xb8\0" +"pointto.us\0" +"gold\0leczna.pl\0" +"americanantiques.museum\0booking\0spacekit.io\0" +"golf\0" +"orkanger.no\0" +"jo\0" +"jp\0akiruno.tokyo.jp\0" +"marker.no\0" +"name.hr\0" +"sn\xc3\xa5""ase.no\0prvcy.page\0" +"av.it\0" +"ke\0bananarepublic\0hbo\0" +"inashiki.ibaraki.jp\0kainan.tokushima.jp\0" +"kg\0adobeaemcloud.com\0" +"video.hu\0ki\0hobol.no\0lolipop.io\0" +"store.bb\0" +"logistics.aero\0prd.mg\0" +"km\0dnsdojo.org\0" +"kn\0" +"kp\0" +"la\0supply\0*.landing.myjino.ru\0" +"kr\0lb\0" +"lc\0cc.sd.us\0" +"name.et\0kiyama.saga.jp\0" +"kw\0" +"trentino-stirol.it\0" +"ky\0li\0illustration.museum\0java\0" +"name.fj\0kz\0" +"lk\0" +"tv.bb\0hitachiota.ibaraki.jp\0ntdll.top\0" +"gouv.fr\0kumejima.okinawa.jp\0agakhan\0" +"mihama.chiba.jp\0ritto.shiga.jp\0hicam.net\0" +"ma\0" +"okaya.nagano.jp\0lr\0" +"ls\0mc\0" +"lt\0md\0" +"lu\0me\0ping\0" +"lv\0" +"mg\0own.pm\0" +"mh\0\xe0\xa6\xad\xe0\xa6\xbe\xe0\xa7\xb0\xe0\xa6\xa4\0" +"tv.bo\0ly\0pink\0" +"mk\0" +"tv.br\0yakumo.shimane.jp\0ml\0" +"goog\0" +"mn\0a.prod.fastly.net\0" +"mo\0nokia\0" +"ashiya.fukuoka.jp\0mp\0barefoot\0" +"mq\0na\0gs.aa.no\0" +"mr\0" +"plc.ly\0ms\0nc\0lib.ne.us\0s3-ap-northeast-1.amazonaws.com\0store.dk\0" +"yoshioka.gunma.jp\0mt\0" +"mu\0ne\0\xc3\xa5mot.no\0" +"mv\0nf\0" +"philadelphiaarea.museum\0mw\0ng\0lima-city.de\0" +"vr.it\0mx\0" +"name.cy\0my\0ni\0*.vps.myjino.ru\0" +"kawanishi.nara.jp\0mz\0" +"nl\0" +"freemasonry.museum\0*.spectrum.myjino.ru\0" +"no\0" +"gouv.ht\0prochowice.pl\0pa.leg.br\0" +"per.la\0" +"toyohashi.aichi.jp\0nr\0" +"isleofman.museum\0valley.museum\0\xe0\xae\x9a\xe0\xae\xbf\xe0\xae\x99\xe0\xaf\x8d\xe0\xae\x95\xe0\xae\xaa\xe0\xaf\x8d\xe0\xae\xaa\xe0\xaf\x82\xe0\xae\xb0\xe0\xaf\x8d\0" +"beskidy.pl\0" +"nu\0" +"otoyo.kochi.jp\0" +"name.eg\0grimstad.no\0" +"fujiidera.osaka.jp\0" +"app.render.com\0" +"nz\0etisalat\0" +"cr.ua\0apartments\0" +"\xe5\x85\xac\xe7\x9b\x8a\0" +"om\0\xe6\x95\x99\xe8\x82\xb2.\xe9\xa6\x99\xe6\xb8\xaf\0" +"hosting\0" +"nu.ca\0pa\0" +"esashi.hokkaido.jp\0" +"tcm.museum\0cc.wi.us\0s3-ca-central-1.amazonaws.com\0" +"pe\0dyn.home-webserver.de\0" +"gouv.bj\0jeonnam.kr\0pf\0lima-city.at\0" +"liguria.it\0takamatsu.kagawa.jp\0ph\0ostroleka.pl\0" +"silk.museum\0tennis\0" +"name.az\0" +"pk\0" +"pl\0" +"pm\0s3.dualstack.us-east-2.amazonaws.com\0" +"semboku.akita.jp\0pn\0democrat\0istanbul\0mattel\0" +"*.transurl.be\0" +"\xe5\xb2\xa9\xe6\x89\x8b.jp\0pb.leg.br\0" +"qa\0" +"wakkanai.hokkaido.jp\0pr\0" +"ps\0" +"abeno.osaka.jp\0wuoz.gov.pl\0pt\0" +"gouv.ci\0" +"per.nf\0" +"pw\0works\0mydatto.com\0hobby-site.org\0" +"taiki.hokkaido.jp\0world\0" +"py\0" +"kariwa.niigata.jp\0lima-city.ch\0" +"id.au\0yk.ca\0" +"griw.gov.pl\0" +"austrheim.no\0marketing\0" +"hokuto.yamanashi.jp\0" +"re\0" +"emilia-romagna.it\0" +"x.se\0nh.us\0" +"musashino.tokyo.jp\0" +"rentals\0" +"cymru.museum\0" +"capetown\0hiv\0" +"\xd9\x85\xd9\x88\xd9\x82\xd8\xb9\0" +"nakaniikawa.toyama.jp\0" +"ro\0" +"sa\0" +"sb\0" +"iris.arpa\0rs\0sc\0" +"sd\0" +"ru\0se\0reise\0" +"carrara-massa.it\0kamagaya.chiba.jp\0rifu.miyagi.jp\0ookuwa.nagano.jp\0" +"americana.museum\0rw\0sg\0hockey\0" +"wegrow.pl\0sh\0" +"si\0" +"sj\0for-the.biz\0" +"otago.museum\0gs.ol.no\0sk\0" +"kashiwara.osaka.jp\0sl\0" +"sm\0" +"sn\0" +"so\0fed.us\0s3.eu-central-1.amazonaws.com\0" +"amsw.nl\0" +"sr\0" +"ss\0tc\0" +"st\0td\0" +"su\0ebiz.tw\0" +"arao.kumamoto.jp\0sv\0tf\0" +"tv.im\0tg\0" +"abashiri.hokkaido.jp\0sx\0th\0" +"skole.museum\0sy\0lib.la.us\0" +"sz\0tj\0hkt\0" +"surgeonshall.museum\0tk\0" +"tl\0""64-b.it\0" +"tm\0" +"siena.it\0tv.it\0fujikawa.yamanashi.jp\0tn\0" +"to\0*.transurl.eu\0" +"ens.tn\0" +"ua\0paris.eu.org\0" +"tr\0" +"audnedaln.no\0*.on-rio.io\0" +"tt\0" +"saitama.saitama.jp\0tv\0" +"tw\0ug\0" +"\xe7\xbb\x84\xe7\xbb\x87.hk\0synology-diskstation.de\0" +"tz\0" +"uk\0wang\0" +"labour.museum\0" +"caltanissetta.it\0" +"claims\0" +"va\0krasnodar.su\0" +"reggioemilia.it\0olsztyn.pl\0av.tr\0" +"hasvik.no\0us\0vc\0" +"seaport.museum\0plc.uk\0ve\0" +"morioka.iwate.jp\0locker\0*.bzz.dapps.earth\0" +"per.sg\0vg\0\xe5\xa4\xa7\xe6\x8b\xbf\0" +"uy\0vi\0lego\0u2-local.xnbay.com\0" +"laz.it\0uz\0" +"ce.gov.br\0lazio.it\0moriguchi.osaka.jp\0tarnobrzeg.pl\0" +"hanamigawa.chiba.jp\0pruszkow.pl\0vn\0" +"hyundai\0" +"stuff-4-sale.us\0" +"\xe6\x94\xbf\xe5\xba\x9c.hk\0planetarium.museum\0" +"nu.it\0" +"vu\0googlecode.com\0" +"tsushima.nagasaki.jp\0wf\0" +"b\xc3\xa5""d\xc3\xa5""ddj\xc3\xa5.no\0" +"schaeffler\0" +"skierva.no\0" +"gob.ar\0hikari.yamaguchi.jp\0" +"priv.hu\0" +"nakadomari.aomori.jp\0" +"kakuda.miyagi.jp\0" +"ws\0cooking\0from-ma.com\0" +"nanmoku.gunma.jp\0" +"broadcast.museum\0ulvik.no\0netlify.com\0" +"servegame.org\0myiphost.com\0" +"hot\0swiftcover\0" +"i.bg\0gob.bo\0tv.na\0" +"ecn.br\0sosnowiec.pl\0" +"how\0" +"us.org\0" +"tokamachi.niigata.jp\0" +"k12.wy.us\0" +"gob.cl\0id.ir\0" +"suwa.nagano.jp\0" +"ogawara.miyagi.jp\0" +"zhytomyr.ua\0" +"trentinosuedtirol.it\0" +"from-il.com\0" +"allfinanz\0" +"yt\0" +"gildesk\xc3\xa5l.no\0" +"walmart\0" +"hopto.me\0hopto.org\0" +"miyawaka.fukuoka.jp\0" +"gob.do\0" +"kurume.fukuoka.jp\0koya.wakayama.jp\0" +"zm\0withyoutube.com\0" +"honai.ehime.jp\0hokuto.hokkaido.jp\0" +"gob.ec\0" +"otsuchi.iwate.jp\0" +"ibm\0*.otap.co\0" +"arakawa.saitama.jp\0" +"television.museum\0christmas\0" +"sondre-land.no\0zw\0" +"\xe5\xb1\xb1\xe6\xa2\xa8.jp\0" +"aosta-valley.it\0\xd8\xb9\xd8\xb1\xd8\xa8\0" +"ice\0" +"cosenza.it\0" +"gob.es\0istmein.de\0" +"bs.it\0chikushino.fukuoka.jp\0yasu.shiga.jp\0" +"home.dyndns.org\0" +"red.sv\0" +"vic.edu.au\0sevastopol.ua\0" +"rimini.it\0\xe9\x95\xb7\xe5\xb4\x8e.jp\0" +"council.aero\0" +"incheon.kr\0" +"sue.fukuoka.jp\0" +"icu\0" +"id.lv\0" +"ushistory.museum\0odesa.ua\0" +"nasu.tochigi.jp\0name.vn\0priv.at\0" +"id.ly\0" +"firm.ht\0" +"barsy.club\0" +"izena.okinawa.jp\0tosu.saga.jp\0naklo.pl\0*.transurl.nl\0" +"oregontrail.museum\0" +"ujiie.tochigi.jp\0" +"linz.museum\0likescandy.com\0*.triton.zone\0" +"mi.it\0" +"delaware.museum\0politie\0" +"ind.br\0firm.in\0nowruz\0" +"tv.sd\0" +"airtraffic.aero\0aigo\0" +"gob.gt\0saarland\0" +"inagi.tokyo.jp\0" +"is-a-celticsfan.org\0" +"nagato.yamaguchi.jp\0oum.gov.pl\0" +"beats\0" +"bill.museum\0cn.com\0from-or.com\0" +"gob.hn\0name.tj\0" +"dovre.no\0" +"lib.nv.us\0guitars\0" +"kamikawa.hokkaido.jp\0pi.leg.br\0" +"chiyoda.tokyo.jp\0name.tr\0" +"samnanger.no\0ifm\0" +"name.tt\0" +"zapto.org\0" +"fedorainfracloud.org\0" +"kiryu.gunma.jp\0ochi.kochi.jp\0" +"\xe3\x82\xaf\xe3\x83\xa9\xe3\x82\xa6\xe3\x83\x89\0" +"pb.ao\0" +"tv.tr\0" +"firm.co\0cc.na\0u2.xnbay.com\0" +"ogaki.gifu.jp\0nishiawakura.okayama.jp\0" +"or.at\0verisign\0" +"redstone\0" +"tv.tz\0" +"or.bi\0potager.org\0" +"iron.museum\0" +"bergamo.it\0nishihara.okinawa.jp\0" +"guernsey.museum\0firm.dk\0freeboxos.com\0" +"kiyosato.hokkaido.jp\0fujisawa.kanagawa.jp\0" +"wzmiuw.gov.pl\0" +"california.museum\0from-al.com\0" +"kagoshima.jp\0" +"cc.wv.us\0" +"forum.hu\0settlement.museum\0dontexist.com\0" +"sex.hu\0georgia.museum\0" +"kamakura.kanagawa.jp\0rmit\0" +"or.ci\0fylkesbibl.no\0from-sc.com\0" +"saotome.st\0" +"annefrank.museum\0" +"gouv.sn\0" +"hirokawa.fukuoka.jp\0" +"aejrie.no\0" +"or.cr\0" +"\xd2\x9b\xd0\xb0\xd0\xb7\0" +"agematsu.nagano.jp\0" +"emerck\0" +"ag.it\0\xe5\xae\xae\xe5\xb4\x8e.jp\0upow.gov.pl\0" +"ee.eu.org\0" +"belluno.it\0isa.kagoshima.jp\0" +"vuelos\0" +"toyonaka.osaka.jp\0higashichichibu.saitama.jp\0" +"riobranco.br\0okawa.kochi.jp\0" +"ind.gt\0" +"lib.sc.us\0bukhara.su\0" +"karatsu.saga.jp\0" +"name.qa\0" +"name.pr\0" +"culturalcenter.museum\0" +"familyds.net\0" +"joso.ibaraki.jp\0" +"oirm.gov.pl\0" +"uslivinghistory.museum\0jondal.no\0" +"imamat\0" +"name.na\0lifestyle\0dyn.ddnss.de\0tashkent.su\0" +"toyotomi.hokkaido.jp\0" +"gob.mx\0" +"gob.ni\0b\xc3\xa5tsfjord.no\0school.za\0dyndns-mail.com\0dyndns-remote.com\0" +"kawaguchi.saitama.jp\0name.mv\0" +"name.ng\0cuisinella\0" +"ind.in\0ogliastra.it\0" +"name.my\0mymailer.com.tw\0" +"nagasaki.nagasaki.jp\0kumagaya.saitama.jp\0kudamatsu.yamaguchi.jp\0" +"i.ng\0" +"yasuoka.nagano.jp\0" +"eu-west-1.elasticbeanstalk.com\0" +"shiga.jp\0ouchi.saga.jp\0" +"railway.museum\0" +"gamvik.no\0viajes\0" +"automotive.museum\0" +"1.bg\0" +"id.us\0" +"valle-aosta.it\0vc.it\0hu.net\0" +"gob.pa\0" +"courses\0" +"gob.pe\0" +"boomla.net\0" +"dyndns-wiki.com\0" +"soccer\0" +"health.museum\0" +"gob.pk\0" +"cricket\0" +"inc\0" +"takahama.aichi.jp\0i.ph\0" +"childrens.museum\0coupons\0ing\0cc.ua\0" +"tonaki.okinawa.jp\0" +"k12.ct.us\0" +"or.id\0town\0pe.leg.br\0" +"ind.kw\0ink\0" +"nf.ca\0virtual-user.de\0" +"localhost.daplie.me\0" +"inazawa.aichi.jp\0" +"geology.museum\0" +"int\0fukui.jp\0dnsdojo.net\0" +"name.mk\0sn\xc3\xa5sa.no\0cloud66.zone\0" +"campidanomedio.it\0" +"s3.dualstack.sa-east-1.amazonaws.com\0" +"mi.th\0" +"american.museum\0taipei\0" +"or.it\0kumano.hiroshima.jp\0chigasaki.kanagawa.jp\0" +"sydney\0" +"furubira.hokkaido.jp\0urawa.saitama.jp\0" +"ako.hyogo.jp\0" +"hair\0" +"kanna.gunma.jp\0sex.pl\0" +"or.jp\0" +"itau\0" +"dabur\0" +"name.jo\0bod\xc3\xb8.no\0" +"or.ke\0kvinesdal.no\0" +"otaki.chiba.jp\0" +"is-gone.com\0" +"transporte.bo\0toys\0" +"v.bg\0england.museum\0us.na\0nes.buskerud.no\0" +"ohtawara.tochigi.jp\0" +"gouv.km\0epilepsy.museum\0i.se\0mi.us\0" +"servebbs.org\0" +"ushuaia.museum\0mer\xc3\xa5ker.no\0rovno.ua\0" +"or.kr\0" +"indiana.museum\0" +"gob.sv\0" +"firm.ve\0" +"he.cn\0taki.mie.jp\0now.sh\0" +"ono.fukushima.jp\0" +"vestv\xc3\xa5g\xc3\xb8y.no\0nico\0" +"go.gov.br\0mombetsu.hokkaido.jp\0" +"repair\0sandvikcoromant\0" +"komatsushima.tokushima.jp\0" +"s3.dualstack.ap-south-1.amazonaws.com\0spdns.org\0" +"nakatane.kagoshima.jp\0gouv.ml\0jcb\0" +"select\0" +"barum.no\0" +"or.na\0" +"bushey.museum\0is-a-llama.com\0" +"or.mu\0honefoss.no\0gob.ve\0pictures\0cyon.link\0" +"sasebo.nagasaki.jp\0" +"tosa.kochi.jp\0asahi.nagano.jp\0" +"aircraft.aero\0" +"jcp\0" +"ist\0" +"sorum.no\0ooguy.com\0" +"nagano.jp\0" +"sciencecenter.museum\0" +"mar.it\0" +"nombre.bo\0no-ip.info\0" +"gs.hl.no\0s3-eu-west-2.amazonaws.com\0" +"satsumasendai.kagoshima.jp\0" +"genoa.it\0yawata.kyoto.jp\0kiwi.nz\0azure-mobile.net\0" +"e4.cz\0" +"press.museum\0nissedal.no\0cc.tn.us\0" +"itv\0" +"ishinomaki.miyagi.jp\0" +"chonan.chiba.jp\0coach\0" +"aukra.no\0college\0vladimir.su\0" +"gonohe.aomori.jp\0" +"ro.eu.org\0" +"hidaka.hokkaido.jp\0bando.ibaraki.jp\0" +"freight.aero\0" +"firm.ro\0km.ua\0" +"vacations\0" +"cards\0contractors\0" +"daito.osaka.jp\0" +"or.pw\0" +"priv.pl\0" +"tsumagoi.gunma.jp\0higashiyama.kyoto.jp\0ind.tn\0*.compute.amazonaws.com.cn\0rackmaze.net\0" +"review\0" +"historisch.museum\0naturalhistorymuseum.museum\0dep.no\0" +"dyndns.info\0" +"matsubara.osaka.jp\0" +"shirataka.yamagata.jp\0" +"cc.nm.us\0" +"radom.pl\0" +"piedmont.it\0" +"rhcloud.com\0" +"songdalen.no\0" +"salem.museum\0k\xc3\xa1r\xc3\xa1\xc5\xa1johka.no\0k12.vt.us\0" +"fi.cr\0pr.leg.br\0" +"pubtls.org\0" +"estate\0vladimir.ru\0" +"play\0" +"priv.no\0s3-website-us-east-1.amazonaws.com\0" +"pordenone.it\0kurate.fukuoka.jp\0kunisaki.oita.jp\0" +"\xc3\xa5l.no\0" +"miyagi.jp\0lgbt\0" +"lyngen.no\0americanexpress\0" +"nike\0" +"kitahata.saga.jp\0firm.nf\0or.th\0" +"jio\0firm.ng\0" +"student.aero\0media.hu\0meeres.museum\0rsc.cdn77.org\0" +"padua.it\0" +"si.eu.org\0" +"muko.kyoto.jp\0izumozaki.niigata.jp\0" +"s3.dualstack.eu-west-2.amazonaws.com\0is-a-soxfan.org\0" +"tomigusuku.okinawa.jp\0" +"nakamura.kochi.jp\0" +"riodejaneiro.museum\0" +"at.it\0" +"theater.museum\0or.ug\0" +"campania.it\0fukuchiyama.kyoto.jp\0club\0" +"medicina.bo\0wales.museum\0" +"iwanai.hokkaido.jp\0minamidaito.okinawa.jp\0or.tz\0" +"dynalias.net\0" +"naturalsciences.museum\0" +"toga.toyama.jp\0" +"k12.al.us\0" +"tec.ve\0services\0\xe3\x82\xb0\xe3\x83\xbc\xe3\x82\xb0\xe3\x83\xab\0" +"priv.me\0or.us\0forgot.her.name\0" +"mitaka.tokyo.jp\0" +"genkai.saga.jp\0" +"kalmykia.su\0" +"aland.fi\0deloitte\0cn.eu.org\0" +"haus\0" +"louvre.museum\0pvt.k12.ma.us\0" +"konskowola.pl\0" +"education.tas.edu.au\0" +"ranzan.saitama.jp\0jll\0" +"kraanghke.no\0" +"nowaruda.pl\0" +"telebit.app\0" +"otobe.hokkaido.jp\0" +"catholic\0flynnhub.com\0" +"katsuura.chiba.jp\0higashiizumo.shimane.jp\0" +"insure\0" +"trainer.aero\0flekkefjord.no\0yahoo\0" +"jmp\0" +"sa.edu.au\0cc.ma.us\0" +"cymru\0sk.eu.org\0" +"erimo.hokkaido.jp\0" +"agrar.hu\0dnsalias.com\0" +"cloudns.asia\0" +"jnj\0" +"fi.it\0" +"kalmykia.ru\0" +"kuwana.mie.jp\0" +"workisboring.com\0" +"trentinostirol.it\0" +"ns.ca\0tolga.no\0" +"storfjord.no\0" +"vibo-valentia.it\0niihama.ehime.jp\0" +"architecture.museum\0recht.pro\0" +"parliament.nz\0" +"washingtondc.museum\0" +"square7.de\0" +"uw.gov.pl\0warszawa.pl\0" +"ragusa.it\0lukow.pl\0jot\0" +"po.it\0daejeon.kr\0" +"sykkylven.no\0" +"joy\0" +"lajolla.museum\0" +"anamizu.ishikawa.jp\0namerikawa.toyama.jp\0" +"neat-url.com\0" +"abo.pa\0" +"pro.az\0" +"mckinsey\0" +"komvux.se\0" +"media.pl\0" +"lur\xc3\xb8y.no\0" +"pro.br\0minoh.osaka.jp\0mizuho.tokyo.jp\0noho.st\0" +"ooshika.nagano.jp\0" +"trentinoa-adige.it\0\xe1\x83\x92\xe1\x83\x94\0" +"florist\0" +"gjerstad.no\0hammerfest.no\0abogado\0cy.eu.org\0" +"ru.eu.org\0se.eu.org\0" +"santamaria.br\0yoshikawa.saitama.jp\0" +"omaha.museum\0" +"stavanger.no\0" +"akdn\0observer\0" +"bykle.no\0" +"tahara.aichi.jp\0vapor.cloud\0" +"press\0ae.org\0" +"dscloud.biz\0" +"seranishi.hiroshima.jp\0shimoji.okinawa.jp\0" +"pro.cy\0" +"square7.ch\0" +"aremark.no\0karaganda.su\0barsy.co.uk\0" +"tome.miyagi.jp\0" +"amusement.aero\0pro.ec\0v.ua\0" +"bd.se\0" +"tt.im\0" +"gs.jan-mayen.no\0lib.ks.us\0cz.eu.org\0" +"hidaka.kochi.jp\0jeep\0" +"gu.us\0appspot.com\0" +"sh.cn\0ud.it\0" +"shimane.jp\0" +"higashiyoshino.nara.jp\0" +"entertainment.aero\0" +"lupin\0" +"pro.fj\0" +"ddnslive.com\0" +"edu.krd\0" +"off.ai\0" +"dk.eu.org\0pokrovsk.su\0" +"gaular.no\0netbank\0" +"sowa.ibaraki.jp\0" +"\xe5\x95\x86\xe5\xba\x97\0iki.fi\0" +"kfh\0" +"carraramassa.it\0" +"assabu.hokkaido.jp\0" +"*.compute.amazonaws.com\0" +"daegu.kr\0cloudapp.net\0" +"weibo\0" +"k12.ma.us\0" +"georgia.su\0" +"etc.br\0" +"os.hedmark.no\0" +"pro.ht\0" +"b\xc3\xa1jddar.no\0\xe5\x80\x8b\xe4\xba\xba.\xe9\xa6\x99\xe6\xb8\xaf\0" +"*.s5y.io\0" +"fuettertdasnetz.de\0dscloud.me\0" +"slg.br\0" +"g.bg\0" +"towada.aomori.jp\0" +"nogata.fukuoka.jp\0sklep.pl\0" +"jewelry.museum\0*.compute.estate\0" +"faith\0" +"graphics\0" +"gniezno.pl\0homedepot\0" +"n\xc3\xa6r\xc3\xb8y.no\0kia\0" +"portland.museum\0troandin.no\0kurgan.su\0" +"garden.museum\0gjemnes.no\0grong.no\0""4lima.de\0" +"nishitosa.kochi.jp\0" +"moonscale.net\0" +"eidskog.no\0" +"trani-andria-barletta.it\0voorloper.cloud\0" +"pvt.ge\0bonn.museum\0kim\0" +"webhop.biz\0" +"forsand.no\0" +"browsersafetymark.io\0de.eu.org\0" +"\xd9\xbe\xd8\xa7\xd9\x83\xd8\xb3\xd8\xaa\xd8\xa7\xd9\x86\0" +"takahama.fukui.jp\0malopolska.pl\0" +"hachijo.tokyo.jp\0" +"charity\0" +"sannan.hyogo.jp\0elblag.pl\0" +"force.museum\0audio\0" +"\xe7\xae\x87\xe4\xba\xba.hk\0" +"matsumae.hokkaido.jp\0" +"shimonoseki.yamaguchi.jp\0" +"windows\0" +"author\0" +"itano.tokushima.jp\0gangwon.kr\0""4lima.at\0" +"is-a-conservative.com\0" +"ca.it\0" +"lincoln.museum\0" +"ninomiya.kanagawa.jp\0" +"ciscofreak.com\0" +"kuroiso.tochigi.jp\0lowicz.pl\0" +"minamiise.mie.jp\0" +"insurance.aero\0mus.mi.us\0" +"dnsup.net\0" +"kunstsammlung.museum\0rennes\xc3\xb8y.no\0" +"gru.br\0" +"ishikawa.jp\0\xe6\xb2\x96\xe7\xb8\x84.jp\0mitou.yamaguchi.jp\0" +"online.museum\0pro.na\0" +"tsukiyono.gunma.jp\0fujishiro.ibaraki.jp\0""4lima.ch\0" +"science-fiction.museum\0plus\0" +"ass.km\0" +"pro.mv\0*.ex.futurecms.at\0" +"katashina.gunma.jp\0" +"otsuka\0" +"cloudcontrolled.com\0" +"inzai.chiba.jp\0" +"koge.tottori.jp\0" +"serveminecraft.net\0" +"is-a-therapist.com\0" +"konsulat.gov.pl\0" +"pharmaciens.km\0" +"hokkaido.jp\0" +"even\xc3\xa1\xc5\xa1\xc5\xa1i.no\0pro.om\0" +"anquan\0" +"lib.oh.us\0room\0sells-for-u.com\0" +"caxias.br\0seiyo.ehime.jp\0toyotsu.fukuoka.jp\0" +"xihuan\0" +"\xe6\x95\x8e\xe8\x82\xb2.hk\0tranby.no\0pramerica\0" +"industria.bo\0andasuolo.no\0cc.mn.us\0" +"fbx-os.fr\0" +"onna.okinawa.jp\0kosai.shizuoka.jp\0" +"familyds.org\0" +"arts.museum\0eastafrica.museum\0\xe9\x9b\xbb\xe8\xa8\x8a\xe7\x9b\x88\xe7\xa7\x91\0" +"chesapeakebay.museum\0ca.na\0nittedal.no\0" +"embaixada.st\0cloud\0garden\0" +"microsoft\0" +"lucerne.museum\0" +"omura.nagasaki.jp\0chuo.yamanashi.jp\0pro.pr\0" +"chiyoda.gunma.jp\0" +"aseral.no\0" +"noshiro.akita.jp\0kakinoki.shimane.jp\0" +"olecko.pl\0" +"ddnss.de\0" +"bari.it\0" +"spydeberg.no\0" +"arezzo.it\0kpn\0" +"aarborte.no\0" +"emr.it\0" +"tychy.pl\0" +"jeju.kr\0" +"santafe.museum\0valle.no\0" +"forl\xc3\xac""cesena.it\0oyodo.nara.jp\0" +"fukushima.hokkaido.jp\0shimizu.hokkaido.jp\0" +"undersea.museum\0" +"saku.nagano.jp\0blogspot.vn\0" +"bus.museum\0" +"s\xc3\xb8ndre-land.no\0" +"tateyama.chiba.jp\0\xd1\x81\xd0\xb0\xd0\xb9\xd1\x82\0memset.net\0" +"ca.eu.org\0" +"shimonita.gunma.jp\0" +"net.eu.org\0" +"krd\0lat\0" +"myactivedirectory.com\0" +"law\0" +"hitachinaka.ibaraki.jp\0atami.shizuoka.jp\0" +"delmenhorst.museum\0" +"urayasu.chiba.jp\0kakegawa.shizuoka.jp\0" +"from-co.net\0" +"tsuwano.shimane.jp\0" +"itako.ibaraki.jp\0" +"\xe5\xbe\xb3\xe5\xb3\xb6.jp\0" +"alfaromeo\0" +"trentinoaltoadige.it\0sakawa.kochi.jp\0" +"starnberg.museum\0" +"yamaguchi.jp\0" +"r\xc3\xa5""de.no\0cc.al.us\0b-data.io\0myddns.rocks\0serveirc.com\0" +"is-very-good.org\0" +"pro.tt\0" +"com.ac\0" +"rotorcraft.aero\0" +"com.af\0shingu.hyogo.jp\0" +"com.ag\0" +"um.gov.pl\0" +"com.ai\0texas.museum\0" +"vibovalentia.it\0isesaki.gunma.jp\0" +"staging.onred.one\0homesecuritypc.com\0" +"com.al\0vall\xc3\xa9""eaoste.it\0" +"com.am\0" +"tagawa.fukuoka.jp\0anan.nagano.jp\0" +"com.ba\0bremanger.no\0" +"com.ar\0com.bb\0urbino-pesaro.it\0" +"lib.md.us\0" +"com.au\0rennesoy.no\0" +"torino.it\0" +"com.aw\0" +"com.bh\0va.it\0" +"com.bi\0savannahga.museum\0fage\0lds\0blogspot.re\0" +"com.az\0kashihara.nara.jp\0" +"pro.vn\0" +"com.bm\0" +"com.bn\0" +"com.bo\0" +"aomori.jp\0" +"hoylandet.no\0" +"com.br\0" +"com.bs\0sandoy.no\0s3-ap-northeast-2.amazonaws.com\0blogspot.ro\0" +"com.bt\0dazaifu.fukuoka.jp\0" +"revista.bo\0" +"kinokawa.wakayama.jp\0" +"blogspot.rs\0" +"sagamihara.kanagawa.jp\0" +"com.by\0com.ci\0athleta\0from-mo.com\0blogspot.ru\0blogspot.se\0" +"com.bz\0ichinomiya.chiba.jp\0settsu.osaka.jp\0" +"blogspot.sg\0" +"com.cm\0blogspot.si\0" +"com.cn\0" +"com.co\0blogspot.sk\0" +"creditunion\0olayangroup\0" +"blogspot.sn\0" +"com.cu\0com.de\0" +"hakodate.hokkaido.jp\0nishimera.miyazaki.jp\0" +"com.cw\0" +"blogspot.td\0" +"com.cy\0afjord.no\0tromso.no\0" +"hirono.fukushima.jp\0ebina.kanagawa.jp\0cnpy.gdn\0" +"macapa.br\0" +"com.dm\0ca.us\0" +"com.do\0" +"fail\0" +"com.ec\0jamison.museum\0" +"com.ee\0" +"juniper\0" +"com.eg\0comsec\0cd.eu.org\0cust.prod.thingdust.io\0" +"tsuno.kochi.jp\0ohira.miyagi.jp\0us.gov.pl\0" +"com.dz\0friulive-giulia.it\0" +"blogspot.tw\0blogspot.ug\0" +"alesund.no\0" +"yokosuka.kanagawa.jp\0" +"from-wi.com\0" +"medio-campidano.it\0" +"com.es\0" +"com.et\0furano.hokkaido.jp\0jeonbuk.kr\0" +"t.bg\0" +"weir\0blogspot.mr\0" +"g.se\0" +"xj.cn\0" +"com.fj\0oiso.kanagawa.jp\0" +"inuyama.aichi.jp\0blogspot.mx\0" +"l\xc3\xa4ns.museum\0blogspot.my\0" +"yamagata.nagano.jp\0" +"cruises\0" +"blogspot.nl\0" +"e12.ve\0" +"com.fr\0iijima.nagano.jp\0" +"va.no\0abbvie\0homelinux.com\0blogspot.no\0" +"gs.cn\0" +"com.ge\0home-webserver.de\0" +"uppo.gov.pl\0" +"sogne.no\0" +"com.gh\0" +"com.gi\0bestbuy\0" +"amami.kagoshima.jp\0" +"discovery.museum\0" +"com.gl\0" +"k12.gu.us\0" +"com.gn\0" +"com.gp\0ms.leg.br\0" +"conference.aero\0" +"com.gr\0" +"com.gt\0" +"com.gu\0" +"lidl\0" +"magazine.aero\0davvenj\xc3\xa1rga.no\0" +"daisen.akita.jp\0" +"com.gy\0ally\0blogspot.pe\0" +"art.br\0uryu.hokkaido.jp\0kikugawa.shizuoka.jp\0nanyo.yamagata.jp\0solar\0" +"com.hk\0" +"tozawa.yamagata.jp\0firewall-gateway.net\0" +"dnsfor.me\0" +"com.hn\0massa-carrara.it\0te.it\0" +"user.srcf.net\0" +"com.hr\0" +"com.ht\0" +"blogspot.qa\0" +"plants.museum\0" +"tohnosho.chiba.jp\0blogspot.pt\0" +"hdfc\0llc\0" +"cn.it\0career\0" +"com.im\0asnes.no\0" +"narashino.chiba.jp\0" +"com.io\0life\0" +"togo.aichi.jp\0numazu.shizuoka.jp\0mt.leg.br\0" +"com.iq\0eastcoast.museum\0sebastopol.ua\0cloud66.ws\0" +"matsuura.nagasaki.jp\0" +"parliament.cy\0com.is\0apple\0" +"minato.osaka.jp\0" +"echizen.fukui.jp\0shichikashuku.miyagi.jp\0llp\0" +"art.do\0fans\0is-a-bulls-fan.com\0blogspot.is\0" +"blogspot.it\0" +"zama.kanagawa.jp\0" +"acct.pro\0smile\0" +"stada\0" +"com.jo\0ryukyu\0" +"ureshino.mie.jp\0" +"wa.gov.au\0" +"art.dz\0mihara.kochi.jp\0" +"barcelona.museum\0" +"mt.it\0northwesternmutual\0blogspot.jp\0za.net\0" +"cc.de.us\0" +"sanjo.niigata.jp\0" +"com.kg\0atlanta.museum\0" +"kamigori.hyogo.jp\0" +"com.ki\0" +"fie.ee\0com.km\0blogsyte.com\0" +"kosuge.yamanashi.jp\0com.kp\0" +"com.la\0s3-ap-south-1.amazonaws.com\0" +"com.lb\0" +"com.lc\0" +"bjark\xc3\xb8y.no\0" +"blogspot.kr\0" +"com.kw\0australia.museum\0skanland.no\0apps.fbsbx.com\0" +"com.ky\0v\xc3\xa1rgg\xc3\xa1t.no\0" +"com.kz\0" +"com.lk\0malvik.no\0dynalias.org\0" +"blogspot.li\0" +"in-vpn.org\0" +"osakikamijima.hiroshima.jp\0iiyama.nagano.jp\0com.lr\0lol\0" +"com.lv\0ic.gov.pl\0" +"com.mg\0" +"blogspot.lt\0blogspot.md\0" +"\xe7\xb6\xb2\xe7\xbb\x9c.hk\0com.ly\0blogspot.lu\0*.sys.qcx.io\0" +"com.mk\0" +"aizumisato.fukushima.jp\0com.ml\0" +"tomika.gifu.jp\0" +"com.mo\0blogspot.mk\0" +"fujieda.shizuoka.jp\0" +"com.na\0farm\0" +"kouzushima.tokyo.jp\0\xd9\xbe\xd8\xa7\xda\xa9\xd8\xb3\xd8\xaa\xd8\xa7\xd9\x86\0lpl\0" +"com.ms\0" +"com.mt\0" +"com.mu\0" +"ono.hyogo.jp\0com.mv\0com.nf\0" +"com.mw\0com.ng\0va.us\0" +"com.mx\0" +"com.my\0com.ni\0" +"art.ht\0kamo.kyoto.jp\0kitayama.wakayama.jp\0" +"l-o-g-i-n.de\0blogspot.fi\0" +"izumiotsu.osaka.jp\0funagata.yamagata.jp\0" +"like\0beta.bounty-full.com\0" +"drive\0" +"rikuzentakata.iwate.jp\0com.nr\0" +"blog.bo\0webhosting.be\0" +"ri.it\0man\0" +"blog.br\0namie.fukushima.jp\0map\0blogspot.fr\0" +"forde.no\0mba\0" +"fast\0" +"nanae.hokkaido.jp\0tsurugi.ishikawa.jp\0dental\0" +"association.museum\0inderoy.no\0lenvik.no\0" +"com.om\0dyn-berlin.de\0" +"ac.leg.br\0" +"co.network\0" +"ar.it\0" +"com.pa\0washtenaw.mi.us\0" +"allstate\0gifts\0" +"com.pe\0" +"brescia.it\0com.pf\0blogspot.gr\0" +"com.ph\0" +"children.museum\0aramco\0" +"tondabayashi.osaka.jp\0" +"gj\xc3\xb8vik.no\0com.pk\0mypi.co\0" +"aogaki.hyogo.jp\0com.pl\0" +"ballooning.aero\0works.aero\0is-a-cpa.com\0" +"!city.kobe.jp\0" +"lind\xc3\xa5s.no\0blogspot.hk\0" +"halsa.no\0com.qa\0photography\0abkhazia.su\0" +"com.pr\0" +"gs.oslo.no\0br\xc3\xb8nn\xc3\xb8y.no\0com.ps\0myshopblocks.com\0" +"com.pt\0" +"columbia.museum\0" +"blogspot.hr\0" +"tuxfamily.org\0" +"kasukabe.saitama.jp\0amex\0" +"com.py\0limo\0blogspot.hu\0blogspot.ie\0" +"jl.cn\0ltd\0" +"dattolocal.com\0" +"kunohe.iwate.jp\0" +"hikone.shiga.jp\0urown.cloud\0" +"vald-aosta.it\0" +"blogspot.in\0" +"devices.resinstaging.io\0" +"tenkawa.nara.jp\0" +"com.re\0link\0safe\0blogspot.ba\0" +"trentin-sud-tirol.it\0hinode.tokyo.jp\0" +"sokndal.no\0from-ak.com\0couchpotatofries.org\0" +"asahi.toyama.jp\0" +"blogspot.be\0" +"moka.tochigi.jp\0med\0" +"associates\0blogspot.bg\0" +"hamburg.museum\0" +"fukuoka.jp\0kawazu.shizuoka.jp\0cool\0blogspot.bj\0" +"com.ro\0dyndns1.de\0" +"skierv\xc3\xa1.no\0com.sa\0" +"coop\0com.sb\0" +"gran.no\0com.sc\0" +"com.sd\0men\0thruhere.net\0" +"aetna\0com.se\0com.ru\0blogspot.ca\0" +"com.sg\0clinique\0" +"com.sh\0" +"lancashire.museum\0" +"tagajo.miyagi.jp\0sakaki.nagano.jp\0blogspot.cf\0" +"air-traffic-control.aero\0te.ua\0" +"adv.br\0com.sl\0blogspot.ch\0" +"k12.tn.us\0trading\0" +"udi.br\0com.sn\0" +"com.so\0" +"fg.it\0setagaya.tokyo.jp\0blogspot.cl\0" +"hemsedal.no\0servebbs.com\0" +"kommunalforbund.se\0com.ss\0" +"ayagawa.kagawa.jp\0com.st\0" +"nodebalancer.linode.com\0" +"com.sv\0for.men\0" +"cn.ua\0" +"akita.jp\0kasuga.fukuoka.jp\0" +"com.sy\0is-a-landscaper.com\0blogspot.de\0" +"com.tj\0blogspot.cv\0" +"mydatto.net\0" +"muenchen.museum\0com.tm\0" +"com.tn\0blogspot.cz\0" +"com.to\0blogspot.dk\0" +"eidfjord.no\0com.ua\0" +"com.tr\0" +"mino.gifu.jp\0ibara.okayama.jp\0izu.shizuoka.jp\0com.tt\0" +"newjersey.museum\0tuva.su\0" +"\xd8\xa7\xd8\xb1\xd8\xa7\xd9\x85\xd9\x83\xd9\x88\0" +"mjondalen.no\0laakesvuemie.no\0com.tw\0com.ug\0" +"ogawa.nagano.jp\0travelchannel\0" +"h\xc3\xb8nefoss.no\0" +"dyndns-home.com\0" +"codes\0" +"palmsprings.museum\0oppdal.no\0" +"design\0" +"monzabrianza.it\0" +"rost.no\0com.vc\0\xe6\x94\xbf\xe5\x8a\xa1\0" +"art.pl\0" +"com.ve\0from-nj.com\0" +"omigawa.chiba.jp\0" +"hokksund.no\0" +"sorocaba.br\0" +"timekeeping.museum\0com.uy\0com.vi\0" +"com.uz\0" +"place\0" +"hiratsuka.kanagawa.jp\0com.vn\0" +"*.webhare.dev\0" +"galsa.no\0" +"mil\0" +"zoological.museum\0sund.no\0t.se\0mt.us\0nd.us\0" +"ora.gunma.jp\0" +"com.vu\0" +"ogano.saitama.jp\0piw.gov.pl\0" +"bulsan-sudtirol.it\0koga.ibaraki.jp\0" +"histoire.museum\0vikna.no\0githubusercontent.com\0" +"mit\0" +"nrw.museum\0" +"es.gov.br\0" +"gyokuto.kumamoto.jp\0" +"kitamoto.saitama.jp\0" +"bolt.hu\0western.museum\0" +"com.ws\0" +"skoczow.pl\0" +"sale\0" +"tochigi.jp\0" +"davvenjarga.no\0" +"k12.id.us\0" +"from-ct.com\0codespot.com\0official.academy\0" +"niigata.jp\0sakura.chiba.jp\0" +"tsubame.niigata.jp\0" +"stcgroup\0" +"art.sn\0" +"\xe5\x98\x89\xe9\x87\x8c\xe5\xa4\xa7\xe9\x85\x92\xe5\xba\x97\0glitch.me\0" +"miyoshi.aichi.jp\0mlb\0" +"\xc3\xb8stre-toten.no\0q-a.eu.org\0blogspot.ae\0" +"tr.it\0" +"ichikawa.chiba.jp\0" +"erni\0" +"live\0" +"blogspot.al\0" +"blogspot.am\0" +"hinohara.tokyo.jp\0" +"\xe6\x9b\xb8\xe7\xb1\x8d\0" +"misato.saitama.jp\0bosch\0" +"helsinki.museum\0bnpparibas\0" +"malselv.no\0mma\0yolasite.com\0" +"mls\0" +"londrina.br\0" +"guge\0" +"com.zm\0ap-northeast-2.elasticbeanstalk.com\0" +"folldal.no\0" +"ri.us\0\xe9\xa3\x9f\xe5\x93\x81\0" +"bahccavuotna.no\0" +"abruzzo.it\0kumatori.osaka.jp\0grajewo.pl\0" +"goip.de\0" +"buyshouses.net\0" +"\xe4\xb8\x89\xe9\x87\x8d.jp\0" +"airguard.museum\0varoy.no\0" +"yoita.niigata.jp\0" +"ar.us\0" +"*.cryptonomic.net\0" +"aquarium.museum\0" +"saito.miyazaki.jp\0" +"meinforum.net\0" +"stream\0s3-website-us-west-2.amazonaws.com\0" +"pohl\0" +"hurum.no\0moe\0" +"takaishi.osaka.jp\0" +"arboretum.museum\0" +"kozagawa.wakayama.jp\0" +"hawaii.museum\0moi\0" +"mup.gov.pl\0" +"mayfirst.info\0" +"mom\0" +"hitachi.ibaraki.jp\0" +"sandvik\0" +"e.bg\0ostre-toten.no\0ch.eu.org\0ybo.science\0" +"homelinux.net\0" +"cc.oh.us\0" +"mov\0for-more.biz\0" +"catanzaro.it\0cieszyn.pl\0" +"mytis.ru\0" +"vn.ua\0" +"guardian\0" +"ac.ae\0" +"tr.no\0" +"gd.cn\0" +"knightpoint.systems\0" +"nab\0" +"lunner.no\0" +"urasoe.okinawa.jp\0isla.pr\0" +"kayabe.hokkaido.jp\0sarl\0" +"tarui.gifu.jp\0" +"ac.at\0emp.br\0" +"ac.be\0" +"adv.mz\0" +"nba\0" +"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xdb\x8c\xd8\xa9\0productions\0" +"eu-4.evennode.com\0synology-ds.de\0" +"imabari.ehime.jp\0iwi.nz\0" +"cherkassy.ua\0" +"kashiwa.chiba.jp\0" +"idv.hk\0mango\0" +"bounty-full.com\0" +"\xe7\xa6\x8f\xe5\xb3\xb6.jp\0" +"s\xc3\xb8r-odal.no\0" +"\xe9\x95\xb7\xe9\x87\x8e.jp\0kuchinotsu.nagasaki.jp\0help\0" +"ac.ci\0condos\0extraspace\0" +"avianca\0" +"trentinos-tirol.it\0msd\0" +"motorcycle.museum\0" +"ac.cn\0bo.it\0shirakawa.fukushima.jp\0" +"bradesco\0" +"makurazaki.kagoshima.jp\0" +"moareke.no\0mypep.link\0" +"ac.cr\0" +"shishikui.tokushima.jp\0\xe0\xae\x87\xe0\xae\xa8\xe0\xaf\x8d\xe0\xae\xa4\xe0\xae\xbf\xe0\xae\xaf\xe0\xae\xbe\0" +"mihama.aichi.jp\0prof.pr\0" +"ac.cy\0vantaa.museum\0stufftoread.com\0" +"air-surveillance.aero\0elverum.no\0" +"misaki.okayama.jp\0" +"nakanojo.gunma.jp\0al.leg.br\0" +"patria.bo\0" +"sakai.fukui.jp\0" +"mtn\0" +"save\0" +"lu.it\0me.it\0tendo.yamagata.jp\0" +"chiropractic.museum\0" +"mtr\0" +"nec\0" +"andriatranibarletta.it\0\xd8\xa8\xda\xbe\xd8\xa7\xd8\xb1\xd8\xaa\0" +"linkyard.cloud\0" +"qbuser.com\0" +"yachiyo.ibaraki.jp\0" +"me.ke\0" +"ac.fj\0ogawa.saitama.jp\0" +"uk0.bigv.io\0" +"net\0univ.sn\0co.financial\0" +"oldnavy\0eu-3.evennode.com\0" +"new\0" +"tatsuno.hyogo.jp\0" +"rahkkeravju.no\0is-a-socialist.com\0" +"nfl\0" +"kiho.mie.jp\0showa.yamanashi.jp\0" +"vodka\0geekgalaxy.com\0" +"k12.vi.us\0" +"sf.no\0n\xc3\xa1vuotna.no\0" +"ac.gn\0fudai.iwate.jp\0" +"saxo\0servep2p.com\0" +"hasama.oita.jp\0nishikata.tochigi.jp\0" +"naturhistorisches.museum\0" +"futuremailing.at\0" +"k12.fl.us\0ngo\0" +"tatebayashi.gunma.jp\0" +"at.eu.org\0" +"on.ca\0assisi.museum\0" +"kokubunji.tokyo.jp\0" +"here\0" +"cookingchannel\0website.yandexcloud.net\0" +"hatogaya.saitama.jp\0" +"berg.no\0nhk\0" +"ac.id\0" +"noheji.aomori.jp\0" +"bearalv\xc3\xa1hki.no\0for.mom\0" +"pz.it\0" +"tube\0" +"misato.akita.jp\0global.ssl.fastly.net\0" +"karate.museum\0uklugs.org\0" +"ac.il\0mol.it\0" +"ac.im\0pittsburgh.museum\0guru\0" +"ac.in\0porn\0" +"gs.vf.no\0" +"k12.or.us\0" +"ac.ir\0" +"bir.ru\0" +"za.org\0" +"damnserver.com\0" +"eu-2.evennode.com\0" +"homesense\0" +"vercelli.it\0ac.jp\0" +"educational.museum\0alstom\0" +"mikasa.hokkaido.jp\0sado.niigata.jp\0" +"dyn-vpn.de\0" +"andriabarlettatrani.it\0post\0router.management\0" +"ac.ke\0hamar.no\0" +"otama.fukushima.jp\0minamiashigara.kanagawa.jp\0" +"oita.jp\0" +"kitahiroshima.hokkaido.jp\0" +"horology.museum\0" +"is-a-nascarfan.com\0" +"ac.kr\0a.run.app\0" +"matsumoto.kagoshima.jp\0" +"brand.se\0prime\0" +"virtueeldomein.nl\0" +"duckdns.org\0" +"ac.lk\0" +"tc.br\0" +"ac.ma\0shouji\0" +"onjuku.chiba.jp\0" +"ac.ls\0\xe7\xb6\xb2\xe8\xb7\xaf.tw\0" +"pomorskie.pl\0" +"ac.me\0kr\xc3\xa5""anghke.no\0" +"shimotsuma.ibaraki.jp\0" +"tokushima.jp\0shikabe.hokkaido.jp\0" +"pixolino.com\0" +"livorno.it\0kira.aichi.jp\0onagawa.miyagi.jp\0" +"masaki.ehime.jp\0" +"camdvr.org\0" +"kembuchi.hokkaido.jp\0" +"ringsaker.no\0rv.ua\0is-a-hard-worker.com\0" +"appchizi.com\0" +"kitagawa.kochi.jp\0" +"ac.mu\0birthplace.museum\0" +"a.ssl.fastly.net\0" +"graz.museum\0ac.mw\0" +"miho.ibaraki.jp\0" +"group.aero\0ac.ni\0bostik\0insurance\0" +"ac.mz\0" +"hiraizumi.iwate.jp\0" +"environmentalconservation.museum\0eu-1.evennode.com\0myftp.org\0" +"naroy.no\0www.ro\0ftpaccess.cc\0" +"nb.ca\0" +"fuefuki.yamanashi.jp\0" +"bergbau.museum\0francaise.museum\0me.so\0delta\0tiffany\0" +"mywire.org\0" +"geometre-expert.fr\0sells-it.net\0" +"ac.nz\0" +"ravendb.me\0" +"kamitsue.oita.jp\0" +"arakawa.tokyo.jp\0" +"idv.tw\0" +"hellas.museum\0ac.pa\0" +"kyiv.ua\0" +"\xe8\x8c\xa8\xe5\x9f\x8e.jp\0soni.nara.jp\0" +"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xdb\x8c\xdb\x83\0" +"*.sapporo.jp\0" +"k12.mn.us\0family\0myhome-server.de\0" +"sera.hiroshima.jp\0" +"me.tz\0" +"lierne.no\0me.uk\0lundbeck\0now\0" +"fukumitsu.toyama.jp\0download\0" +"3utilities.com\0" +"ac.pr\0" +"!www.ck\0" +"r.bg\0" +"tobe.ehime.jp\0" +"e.se\0me.us\0" +"sites.static.land\0" +"d.gv.vc\0" +"motegi.tochigi.jp\0" +"\xd8\xb4\xd8\xa8\xd9\x83\xd8\xa9\0" +"qld.au\0villas\0" +"journalism.museum\0" +"chizu.tottori.jp\0ravendb.run\0" +"ha.cn\0im.it\0" +"\xe0\xb6\xbd\xe0\xb6\x82\xe0\xb6\x9a\xe0\xb7\x8f\0" +"hiroo.hokkaido.jp\0" +"lel.br\0" +"nra\0" +"kodaira.tokyo.jp\0" +"higashi.fukuoka.jp\0kawara.fukuoka.jp\0hikawa.shimane.jp\0" +"basel.museum\0" +"\xe7\x8f\xa0\xe5\xae\x9d\0" +"yakumo.hokkaido.jp\0" +"inder\xc3\xb8y.no\0obi\0" +"otofuke.hokkaido.jp\0frontdoor\0" +"heroy.more-og-romsdal.no\0ac.rs\0onrender.com\0" +"haboro.hokkaido.jp\0" +"enebakk.no\0ac.se\0ac.ru\0" +"ac.rw\0" +"asakuchi.okayama.jp\0calvinklein\0" +"ss.it\0yamashina.kyoto.jp\0" +"nrw\0uy.com\0" +"in-vpn.net\0" +"azerbaijan.su\0" +"soo.kagoshima.jp\0" +"ddr.museum\0" +"vda.it\0kyoto.jp\0fuchu.toyama.jp\0ac.th\0" +"cl.it\0hatsukaichi.hiroshima.jp\0ac.sz\0ac.tj\0" +"shingu.wakayama.jp\0boston\0" +"time.no\0" +"co.events\0" +"sano.tochigi.jp\0" +"inatsuki.fukuoka.jp\0" +"ac.ug\0" +"ac.tz\0" +"ac.uk\0" +"sassari.it\0ntt\0theater\0" +"crew.aero\0ullensvang.no\0" +"wazuka.kyoto.jp\0" +"yamanakako.yamanashi.jp\0" +"cc.dc.us\0" +"lubartow.pl\0" +"brunel.museum\0" +"jgora.pl\0" +"york.museum\0" +"friulivenezia-giulia.it\0" +"\xc3\xa5rdal.no\0lelux.site\0" +"cci.fr\0chungbuk.kr\0ac.vn\0off\0" +"tadaoka.osaka.jp\0" +"rochester.museum\0" +"\xd8\xa7\xd8\xa8\xd9\x88\xd8\xb8\xd8\xa8\xd9\x8a\0" +"vanguard\0" +"budejju.no\0" +"wiih.gov.pl\0privatizehealthinsurance.net\0" +"erotica.hu\0" +"clubmed\0" +"*.awdev.ca\0" +"yugawa.fukushima.jp\0nagaoka.niigata.jp\0" +"yamanouchi.nagano.jp\0" +"lakas.hu\0" +"minakami.gunma.jp\0yoka.hyogo.jp\0gov.scot\0" +"nfshost.com\0" +"koshigaya.saitama.jp\0" +"ina.ibaraki.jp\0" +"is-an-anarchist.com\0" +"ciencia.bo\0traeumtgerade.de\0" +"riik.ee\0maritimo.museum\0""1kapp.com\0" +"spreadbetting\0" +"sanda.hyogo.jp\0ikeda.nagano.jp\0" +"franziskaner.museum\0" +"crd.co\0" +"nagareyama.chiba.jp\0" +"shimoda.shizuoka.jp\0" +"s3-website-sa-east-1.amazonaws.com\0" +"kasuya.fukuoka.jp\0" +"nyc\0s3.dualstack.ap-northeast-1.amazonaws.com\0" +"biella.it\0kosei.shiga.jp\0" +"groks-this.info\0" +"social\0" +"ac.za\0" +"riopreto.br\0rg.it\0" +"data\0" +"kawamata.fukushima.jp\0" +"date\0au.eu.org\0be.eu.org\0" +"*.hosting.myjino.ru\0" +"treviso.it\0" +"anthro.museum\0ac.zm\0" +"mr.no\0" +"ap.it\0parma.it\0" +"chuo.chiba.jp\0" +"is-an-accountant.com\0" +"sannohe.aomori.jp\0" +"ac.zw\0" +"trentinosud-tirol.it\0" +"\xe9\xa4\x90\xe5\x8e\x85\0" +"yoro.gifu.jp\0worse-than.tv\0" +"sardegna.it\0\xd8\xa7\xd9\x84\xd9\x8a\xd9\x85\xd9\x86\0" +"mitsubishi\0is-certified.com\0" +"oe.yamagata.jp\0" +"lib.ca.us\0" +"aju.br\0shinkamigoto.nagasaki.jp\0" +"ar.com\0" +"veg\xc3\xa5rshei.no\0homelinux.org\0" +"whaling.museum\0" +"minamiaiki.nagano.jp\0" +"handson.museum\0ha.no\0" +"soma.fukushima.jp\0" +"kasuga.hyogo.jp\0ryuoh.shiga.jp\0\xe0\xa8\xad\xe0\xa8\xbe\xe0\xa8\xb0\xe0\xa8\xa4\0" +"civilwar.museum\0" +"susono.shizuoka.jp\0" +"naie.hokkaido.jp\0" +"tachiarai.fukuoka.jp\0tokushima.tokushima.jp\0" +"birkenes.no\0" +"\xd8\xa7\xd9\x8a\xd8\xb1\xd8\xa7\xd9\x86\0" +"k\xc3\xa5""fjord.no\0" +"gunma.jp\0saroma.hokkaido.jp\0" +"bg.eu.org\0" +"one\0x443.pw\0" +"ong\0" +"fe.it\0" +"gok.pk\0" +"mifune.kumamoto.jp\0aguni.okinawa.jp\0ostrowwlkp.pl\0" +"laspezia.it\0onl\0scor\0" +"ringerike.no\0" +"scot\0" +"blogdns.org\0" +"yaotsu.gifu.jp\0" +"mortgage\0" +"cam.it\0actor\0" +"fhs.no\0ooo\0" +"tempioolbia.it\0" +"trader.aero\0cc.fl.us\0dyn-ip24.de\0" +"act.edu.au\0larvik.no\0" +"k12.ny.us\0" +"now-dns.top\0" +"vic.au\0" +"vpnplus.to\0" +"iz.hr\0durban\0" +"nationwide\0" +"\xe7\xbb\x84\xe7\xbb\x87\xe6\x9c\xba\xe6\x9e\x84\0" +"nic.in\0" +"r.se\0" +"halden.no\0cc.pr.us\0" +"iveland.no\0tr\xc3\xb8gstad.no\0" +"trafficplex.cloud\0" +"sci.eg\0tec.mi.us\0" +"org\0" +"hn.cn\0" +"pay\0" +"dynserv.org\0" +"\xe6\x96\xb0\xe6\xbd\x9f.jp\0fujinomiya.shizuoka.jp\0" +"yatsuka.shimane.jp\0" +"gs.of.no\0" +"the.br\0" +"minamiawaji.hyogo.jp\0comcast\0" +"network\0soundcast.me\0" +"*.sendai.jp\0" +"chuo.osaka.jp\0" +"mallorca.museum\0" +"nanbu.yamanashi.jp\0" +"nikon\0map.fastly.net\0" +"money.museum\0hr.eu.org\0" +"sd.cn\0tp.it\0" +"stjohn.museum\0" +"yatsushiro.kumamoto.jp\0ouda.nara.jp\0" +"rogers\0" +"wien\0" +"seto.aichi.jp\0" +"gujo.gifu.jp\0mitoyo.kagawa.jp\0nishikawa.yamagata.jp\0malbork.pl\0ott\0" +"torsken.no\0" +"torahime.shiga.jp\0" +"engine.aero\0lib.va.us\0xfinity\0" +"yokoshibahikari.chiba.jp\0" +"tcp4.me\0" +"rsvp\0" +"clothing\0" +"dst.mi.us\0" +"chijiwa.nagasaki.jp\0" +"iki.nagasaki.jp\0" +"airforce\0operaunite.com\0" +"pet\0" +"is-with-theband.com\0" +"cesenaforli.it\0" +"entomology.museum\0" +"no.it\0ovh\0trust\0" +"naturalhistory.museum\0" +"potenza.it\0hosting-cluster.nl\0" +"\xe9\xa6\x99\xe6\xb8\xaf\0" +"kv.ua\0" +"basketball\0" +"k12.me.us\0staples\0" +"kushimoto.wakayama.jp\0" +"tsuruta.aomori.jp\0" +"karasuyama.tochigi.jp\0" +"database.museum\0for.one\0" +"static-access.net\0" +"politica.bo\0\xc3\xb8vre-eiker.no\0" +"c.bg\0" +"flog.br\0*.nom.br\0" +"in-brb.de\0" +"cc.nv.us\0" +"bulsan-s\xc3\xbc""dtirol.it\0phd\0eating-organic.net\0" +"leikanger.no\0" +"med.br\0" +"withgoogle.com\0" +"okuizumo.shimane.jp\0" +"chikugo.fukuoka.jp\0" +"dyndns.ddnss.de\0" +"cyon.site\0" +"ama.aichi.jp\0" +"bingo\0" +"pid\0" +"theatre\0" +"\xe9\xb9\xbf\xe5\x85\x90\xe5\xb3\xb6.jp\0" +"ruovat.no\0" +"\xd0\xb4\xd0\xb5\xd1\x82\xd0\xb8\0" +"vads\xc3\xb8.no\0" +"omihachiman.shiga.jp\0" +"pin\0" +"ip6.arpa\0" +"vlog.br\0" +"bo.telemark.no\0" +"suzuka.mie.jp\0" +"computer.museum\0russia.museum\0supplies\0" +"lezajsk.pl\0" +"med.ec\0wiki\0" +"qh.cn\0sakae.nagano.jp\0" +"med.ee\0" +"mihama.wakayama.jp\0" +"dyndns-server.com\0" +"tel.tr\0senseering.net\0" +"latina.it\0kuju.oita.jp\0tokashiki.okinawa.jp\0" +"yasuda.kochi.jp\0datsun\0" +"wildlife.museum\0" +"trieste.it\0" +"\xe6\xbb\x8b\xe8\xb3\x80.jp\0sakae.chiba.jp\0kikuchi.kumamoto.jp\0hgtv\0" +"irish\0" +"isa-geek.org\0" +"nasushiobara.tochigi.jp\0mikawa.yamagata.jp\0" +"kamaishi.iwate.jp\0vlaanderen\0" +"kozaki.chiba.jp\0setouchi.okayama.jp\0" +"qa2.com\0" +"curitiba.br\0fukushima.fukushima.jp\0" +"\xe7\xbd\x91\xe7\xbb\x9c.cn\0nic.tj\0" +"grozny.su\0" +"mizunami.gifu.jp\0kamikitayama.nara.jp\0nagatoro.saitama.jp\0*.stg.dev\0" +"black\0" +"mc.it\0rzeszow.pl\0workers.dev\0" +"l\xc3\xa1hppi.no\0" +"stadt.museum\0" +"szkola.pl\0" +"skiptvet.no\0wine\0" +"kobayashi.miyazaki.jp\0tonami.toyama.jp\0" +"pharmacy.museum\0lease\0" +"nhs.uk\0accountants\0" +"wakasa.fukui.jp\0" +"vicenza.it\0" +"brumunddal.no\0" +"gs.ah.no\0" +"pnc\0" +"no-ip.co.uk\0" +"ma.gov.br\0med.ht\0\xe7\xbe\xa4\xe9\xa6\xac.jp\0" +"hakusan.ishikawa.jp\0" +"minamimaki.nagano.jp\0\xe9\x9b\x86\xe5\x9b\xa2\0" +"usdecorativearts.museum\0from-va.com\0" +"shinshinotsu.hokkaido.jp\0fujimi.nagano.jp\0" +"wiki.bo\0nebraska.museum\0" +"fr.it\0shunan.yamaguchi.jp\0serveftp.net\0" +"lib.ee\0" +"wiki.br\0credit\0" +"grozny.ru\0" +"\xd0\xba\xd0\xbe\xd0\xbc\0" +"doomdns.org\0" +"brandywinevalley.museum\0" +"kita.tokyo.jp\0" +"mj\xc3\xb8ndalen.no\0" +"shirako.chiba.jp\0" +"sunagawa.hokkaido.jp\0" +"championship.aero\0" +"rikubetsu.hokkaido.jp\0hanyu.saitama.jp\0" +"mesaverde.museum\0amsterdam\0" +"v-info.info\0" +"rieti.it\0joboji.iwate.jp\0\xe5\xa4\xa7\xe4\xbc\x97\xe6\xb1\xbd\xe8\xbd\xa6\0" +"aure.no\0" +"direct\0" +"bievat.no\0" +"okayama.jp\0kawasaki.miyagi.jp\0seat\0" +"varese.it\0" +"b\xc3\xb8.telemark.no\0" +"hirosaki.aomori.jp\0" +"\xe7\xbd\x91\xe7\xbb\x9c.hk\0baby\0" +"bas.it\0" +"s3.dualstack.ca-central-1.amazonaws.com\0c.la\0" +"trentinsuedtirol.it\0" +"lewismiller.museum\0" +"anjo.aichi.jp\0" +"nic.za\0living\0" +"shinjo.okayama.jp\0" +"boehringer\0" +"compare\0" +"kaszuby.pl\0" +"dclk\0" +"game.tw\0" +"vall\xc3\xa9""edaoste.it\0" +"country\0is-a-patsfan.org\0" +"mizusawa.iwate.jp\0" +"med.ly\0" +"nikko.tochigi.jp\0linkyard-cloud.ch\0" +"pro\0mobile\0" +"arendal.no\0" +"r\xc3\xa1isa.no\0ru.com\0" +"pru\0" +"trentin-sued-tirol.it\0" +"yoichi.hokkaido.jp\0uto.kumamoto.jp\0" +"podhale.pl\0" +"ecologia.bo\0" +"green\0" +"\xd0\xbf\xd1\x80.\xd1\x81\xd1\x80\xd0\xb1\0" +"portal.museum\0schweiz.museum\0" +"okuma.fukushima.jp\0" +"seek\0" +"travelersinsurance\0" +"9guacu.br\0soja.okayama.jp\0sp.leg.br\0" +"scientist.aero\0wanggou\0" +"rankoshi.hokkaido.jp\0" +"ventures\0" +"tadotsu.kagawa.jp\0" +"med.om\0" +"mitsuke.niigata.jp\0kg.kr\0pub\0" +"termez.su\0" +"med.pa\0frogans\0" +"umaji.kochi.jp\0unnan.shimane.jp\0" +"farmequipment.museum\0" +"tottori.jp\0" +"rissa.no\0" +"readthedocs.io\0" +"prod\0" +"prof\0" +"gjerdrum.no\0barclays\0" +"med.pl\0" +"aa.no\0" +"sd.us\0redumbrella\0" +"mp.br\0" +"cc.ut.us\0" +"sayama.osaka.jp\0" +"b\xc3\xa6rum.no\0" +"obira.hokkaido.jp\0" +"loginline.dev\0" +"verran.no\0organic\0\xe6\xb7\xa1\xe9\xa9\xac\xe9\x94\xa1\0" +"inagawa.hyogo.jp\0matsushima.miyagi.jp\0at-band-camp.net\0" +"pwc\0" +"zagan.pl\0" +"haugesund.no\0company\0technology\0" +"biev\xc3\xa1t.no\0" +"tokai.ibaraki.jp\0" +"mayfirst.org\0" +"siracusa.it\0yaizu.shizuoka.jp\0ruhr\0" +"rivne.ua\0k12.mt.us\0security\0" +"taku.saga.jp\0" +"rennebu.no\0from-dc.com\0" +"choshi.chiba.jp\0" +"il.eu.org\0nh-serv.co.uk\0" +"coloradoplateau.museum\0kommune.no\0" +"matsubushi.saitama.jp\0" +"med.sa\0" +"shibecha.hokkaido.jp\0med.sd\0" +"firebaseapp.com\0" +"p.bg\0" +"c.se\0" +"bato.tochigi.jp\0" +"isa-geek.com\0" +"okoppe.hokkaido.jp\0" +"servepics.com\0" +"tsunan.niigata.jp\0" +"sabae.fukui.jp\0" +"go.ci\0" +"kosaka.akita.jp\0" +"kanmaki.nara.jp\0kamikawa.saitama.jp\0" +"webhop.org\0" +"kijo.miyazaki.jp\0" +"aktyubinsk.su\0" +"go.cr\0" +"ris\xc3\xb8r.no\0" +"leangaviika.no\0hu.eu.org\0ie.eu.org\0" +"higashiyamato.tokyo.jp\0netflix\0" +"luroy.no\0wi.us\0" +"powiat.pl\0" +"dynamic-dns.info\0" +"fujixerox\0" +"tatsuno.nagano.jp\0ikaruga.nara.jp\0" +"from-fl.com\0" +"pors\xc3\xa1\xc5\x8bgu.no\0" +"shima.mie.jp\0" +"s3-external-1.amazonaws.com\0s3-website.ap-northeast-2.amazonaws.com\0" +"realestate.pl\0kmpsp.gov.pl\0" +"ta.it\0sko.gov.pl\0sopot.pl\0" +"*.compute-1.amazonaws.com\0" +"town.museum\0" +"band\0" +"ol.no\0" +"bz.it\0bibai.hokkaido.jp\0" +"directory\0" +"asmatart.museum\0humanities.museum\0kongsberg.no\0" +"other.nf\0" +"cog.mi.us\0bank\0" +"florence.it\0" +"space\0" +"livinghistory.museum\0k12.ar.us\0lib.tn.us\0" +"nsw.edu.au\0" +"gb.net\0" +"space.museum\0" +"berlin\0" +"kaga.ishikawa.jp\0" +"dscloud.mobi\0" +"tomobe.ibaraki.jp\0" +"\xe6\x94\xbf\xe5\xba\x9c.\xe9\xa6\x99\xe6\xb8\xaf\0" +"celtic.museum\0" +"kamisato.saitama.jp\0" +"bentley\0" +"chihayaakasaka.osaka.jp\0" +"gjesdal.no\0" +"gs.rl.no\0" +"ando.nara.jp\0" +"dentist\0" +"ancona.it\0accountant\0" +"arab\0" +"contemporary.museum\0" +"aeroclub.aero\0" +"go.id\0" +"jinsekikogen.hiroshima.jp\0" +"bnr.la\0from-pr.com\0" +"skj\xc3\xa5k.no\0singles\0quicksytes.com\0" +"higashinaruse.akita.jp\0zuerich\0" +"muni.il\0" +"british.museum\0kvitsoy.no\0voagat.no\0" +"go.it\0inawashiro.fukushima.jp\0" +"direct.quickconnect.to\0" +"huissier-justice.fr\0" +"backplaneapp.io\0" +"\xe4\xbd\x9b\xe5\xb1\xb1\0" +"indianmarket.museum\0" +"go.jp\0" +"algard.no\0" +"webredirect.org\0outsystemscloud.com\0" +"go.ke\0" +"moscow.museum\0flowers\0" +"doctor\0lublin.pl\0" +"corvette.museum\0" +"draydns.de\0" +"volkswagen\0" +"re.it\0" +"her\xc3\xb8y.m\xc3\xb8re-og-romsdal.no\0" +"go.kr\0" +"pubol.museum\0cust.dev.thingdust.io\0" +"systems\0versicherung\0" +"an.it\0yachimata.chiba.jp\0" +"tattoo\0" +"kujukuri.chiba.jp\0" +"alabama.museum\0" +"ashiya.hyogo.jp\0blogdns.net\0" +"tas.edu.au\0finearts.museum\0" +"sande.more-og-romsdal.no\0" +"pomorze.pl\0principe.st\0tatar\0" +"re.kr\0" +"s3-fips-us-gov-west-1.amazonaws.com\0" +"kasumigaura.ibaraki.jp\0" +"miyazaki.miyazaki.jp\0" +"byen.site\0" +"schlesisches.museum\0gr.eu.org\0" +"capital\0" +"tamakawa.fukushima.jp\0" +"maritime.museum\0" +"uenohara.yamanashi.jp\0\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa5\x8b\xe0\xa4\xa4\0" +"is-leet.com\0" +"nakagawa.nagano.jp\0" +"opoczno.pl\0" +"miasta.pl\0blogspot.co.at\0" +"family.museum\0dubai\0" +"kunitomi.miyazaki.jp\0cloudaccess.net\0" +"nagaokakyo.kyoto.jp\0global\0red\0" +"lib.nm.us\0" +"8.bg\0" +"stuff-4-sale.org\0" +"perso.ht\0haibara.shizuoka.jp\0ren\0" +"vladikavkaz.ru\0" +"misawa.aomori.jp\0ashoro.hokkaido.jp\0" +"qvc\0from-me.org\0" +"luzern.museum\0cechire.com\0" +"fc.it\0" +"uk.com\0" +"atsugi.kanagawa.jp\0" +"wsa.gov.pl\0" +"berkeley.museum\0fedje.no\0" +"vladikavkaz.su\0" +"bydgoszcz.pl\0" +"shinonsen.hyogo.jp\0" +"go.pw\0" +"cc.wa.us\0" +"hioki.kagoshima.jp\0" +"deal\0" +"campobasso.it\0" +"gov.ac\0" +"fukushima.jp\0hotel.tz\0" +"gov.ae\0is-a-player.com\0" +"gov.af\0tamano.okayama.jp\0tokorozawa.saitama.jp\0" +"\xe0\xb0\xad\xe0\xb0\xbe\xe0\xb0\xb0\xe0\xb0\xa4\xe0\xb1\x8d\0ras.ru\0" +"nm.cn\0pi.it\0" +"go.dyndns.org\0" +"loan\0" +"sexy\0virtualuser.de\0" +"gov.al\0es.kr\0\xe0\xa4\xb8\xe0\xa4\x82\xe0\xa4\x97\xe0\xa4\xa0\xe0\xa4\xa8\0" +"khakassia.su\0" +"gov.ba\0" +"gov.ar\0gov.bb\0kaminoyama.yamagata.jp\0\xd8\xb3\xd9\x88\xd8\xaf\xd8\xa7\xd9\x86\0" +"gov.as\0jan-mayen.no\0" +"gov.au\0" +"gov.bf\0carbonia-iglesias.it\0" +"gov.bh\0" +"gov.az\0r.cdn77.net\0" +"\xe5\xb7\xa5\xe8\xa1\x8c\0nhlfan.net\0" +"gov.bm\0" +"gov.bn\0lecco.it\0" +"norfolk.museum\0" +"aurskog-holand.no\0holt\xc3\xa5len.no\0p.se\0" +"gov.br\0iwate.iwate.jp\0" +"gov.bs\0" +"gov.bt\0gov.cd\0ril\0" +"\xd9\x82\xd8\xb7\xd8\xb1\0dyndns-blog.com\0" +"otari.nagano.jp\0" +"andebu.no\0commbank\0rio\0oy.lc\0" +"rip\0" +"gov.by\0" +"gov.bz\0nadex\0" +"show.aero\0capebreton.museum\0" +"gov.cl\0go.th\0" +"gov.cm\0" +"gov.cn\0hl.cn\0go.tj\0" +"gov.co\0" +"mg.gov.br\0" +"gov.cu\0gs.nt.no\0leka.no\0" +"zoology.museum\0naturbruksgymn.se\0" +"gov.cx\0\xd0\xbc\xd0\xba\xd0\xb4\0" +"gov.cy\0" +"go.ug\0wv.us\0" +"karumai.iwate.jp\0" +"gov.dm\0konyvelo.hu\0" +"namegata.ibaraki.jp\0go.tz\0" +"gov.do\0pri.ee\0" +"tgory.pl\0" +"pantheonsite.io\0" +"arts.co\0gov.ec\0lib.ky.us\0temasek\0" +"gov.ee\0carrier.museum\0" +"kitami.hokkaido.jp\0dyndns.biz\0blogspot.co.id\0" +"gov.eg\0" +"tn.it\0tjmaxx\0" +"showtime\0" +"gov.dz\0takaoka.toyama.jp\0" +"army\0from-ks.com\0" +"yamazoe.nara.jp\0" +"square.museum\0" +"campinagrande.br\0en-root.fr\0blogspot.co.il\0" +"hirogawa.wakayama.jp\0" +"kaluga.su\0" +"fuossko.no\0altervista.org\0s3-sa-east-1.amazonaws.com\0" +"gov.et\0" +"konan.shiga.jp\0" +"ann-arbor.mi.us\0" +"nara.jp\0" +"sogndal.no\0" +"gov.fj\0tokoname.aichi.jp\0from-la.net\0sytes.net\0" +"detroit.museum\0and\xc3\xb8y.no\0loten.no\0fin.ci\0" +"trentino-sud-tirol.it\0nakamichi.yamanashi.jp\0*.in.futurecms.at\0" +"oshima.tokyo.jp\0" +"in-berlin.de\0" +"matsukawa.nagano.jp\0loft\0" +"blackfriday\0" +"arpa\0" +"gov.ge\0ismaili\0" +"press.cy\0" +"gov.gh\0wanouchi.gifu.jp\0" +"wa.edu.au\0gov.gi\0cody.museum\0" +"ninja\0" +"\xe6\x84\x9b\xe5\xaa\x9b.jp\0sanuki.kagawa.jp\0iheya.okinawa.jp\0swiebodzin.pl\0" +"fst.br\0gov.gn\0przeworsk.pl\0myftp.biz\0" +"toshiba\0" +"gov.gr\0" +"date.fukushima.jp\0" +"fin.ec\0gov.gu\0hotel.lk\0" +"oshu.iwate.jp\0" +"gov.gy\0vaapste.no\0us-4.evennode.com\0" +"zapto.xyz\0" +"gov.hk\0" +"kasai.hyogo.jp\0jobs.tt\0" +"jpmorgan\0isa-geek.net\0" +"sec.ps\0" +"nonoichi.ishikawa.jp\0\xd8\xb9\xd9\x85\xd8\xa7\xd9\x86\0" +"os.hordaland.no\0\xd0\xbc\xd0\xbe\xd0\xbd\0" +"lib.or.us\0\xe6\x96\xb0\xe9\x97\xbb\0" +"ipifony.net\0" +"a.bg\0gov.ie\0history.museum\0spy.museum\0" +"motoyama.kochi.jp\0" +"hattfjelldal.no\0motorcycles\0" +"shizukuishi.iwate.jp\0" +"gov.il\0bolzano.it\0" +"gov.in\0" +"uz.ua\0hughes\0" +"gov.iq\0k12.wa.us\0" +"gov.ir\0iwanuma.miyagi.jp\0" +"gov.is\0" +"gov.it\0" +"chofu.tokyo.jp\0" +"tank.museum\0h\xc3\xa1pmir.no\0" +"gov.jo\0kharkiv.ua\0" +"!city.sapporo.jp\0" +"bmoattachments.org\0*.platformsh.site\0" +"kawanehon.shizuoka.jp\0" +"asda\0alpha-myqnapcloud.com\0" +"\xc3\xa5s.no\0eidsberg.no\0" +"gov.kg\0skodje.no\0arte\0" +"sap\0" +"gov.ki\0s\xc3\xb8rreisa.no\0" +"caserta.it\0" +"sas\0" +"gov.km\0co.business\0" +"gov.kn\0" +"village.museum\0" +"gov.kp\0dell\0" +"gov.la\0sbi\0" +"nakai.kanagawa.jp\0gov.lb\0to.leg.br\0" +"gov.lc\0" +"partners\0" +"gov.kw\0" +"kamikoani.akita.jp\0funahashi.toyama.jp\0" +"accident-prevention.aero\0gov.ky\0sca\0us-3.evennode.com\0" +"gov.kz\0scb\0" +"gov.lk\0historical.museum\0sbs\0" +"mutsuzawa.chiba.jp\0mibu.tochigi.jp\0" +"hotel.hu\0serveftp.org\0" +"gov.ma\0\xe0\xa4\xa8\xe0\xa5\x87\xe0\xa4\x9f\0" +"kitakata.miyazaki.jp\0gov.lr\0" +"gov.ls\0hemnes.no\0bbva\0" +"gov.lt\0" +"gov.me\0" +"gov.lv\0\xd8\xa7\xd9\x84\xd8\xb9\xd9\x84\xd9\x8a\xd8\xa7\xd9\x86\0" +"gov.mg\0" +"gov.ly\0attorney\0protonet.io\0" +"gorizia.it\0" +"gov.mk\0" +"gov.ml\0" +"omega\0" +"sennan.osaka.jp\0oyama.tochigi.jp\0gov.mn\0" +"gov.mo\0s\xc3\xb8mna.no\0lib.ct.us\0" +"today\0" +"gov.mr\0" +"gov.ms\0" +"biratori.hokkaido.jp\0kasama.ibaraki.jp\0" +"gov.mu\0" +"viterbo.it\0gov.mv\0wielun.pl\0selfip.net\0" +"gov.mw\0gov.ng\0is-a-candidate.org\0" +"gov.my\0roros.no\0" +"gov.mz\0" +"ed.ao\0society.museum\0" +"shinanomachi.nagano.jp\0" +"\xe7\xb6\xb2\xe7\xb5\xa1.cn\0fujikawaguchiko.yamanashi.jp\0demon.nl\0" +"hl.no\0" +"pyatigorsk.ru\0" +"gov.nr\0" +"\xe5\x85\xac\xe5\x8f\xb8.cn\0" +"yuzawa.niigata.jp\0reisen\0run\0" +"poa.br\0" +"lib.mn.us\0arts.ve\0" +"\xe5\x92\x8c\xe6\xad\x8c\xe5\xb1\xb1.jp\0" +"beeldengeluid.museum\0habmer.no\0ses\0" +"suisse.museum\0gov.om\0" +"shimamaki.hokkaido.jp\0wios.gov.pl\0" +"sew\0" +"cuneo.it\0sex\0" +"\xe5\x85\xac\xe5\x8f\xb8.hk\0" +"tmall\0" +"asia\0" +"ed.ci\0sveio.no\0" +"cesenaforl\xc3\xac.it\0niiza.saitama.jp\0gov.ph\0" +"abudhabi\0us-2.evennode.com\0" +"sfr\0" +"gov.pk\0" +"gov.pl\0" +"royken.no\0rwe\0" +"ed.cr\0gov.pn\0" +"gov.qa\0ivano-frankivsk.ua\0bloxcms.com\0" +"gov.pr\0" +"gov.ps\0" +"gov.pt\0" +"hanawa.fukushima.jp\0" +"tn.us\0" +"takasago.hyogo.jp\0mishima.shizuoka.jp\0" +"gov.py\0" +"odessa.ua\0blogspot.co.uk\0" +"karm\xc3\xb8y.no\0" +"honjo.saitama.jp\0perso.sn\0" +"shop.ht\0pv.it\0" +"shop.hu\0" +"bellevue.museum\0s3-website-ap-northeast-1.amazonaws.com\0" +"asahi.mie.jp\0" +"watch-and-clock.museum\0" +"tokigawa.saitama.jp\0" +"solund.no\0desi\0mycd.eu\0" +"info.gu\0us-east-1.elasticbeanstalk.com\0" +"perso.tn\0" +"gov.sa\0" +"ariake.saga.jp\0gov.sb\0" +"gov.rs\0gov.sc\0" +"como.it\0takagi.nagano.jp\0gov.sd\0" +"gov.ru\0forumz.info\0" +"search\0" +"gov.rw\0gov.sg\0" +"ohkura.yamagata.jp\0gov.sh\0" +"kiyokawa.kanagawa.jp\0" +"\xe7\xb6\xb2\xe7\xb5\xa1.hk\0wales\0" +"gov.sl\0" +"movimiento.bo\0scotland.museum\0nm.us\0" +"info.ht\0yawatahama.ehime.jp\0" +"info.hu\0gov.so\0" +"mansions.museum\0" +"arts.ro\0gov.ss\0" +"gov.st\0" +"presse.km\0" +"environment.museum\0" +"gov.sx\0" +"gov.sy\0us-1.evennode.com\0" +"gov.tj\0" +"bieszczady.pl\0gov.tl\0" +"gov.tm\0" +"info.et\0valle-daosta.it\0gov.tn\0" +"gov.to\0" +"higashihiroshima.hiroshima.jp\0daigo.ibaraki.jp\0iizuna.nagano.jp\0" +"stryn.no\0gov.ua\0ski\0" +"takatori.nara.jp\0hita.oita.jp\0gov.tr\0" +"info.fj\0kagawa.jp\0gov.tt\0" +"minamiyamashiro.kyoto.jp\0" +"gov.tw\0shriram\0eu-west-2.elasticbeanstalk.com\0" +"yoshino.nara.jp\0" +"gov.uk\0" +"shiojiri.nagano.jp\0" +"suldal.no\0" +"love\0sky\0" +"tsugaru.aomori.jp\0mihara.hiroshima.jp\0" +"gov.vc\0" +"presse.ml\0" +"gov.ve\0" +"osakasayama.osaka.jp\0broker\0" +"servequake.com\0" +"iglesias-carbonia.it\0zushi.kanagawa.jp\0" +"sb.ua\0homeftp.org\0" +"valledaosta.it\0" +"agro.bo\0erotika.hu\0donostia.museum\0" +"taishin.fukushima.jp\0kep.tr\0gov.vn\0webhop.net\0" +"casino.hu\0" +"iitate.fukushima.jp\0" +"ullensaker.no\0" +"meguro.tokyo.jp\0b.ssl.fastly.net\0info.cx\0" +"crafts.museum\0" +"barletta-trani-andria.it\0hongo.hiroshima.jp\0" +"judygarland.museum\0os\xc3\xb8yro.no\0onyourside\0" +"deporte.bo\0blogspot.co.ke\0" +"lib.vt.us\0yoga\0" +"arts.nf\0" +"us.eu.org\0" +"\xd8\xa7\xd9\x8a\xd8\xb1\xd8\xa7\xd9\x86.ir\0ed.jp\0kwpsp.gov.pl\0" +"info.ec\0" +"myfritz.net\0" +"edugit.org\0" +"fin.tn\0" +"trani-barletta-andria.it\0" +"gov.ws\0" +"kawachinagano.osaka.jp\0" +"info.bb\0" +"info.at\0" +"info.au\0" +"frontier\0" +"britishcolumbia.museum\0" +"info.az\0" +"stat.no\0br\xc3\xb8nn\xc3\xb8ysund.no\0" +"palmas.br\0" +"leirfjord.no\0" +"friulivgiulia.it\0higashisumiyoshi.osaka.jp\0" +"info.bo\0kopervik.no\0spa\0" +"fiat\0" +"kvits\xc3\xb8y.no\0" +"blockbuster\0" +"vestre-toten.no\0ashgabad.su\0" +"nakatombetsu.hokkaido.jp\0" +"n.bg\0gov.za\0soy\0" +"a.se\0press.se\0ma.us\0" +"cc.pa.us\0" +"campinas.br\0" +"okinoshima.shimane.jp\0lancaster\0" +"info.co\0gateway.museum\0shaw\0lima-city.rocks\0" +"uwajima.ehime.jp\0tab\0" +"windmill.museum\0lib.al.us\0" +"otaru.hokkaido.jp\0\xe6\x89\x8b\xe8\xa1\xa8\0" +"gov.zm\0" +"mizumaki.fukuoka.jp\0" +"drobak.no\0" +"loginline.app\0" +"\xe8\x87\xba\xe7\x81\xa3\0" +"production.aero\0leadpages.co\0" +"gov.zw\0" +"rade.no\0" +"debian.net\0blogspot.co.nz\0" +"greta.fr\0oarai.ibaraki.jp\0umig.gov.pl\0" +"medizinhistorisches.museum\0" +"tax\0" +"is-a-republican.com\0" +"americanart.museum\0holdings\0" +"ostroda.pl\0srl\0" +"batsfjord.no\0fido\0" +"kamifurano.hokkaido.jp\0ichinoseki.iwate.jp\0" +"hs.run\0" +"stranda.no\0" +"saobernardo.br\0so.it\0kochi.kochi.jp\0gdansk.pl\0" +"szex.hu\0" +"chirurgiens-dentistes-en-france.fr\0" +"homeip.net\0" +"pub.sa\0tci\0" +"akkeshi.hokkaido.jp\0" +"can.museum\0" +"ch.it\0targi.pl\0" +"sweetpepper.org\0" +"ericsson\0office-on-the.net\0" +"rugby\0fr.eu.org\0" +"suginami.tokyo.jp\0swidnica.pl\0" +"stc\0" +"is-very-sweet.org\0" +"h\xc3\xb8yanger.no\0nedre-eiker.no\0" +"bmd.br\0omiya.saitama.jp\0" +"gets-it.net\0" +"ed.pw\0tdk\0" +"ryugasaki.ibaraki.jp\0obuse.nagano.jp\0" +"ovre-eiker.no\0" +"nahari.kochi.jp\0\xe0\xb9\x80\xe0\xb8\x99\xe0\xb9\x87\xe0\xb8\x95.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" +"\xe0\xb8\xad\xe0\xb8\x87\xe0\xb8\x84\xe0\xb9\x8c\xe0\xb8\x81\xe0\xb8\xa3.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" +"gildeskal.no\0" +"ponpes.id\0" +"sm\xc3\xb8la.no\0blogspot.com.cy\0" +"mn.it\0mitake.gifu.jp\0mysecuritycamera.net\0" +"cc.co.us\0" +"ballangen.no\0" +"shakotan.hokkaido.jp\0nishinomiya.hyogo.jp\0tel\0" +"tickets\0" +"awaji.hyogo.jp\0" +"philadelphia.museum\0" +"blogspot.com.ee\0" +"lanbib.se\0blogspot.com.eg\0" +"samegawa.fukushima.jp\0" +"press.ma\0tonsberg.no\0" +"trentino-aadige.it\0muika.niigata.jp\0" +"friuli-veneziagiulia.it\0" +"onojo.fukuoka.jp\0blogspot.com.ar\0" +"dd-dns.de\0" +"brother\0" +"blogspot.com.au\0" +"ham-radio-op.net\0" +"masfjorden.no\0cc.ne.us\0" +"catania.it\0" +"nikolaev.ua\0" +"uozu.toyama.jp\0" +"fr\xc3\xa6na.no\0" +"narusawa.yamanashi.jp\0" +"spjelkavik.no\0selje.no\0est-mon-blogueur.com\0from-hi.com\0" +"of.london\0" +"matta-varjjat.no\0shia\0" +"aibetsu.hokkaido.jp\0blogspot.com.br\0" +"to.work\0" +"zlg.br\0koto.shiga.jp\0" +"balat.no\0" +"is.gov.pl\0" +"thd\0" +"dyndns-web.com\0blogspot.com.by\0" +"yoshida.saitama.jp\0minami-alps.yamanashi.jp\0" +"frosinone.it\0df.leg.br\0" +"!city.nagoya.jp\0realtor\0" +"s3-us-west-1.amazonaws.com\0blogspot.com.co\0" +"tono.iwate.jp\0redirectme.net\0" +"genting\0" +"marche.it\0" +"nishiwaki.hyogo.jp\0" +"austevoll.no\0" +"\xd8\xa7\xdb\x8c\xd8\xb1\xd8\xa7\xd9\x86.ir\0yokkaichi.mie.jp\0" +"education.museum\0" +"rc.it\0in-the-band.net\0" +"gorge.museum\0" +"misasa.tottori.jp\0" +"s\xc3\xb8r-varanger.no\0" +"mishima.fukushima.jp\0" +"svelvik.no\0" +"assn.lk\0juif.museum\0k12.pa.us\0glade\0" +"kaas.gg\0" +"al.it\0" +"channel\0" +"floro.no\0myfirewall.org\0" +"niepce.museum\0film\0" +"\xe4\xbd\x90\xe8\xb3\x80.jp\0" +"games.hu\0blogspot.com.es\0" +"floripa.br\0" +"info.ve\0" +"tjx\0" +"webcam\0azimuth.network\0" +"flynnhosting.net\0" +"kr.it\0" +"cc.as.us\0" +"info.vn\0shop.th\0" +"\xd9\x83\xd9\x88\xd9\x85\0" +"urn.arpa\0community-pro.de\0" +"fujisawa.iwate.jp\0hino.tokyo.jp\0" +"newport.museum\0overhalla.no\0" +"ami.ibaraki.jp\0" +"promo\0" +"katowice.pl\0" +"joburg\0" +"takanezawa.tochigi.jp\0" +"amsterdam.museum\0blogspot.co.za\0" +"uvic.museum\0sarpsborg.no\0" +"tamaki.mie.jp\0" +"ipiranga\0" +"6.bg\0essex.museum\0\xe5\x95\x86\xe6\xa0\x87\0" +"fukuyama.hiroshima.jp\0" +"gulen.no\0nflfan.org\0" +"turystyka.pl\0on-the-web.tv\0" +"cc.ky.us\0" +"dance\0" +"!city.yokohama.jp\0" +"charter.aero\0" +"utsunomiya.tochigi.jp\0" +"info.tn\0" +"k12.tx.us\0" +"opole.pl\0info.tr\0" +"edu.eu.org\0" +"togakushi.nagano.jp\0info.tt\0" +"gentapps.com\0shop.ro\0" +"shop\0" +"ozu.ehime.jp\0nirasaki.yamanashi.jp\0info.tz\0memorial\0" +"city.hu\0k12.co.us\0lib.wy.us\0from-tx.com\0" +"al.no\0homedns.org\0" +"prudential\0" +"show\0" +"h\xc3\xa4kkinen.fi\0" +"date.hokkaido.jp\0u.channelsdvr.net\0" +"science.museum\0" +"bauhaus\0" +"maif\0" +"r\xc3\xa6lingen.no\0" +"pg.it\0" +"jab.br\0saikai.nagasaki.jp\0shioya.tochigi.jp\0legnica.pl\0top\0" +"info.ro\0" +"iwama.ibaraki.jp\0" +"fire\0ddns.me\0" +"shop.pl\0\xe6\x8b\x9b\xe8\x81\x98\0" +"info.sd\0exposed\0" +"sibenik.museum\0" +"iwakura.aichi.jp\0ishigaki.okinawa.jp\0" +"toyone.aichi.jp\0minamitane.kagoshima.jp\0kunitachi.tokyo.jp\0" +"tselinograd.su\0" +"secure\0" +"komoro.nagano.jp\0yaese.okinawa.jp\0" +"\xd0\xbe\xd1\x80\xd0\xb3\0" +"jobs\0" +"kisarazu.chiba.jp\0fish\0" +"n.se\0mn.us\0\xe4\xb8\xad\xe4\xbf\xa1\0" +"wskr.gov.pl\0" +"nalchik.ru\0" +"info.pk\0" +"info.pl\0nowtv\0" +"hashimoto.wakayama.jp\0" +"is-a-personaltrainer.com\0" +"aisai.aichi.jp\0" +"audi\0" +"gz.cn\0friuli-venezia-giulia.it\0kameyama.mie.jp\0chungnam.kr\0starachowice.pl\0info.pr\0" +"for.sale\0" +"betainabox.com\0" +"presse.ci\0nalchik.su\0" +"iwate.jp\0ayabe.kyoto.jp\0" +"ap-southeast-2.elasticbeanstalk.com\0" +"pisz.pl\0" +"blogspot.com.mt\0" +"\xe6\x96\xb0\xe5\x8a\xa0\xe5\x9d\xa1\0misconfused.org\0" +"agro.pl\0" +"info.na\0ubs\0blogspot.com.ng\0my-wan.de\0" +"svalbard.no\0valer.ostfold.no\0" +"minowa.nagano.jp\0trv\0" +"halloffame.museum\0v\xc3\xa5gan.no\0" +"trentinosudtirol.it\0info.mv\0info.nf\0" +"ohira.tochigi.jp\0" +"info.ni\0voting\0" +"aioi.hyogo.jp\0beer\0" +"\xc4\x8d\xc3\xa1hcesuolo.no\0" +"tamba.hyogo.jp\0" +"reviews\0toyota\0" +"\xc3\xb8rsta.no\0" +"aurskog-h\xc3\xb8land.no\0" +"kaizuka.osaka.jp\0info.nr\0" +"rovigo.it\0nemuro.hokkaido.jp\0" +"hiroshima.jp\0nagiso.nagano.jp\0" +"gotdns.com\0" +"piacenza.it\0rishiri.hokkaido.jp\0ng.school\0" +"minamisanriku.miyagi.jp\0" +"from-wy.com\0basicserver.io\0" +"info.la\0" +"ino.kochi.jp\0" +"indigena.bo\0tui\0" +"nabari.mie.jp\0" +"baidu\0" +"verm\xc3\xb6gensberater\0blogspot.com.tr\0" +"foundation.museum\0" +"al.us\0" +"\xe6\x89\x8b\xe6\x9c\xba\0\xe7\xbd\x91\xe5\x9d\x80\0" +"info.ls\0" +"ehime.jp\0" +"gen.in\0" +"southwest.museum\0kr.ua\0" +"ogimi.okinawa.jp\0" +"house.museum\0k12.mi.us\0" +"kanoya.kagoshima.jp\0schwarz\0" +"nom.ad\0" +"tvs\0we.bs\0nom.ae\0" +"nyuzen.toyama.jp\0nom.af\0" +"nom.ag\0s3-us-gov-west-1.amazonaws.com\0" +"express\0nom.ai\0" +"vision\0" +"finland.museum\0thingdustdata.com\0" +"goshiki.hyogo.jp\0nom.al\0" +"bomlo.no\0\xd9\x85\xd8\xb5\xd8\xb1\0" +"honjo.akita.jp\0" +"shibata.niigata.jp\0" +"info.ke\0hole.no\0kerrylogistics\0lefrak\0" +"pharmacien.fr\0morimachi.shizuoka.jp\0rj.leg.br\0" +"info.ki\0" +"barueri.br\0yamakita.kanagawa.jp\0" +"l\xc3\xb8""dingen.no\0dyndns-ip.com\0" +"katsuragi.wakayama.jp\0homeftp.net\0" +"selfip.org\0" +"oharu.aichi.jp\0" +"mihama.fukui.jp\0tomiya.miyagi.jp\0omachi.nagano.jp\0" +"video\0" +"narita.chiba.jp\0" +"civilaviation.aero\0academy.museum\0" +"bozen-sudtirol.it\0nom.cl\0" +"nom.co\0agency\0" +"divtasvuodna.no\0chrome\0glass\0ufcfan.org\0" +"onomichi.hiroshima.jp\0tobetsu.hokkaido.jp\0shimodate.ibaraki.jp\0" +"cc.ia.us\0" +"hida.gifu.jp\0kartuzy.pl\0" +"costume.museum\0plantation.museum\0" +"shiso.hyogo.jp\0" +"s3-ap-southeast-2.amazonaws.com\0" +"bi.it\0" +"yamagata.yamagata.jp\0" +"jewishart.museum\0gen.ng\0" +"lincoln\0" +"oracle\0silk\0certmgr.org\0blogspot.com.uy\0" +"smola.no\0" +"shimokitayama.nara.jp\0adachi.tokyo.jp\0\xda\x80\xd8\xa7\xd8\xb1\xd8\xaa\0legal\0" +"mashike.hokkaido.jp\0" +"grosseto.it\0katsuyama.fukui.jp\0" +"broker.aero\0nom.es\0" +"odate.akita.jp\0" +"for-some.biz\0" +"reg.dk\0" +"hakuba.nagano.jp\0toda.saitama.jp\0gen.nz\0" +"js.cn\0lo.it\0" +"sina\0" +"nom.fr\0" +"international\0nom.gd\0" +"nom.ge\0" +"suifu.ibaraki.jp\0" +"sakura\0" +"dynamisches-dns.de\0freeddns.org\0" +"kiyosu.aichi.jp\0nom.gl\0" +"vinnytsia.ua\0" +"sjc.br\0motobu.okinawa.jp\0" +"kanazawa.ishikawa.jp\0nom.gt\0" +"foodnetwork\0mc.eu.org\0" +"shiiba.miyazaki.jp\0blackbaudcdn.net\0ptplus.fit\0" +"paderborn.museum\0osen.no\0" +"ukiha.fukuoka.jp\0" +"gripe\0" +"16-b.it\0" +"qld.gov.au\0barrel-of-knowledge.info\0" +"higashishirakawa.gifu.jp\0kadogawa.miyazaki.jp\0" +"aizubange.fukushima.jp\0nom.hn\0" +"ayase.kanagawa.jp\0" +"uno\0" +"bible.museum\0" +"ujitawara.kyoto.jp\0" +"from-ky.com\0" +"tsukuba.ibaraki.jp\0" +"bristol.museum\0" +"taishi.osaka.jp\0" +"murata.miyagi.jp\0" +"nom.im\0" +"yuza.yamagata.jp\0center\0uol\0\xe6\x85\x88\xe5\x96\x84\0" +"balsan-sudtirol.it\0isshiki.aichi.jp\0" +"kudoyama.wakayama.jp\0" +"lt.eu.org\0" +"sondrio.it\0" +"memorial.museum\0" +"kicks-ass.net\0" +"de.us\0tunes\0is-a-anarchist.com\0" +"nx.cn\0pt.it\0midori.chiba.jp\0" +"tsuruga.fukui.jp\0" +"chuo.tokyo.jp\0" +"cranbrook.museum\0kvam.no\0selbu.no\0from-id.com\0" +"deatnu.no\0ups\0nom.ke\0" +"frogn.no\0" +"and.mom\0" +"nom.km\0mysecuritycamera.org\0" +"kviteseid.no\0tran\xc3\xb8y.no\0" +"terni.it\0gen.tr\0best\0" +"asahi.chiba.jp\0kibichuo.okayama.jp\0" +"osteroy.no\0" +"consulado.st\0" +"uhren.museum\0" +"yn.cn\0shizuoka.jp\0" +"nom.li\0" +"auto\0" +"higashikawa.hokkaido.jp\0okayama.okayama.jp\0" +"lib.ar.us\0" +"kainan.wakayama.jp\0" +"def.br\0trentino-altoadige.it\0" +"site\0linkitools.space\0" +"foz.br\0" +"\xd9\x87\xd9\x85\xd8\xb1\xd8\xa7\xd9\x87\0" +"cdn77-ssl.net\0" +"baseball.museum\0gloppen.no\0" +"nom.mg\0ambulance.museum\0" +"historicalsociety.museum\0mansion.museum\0strand.no\0infiniti\0" +"club.aero\0k12.ia.us\0nom.mk\0" +"shikokuchuo.ehime.jp\0" +"s3-eu-central-1.amazonaws.com\0" +"mukawa.hokkaido.jp\0" +"wafflecell.com\0" +"watari.miyagi.jp\0" +"sydney.museum\0esurance\0" +"mie.jp\0" +"nom.nc\0" +"is-a-lawyer.com\0" +"massacarrara.it\0miyama.mie.jp\0shiogama.miyagi.jp\0" +"nom.ni\0dvrcam.info\0" +"*.dapps.earth\0" +"nachikatsuura.wakayama.jp\0*.telebit.xyz\0" +"alipay\0" +"cooperativa.bo\0mangyshlak.su\0" +"kumamoto.kumamoto.jp\0suwalki.pl\0" +"sellsyourhome.org\0" +"evje-og-hornnes.no\0" +"h\xc3\xa1mm\xc3\xa1rfeasta.no\0nom.nu\0" +"enterprises\0" +"is-a-designer.com\0" +"stpetersburg.museum\0" +"kumano.mie.jp\0ath.cx\0" +"\xd9\x85\xd9\x84\xd9\x8a\xd8\xb3\xd9\x8a\xd8\xa7\0" +"nom.pa\0" +"kure.hiroshima.jp\0" +"es.eu.org\0" +"matsuyama.ehime.jp\0minami.kyoto.jp\0" +"net.ac\0nom.pe\0is-into-cartoons.com\0" +"wloclawek.pl\0vet\0" +"net.ae\0" +"net.af\0" +"net.ag\0" +"*.lcl.dev\0" +"net.ai\0" +"nom.pl\0" +"fauske.no\0sola.no\0" +"net.al\0" +"net.am\0nesset.no\0" +"on.fashion\0" +"technology.museum\0nom.qa\0" +"net.ba\0davvesiida.no\0club.tw\0" +"net.ar\0net.bb\0" +"net.au\0nom.pw\0" +"anan.tokushima.jp\0" +"gs.st.no\0" +"net.bh\0" +"k12.nh.us\0" +"net.az\0" +"net.bm\0asker.no\0b\xc3\xa1hcavuotna.no\0grue.no\0lilly\0is-a-painter.com\0freedesktop.org\0" +"net.bn\0" +"net.bo\0info.zm\0\xe7\xbd\x91\xe7\xab\x99\0" +"net.br\0" +"net.bs\0nom.re\0" +"net.bt\0trentinsud-tirol.it\0" +"l.bg\0myvnc.com\0" +"net.ci\0" +"net.bz\0rr.leg.br\0mymediapc.net\0" +"marine.ru\0" +"net.cm\0nom.ro\0serveftp.com\0" +"net.cn\0yokote.akita.jp\0" +"net.co\0" +"carboniaiglesias.it\0" +"v\xc3\xa6r\xc3\xb8y.no\0zara\0nom.rs\0" +"twmail.net\0" +"dr.na\0" +"\xe4\xb8\x96\xe7\x95\x8c\0" +"net.cu\0oystre-slidre.no\0" +"padova.it\0" +"net.cw\0vig\0builtwithdark.com\0nom.si\0" +"machida.tokyo.jp\0" +"net.cy\0s3-website.eu-central-1.amazonaws.com\0" +"\xd8\xb3\xd9\x88\xd8\xb1\xd9\x8a\xd8\xa7\0" +"natori.miyagi.jp\0" +"net.dm\0\xd8\xb3\xd9\x88\xd8\xb1\xd9\x8a\xd8\xa9\0" +"vin\0" +"net.do\0app.lmpm.com\0" +"vip\0" +"archaeology.museum\0salat.no\0passagens\0" +"eng.br\0nom.st\0" +"net.ec\0" +"osoyro.no\0" +"nishi.osaka.jp\0oyabe.toyama.jp\0" +"net.eg\0research.museum\0lugs.org.uk\0" +"nom.tj\0" +"s3-website-eu-west-1.amazonaws.com\0" +"net.dz\0rs.leg.br\0sc.leg.br\0" +"nom.tm\0" +"cultural.museum\0historisches.museum\0\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa4\xa4\xe0\xa4\xae\xe0\xa5\x8d\0" +"kokonoe.oita.jp\0" +"cc.in.us\0" +"oirase.aomori.jp\0" +"adygeya.su\0" +"net.et\0" +"nom.ug\0" +"emiliaromagna.it\0" +"tr\xc3\xa6na.no\0" +"net.fj\0takasaki.gunma.jp\0" +"hirakata.osaka.jp\0", + +"diet\0" +"mordovia.su\0nom.vc\0" +"tourism.tn\0" +"taobao\0" +"bihoro.hokkaido.jp\0instantcloud.cn\0" +"net.ge\0nom.vg\0" +"kamitonda.wakayama.jp\0" +"net.gg\0nom.uy\0" +"williamsburg.museum\0flights\0" +"net.gl\0" +"chattanooga.museum\0" +"net.gn\0" +"net.gp\0" +"net.gr\0" +"fet.no\0" +"net.gt\0" +"net.gu\0uber.space\0" +"shisui.chiba.jp\0moriya.ibaraki.jp\0" +"net.gy\0corporation.museum\0" +"net.hk\0is-a-geek.com\0" +"odo.br\0" +"net.hn\0nisshin.aichi.jp\0" +"msk.ru\0xnbay.com\0" +"takazaki.miyazaki.jp\0" +"from-de.com\0is-a-financialadvisor.com\0" +"tomari.hokkaido.jp\0" +"localhistory.museum\0mk.eu.org\0adygeya.ru\0" +"net.ht\0net.id\0tokyo.jp\0" +"apps.lair.io\0" +"pa.gov.br\0ba.leg.br\0" +"g\xc3\xa1ivuotna.no\0" +"net.il\0" +"net.im\0" +"vet.br\0net.in\0novara.it\0" +"msk.su\0" +"net.iq\0muenster.museum\0cc.ms.us\0cc.nc.us\0mordovia.ru\0" +"net.ir\0" +"net.is\0" +"neyagawa.osaka.jp\0" +"net.je\0" +"mediocampidano.it\0venice.it\0" +"rauma.no\0mydrobo.com\0" +"kadoma.osaka.jp\0" +"net.jo\0nordkapp.no\0nom.za\0" +"s3-website-ap-southeast-1.amazonaws.com\0" +"!city.kitakyushu.jp\0kofu.yamanashi.jp\0makeup\0" +"dr.tr\0" +"app.os.stg.fedoraproject.org\0" +"net.kg\0" +"pb.gov.br\0" +"pe.ca\0net.ki\0rygge.no\0" +"rn.leg.br\0wedeploy.sh\0" +"cc.wy.us\0" +"asahi.yamagata.jp\0" +"gen.mi.us\0" +"ibaraki.jp\0ogose.saitama.jp\0nichinan.tottori.jp\0net.kn\0" +"\xe6\x84\x9b\xe7\x9f\xa5.jp\0" +"net.la\0lib.id.us\0" +"pol.dz\0shichinohe.aomori.jp\0net.lb\0" +"net.lc\0" +"trento.it\0miasa.nagano.jp\0" +"jprs\0mein-iserv.de\0" +"ra.it\0takatsuki.osaka.jp\0" +"net.kw\0volkenkunde.museum\0" +"net.ky\0work\0readmyblog.org\0" +"uchihara.ibaraki.jp\0net.kz\0" +"net.lk\0" +"\xe7\x86\x8a\xe6\x9c\xac.jp\0unazuki.toyama.jp\0" +"it.ao\0cahcesuolo.no\0lifeinsurance\0" +"higashikagura.hokkaido.jp\0ama.shimane.jp\0" +"vao.it\0togane.chiba.jp\0" +"net.ma\0amfam\0fi.eu.org\0" +"miyazaki.jp\0net.lr\0" +"net.ls\0lu.eu.org\0me.eu.org\0" +"takayama.gunma.jp\0" +"net.me\0" +"net.lv\0" +"amazon\0" +"net.ly\0alaska.museum\0" +"tohma.hokkaido.jp\0seika.kyoto.jp\0ro.leg.br\0" +"net.mk\0" +"net.ml\0" +"volvo\0lpages.co\0" +"takikawa.hokkaido.jp\0" +"net.mo\0grandrapids.museum\0sweden.museum\0oh.us\0" +"kinko.kagoshima.jp\0" +"net.ms\0\xd8\xa8\xd8\xa7\xd8\xb2\xd8\xa7\xd8\xb1\0spdns.eu\0myforum.community\0" +"aizumi.tokushima.jp\0net.mt\0" +"net.mu\0labor.museum\0moskenes.no\0" +"net.mv\0net.nf\0dynathome.net\0" +"net.mw\0net.ng\0" +"taa.it\0net.mx\0" +"utah.museum\0net.my\0net.ni\0vard\xc3\xb8.no\0" +"bologna.it\0uki.kumamoto.jp\0net.mz\0" +"hol.no\0vestre-slidre.no\0" +"diskstation.org\0" +"anani.br\0" +"\xe5\xa4\xa7\xe5\x88\x86.jp\0zgorzelec.pl\0" +"catering\0" +"net.nr\0" +"lv.eu.org\0" +"stalowa-wola.pl\0expert\0" +"nanporo.hokkaido.jp\0net.nz\0wif.gov.pl\0" +"pol.ht\0" +"net.om\0travelers\0\xd1\x80\xd1\x83\xd1\x81\0" +"nakagyo.kyoto.jp\0" +"net.pa\0lib.ma.us\0realty\0chimkent.su\0" +"4.bg\0" +"wed\0" +"plurinacional.bo\0froland.no\0net.pe\0" +"tj.cn\0trentins\xc3\xbc""d-tirol.it\0niimi.okayama.jp\0kaminokawa.tochigi.jp\0" +"net.ph\0" +"harvestcelebration.museum\0judaica.museum\0" +"airtel\0" +"rad\xc3\xb8y.no\0net.pk\0" +"net.pl\0static.land\0" +"sm.ua\0" +"net.pn\0" +"gotpantheon.com\0" +"trentins\xc3\xbc""dtirol.it\0" +"net.qa\0cyou\0" +"net.pr\0""32-b.it\0" +"net.ps\0" +"net.pt\0jp.net\0" +"baltimore.museum\0ralingen.no\0" +"indianapolis.museum\0" +"*.elb.amazonaws.com.cn\0am.leg.br\0" +"net.py\0" +"k12.de.us\0" +"repl.run\0" +"kirkenes.no\0" +"yurihonjo.akita.jp\0rzgw.gov.pl\0" +"lotte\0" +"savona.it\0rocher\0" +"yufu.oita.jp\0" +"slask.pl\0cloudeity.net\0" +"marylhurst.museum\0" +"laquila.it\0" +"lotto\0" +"hiphop\0" +"association.aero\0" +"pe.it\0wada.nagano.jp\0" +"noto.ishikawa.jp\0" +"s\xc3\xb8rfold.no\0" +"tourism.pl\0flir\0monster\0" +"net.sa\0" +"net.sb\0" +"net.sc\0" +"toyoura.hokkaido.jp\0net.sd\0" +"k12.ok.us\0is-a-geek.org\0net.ru\0" +"tmp.br\0winb.gov.pl\0" +"net.rw\0net.sg\0" +"net.sh\0skin\0" +"from-md.com\0" +"net.sl\0" +"hasami.nagasaki.jp\0support\0" +"aaa.pro\0net.so\0" +"lindas.no\0" +"bhz.br\0" +"y.bg\0net.ss\0spdns.de\0" +"net.st\0dish\0" +"l.se\0" +"pfizer\0" +"marshalls\0" +"net.th\0" +"net.sy\0" +"iwaizumi.iwate.jp\0pe.kr\0net.tj\0" +"*.stolos.io\0" +"sakado.saitama.jp\0" +"net.tm\0" +"naples.it\0net.tn\0win\0" +"net.to\0" +"tonosho.kagawa.jp\0" +"vf.no\0net.ua\0\xd0\xbe\xd0\xb4.\xd1\x81\xd1\x80\xd0\xb1\0" +"gx.cn\0net.tr\0" +"paragliding.aero\0" +"net.tt\0" +"ltda\0" +"ing.pa\0net.tw\0simple-url.com\0wedeploy.me\0" +"trentinoalto-adige.it\0shiranuka.hokkaido.jp\0" +"maebashi.gunma.jp\0gdynia.pl\0" +"langevag.no\0net.uk\0k12.il.us\0" +"sodegaura.chiba.jp\0psse.gov.pl\0" +"\xe7\xbd\x91\xe7\xb5\xa1.hk\0net.vc\0dynns.com\0" +"hjelmeland.no\0net.ve\0ca-central-1.elasticbeanstalk.com\0" +"ibaraki.osaka.jp\0" +"ivanovo.su\0" +"community.museum\0f\xc3\xb8rde.no\0net.uy\0net.vi\0" +"napoli.it\0matsudo.chiba.jp\0namikata.ehime.jp\0net.uz\0" +"krokstadelva.no\0" +"engineer\0" +"net.vn\0\xe3\x82\xb9\xe3\x83\x88\xe3\x82\xa2\0" +"kusu.oita.jp\0takahata.yamagata.jp\0" +"historichouses.museum\0kr.eu.org\0" +"net.vu\0" +"steam.museum\0h\xc3\xa5.no\0" +"cs.it\0ap.leg.br\0" +"kicks-ass.org\0" +"dnsalias.net\0" +"monmouth.museum\0voyage\0" +"yamagata.jp\0" +"ap-northeast-1.elasticbeanstalk.com\0" +"hakone.kanagawa.jp\0kumiyama.kyoto.jp\0" +"my.id\0" +"government.aero\0net.ws\0" +"int.ar\0" +"sandnessj\xc3\xb8""en.no\0wme\0dyn.cosidns.de\0" +"yachiyo.chiba.jp\0" +"telebit.io\0" +"int.az\0" +"lib.fl.us\0is-a-rockstar.com\0" +"int.bo\0barsyonline.com\0" +"elk.pl\0development.run\0" +"varggat.no\0" +"pi.gov.br\0shinichi.hiroshima.jp\0" +"linde\0" +"se.leg.br\0" +"int.ci\0" +"nishiaizu.fukushima.jp\0" +"b\xc3\xa1l\xc3\xa1t.no\0" +"online.th\0" +"co.com\0" +"int.co\0net.za\0mine.nu\0" +"shell.museum\0" +"shimada.shizuoka.jp\0freeboxos.fr\0" +"vm.bytemark.co.uk\0" +"mmafan.biz\0" +"tysvar.no\0" +"\xd0\xb0\xd0\xba.\xd1\x81\xd1\x80\xd0\xb1\0net.zm\0" +"arna.no\0rightathome\0" +"asti.it\0" +"0e.vc\0" +"wow\0" +"nishinoomote.kagoshima.jp\0" +"chiryu.aichi.jp\0pol.tr\0" +"\xd1\x81\xd1\x80\xd0\xb1\0" +"microlight.aero\0" +"ohi.fukui.jp\0" +"selfip.biz\0" +"chanel\0" +"\xe4\xba\xac\xe9\x83\xbd.jp\0" +"minamiuonuma.niigata.jp\0definima.net\0" +"circle\0" +"gamo.shiga.jp\0" +"rn.it\0shikatsu.aichi.jp\0" +"oster\xc3\xb8y.no\0" +"miyakonojo.miyazaki.jp\0" +"textile.museum\0" +"getmyip.com\0" +"tsuruoka.yamagata.jp\0" +"winners\0" +"risor.no\0us-east-2.elasticbeanstalk.com\0" +"bg.it\0" +"s3.dualstack.ap-southeast-2.amazonaws.com\0" +"nakagusuku.okinawa.jp\0" +"freiburg.museum\0" +"abr.it\0" +"sugito.saitama.jp\0" +"theworkpc.com\0" +"taifun-dns.de\0" +"montreal.museum\0sumy.ua\0wtc\0" +"ybo.faith\0" +"hareid.no\0rocks\0" +"wtf\0" +"yosemite.museum\0\xe5\x95\x86\xe6\xa5\xad.tw\0" +"uruma.okinawa.jp\0" +"h\xc3\xa6gebostad.no\0" +"vaporcloud.io\0" +"newhampshire.museum\0" +"war.museum\0bloomberg\0" +"int.is\0eu-west-3.elasticbeanstalk.com\0" +"alwaysdata.net\0" +"amber.museum\0" +"gobo.wakayama.jp\0" +"troms\xc3\xb8.no\0" +"map.fastlylb.net\0" +"mod.gi\0" +"tw.cn\0vs.it\0takayama.nagano.jp\0hino.tottori.jp\0" +"chernigov.ua\0cc.md.us\0" +"pe.gov.br\0" +"noboribetsu.hokkaido.jp\0" +"artgallery.museum\0sochi.su\0" +"wolterskluwer\0" +"encyclopedic.museum\0pilots.museum\0of.work\0" +"kamikawa.hyogo.jp\0kinghost.net\0" +"lenug.su\0" +"milan.it\0mutual\0" +"isteingeek.de\0wedeploy.io\0" +"int.la\0sk\xc3\xa1nit.no\0" +"richardli\0" +"barsy.net\0" +"eurovision\0" +"ravendb.community\0" +"salud.bo\0art.museum\0energy\0" +"int.lk\0bahcavuotna.no\0" +"fuchu.tokyo.jp\0" +"dnipropetrovsk.ua\0" +"obama.fukui.jp\0" +"of.by\0lib.gu.us\0" +"nishiarita.saga.jp\0for-better.biz\0" +"dc.us\0lasalle\0" +"pr.it\0higashimatsushima.miyagi.jp\0" +"chikuzen.fukuoka.jp\0" +"in-butter.de\0" +"tranibarlettaandria.it\0" +"yanaizu.fukushima.jp\0int.mv\0" +"int.mw\0stage.nodeart.io\0" +"int.ni\0" +"ebino.miyazaki.jp\0" +"askvoll.no\0" +"xin\0" +"stockholm.museum\0mosj\xc3\xb8""en.no\0shiksha\0" +"\xe7\x9f\xb3\xe5\xb7\x9d.jp\0okazaki.aichi.jp\0" +"manx.museum\0y.se\0" +"homegoods\0\xd7\xa7\xd7\x95\xd7\x9d\0" +"host\0" +"from-ga.com\0" +"val-d-aosta.it\0" +"farsund.no\0" +"is-saved.org\0" +"maringa.br\0yamada.fukuoka.jp\0" +"omi.nagano.jp\0nerima.tokyo.jp\0olayan\0" +"is-an-engineer.com\0" +"glogow.pl\0report\0" +"sk.ca\0durham.museum\0donna.no\0" +"flanders.museum\0florida.museum\0" +"goodyear\0" +"pa.gov.pl\0" +"customer.speedpartner.de\0" +"int.pt\0" +"meet\0" +"alta.no\0" +"aip.ee\0" +"itami.hyogo.jp\0ota.tokyo.jp\0" +"jur.pro\0" +"grondar.za\0" +"yokaichiba.chiba.jp\0" +"twmail.org\0" +"kochi.jp\0" +"union.aero\0vinnica.ua\0armenia.su\0" +"eiheiji.fukui.jp\0" +"caravan\0" +"sel.no\0firestone\0" +"kuji.iwate.jp\0" +"from-ca.com\0" +"toya.hokkaido.jp\0kagamino.okayama.jp\0" +"url.tw\0" +"shiroishi.saga.jp\0" +"rodeo\0" +"biei.hokkaido.jp\0takasu.hokkaido.jp\0koryo.nara.jp\0" +"journal.aero\0" +"kasahara.gifu.jp\0tomioka.gunma.jp\0" +"avocat.pro\0paroch.k12.ma.us\0" +"abu.yamaguchi.jp\0klodzko.pl\0" +"kiev.ua\0int.ru\0selfip.com\0" +"mazury.pl\0" +"stalbans.museum\0" +"astronomy.museum\0" +"health.nz\0" +"l\xc3\xa6rdal.no\0" +"konin.pl\0" +"leitungsen.de\0myravendb.com\0" +"int.tj\0" +"columbus.museum\0" +"nomi.ishikawa.jp\0seoul.kr\0" +"computerhistory.museum\0stord.no\0cleaning\0" +"lplfinancial\0" +"here-for-more.info\0" +"myoko.niigata.jp\0" +"lima.zone\0" +"j.bg\0settlers.museum\0" +"eco.br\0minamifurano.hokkaido.jp\0int.tt\0" +"pr.gov.br\0" +"miniserver.com\0" +"baseball\0" +"minnesota.museum\0" +"nesna.no\0progressive\0" +"banamex\0" +"westfalen.museum\0is-a-nurse.com\0" +"chosei.chiba.jp\0orx.biz\0" +"scienceandindustry.museum\0us-east-1.amazonaws.com\0" +"int.ve\0" +"salvador.br\0ikeda.fukui.jp\0" +"\xe9\xb3\xa5\xe5\x8f\x96.jp\0" +"toyokawa.aichi.jp\0kotoura.tottori.jp\0int.vn\0" +"futaba.fukushima.jp\0" +"eu.com\0" +"sayo.hyogo.jp\0bielawa.pl\0" +"v\xc3\xa5gs\xc3\xb8y.no\0" +"t\xc3\xb8nsberg.no\0" +"gitlab.io\0" +"inabe.mie.jp\0co.education\0" +"fam.pk\0fl.us\0" +"cc.il.us\0" +"jdf.br\0" +"pacific.museum\0" +"perugia.it\0" +"abc.br\0" +"n\xc3\xa5\xc3\xa5mesjevuemie.no\0k12.ri.us\0" +"kanuma.tochigi.jp\0poznan.pl\0" +"of.no\0meme\0" +"ah.cn\0bt.it\0" +"frei.no\0spb.ru\0" +"ferrara.it\0kusatsu.shiga.jp\0" +"barsy.pro\0" +"management\0is-a-geek.net\0" +"melbourne\0" +"horten.no\0" +"pr.us\0\xd8\xaa\xd9\x88\xd9\x86\xd8\xb3\0" +"ozora.hokkaido.jp\0" +"accenture\0" +"radio.br\0" +"spb.su\0" +"slupsk.pl\0" +"bruxelles.museum\0kafjord.no\0" +"himeshima.oita.jp\0limanowa.pl\0" +"kragero.no\0stj\xc3\xb8rdal.no\0" +"sirdal.no\0" +"friuliv-giulia.it\0\xe9\xa6\x99\xe5\xb7\x9d.jp\0" +"menu\0is-an-actress.com\0" +"kota.aichi.jp\0mihama.mie.jp\0" +"andoy.no\0" +"zgora.pl\0" +"living.museum\0gwiddle.co.uk\0" +"barsy.pub\0" +"shinyoshitomi.fukuoka.jp\0" +"fredrikstad.no\0markets\0" +"health.vn\0" +"l\xc3\xb8ten.no\0" +"kamogawa.chiba.jp\0shinto.gunma.jp\0" +"freebox-os.com\0" +"is-very-nice.org\0" +"gaivuotna.no\0" +"mochizuki.nagano.jp\0shinjo.yamagata.jp\0\xe8\x81\x94\xe9\x80\x9a\0" +"film.hu\0skanit.no\0*.moonscale.io\0" +"from-ar.com\0" +"bindal.no\0giving\0" +"coffee\0" +"from-wa.com\0" +"yamanashi.jp\0" +"catering.aero\0dp.ua\0" +"johana.toyama.jp\0" +"s3.dualstack.us-east-1.amazonaws.com\0" +"toon.ehime.jp\0" +"nannestad.no\0" +"takahagi.ibaraki.jp\0" +"stavern.no\0business\0" +"tochio.niigata.jp\0barclaycard\0\xe6\x94\xbf\xe5\xba\x9c\0" +"bodo.no\0" +"bryansk.su\0" +"shimizu.shizuoka.jp\0" +"cadaques.museum\0bike\0" +"cust.testing.thingdust.io\0" +"ggf.br\0" +"natuurwetenschappen.museum\0" +"xxx\0" +"l\xc3\xb8renskog.no\0" +"takehara.hiroshima.jp\0horonobe.hokkaido.jp\0" +"cremona.it\0nishiazai.shiga.jp\0" +"haebaru.okinawa.jp\0" +"yatomi.aichi.jp\0shibata.miyagi.jp\0hangout\0" +"pesarourbino.it\0kushiro.hokkaido.jp\0toyono.osaka.jp\0" +"shopping\0land-4-sale.us\0" +"kiyose.tokyo.jp\0" +"tsurugashima.saitama.jp\0xyz\0" +"is-a-libertarian.com\0" +"nv.us\0" +"kashiwazaki.niigata.jp\0" +"yame.fukuoka.jp\0" +"aver\xc3\xb8y.no\0namdalseid.no\0" +"koshu.yamanashi.jp\0" +"is-lost.org\0" +"toyama.jp\0haga.tochigi.jp\0" +"karpacz.pl\0\xd1\x83\xd0\xba\xd1\x80\0storage.yandexcloud.net\0" +"kaho.fukuoka.jp\0" +"vic.gov.au\0gratangen.no\0bing\0" +"shintomi.miyazaki.jp\0unzen.nagasaki.jp\0" +"k12.in.us\0" +"himeji.hyogo.jp\0" +"sandiego.museum\0" +"salangen.no\0" +"hasuda.saitama.jp\0" +"artanddesign.museum\0" +"elasticbeanstalk.com\0" +"kumamoto.jp\0sakai.osaka.jp\0kurobe.toyama.jp\0" +"bronnoysund.no\0" +"hagi.yamaguchi.jp\0" +"2.bg\0" +"contact\0" +"tienda\0" +"sx.cn\0" +"fundacio.museum\0tjeldsund.no\0" +"tako.chiba.jp\0tsukumi.oita.jp\0usuki.oita.jp\0fhapp.xyz\0" +"tsuno.miyazaki.jp\0" +"yotsukaido.chiba.jp\0" +"hembygdsforbund.museum\0s\xc3\xb8r-aurdal.no\0" +"cq.cn\0akagi.shimane.jp\0" +"krym.ua\0" +"otoineppu.hokkaido.jp\0czest.pl\0" +"komagane.nagano.jp\0" +"shikama.miyagi.jp\0" +"\xe3\x83\x9d\xe3\x82\xa4\xe3\x83\xb3\xe3\x83\x88\0" +"k12.dc.us\0luxe\0" +"kanonji.kagawa.jp\0" +"ah.no\0" +"fuchu.hiroshima.jp\0" +"kyoto\0" +"hoteles\0tatamotors\0point2this.com\0" +"xbox\0" +"fidelity\0" +"pc.it\0" +"my-gateway.de\0" +"dynu.net\0" +"s\xc3\xb8r-fron.no\0" +"physio\0" +"gv.ao\0" +"po.gov.pl\0freebox-os.fr\0" +"botanical.museum\0" +"mosjoen.no\0you\0nohost.me\0" +"gv.at\0" +"logoip.com\0" +"\xe7\xb6\xb2\xe7\xb5\xa1.\xe9\xa6\x99\xe6\xb8\xaf\0miami\0" +"dnsalias.org\0" +"w.bg\0vennesla.no\0scholarships\0" +"ofunato.iwate.jp\0" +"bashkiria.ru\0" +"karmoy.no\0" +"design.aero\0" +"marburg.museum\0selfip.info\0" +"hazu.aichi.jp\0itayanagi.aomori.jp\0" +"ng.ink\0" +"ginoza.okinawa.jp\0" +"seljord.no\0" +"sncf\0" +"bashkiria.su\0" +"tsuyama.okayama.jp\0okinawa.okinawa.jp\0" +"toei.aichi.jp\0ichinohe.iwate.jp\0" +"hiji.oita.jp\0cancerresearch\0" +"trentinsued-tirol.it\0kamioka.akita.jp\0" +"boston.museum\0kddi\0" +"bungotakada.oita.jp\0" +"kristiansand.no\0" +"reggiocalabria.it\0" +"barcelona\0asso.eu.org\0" +"nagara.chiba.jp\0hidaka.saitama.jp\0" +"building.museum\0amica\0" +"dnsking.ch\0" +"kitaakita.akita.jp\0" +"arteducation.museum\0barsy.org\0" +"of.football\0" +"medecin.km\0zaporizhzhe.ua\0" +"kihoku.ehime.jp\0" +"bedzin.pl\0" +"pmn.it\0" +"soc.lk\0filegear-au.me\0" +"ogori.fukuoka.jp\0naka.hiroshima.jp\0" +"usculture.museum\0" +"\xd1\x83\xd0\xbf\xd1\x80.\xd1\x81\xd1\x80\xd0\xb1\0" +"cloudfront.net\0" +"gs.hm.no\0fr\xc3\xb8ya.no\0tysnes.no\0" +"pvh.br\0kounosu.saitama.jp\0" +"lib.vi.us\0is-a-techie.com\0" +"virginia.museum\0homes\0" +"\xd8\xa7\xdb\x8c\xd8\xb1\xd8\xa7\xd9\x86\0" +"maceio.br\0" +"yukuhashi.fukuoka.jp\0" +"hk.com\0" +"intuit\0" +"nakijin.okinawa.jp\0" +"woodside\0" +"kamiamakusa.kumamoto.jp\0yun\0" +"omuta.fukuoka.jp\0" +"wa.au\0user.party.eus\0in-dsl.de\0" +"pc.pl\0turek.pl\0" +"katagami.akita.jp\0" +"klepp.no\0realestate\0is-a-doctor.com\0" +"ilawa.pl\0" +"trondheim.no\0" +"shiki.saitama.jp\0ce.leg.br\0" +"tagami.niigata.jp\0" +"nishiokoppe.hokkaido.jp\0hizen.saga.jp\0" +"ppg.br\0" +"bergen.no\0" +"from.hr\0" +"figueres.museum\0" +"nordreisa.no\0" +"digital\0" +"pizza\0s3-website.ap-south-1.amazonaws.com\0" +"\xe7\xbd\x91\xe7\xbb\x9c\0" +"jp.eu.org\0" +"cri.br\0" +"fj.cn\0ishikawa.okinawa.jp\0" +"artdeco.museum\0" +"agdenes.no\0" +"pp.az\0avoues.fr\0" +"cinema.museum\0" +"verona.it\0kameoka.kyoto.jp\0" +"ut.us\0" +"asuke.aichi.jp\0" +"r\xc3\xb8yken.no\0" +"namegawa.saitama.jp\0minobu.yamanashi.jp\0" +"zero\0" +"miyako.iwate.jp\0zip\0" +"pavia.it\0venezia.it\0" +"conf.au\0\xe7\x82\xb9\xe7\x9c\x8b\0*.advisor.ws\0" +"county.museum\0forgot.his.name\0keymachine.de\0" +"hadano.kanagawa.jp\0olawa.pl\0" +"rec.br\0" +"steiermark.museum\0" +"oxford.museum\0" +"oceanographic.museum\0yombo.me\0" +"madrid\0" +"no-ip.ca\0" +"lapy.pl\0\xe0\xb8\xa8\xe0\xb8\xb6\xe0\xb8\x81\xe0\xb8\xa9\xe0\xb8\xb2.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" +"rec.co\0k12.ak.us\0" +"writesthisblog.com\0" +"kusatsu.gunma.jp\0" +"okinawa\0" +"cc.sc.us\0" +"my-router.de\0" +"chichibu.saitama.jp\0" +"control.aero\0oppeg\xc3\xa5rd.no\0" +"trogstad.no\0" +"onga.fukuoka.jp\0" +"lindesnes.no\0" +"aki.kochi.jp\0" +"karelia.su\0" +"kakamigahara.gifu.jp\0" +"botanicalgarden.museum\0" +"christiansburg.museum\0" +"food\0freetls.fastly.net\0" +"statebank\0" +"ena.gifu.jp\0achi.nagano.jp\0minamiizu.shizuoka.jp\0" +"lib.mt.us\0lib.nd.us\0svn-repos.de\0" +"iida.nagano.jp\0govt.nz\0" +"harstad.no\0" +"its.me\0" +"isen.kagoshima.jp\0" +"railroad.museum\0her\xc3\xb8y.nordland.no\0onthewifi.com\0" +"gyeonggi.kr\0" +"is-a-green.com\0webhop.info\0" +"trentinsudtirol.it\0" +"ina.nagano.jp\0" +"heguri.nara.jp\0" +"baghdad.museum\0rl.no\0" +"nt.au\0gop.pk\0lipsy\0" +"grocery\0" +"salerno.it\0" +"stor-elvdal.no\0" +"studio\0" +"monzaebrianza.it\0*.nagoya.jp\0hitachiomiya.ibaraki.jp\0yono.saitama.jp\0podzone.net\0" +"hitra.no\0nodum.co\0" +"kitadaito.okinawa.jp\0ikeda.osaka.jp\0" +"trading.aero\0nt.ca\0" +"construction\0" +"square7.net\0" +"coal.museum\0" +"mw.gov.pl\0zarow.pl\0ford\0" +"imizu.toyama.jp\0" +"nativeamerican.museum\0cc.ga.us\0" +"ownip.net\0" +"tsukigata.hokkaido.jp\0" +"nesoddtangen.no\0" +"urbinopesaro.it\0" +"vestvagoy.no\0" +"morena.br\0miyoshi.hiroshima.jp\0" +"express.aero\0nodum.io\0" +"iwatsuki.saitama.jp\0" +"kunigami.okinawa.jp\0ugim.gov.pl\0" +"gs.svalbard.no\0eidsvoll.no\0w.se\0" +"xz.cn\0geisei.kochi.jp\0" +"langev\xc3\xa5g.no\0" +"herad.no\0sells-for-less.com\0" +"ms.gov.br\0" +"aerodrome.aero\0loginline.services\0" +"szczytno.pl\0" +"sciencehistory.museum\0fyresdal.no\0honda\0" +"togitsu.nagasaki.jp\0pgafan.net\0" +"gyeongbuk.kr\0" +"foggia.it\0" +"us-gov-west-1.elasticbeanstalk.com\0" +"happou.akita.jp\0*.on-rancher.cloud\0" +"randaberg.no\0" +"seirou.niigata.jp\0" +"elburg.museum\0tushu\0" +"nord-fron.no\0" +"hirara.okinawa.jp\0" +"usgarden.museum\0" +"gangaviika.no\0us-west-1.elasticbeanstalk.com\0" +"nerdpol.ovh\0" +"blogdns.com\0" +"nagi.okayama.jp\0" +"gv.vc\0" +"cloud.fedoraproject.org\0" +"mt.gov.br\0dellogliastra.it\0kin.okinawa.jp\0" +"s3-eu-west-1.amazonaws.com\0" +"basilicata.it\0kunneppu.hokkaido.jp\0" +"godo.gifu.jp\0sakura.tochigi.jp\0cri.nz\0" +"feedback\0vana\0giize.com\0" +"\xe0\xaa\xad\xe0\xaa\xbe\xe0\xaa\xb0\xe0\xaa\xa4\0williamhill\0" +"cologne\0twmail.cc\0" +"kanzaki.saga.jp\0\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa4\xa4\0\xe0\xb8\x97\xe0\xb8\xab\xe0\xb8\xb2\xe0\xb8\xa3.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" +"jefferson.museum\0" +"badaddja.no\0doesntexist.com\0" +"ichikai.tochigi.jp\0" +"rec.nf\0" +"chernihiv.ua\0" +"enna.it\0" +"tuscany.it\0s\xc3\xbc""dtirol.it\0" +"kitakata.fukushima.jp\0" +"narviika.no\0" +"sener\0barsy.shop\0" +"trolley.museum\0" +"shiftedit.io\0" +"medecin.fr\0" +"watchandclock.museum\0" +"run.app\0" +"fvg.it\0watch\0" +"shiwa.iwate.jp\0" +"paris\0" +"dynv6.net\0" +"tj\xc3\xb8me.no\0sohu\0jambyl.su\0" +"zao.miyagi.jp\0" +"babia-gora.pl\0" +"h.bg\0hsbc\0icbc\0" +"half.host\0" +"consulting.aero\0" +"wnext.app\0" +"childrensgarden.museum\0school.museum\0cc.ok.us\0" +"takanabe.miyazaki.jp\0" +"is-a-knight.org\0" +"agr.br\0" +"yugawara.kanagawa.jp\0tarama.okinawa.jp\0shinjuku.tokyo.jp\0" +"sakaiminato.tottori.jp\0" +"higashiizu.shizuoka.jp\0" +"pp.se\0pp.ru\0mlbfan.org\0" +"sakegawa.yamagata.jp\0vpndns.net\0" +"nosegawa.nara.jp\0se.net\0ru.net\0" +"k12.ga.us\0" +"ikeda.gifu.jp\0" +"wa.us\0" +"rec.ro\0" +"ac.gov.br\0" +"go.leg.br\0" +"fla.no\0" +"naoshima.kagawa.jp\0arida.wakayama.jp\0nome.pt\0" +"ambulance.aero\0" +"si.it\0tsu.mie.jp\0" +"\xe3\x83\x95\xe3\x82\xa1\xe3\x83\x83\xe3\x82\xb7\xe3\x83\xa7\xe3\x83\xb3\0" +"kaufen\0" +"teaches-yoga.com\0" +"hs.kr\0merckmsd\0" +"edgestack.me\0" +"conf.se\0pp.ua\0" +"steinkjer.no\0" +"nt.no\0" +"br.it\0cb.it\0" +"mill.museum\0domains\0" +"etajima.hiroshima.jp\0" +"store\0" +"yashiro.hyogo.jp\0" +"tysfjord.no\0tokyo\0" +"aya.miyazaki.jp\0" +"k12.az.us\0" +"trentin-sudtirol.it\0pippu.hokkaido.jp\0" +"ryokami.saitama.jp\0" +"neues.museum\0" +"amli.no\0" +"satx.museum\0" +"ine.kyoto.jp\0" +"lib.co.us\0" +"abarth\0" +"iwamizawa.hokkaido.jp\0" +"e164.arpa\0\xe5\x85\xac\xe5\x8f\xb8.\xe9\xa6\x99\xe6\xb8\xaf\0song\0" +"moss.no\0" +"equipment.aero\0qld.edu.au\0" +"\xd8\xa7\xd9\x84\xd8\xa7\xd8\xb1\xd8\xaf\xd9\x86\0de.cool\0" +"notodden.no\0" +"resistance.museum\0" +"sar.it\0kawagoe.saitama.jp\0" +"soundandvision.museum\0rec.ve\0filegear-ie.me\0" +"numata.hokkaido.jp\0shijonawate.osaka.jp\0" +"catholic.edu.au\0naamesjevuemie.no\0" +"sony\0is.eu.org\0" +"ybo.party\0" +"akrehamn.no\0lib.ny.us\0" +"sardinia.it\0koeln\0" +"tsuchiura.ibaraki.jp\0\xd8\xa8\xd8\xa7\xd8\xb1\xd8\xaa\0" +"cc.mo.us\0solutions\0" +"midsund.no\0" +"ap-south-1.elasticbeanstalk.com\0dyndns-at-home.com\0" +"rindal.no\0nt.ro\0sa.com\0" +"kawakami.nagano.jp\0kitagata.saga.jp\0otsu.shiga.jp\0" +"dynvpn.de\0" +"nankoku.kochi.jp\0" +"nsn.us\0c66.me\0" +"takahashi.okayama.jp\0koto.tokyo.jp\0" +"dn.ua\0" +"it.eu.org\0" +"yusui.kagoshima.jp\0" +"maintenance.aero\0narvik.no\0" +"mel\xc3\xb8y.no\0" +"koori.fukushima.jp\0" +"hyuga.miyazaki.jp\0" +"tksat.bo\0drangedal.no\0autos\0" +"akabira.hokkaido.jp\0" +"\xd8\xa8\xd9\x8a\xd8\xaa\xd9\x83\0is-a-liberal.com\0" +"surnadal.no\0" +"mail.pl\0" +"od.ua\0" +"agric.za\0" +"from-nm.com\0" +"niikappu.hokkaido.jp\0taiji.wakayama.jp\0" +"newmexico.museum\0" +"plo.ps\0" +"iide.yamagata.jp\0" +"saga.saga.jp\0" +"racing\0" +"kagoshima.kagoshima.jp\0" +"s3-ap-southeast-1.amazonaws.com\0" +"fussa.tokyo.jp\0cn-northwest-1.eb.amazonaws.com.cn\0" +"schools.nsw.edu.au\0parts\0eu-central-1.elasticbeanstalk.com\0" +"inc.hk\0" +"museum\0git-repos.de\0brasilia.me\0" +"tysv\xc3\xa6r.no\0party\0verm\xc3\xb6gensberatung\0barsy.site\0" +"\xe4\xb8\xad\xe5\x9b\xbd\0" +"co.ae\0" +"minamiminowa.nagano.jp\0wake.okayama.jp\0" +"co.ag\0" +"kuroishi.aomori.jp\0*.sensiosite.cloud\0" +"co.am\0hvaler.no\0gives\0" +"co.ao\0dyndns-at-work.com\0" +"state.museum\0\xe4\xb8\xad\xe5\x9c\x8b\0" +"co.bb\0rep.kp\0group\0*.kunden.ortsinfo.at\0" +"in.eu.org\0" +"co.at\0" +"feira.br\0" +"herokussl.com\0" +"lig.it\0lodi.it\0shobara.hiroshima.jp\0" +"co.bi\0hasura-app.io\0" +"katori.chiba.jp\0user.aseinet.ne.jp\0" +"cambridge.museum\0" +"skjak.no\0lib.me.us\0" +"matsusaka.mie.jp\0co.bn\0" +"0.bg\0" +"co.ca\0" +"vb.it\0" +"nord-odal.no\0cc.ks.us\0" +"conf.lv\0" +"*.sch.uk\0software\0is-into-games.com\0" +"yamanashi.yamanashi.jp\0bialystok.pl\0" +"co.bw\0idrett.no\0" +"est.pr\0" +"co.ci\0rodoy.no\0" +"co.cl\0" +"co.cm\0" +"co.cr\0" +"srv.br\0yusuhara.kochi.jp\0" +"suli.hu\0stange.no\0loseyourip.com\0" +"co.cz\0" +"co.dk\0" +"clock.museum\0cc.vi.us\0" +"dsmynas.org\0" +"broke-it.net\0" +"gallup\0" +"xen.prgmr.com\0" +"yawara.ibaraki.jp\0" +"pa.it\0tosashimizu.kochi.jp\0izunokuni.shizuoka.jp\0edogawa.tokyo.jp\0" +"project.museum\0" +"kiso.nagano.jp\0" +"\xc3\xa5lesund.no\0" +"\xd7\x99\xd7\xa8\xd7\x95\xd7\xa9\xd7\x9c\xd7\x99\xd7\x9d.museum\0" +"vallee-d-aoste.it\0" +"gs.tm.no\0" +"fortmissoula.museum\0k12.mo.us\0from-tn.com\0" +"cim.br\0lombardia.it\0" +"oshino.yamanashi.jp\0" +"chita.aichi.jp\0tomisato.chiba.jp\0" +"j\xc3\xb8rpeland.no\0modum.no\0" +"bern.museum\0" +"niteroi.br\0" +"chuo.fukuoka.jp\0uda.nara.jp\0" +"u.bg\0" +"h.se\0stackhero-network.com\0" +"fukudomi.saga.jp\0" +"usantiques.museum\0" +"teramo.it\0" +"media.museum\0is-a-caterer.com\0" +"co.gg\0gub.uy\0barsycenter.com\0eu.meteorapp.com\0" +"vang.no\0collegefan.org\0" +"kvafjord.no\0nov.ru\0" +"co.gl\0" +"madrid.museum\0gucci\0" +"docs\0sanofi\0" +"gallo\0" +"lans.museum\0" +"web.app\0" +"gs.nl.no\0crimea.ua\0" +"co.gy\0" +"coop.ht\0" +"slattum.no\0tranoy.no\0nov.su\0" +"vall\xc3\xa9""e-aoste.it\0" +"swidnik.pl\0" +"fitjar.no\0" +"\xe5\xbe\xae\xe5\x8d\x9a\0" +"game\0" +"co.id\0tenei.fukushima.jp\0" +"co.hu\0" +"yonezawa.yamagata.jp\0" +"bc.ca\0" +"sv.it\0" +"podzone.org\0" +"sharp\0" +"vlaanderen.museum\0\xe7\xbd\x91\xe5\xba\x97\0" +"co.il\0" +"co.im\0" +"co.in\0" +"bardu.no\0" +"chambagri.fr\0\xe5\xae\xae\xe5\x9f\x8e.jp\0yanagawa.fukuoka.jp\0yamaxun\0" +"ivgu.no\0" +"g12.br\0co.ir\0" +"co.it\0" +"co.je\0" +"al.gov.br\0yamagata.ibaraki.jp\0" +"coop.br\0london.cloudapps.digital\0" +"shimosuwa.nagano.jp\0auction\0" +"kakogawa.hyogo.jp\0ome.tokyo.jp\0mragowo.pl\0" +"c.cdn77.org\0*.customer-oci.com\0api.stdlib.com\0" +"uk.net\0" +"net-freaks.com\0" +"co.jp\0toyota.aichi.jp\0" +"blog\0" +"misato.shimane.jp\0" +"co.ke\0" +"soka.saitama.jp\0" +"free.hr\0" +"\xe8\xb4\xad\xe7\x89\xa9\0yodobashi\0" +"s\xc3\xb8rum.no\0" +"izumizaki.fukushima.jp\0co.kr\0better-than.tv\0" +"co.lc\0" +"kariya.aichi.jp\0" +"tjome.no\0" +"ainan.ehime.jp\0" +"dyndns-pics.com\0for-our.info\0" +"ne.jp\0" +"spot\0" +"parachuting.aero\0ne.ke\0\xe7\xb5\x84\xe7\xb9\x94.tw\0consulting\0" +"co.ma\0usa.museum\0" +"kagami.kochi.jp\0mugi.tokushima.jp\0" +"co.ls\0" +"minato.tokyo.jp\0" +"co.me\0assassination.museum\0paleo.museum\0hammarfeasta.no\0" +"*.futurecms.at\0" +"co.mg\0" +"caseih\0" +"ne.kr\0" +"bci.dnstrace.pro\0" +"psp.gov.pl\0" +"bahn.museum\0" +"kosher\0" +"botanicgarden.museum\0co.na\0k12.wi.us\0is-a-cubicle-slave.com\0" +"co.mu\0" +"embetsu.hokkaido.jp\0" +"co.mw\0" +"kitagata.gifu.jp\0" +"flight.aero\0co.ni\0hb.cldmail.ru\0" +"co.mz\0" +"ichikawamisato.yamanashi.jp\0co.nl\0" +"teo.br\0" +"sanfrancisco.museum\0tele.amune.org\0co.no\0groks-the.info\0" +"bearalvahki.no\0" +"kawaue.gifu.jp\0" +"k12.ec\0endoftheinternet.org\0" +"co.nz\0" +"ichihara.chiba.jp\0" +"co.om\0" +"uri.arpa\0" +"financial\0" +"luxury\0" +"oketo.hokkaido.jp\0" +"modalen.no\0orskog.no\0" +"k12.pr.us\0" +"kv\xc3\xa6""fjord.no\0" +"tunk.org\0nym.by\0" +"monash\0co.pl\0nym.bz\0" +"kashima.saga.jp\0co.pn\0discover\0" +"blue\0" +"kitashiobara.fukushima.jp\0" +"glas.museum\0free\0" +"yaita.tochigi.jp\0" +"leasing.aero\0games\0" +"contagem.br\0" +"co.pw\0pa.us\0azurecontainer.io\0" +"museumcenter.museum\0opencraft.hosting\0" +"properties\0" +"uchinada.ishikawa.jp\0" +"law.pro\0homelink.one\0" +"aparecida.br\0" +"workshop.museum\0" +"li.it\0" +"cc.az.us\0nym.ec\0" +"nanao.ishikawa.jp\0gorlice.pl\0community-pro.net\0" +"\xc3\xa5snes.no\0pharmacy\0shangrila\0\xe3\x82\xbb\xe3\x83\xbc\xe3\x83\xab\0" +"valleedaoste.it\0lubin.pl\0" +"seki.gifu.jp\0" +"stuttgart.museum\0mini\0" +"tra.kp\0" +"estate.museum\0ne.pw\0" +"romskog.no\0co.rs\0" +"geelvinck.museum\0lacaixa\0alpha.bounty-full.com\0" +"mo-i-rana.no\0co.rw\0vegas\0" +"mint\0" +"dgca.aero\0kristiansund.no\0dielddanuorri.no\0" +"kozow.com\0" +"\xe6\x9d\xb1\xe4\xba\xac.jp\0walbrzych.pl\0" +"panama.museum\0alsace\0" +"alto-adige.it\0" +"k12.il\0" +"co.st\0" +"kvalsund.no\0" +"co.th\0" +"clinton.museum\0" +"shirakawa.gifu.jp\0co.sz\0co.tj\0" +"gon.pk\0" +"\xe5\xb1\xb1\xe5\x8f\xa3.jp\0shiroi.chiba.jp\0" +"co.tm\0" +"kawatana.nagasaki.jp\0" +"mysecuritycamera.com\0" +"co.ua\0" +"kazo.saitama.jp\0blogsite.xyz\0" +"co.tt\0nym.gr\0" +"industries\0" +"colonialwilliamsburg.museum\0co.ug\0leclerc\0" +"turin.it\0" +"s3.ca-central-1.amazonaws.com\0" +"co.tz\0" +"interactive.museum\0co.uk\0nym.gy\0dray-dns.de\0" +"trentinos\xc3\xbc""dtirol.it\0yomitan.okinawa.jp\0" +"nym.hk\0" +"shibuya.tokyo.jp\0" +"lib.hi.us\0s3-website-ap-southeast-2.amazonaws.com\0" +"sekigahara.gifu.jp\0omitama.ibaraki.jp\0" +"co.us\0" +"pn.it\0kwp.gov.pl\0" +"org.ac\0co.ve\0" +"org.ae\0safety\0nym.ie\0" +"org.af\0kumakogen.ehime.jp\0gbiz\0" +"org.ag\0palace.museum\0co.vi\0" +"minamiechizen.fukui.jp\0co.uz\0" +"org.ai\0yalta.ua\0" +"\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" +"valer.hedmark.no\0" +"org.al\0" +"org.am\0salzburg.museum\0" +"trentino-a-adige.it\0aoste.it\0" +"stathelle.no\0g\xc3\xa1ls\xc3\xa1.no\0ne.ug\0" +"sumoto.hyogo.jp\0yamatokoriyama.nara.jp\0otsuki.yamanashi.jp\0" +"org.ba\0builders\0" +"org.ar\0org.bb\0tajimi.gifu.jp\0ne.tz\0" +"org.au\0" +"org.bh\0" +"org.bi\0" +"org.az\0kami.kochi.jp\0aga.niigata.jp\0itabashi.tokyo.jp\0" +"u.se\0ne.us\0nagoya\0" +"org.bm\0" +"org.bn\0tsubata.ishikawa.jp\0" +"org.bo\0" +"friuli-v-giulia.it\0olbiatempio.it\0tempio-olbia.it\0" +"org.br\0kisofukushima.nagano.jp\0" +"org.bs\0" +"org.bt\0" +"\xce\xb5\xce\xbb\0" +"org.bw\0philips\0" +"fot.br\0" +"org.ci\0" +"org.bz\0" +"stordal.no\0" +"org.cn\0okinawa.jp\0" +"empresa.bo\0org.co\0bale.museum\0ski.no\0med.pro\0\xce\xb5\xcf\x85\0" +"sasaguri.fukuoka.jp\0" +"nym.la\0mo-siemens.io\0" +"eun.eg\0sologne.museum\0ieee\0ollo\0talk\0from-nh.com\0nym.lc\0" +"org.cu\0" +"org.cw\0" +"org.cy\0ibestad.no\0nym.li\0" +"imakane.hokkaido.jp\0nym.kz\0" +"taishi.hyogo.jp\0" +"org.dm\0" +"org.do\0co.za\0" +"ts.it\0witd.gov.pl\0" +"ekloges.cy\0org.ec\0" +"nym.lt\0" +"org.ee\0fhv.se\0nym.lu\0nym.me\0" +"org.eg\0loginline.io\0" +"recife.br\0soc.srcf.net\0" +"haram.no\0" +"org.dz\0" +"coop.rw\0co.zm\0" +"yura.wakayama.jp\0nym.mn\0" +"muosat.no\0" +"masuda.shimane.jp\0" +"org.es\0" +"org.et\0" +"co.zw\0s3.eu-west-3.amazonaws.com\0" +"anthropology.museum\0coastaldefence.museum\0" +"nym.mx\0" +"org.fj\0" +"cloudns.pro\0mypets.ws\0" +"modern.museum\0n\xc3\xb8tter\xc3\xb8y.no\0" +"landes.museum\0repl.co\0" +"nichinan.miyazaki.jp\0" +"onred.one\0" +"*.yokohama.jp\0aogashima.tokyo.jp\0" +"org.ge\0dni.us\0trade\0" +"org.gg\0radoy.no\0as.us\0" +"org.gh\0coop.tt\0" +"org.gi\0" +"nym.nz\0" +"marnardal.no\0" +"org.gl\0ascoli-piceno.it\0" +"org.gn\0" +"org.gp\0traniandriabarletta.it\0" +"bamble.no\0k12.nj.us\0" +"org.gr\0hospital\0" +"academia.bo\0" +"org.gt\0gojome.akita.jp\0marumori.miyagi.jp\0nishikatsura.yamanashi.jp\0" +"org.gu\0ingatlan.hu\0no-ip.org\0nym.pe\0" +"blogspot.com\0" +"org.gy\0evenes.no\0fh.se\0" +"coop.mv\0" +"org.hk\0coop.mw\0" +"org.hn\0nishiizu.shizuoka.jp\0" +"f.bg\0" +"ky.us\0pt.eu.org\0" +"cc.ny.us\0" +"org.ht\0nym.pt\0" +"org.hu\0" +"iserv.dev\0" +"townnews-staging.com\0" +"\xd0\xb8\xd0\xba\xd0\xbe\xd0\xbc.museum\0" +"xs4all.space\0" +"org.il\0nakagawa.fukuoka.jp\0" +"org.im\0" +"org.in\0" +"org.iq\0youth.museum\0" +"org.ir\0" +"org.is\0sauda.no\0" +"not.br\0niigata.niigata.jp\0" +"org.je\0finn\xc3\xb8y.no\0" +"modena.it\0k12.tr\0" +"alvdal.no\0\xc3\xb8ygarden.no\0" +"res.aero\0" +"gehirn.ne.jp\0" +"mosvik.no\0" +"org.jo\0zhitomir.ua\0nym.ro\0" +"kinder\0" +"\xe7\xb5\x84\xe7\xb9\x94.hk\0" +"lib.in.us\0" +"\xc3\xa5mli.no\0eaton.mi.us\0" +"yakage.okayama.jp\0" +"mil.ac\0org.kg\0jfk.museum\0posts-and-telecommunications.museum\0finance\0" +"mil.ae\0org.ki\0" +"hisayama.fukuoka.jp\0sekikawa.niigata.jp\0nissan\0" +"nym.sk\0" +"soeda.fukuoka.jp\0" +"org.km\0coop.py\0k12.vi\0" +"org.kn\0" +"bronnoy.no\0" +"mil.al\0org.kp\0" +"org.la\0" +"manaus.br\0org.lb\0" +"org.lc\0" +"mil.ba\0nissay\0nym.su\0" +"mil.ar\0" +"org.kw\0" +"nym.sx\0" +"org.ky\0" +"taka.hyogo.jp\0org.kz\0" +"org.lk\0muos\xc3\xa1t.no\0" +"lib.tx.us\0" +"mil.az\0" +"monza.it\0" +"org.ma\0" +"org.lr\0" +"mil.bo\0org.ls\0larsson.museum\0virtual.museum\0" +"org.me\0" +"mil.br\0org.lv\0" +"org.mg\0alt.za\0nym.tw\0" +"org.ly\0zt.ua\0" +"org.mk\0" +"\xe9\x9d\x92\xe6\xa3\xae.jp\0org.ml\0" +"mil.by\0" +"port.fr\0org.mn\0" +"org.mo\0" +"mil.cl\0watarai.mie.jp\0*.magentosite.cloud\0" +"coop.km\0org.na\0iamallama.com\0" +"mil.cn\0hamatonbetsu.hokkaido.jp\0" +"mil.co\0org.ms\0" +"kitagawa.miyazaki.jp\0org.mt\0" +"org.mu\0" +"org.mv\0" +"org.mw\0org.ng\0" +"takamori.kumamoto.jp\0org.mx\0" +"org.my\0org.ni\0loabat.no\0" +"org.mz\0" +"vestnes.no\0" +"bar.pro\0" +"org.nr\0" +"mil.do\0lib.ok.us\0" +"lillesand.no\0\xe4\xbf\xa1\xe6\x81\xaf\0" +"shingo.aomori.jp\0" +"mil.ec\0" +"losangeles.museum\0" +"org.nz\0" +"mil.eg\0rockart.museum\0" +"org.om\0" +"servecounterstrike.com\0" +"org.pa\0k12.ut.us\0taxi\0" +"ge.it\0" +"org.pe\0ddnsfree.com\0" +"yorii.saitama.jp\0org.pf\0" +"org.ph\0" +"and.museum\0center.museum\0" +"org.pk\0" +"seiro.niigata.jp\0org.pl\0augustow.pl\0" +"mil.fj\0osaka.jp\0org.pn\0" +"notteroy.no\0saltdal.no\0farmers\0" +"org.qa\0" +"org.pr\0" +"brussel.museum\0org.ps\0\xd8\xa7\xd9\x84\xd8\xac\xd8\xb2\xd8\xa7\xd8\xa6\xd8\xb1\0kindle\0from-mi.com\0is-an-artist.com\0" +"org.pt\0" +"cartoonart.museum\0" +"friuli-ve-giulia.it\0" +"mil.ge\0org.py\0" +"ogawa.ibaraki.jp\0" +"ubank\0" +"mil.gh\0tsushima.aichi.jp\0" +"airport.aero\0" +"grane.no\0" +"meiwa.mie.jp\0" +"mil.gt\0abira.hokkaido.jp\0higashikurume.tokyo.jp\0" +"culture.museum\0" +"kyonan.chiba.jp\0sakahogi.gifu.jp\0ueda.nagano.jp\0" +"skaun.no\0" +"joinville.br\0sanok.pl\0" +"org.ro\0dy.fi\0" +"org.sa\0" +"mil.hn\0kani.gifu.jp\0shimotsuke.tochigi.jp\0org.sb\0" +"org.rs\0org.sc\0lib.sd.us\0" +"shinagawa.tokyo.jp\0org.sd\0" +"ethnology.museum\0org.se\0lamborghini\0org.ru\0" +"ad.jp\0bayern\0" +"aerobatic.aero\0exchange.aero\0fineart.museum\0org.rw\0org.sg\0" +"mil.id\0shimoichi.nara.jp\0nanjo.okinawa.jp\0org.sh\0" +"koka.shiga.jp\0wiw.gov.pl\0dsmynas.net\0" +"mozilla-iot.org\0" +"org.sl\0" +"mein-vigor.de\0" +"pug.it\0shimokawa.hokkaido.jp\0org.sn\0" +"org.so\0" +"mil.in\0" +"hof.no\0org.ss\0" +"org.st\0" +"mil.iq\0cc.ak.us\0" +"org.sv\0" +"mo\xc3\xa5reke.no\0" +"saitama.jp\0mypsx.net\0" +"org.sy\0" +"usui.fukuoka.jp\0org.sz\0org.tj\0" +"\xe9\xa3\x9e\xe5\x88\xa9\xe6\xb5\xa6\0" +"org.tm\0" +"org.tn\0" +"music.museum\0org.to\0" +"taxi.br\0toho.fukuoka.jp\0inami.wakayama.jp\0" +"org.ua\0" +"cagliari.it\0org.tr\0kitchen\0" +"mil.jo\0recipes\0" +"kaneyama.fukushima.jp\0org.tt\0" +"loab\xc3\xa1t.no\0" +"takinoue.hokkaido.jp\0" +"indian.museum\0org.tw\0org.ug\0" +"guovdageaidnu.no\0" +"ato.br\0" +"mil.kg\0org.uk\0doomdns.com\0" +"takashima.shiga.jp\0" +"ia.us\0" +"valleeaoste.it\0" +"cc.la.us\0" +"*.statics.cloud\0" +"mil.km\0komatsu\0" +"piemonte.it\0" +"org.vc\0cloudns.org\0" +"\xe7\xa6\x8f\xe4\xba\x95.jp\0" +"democracia.bo\0uscountryestate.museum\0org.ve\0health-carereform.com\0" +"mil.kr\0" +"ven.it\0" +"org.uy\0org.vi\0" +"komaki.aichi.jp\0org.uz\0" +"law.za\0" +"mil.kz\0org.vn\0" +"kamimine.saga.jp\0" +"tamatsukuri.ibaraki.jp\0" +"ardal.no\0lib.wa.us\0" +"oishida.yamagata.jp\0" +"engineer.aero\0org.vu\0" +"minokamo.gifu.jp\0matsumoto.nagano.jp\0from-az.net\0" +"kazuno.akita.jp\0" +"kanie.aichi.jp\0shinshiro.aichi.jp\0kashima.ibaraki.jp\0mil.lv\0" +"modelling.aero\0mil.mg\0beiarn.no\0" +"carrd.co\0" +"tabayama.yamanashi.jp\0" +"tools\0" +"musashimurayama.tokyo.jp\0" +"org.ws\0" +"nuoro.it\0" +"kurogi.fukuoka.jp\0ozu.kumamoto.jp\0" +"auspost\0" +"mil.mv\0" +"ski.museum\0mil.ng\0lv.ua\0" +"mil.my\0mil.ni\0k12.ne.us\0" +"\xe5\xb3\xb6\xe6\xa0\xb9.jp\0shonai.fukuoka.jp\0mil.mz\0" +"filegear-jp.me\0" +"salon\0" +"mil.no\0" +"kannami.shizuoka.jp\0" +"farmers.museum\0fosnes.no\0" +"lecce.it\0" +"s.bg\0" +"f.se\0*.quipelements.com\0" +"amagasaki.hyogo.jp\0oi.kanagawa.jp\0mil.nz\0" +"niyodogawa.kochi.jp\0mamurogawa.yamagata.jp\0" +"org.za\0" +"moriyama.shiga.jp\0" +"station.museum\0" +"caa.li\0ui.nabu.casa\0" +"lier.no\0" +"eu.int\0valdaosta.it\0matsuzaki.shizuoka.jp\0higashimurayama.tokyo.jp\0" +"mil.pe\0" +"hb.cn\0" +"tanabe.wakayama.jp\0mil.ph\0" +"b\xc3\xb8.nordland.no\0org.zm\0" +"godaddy\0money\0balashov.su\0" +"misaki.osaka.jp\0mil.pl\0" +"khmelnytskyi.ua\0" +"kalisz.pl\0" +"ap-southeast-1.elasticbeanstalk.com\0" +"mil.qa\0kids.us\0" +"es.leg.br\0on-web.fr\0" +"org.zw\0cityeats\0space-to-rent.com\0" +"ina.saitama.jp\0" +"nayoro.hokkaido.jp\0" +"brussels.museum\0""4u.com\0" +"mil.py\0" +"\xe3\x81\xbf\xe3\x82\x93\xe3\x81\xaa\0" +"midtre-gauldal.no\0" +"read-books.org\0" +"kamijima.ehime.jp\0flt.cloud.muni.cz\0" +"s\xc3\xb8gne.no\0is-a-photographer.com\0" +"friuli-vegiulia.it\0miyako.fukuoka.jp\0" +"bofa\0dyndns.org\0" +"\xd0\xbe\xd1\x80\xd0\xb3.\xd1\x81\xd1\x80\xd0\xb1\0" +"kahoku.yamagata.jp\0" +"jpn.com\0knowsitall.info\0" +"toki.gifu.jp\0" +"trapani.it\0school\0" +"k12.as.us\0mil.ru\0" +"mil.rw\0from-ok.com\0ditchyourip.com\0" +"ginan.gifu.jp\0mil.sh\0" +"miners.museum\0" +"iobb.net\0" +"yamatotakada.nara.jp\0" +"in.na\0sucks\0viking\0" +"rome.it\0zamami.okinawa.jp\0mil.st\0" +"ms.it\0from-ny.net\0" +"cc.ct.us\0us.com\0" +"jaworzno.pl\0build\0" +"odda.no\0mil.sy\0" +"kagamiishi.fukushima.jp\0mil.tj\0" +"in.ni\0" +"aviation.museum\0mil.tm\0" +"mil.to\0k12.la.us\0" +"daiwa.hiroshima.jp\0qpon\0" +"\xe7\xbb\x84\xe7\xb9\x94.hk\0boats\0" +"mil.tr\0cloudfunctions.net\0" +"kunst.museum\0is-a-bruinsfan.org\0" +"bunkyo.tokyo.jp\0" +"hatoyama.saitama.jp\0" +"bajddar.no\0mil.tw\0" +"doshi.yamanashi.jp\0mil.tz\0" +"poltava.ua\0" +"ono.fukui.jp\0" +"sling\0" +"cc.nj.us\0" +"mil.vc\0beauty\0" +"ms.kr\0in.london\0" +"mil.ve\0from-ut.com\0" +"mil.uy\0" +"naka.ibaraki.jp\0pioneer\0*.platform.sh\0" +"st.no\0" +"gr.it\0ushiku.ibaraki.jp\0warabi.saitama.jp\0" +"gallery\0" +"osasco.br\0" +"*.oci.customer-oci.com\0" +"git-pages.rit.edu\0" +"lavangen.no\0engineering\0dnsdojo.com\0" +"gr.jp\0" +"hadsel.no\0col.ng\0" +"geek.nz\0test.tj\0" +"archi\0" +"bridgestone\0skype\0" +"denmark.museum\0" +"sandnes.no\0" +"cc.hi.us\0" +"takatsuki.shiga.jp\0" +"\xe6\x9c\xba\xe6\x9e\x84\0" +"creation.museum\0" +"realm.cz\0" +"filegear-de.me\0" +"balsan-suedtirol.it\0" +"trustee.museum\0" +"aq.it\0ba.it\0" +"susaki.kochi.jp\0tama.tokyo.jp\0" +"in.rs\0nis.za\0" +"trentino-sudtirol.it\0" +"izumisano.osaka.jp\0" +"gs.fm.no\0" +"iwaki.fukushima.jp\0nishigo.fukushima.jp\0" +"kyowa.akita.jp\0no-ip.net\0" +"nord-aurdal.no\0porsanger.no\0" +"tomi.nagano.jp\0" +"telekommunikation.museum\0mil.za\0" +"topology.museum\0analytics\0" +"bryne.no\0test.ru\0" +"bond\0" +"aeroport.fr\0fujikawa.shizuoka.jp\0in.th\0" +"ssl.origin.cdn77-secure.org\0" +"sobetsu.hokkaido.jp\0" +"mil.zm\0" +"imb.br\0poniatowa.pl\0" +"r\xc3\xb8st.no\0" +"in.ua\0" +"boavista.br\0" +"cust.disrec.thingdust.io\0" +"koriyama.fukushima.jp\0" +"gol.no\0mil.zw\0" +"lg.jp\0" +"futbol\0bounceme.net\0" +"nakayama.yamagata.jp\0" +"showa.fukushima.jp\0tsubetsu.hokkaido.jp\0kisosaki.mie.jp\0misugi.mie.jp\0taiwa.miyagi.jp\0computer\0" +"academy\0book\0" +"lib.nh.us\0" +"intel\0" +"dnsiskinky.com\0" +"isumi.chiba.jp\0" +"in.us\0" +"shibetsu.hokkaido.jp\0taito.tokyo.jp\0" +"cargo.aero\0" +"kawai.iwate.jp\0tateshina.nagano.jp\0" +"est-le-patron.com\0" +"gose.nara.jp\0gmina.pl\0" +"depot.museum\0" +"aichi.jp\0choyo.kumamoto.jp\0" +"from-mt.com\0from-nd.com\0" +"foundation\0" +"toscana.it\0" +"v\xc3\xa5ler.\xc3\xb8stfold.no\0" +"*.0emm.com\0" +"travel\0" +"aquarelle\0" +"naganohara.gunma.jp\0dunlop\0ricoh\0" +"matsue.shimane.jp\0" +"cc.vt.us\0" +"*.kawasaki.jp\0" +"nikaho.akita.jp\0tsk.tr\0" +"edu.ac\0" +"raid\0" +"edu.af\0jampa.br\0" +"balsan.it\0" +"toyoake.aichi.jp\0equipment\0" +"brussels\0" +"edu.al\0gokase.miyazaki.jp\0wlocl.pl\0" +"giske.no\0" +"suzaka.nagano.jp\0" +"edu.ba\0ask\xc3\xb8y.no\0" +"edu.ar\0edu.bb\0nc.tr\0" +"uji.kyoto.jp\0agano.niigata.jp\0tateyama.toyama.jp\0star\0" +"edu.au\0" +"mima.tokushima.jp\0" +"edu.bh\0hamada.shimane.jp\0" +"edu.bi\0berlev\xc3\xa5g.no\0etnedal.no\0" +"edu.az\0kasaoka.okayama.jp\0" +"cloudns.eu\0" +"misato.wakayama.jp\0" +"edu.bm\0b\xc3\xb8mlo.no\0chernivtsi.ua\0" +"edu.bn\0co.krd\0" +"edu.bo\0kustanai.ru\0" +"tos.it\0" +"edu.br\0" +"edu.bs\0heroy.nordland.no\0vadso.no\0s.se\0ms.us\0nc.us\0nid.io\0" +"edu.bt\0firenze.it\0" +"qcx.io\0" +"edu.ci\0elvendrell.museum\0" +"edu.bz\0" +"emb.kw\0lib.az.us\0horse\0" +"exeter.museum\0" +"edu.cn\0" +"edu.co\0mex.com\0kustanai.su\0" +"rexroth\0" +"edu.cu\0" +"edu.cw\0" +"koshimizu.hokkaido.jp\0" +"edu.dm\0cincinnati.museum\0wy.us\0" +"bialowieza.pl\0" +"edu.do\0" +"jus.br\0" +"is-a-democrat.com\0" +"edu.ec\0" +"gosen.niigata.jp\0" +"edu.ee\0" +"edu.eg\0" +"edu.dz\0" +"averoy.no\0zaporizhzhia.ua\0" +"krasnik.pl\0" +"miyama.fukuoka.jp\0wajima.ishikawa.jp\0" +"film.museum\0" +"edu.es\0dynalias.com\0scrysec.com\0" +"edu.et\0cloudns.in\0" +"lea\xc5\x8bgaviika.no\0" +"cz.it\0iruma.saitama.jp\0toyota.yamaguchi.jp\0" +"bbs.tr\0" +"bplaced.com\0" +"shell\0" +"bozen-suedtirol.it\0takayama.gifu.jp\0" +"hurdal.no\0" +"ikawa.akita.jp\0" +"kiwi\0" +"accident-investigation.aero\0edu.ge\0oceanographique.museum\0cc.tx.us\0" +"jor.br\0mito.ibaraki.jp\0cloudapps.digital\0" +"edu.gh\0yamato.kanagawa.jp\0" +"edu.gi\0cloudns.cc\0" +"md.ci\0" +"edu.gl\0" +"bjugn.no\0orange\0" +"edu.gn\0" +"hobby-site.com\0" +"edu.gp\0" +"edu.gr\0dupont\0" +"edu.gt\0swinoujscie.pl\0" +"edu.gu\0fetsund.no\0" +"umbria.it\0sagae.yamagata.jp\0" +"lg.ua\0" +"edu.gy\0saintlouis.museum\0oygarden.no\0volyn.ua\0" +"edu.hk\0" +"esp.br\0molise.it\0" +"edu.hn\0" +"shirahama.wakayama.jp\0" +"gs.bu.no\0" +"edu.ht\0kyotango.kyoto.jp\0" +"lib.pa.us\0" +"d.bg\0" +"gc.ca\0chicago.museum\0" +"in-vpn.de\0" +"edu.in\0polkowice.pl\0" +"sciences.museum\0filegear-sg.me\0" +"edu.iq\0discourse.team\0" +"barreau.bj\0" +"edu.is\0" +"edu.it\0" +"is-into-cars.com\0" +"\xe4\xbc\x81\xe4\xb8\x9a\0" +"vindafjord.no\0" +"urakawa.hokkaido.jp\0" +"edu.jo\0roma.museum\0\xc3\xb8rskog.no\0" +"sld.do\0" +"mobi.gp\0hyogo.jp\0" +"edu.kg\0is-a-hunter.com\0" +"edu.ki\0applinzi.com\0" +"kawanishi.yamagata.jp\0" +"kutchan.hokkaido.jp\0kawanishi.hyogo.jp\0" +"edu.km\0giessen.museum\0" +"edu.kn\0" +"ab.ca\0" +"natal.br\0edu.kp\0" +"edu.la\0" +"edu.lb\0" +"edu.lc\0" +"goiania.br\0macerata.it\0" +"edu.kw\0pl.ua\0" +"honjyo.akita.jp\0hashikami.aomori.jp\0\xd0\xba\xd0\xb0\xd1\x82\xd0\xbe\xd0\xbb\xd0\xb8\xd0\xba\0" +"edu.ky\0" +"edu.kz\0" +"edu.lk\0rana.no\0" +"bn.it\0kyowa.hokkaido.jp\0" +"in-dsl.org\0" +"kanan.osaka.jp\0" +"edu.lr\0" +"edu.ls\0" +"edu.me\0fjaler.no\0" +"nantan.kyoto.jp\0satosho.okayama.jp\0edu.lv\0" +"edu.mg\0" +"\xe5\x85\xb5\xe5\xba\xab.jp\0" +"edu.ly\0" +"fund\0" +"edu.mk\0" +"edu.ml\0" +"kawanabe.kagoshima.jp\0edu.mn\0sport\0" +"nsw.au\0edu.mo\0" +"design.museum\0lib.dc.us\0" +"edu.ms\0schokoladen.museum\0s3-eu-west-3.amazonaws.com\0" +"mutsu.aomori.jp\0edu.mt\0" +"jx.cn\0lt.it\0edu.mv\0mydissent.net\0" +"safety.aero\0edu.mw\0edu.ng\0" +"toyako.hokkaido.jp\0edu.mx\0kepno.pl\0adult\0" +"edu.my\0edu.ni\0\xe5\xae\xb6\xe9\x9b\xbb\0ua.rs\0" +"higashiosaka.osaka.jp\0edu.mz\0gent\0" +"skygearapp.com\0" +"fermo.it\0" +"exnet.su\0" +"hornindal.no\0" +"umb.it\0" +"edu.nr\0rnu.tn\0hasura.app\0" +"workinggroup.aero\0" +"kitanakagusuku.okinawa.jp\0" +"loyalist.museum\0" +"h\xc3\xa1""bmer.no\0edu.om\0from-nv.com\0saves-the-whales.com\0" +"bandai.fukushima.jp\0kutno.pl\0" +"folkebibl.no\0scapp.io\0" +"habikino.osaka.jp\0" +"edu.pa\0mytuleap.com\0" +"edu.pe\0" +"ishikari.hokkaido.jp\0edu.pf\0" +"molde.no\0study\0\xe9\x80\x9a\xe8\xb2\xa9\0" +"okawa.fukuoka.jp\0niki.hokkaido.jp\0edu.ph\0" +"edu.pk\0" +"sakai.ibaraki.jp\0edu.pl\0" +"edu.pn\0" +"bel.tr\0" +"versailles.museum\0edu.qa\0vologda.su\0" +"edu.pr\0" +"casadelamoneda.museum\0rollag.no\0edu.ps\0" +"edu.pt\0" +"castle.museum\0" +"lamer\0" +"doesntexist.org\0" +"freesite.host\0" +"edu.py\0is-into-anime.com\0" +"trentin-s\xc3\xbc""d-tirol.it\0" +"pl.eu.org\0" +"news.hu\0" +"syncloud.it\0" +"team\0" +"mashiko.tochigi.jp\0clan.rip\0" +"scienceandhistory.museum\0hjartdal.no\0lib.il.us\0samsung\0" +"travel.pl\0" +"wedding\0lebtimnetz.de\0" +"matsuno.ehime.jp\0" +"hamaroy.no\0" +"americanfamily\0" +"cloudns.us\0" +"rel.ht\0sakyo.kyoto.jp\0" +"collection.museum\0" +"oppegard.no\0audible\0" +"ishikawa.fukushima.jp\0" +"ltd.co.im\0dyr\xc3\xb8y.no\0" +"edu.sa\0" +"edu.sb\0" +"porsangu.no\0edu.rs\0edu.sc\0est-a-la-maison.com\0" +"edu.sd\0schokokeks.net\0" +"edu.ru\0" +"sampa.br\0" +"edu.sg\0" +"forlicesena.it\0podlasie.pl\0" +"psi.br\0tech\0" +"no.com\0" +"edu.sl\0" +"edu.sn\0" +"edu.so\0" +"pony.club\0" +"google\0" +"cloudns.club\0" +"university.museum\0edu.ss\0s3-us-east-2.amazonaws.com\0" +"murayama.yamagata.jp\0edu.st\0" +"toyo.kochi.jp\0edu.sv\0" +"newspaper.museum\0" +"edu.sy\0" +"iglesiascarbonia.it\0edu.tj\0" +"heimatunduhren.museum\0edu.tm\0maserati\0" +"edu.to\0" +"edu.ua\0" +"edu.tr\0" +"edu.tt\0" +"canada.museum\0utsira.no\0" +"vall\xc3\xa9""e-d-aoste.it\0" +"rakkestad.no\0edu.tw\0cafe\0apigee.io\0" +"phone\0" +"open\0" +"nishio.aichi.jp\0" +"saogonca.br\0lucania.it\0kishiwada.osaka.jp\0" +"lib.mi.us\0toray\0" +"yokawa.hyogo.jp\0" +"edu.vc\0bitballoon.com\0" +"sld.pa\0edu.ve\0" +"publ.pt\0tkmaxx\0" +"salvadordali.museum\0edu.uy\0casino\0gr.com\0" +"travel.tt\0" +"sosa.chiba.jp\0" +"izumi.osaka.jp\0edu.vn\0" +"bozen.it\0" +"murmansk.su\0" +"katano.osaka.jp\0" +"media.aero\0" +"edu.vu\0" +"is-a-guru.com\0" +"shimane.shimane.jp\0discourse.group\0" +"surrey.museum\0edu.ws\0" +"torino.museum\0" +"meiwa.gunma.jp\0" +"\xd8\xb9\xd8\xb1\xd8\xa7\xd9\x82\0" +"field.museum\0uwu.ai\0" +"lt.ua\0" +"bauern.museum\0k12.ms.us\0k12.nc.us\0" +"toyooka.hyogo.jp\0" +"al.eu.org\0" +"kr.com\0" +"profesional.bo\0lib.pr.us\0edu.za\0" +"rel.pl\0" +"q.bg\0logoip.de\0" +"d.se\0md.us\0hepforge.org\0" +"olkusz.pl\0" +"kerryhotels\0\xe3\x82\xa2\xe3\x83\x9e\xe3\x82\xbe\xe3\x83\xb3\0" +"moma.museum\0lib.ak.us\0edu.zm\0" +"antiques.museum\0granvin.no\0s3.us-east-2.amazonaws.com\0game-server.cc\0service.gov.uk\0" +"rawa-maz.pl\0" +"my-firewall.org\0applicationcloud.io\0ybo.trade\0" +"protection\0" +"agrigento.it\0" +"kr\xc3\xb8""dsherad.no\0" +"call\0crafting.xyz\0" +"enonic.io\0" +"\xe5\xb2\x90\xe9\x98\x9c.jp\0" +"hotels\0" +"kuki.saitama.jp\0" +"photo\0" +"miharu.fukushima.jp\0pcloud.host\0gliwice.pl\0" +"arq.br\0kita.kyoto.jp\0" +"owani.aomori.jp\0" +"sr.it\0yuasa.wakayama.jp\0" +"sorfold.no\0" +"n4t.co\0" +"cuiaba.br\0trentinosued-tirol.it\0" +"camp\0bplaced.net\0" +"omachi.saga.jp\0" +"*.uberspace.de\0" +"ikata.ehime.jp\0" +"communications.museum\0snoasa.no\0media\0" +"hemne.no\0" +"kazimierz-dolny.pl\0" +"cloudns.pw\0familyds.com\0" +"beppu.oita.jp\0" +"birdart.museum\0" +"higashitsuno.kochi.jp\0aisho.shiga.jp\0hamamatsu.shizuoka.jp\0" +"dlugoleka.pl\0" +"est-a-la-masion.com\0" +"ikoma.nara.jp\0auto.pl\0" +"customer.enonic.io\0" +"a\xc3\xa9roport.ci\0embroidery.museum\0" +"nextdirect\0" +"karikatur.museum\0" +"urausu.hokkaido.jp\0" +"kppsp.gov.pl\0" +"na.it\0" +"alibaba\0" +"ng.city\0" +"\xe7\xa6\x8f\xe5\xb2\xa1.jp\0yonaguni.okinawa.jp\0" +"gausdal.no\0" +"kh.ua\0poivron.org\0" +"atsuma.hokkaido.jp\0nose.osaka.jp\0" +"seihi.nagasaki.jp\0" +"steigen.no\0hu.com\0awsmppl.com\0" +"hoyanger.no\0" +"tur.ar\0calabria.it\0takino.hyogo.jp\0" +"s3-website-us-west-1.amazonaws.com\0" +"zp.gov.pl\0mobi.tt\0" +"tsuru.yamanashi.jp\0\xd8\xa7\xd9\x84\xd9\x85\xd8\xba\xd8\xb1\xd8\xa8\0" +"cc.nh.us\0" +"yamagata.gifu.jp\0" +"nieruchomosci.pl\0mobi.tz\0jaguar\0" +"tur.br\0hakui.ishikawa.jp\0" +"care\0" +"krakow.pl\0" +"oz.au\0oregon.museum\0" +"\xd0\xbe\xd0\xbd\xd0\xbb\xd0\xb0\xd0\xb9\xd0\xbd\0" +"nore-og-uvdal.no\0chtr.k12.ma.us\0internet-dns.de\0" +"\xe5\x8c\x97\xe6\xb5\xb7\xe9\x81\x93.jp\0murakami.niigata.jp\0iwade.wakayama.jp\0" +"googleapis.com\0" +"casa\0isa-hockeynut.com\0" +"\xe6\x95\x99\xe8\x82\xb2.hk\0cars\0yokohama\0" +"case\0" +"surf\0" +"lpusercontent.com\0" +"friuli-vgiulia.it\0cash\0" +"gifu.jp\0" +"lib.ia.us\0" +"dev.static.land\0" +"gleeze.com\0" +"*.kobe.jp\0" +"barsy.menu\0" +"sicily.it\0oamishirasato.chiba.jp\0sumida.tokyo.jp\0" +"gemological.museum\0\xc3\xa1laheadju.no\0" +"benevento.it\0obihiro.hokkaido.jp\0" +"servemp3.com\0" +"\xe5\xb2\xa1\xe5\xb1\xb1.jp\0mobara.chiba.jp\0atm.pl\0" +"ao.it\0" +"dattolocal.net\0" +"idf.il\0" +"bulsan-suedtirol.it\0" +"cheltenham.museum\0\xc3\xa5lg\xc3\xa5rd.no\0" +"\xe5\xa5\x88\xe8\x89\xaf.jp\0asakawa.fukushima.jp\0" +"ggee\0" +"noticias.bo\0" +"lombardy.it\0moseushi.hokkaido.jp\0wolomin.pl\0" +"hikimi.shimane.jp\0" +"events\0" +"svizzera.museum\0is-very-bad.org\0" +"nysa.pl\0pictet\0" +"dolls.museum\0mobi.na\0" +"le.it\0lixil\0\xd0\xbc\xd0\xbe\xd1\x81\xd0\xba\xd0\xb2\xd0\xb0\0" +"alaheadju.no\0" +"shirosato.ibaraki.jp\0" +"mobi.ng\0" +"sp.gov.br\0" +"lebork.pl\0" +"teva\0" +"kawakita.ishikawa.jp\0" +"experts-comptables.fr\0" +"glass.museum\0" +"skjerv\xc3\xb8y.no\0" +"storage\0fedorapeople.org\0js.org\0" +"lib.nj.us\0syno-ds.de\0" +"9.bg\0" +"itakura.gunma.jp\0imari.saga.jp\0" +"lebesby.no\0il.us\0" +"page\0" +"channelsdvr.net\0" +"correios-e-telecomunica\xc3\xa7\xc3\xb5""es.museum\0kherson.ua\0" +"sch.ae\0philately.museum\0yorkshire.museum\0furniture\0" +"myds.me\0" +"kouyama.kagoshima.jp\0nat.tn\0" +"tana.no\0no.eu.org\0navoi.su\0" +"yuki.ibaraki.jp\0agrinet.tn\0norton\0" +"mitane.akita.jp\0m\xc4\x81ori.nz\0" +"ikano\0" +"tara.saga.jp\0gotdns.ch\0" +"fairwinds\0" +"ck.ua\0" +"\xe5\x8d\x83\xe8\x91\x89.jp\0" +"takamori.nagano.jp\0tenri.nara.jp\0in-dsl.net\0" +"kobierzyce.pl\0" +"ebetsu.hokkaido.jp\0muroran.hokkaido.jp\0\xe6\x97\xb6\xe5\xb0\x9a\0" +"oyer.no\0" +"airline.aero\0" +"cal.it\0" +"military.museum\0" +"fukui.fukui.jp\0" +"bulsan.it\0so.gov.pl\0" +"kyotamba.kyoto.jp\0sakuho.nagano.jp\0nanto.toyama.jp\0" +"boutique\0" +"higashiura.aichi.jp\0" +"cloudns.info\0" +"udine.it\0asaminami.hiroshima.jp\0" +"gifu.gifu.jp\0" +"globo\0""12hp.de\0" +"aosta.it\0" +"mobi\0" +"suita.osaka.jp\0" +"milano.it\0" +"mobi.ke\0naumburg.museum\0\xe6\xb8\xb8\xe6\x88\x8f\0" +"puglia.it\0" +"meloy.no\0" +"bio.br\0" +"duck\0" +"shonai.yamagata.jp\0adobeaemcloud.net\0" +"\xe7\xa5\x9e\xe5\xa5\x88\xe5\xb7\x9d.jp\0" +"\xe5\xa4\xa9\xe4\xb8\xbb\xe6\x95\x99\0" +"marugame.kagawa.jp\0" +"dominic.ua\0nexus\0" +"sumita.iwate.jp\0" +"nyc.museum\0" +"shimofusa.chiba.jp\0" +"cipriani\0moda\0" +"maori.nz\0" +"mulhouse.museum\0cpa.pro\0guide\0" +"owariasahi.aichi.jp\0""12hp.at\0" +"fukusaki.hyogo.jp\0asahi.ibaraki.jp\0" +"abiko.chiba.jp\0naha.okinawa.jp\0" +"asn.au\0xenapponazure.com\0" +"matsushige.tokushima.jp\0" +"coupon\0" +"from-pa.com\0" +"otake.hiroshima.jp\0" +"recreation.aero\0" +"tochigi.tochigi.jp\0dyndns.tv\0" +"is-a-chef.org\0" +"kamiichi.toyama.jp\0""12hp.ch\0" +"sc.cn\0to.it\0" +"homebuilt.aero\0rendalen.no\0" +"artcenter.museum\0convent.museum\0nz.eu.org\0" +"chieti.it\0" +"holiday\0" +"asso.fr\0" +"tas.au\0" +"okagaki.fukuoka.jp\0" +"gamagori.aichi.jp\0" +"togura.nagano.jp\0" +"uchiko.ehime.jp\0" +"tsuga.tochigi.jp\0" +"asso.gp\0kawajima.saitama.jp\0" +"mb.ca\0enterprisecloud.nu\0" +"karuizawa.nagano.jp\0wakasa.tottori.jp\0" +"nationalfirearms.museum\0" +"nakasatsunai.hokkaido.jp\0utashinai.hokkaido.jp\0" +"sch.id\0" +"jevnaker.no\0kerryproperties\0" +"kamiizumi.saitama.jp\0kai.yamanashi.jp\0" +"tromsa.no\0serveexchange.com\0" +"izumi.kagoshima.jp\0nobeoka.miyazaki.jp\0football\0" +"dyndns.ws\0" +"\xe0\xa4\x95\xe0\xa5\x89\xe0\xa4\xae\0\xe7\xa7\xbb\xe5\x8a\xa8\0" +"wellbeingzone.co.uk\0" +"asso.ht\0kunimi.fukushima.jp\0amakusa.kumamoto.jp\0bungoono.oita.jp\0" +"youtube\0" +"sch.ir\0" +"axis.museum\0sigdal.no\0" +"tado.mie.jp\0" +"repbody.aero\0siljan.no\0cable-modem.org\0" +"education\0" +"r\xc3\xb8mskog.no\0unusualperson.com\0" +"sch.jo\0" +"roan.no\0" +"imperia.it\0" +"b.bg\0webhop.me\0" +"endofinternet.net\0" +"cbre\0" +"asso.bj\0" +"newholland\0weatherchannel\0" +"paris.museum\0" +"homeunix.net\0" +"barsy.me\0" +"b.br\0obu.aichi.jp\0yamanobe.yamagata.jp\0" +"fnd.br\0\xe6\xa0\x83\xe6\x9c\xa8.jp\0" +"oumu.hokkaido.jp\0" +"asso.ci\0is-a-chef.com\0" +"taiki.mie.jp\0" +"servehalflife.com\0" +"hichiso.gifu.jp\0" +"lesja.no\0freeddns.us\0" +"ulsan.kr\0" +"sch.lk\0" +"avellino.it\0" +"pars\0" +"campidano-medio.it\0munakata.fukuoka.jp\0" +"moriyoshi.akita.jp\0kashiba.nara.jp\0" +"publishproxy.com\0" +"sr.gov.pl\0" +"sch.ly\0house\0suzuki\0servehumour.com\0" +"cc.id.us\0" +"chirurgiens-dentistes.fr\0budapest\0" +"cya.gg\0" +"jewish.museum\0somna.no\0" +"miyota.nagano.jp\0fedex\0yandex\0" +"asso.dz\0iwakuni.yamaguchi.jp\0" +"sch.ng\0royrvik.no\0dvrdns.org\0" +"bl.it\0" +"askim.no\0penza.su\0" +"sc.ke\0is-a-student.com\0" +"hamura.tokyo.jp\0" +"total\0" +"kharkov.ua\0" +"lcube-server.de\0" +"hirono.iwate.jp\0" +"s3-website.eu-west-3.amazonaws.com\0" +"sc.kr\0" +"*.kitakyushu.jp\0\xe8\xaf\xba\xe5\x9f\xba\xe4\xba\x9a\0" +"zp.ua\0lib.de.us\0" +"agriculture.museum\0" +"vegarshei.no\0" +"mb.it\0" +"lahppi.no\0isa.us\0" +"kawahara.tottori.jp\0" +"trentino-s\xc3\xbc""d-tirol.it\0nago.okinawa.jp\0asaka.saitama.jp\0" +"komatsu.ishikawa.jp\0kolobrzeg.pl\0" +"economia.bo\0d\xc3\xb8nna.no\0s3-website.ca-central-1.amazonaws.com\0" +"sc.ls\0" +"hm.no\0" +"far.br\0yamada.iwate.jp\0rns.tn\0" +"sch.qa\0swiss\0" +"komae.tokyo.jp\0" +"portlligat.museum\0boldlygoingnowhere.org\0ddnss.org\0synology.me\0" +"yonago.tottori.jp\0asn.lv\0" +"lib.mo.us\0" +"trentinos\xc3\xbc""d-tirol.it\0" +"saga.jp\0" +"kanagawa.jp\0shiraoi.hokkaido.jp\0seven\0" +"koeln.museum\0photography.museum\0cc.mi.us\0" +"filatelia.museum\0lodingen.no\0" +"yamato.kumamoto.jp\0" +"voss.no\0" +"kyotanabe.kyoto.jp\0" +"rio.br\0pisa.it\0akune.kagoshima.jp\0" +"exchange\0" +"trentino-alto-adige.it\0" +"sor-odal.no\0dvag\0" +"ube.yamaguchi.jp\0" +"bss.design\0" +"sandefjord.no\0" +"sch.sa\0ownprovider.com\0" +"read\0" +"sk\xc3\xa5nland.no\0" +"ug.gov.pl\0" +"lugansk.ua\0" +"dnepropetrovsk.ua\0" +"veterinaire.km\0kautokeino.no\0" +"sch.so\0" +"shari.hokkaido.jp\0" +"engerdal.no\0" +"omasvuotna.no\0barsy.uk\0" +"taketomi.okinawa.jp\0nishinoshima.shimane.jp\0" +"mad.museum\0aaa\0" +"s3.dualstack.ap-northeast-2.amazonaws.com\0likes-pie.com\0" +"\xed\x95\x9c\xea\xb5\xad\0" +"\xe5\xb1\xb1\xe5\xbd\xa2.jp\0toshima.tokyo.jp\0" +}; + +static const quint16 tldChunkCount = 2; +static const quint32 tldChunks[] = {65532, 103868}; + +QT_END_NAMESPACE + +#endif // QURLTLD_P_H diff --git a/src/network/kernel/qurltlds_p.h.INFO b/src/network/kernel/qurltlds_p.h.INFO new file mode 100644 index 0000000000..33ccd458bf --- /dev/null +++ b/src/network/kernel/qurltlds_p.h.INFO @@ -0,0 +1,14 @@ +The file qurltlds_p.h is generated from the Public Suffix +List (see [1] and [2]), by the program residing at +util/corelib/qurl-generateTLDs in the Qt source tree. + +That program generates a character array and an index array from the +list to provide fast lookups of elements within C++. + +Those arrays in qurltlds_p.h are derived from the Public +Suffix List ([2]), which was originally provided by +Jo Hermans <jo.hermans@gmail.com>. + +---- +[1] list: http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1 +[2] homepage: http://publicsuffix.org/ diff --git a/src/network/network.pro b/src/network/network.pro index d8453e879c..7bd54fd12e 100644 --- a/src/network/network.pro +++ b/src/network/network.pro @@ -15,29 +15,15 @@ msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x64000000 QMAKE_DOCS = $$PWD/doc/qtnetwork.qdocconf include(access/access.pri) -include(bearer/bearer.pri) include(kernel/kernel.pri) include(socket/socket.pri) include(ssl/ssl.pri) QMAKE_LIBS += $$QMAKE_LIBS_NETWORK -qtConfig(bearermanagement) { - ANDROID_BUNDLED_JAR_DEPENDENCIES = \ - jar/QtAndroidBearer.jar - ANDROID_LIB_DEPENDENCIES = \ - plugins/bearer/libplugins_bearer_qandroidbearer.so - MODULE_PLUGIN_TYPES = \ - bearer - ANDROID_PERMISSIONS += \ - android.permission.ACCESS_NETWORK_STATE -} - MODULE_WINRT_CAPABILITIES = \ internetClient \ internetClientServer \ privateNetworkClientServer -MODULE_PLUGIN_TYPES = \ - bearer load(qt_module) diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index fa85f48ad5..bbaaf5e609 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -475,10 +475,6 @@ #include "qabstractsocket_p.h" #include "private/qhostinfo_p.h" -#if QT_CONFIG(bearermanagement) // ### Qt6: Remove section -#include "private/qnetworksession_p.h" -#endif -#include "private/qnetworkconfiguration_p.h" // ### Qt6: Remove include #include <qabstracteventdispatcher.h> #include <qhostaddress.h> @@ -514,6 +510,8 @@ QT_BEGIN_NAMESPACE +static const int DefaultConnectTimeout = 30000; + #if defined QABSTRACTSOCKET_DEBUG QT_BEGIN_INCLUDE_NAMESPACE #include <qstring.h> @@ -657,10 +655,6 @@ bool QAbstractSocketPrivate::initSocketLayer(QAbstractSocket::NetworkLayerProtoc QAbstractSocket::tr("Operation on socket is not supported")); return false; } -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - //copy network session down to the socket engine (if it has been set) - socketEngine->setProperty("_q_networksession", q->property("_q_networksession")); -#endif if (!socketEngine->initialize(q->socketType(), protocol)) { #if defined (QABSTRACTSOCKET_DEBUG) qDebug("QAbstractSocketPrivate::initSocketLayer(%s, %s) failed (%s)", @@ -1159,14 +1153,7 @@ void QAbstractSocketPrivate::_q_connectToNextAddress() q, SLOT(_q_abortConnectionAttempt()), Qt::DirectConnection); } - int connectTimeout = QNetworkConfigurationPrivate::DefaultTimeout; -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - QSharedPointer<QNetworkSession> networkSession = qvariant_cast< QSharedPointer<QNetworkSession> >(q->property("_q_networksession")); - if (networkSession) { - QNetworkConfiguration networkConfiguration = networkSession->configuration(); - connectTimeout = networkConfiguration.connectTimeout(); - } -#endif + int connectTimeout = DefaultConnectTimeout; connectTimer->start(connectTimeout); } @@ -1953,10 +1940,6 @@ bool QAbstractSocket::setSocketDescriptor(qintptr socketDescriptor, SocketState d->setError(UnsupportedSocketOperationError, tr("Operation on socket is not supported")); return false; } -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - //copy network session down to the socket engine (if it has been set) - d->socketEngine->setProperty("_q_networksession", property("_q_networksession")); -#endif bool result = d->socketEngine->initialize(socketDescriptor, socketState); if (!result) { d->setError(d->socketEngine->error(), d->socketEngine->errorString()); @@ -2146,10 +2129,6 @@ bool QAbstractSocket::waitForConnected(int msecs) QElapsedTimer stopWatch; stopWatch.start(); -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - QSharedPointer<QNetworkSession> networkSession = qvariant_cast< QSharedPointer<QNetworkSession> >(property("_q_networksession")); -#endif - if (d->state == HostLookupState) { #if defined (QABSTRACTSOCKET_DEBUG) qDebug("QAbstractSocket::waitForConnected(%i) doing host name lookup", msecs); @@ -2168,13 +2147,7 @@ bool QAbstractSocket::waitForConnected(int msecs) if (state() == UnconnectedState) return false; // connect not im progress anymore! - int connectTimeout = QNetworkConfigurationPrivate::DefaultTimeout; -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - if (networkSession) { - QNetworkConfiguration networkConfiguration = networkSession->configuration(); - connectTimeout = networkConfiguration.connectTimeout(); - } -#endif + int connectTimeout = DefaultConnectTimeout; bool timedOut = true; #if defined (QABSTRACTSOCKET_DEBUG) int attempt = 1; diff --git a/src/network/socket/qabstractsocketengine.cpp b/src/network/socket/qabstractsocketengine.cpp index 54c7452c66..44139ff81d 100644 --- a/src/network/socket/qabstractsocketengine.cpp +++ b/src/network/socket/qabstractsocketengine.cpp @@ -274,3 +274,5 @@ int QAbstractSocketEngine::outboundStreamCount() const } QT_END_NAMESPACE + +#include "moc_qabstractsocketengine_p.cpp" diff --git a/src/network/socket/qhttpsocketengine.cpp b/src/network/socket/qhttpsocketengine.cpp index 9de9b284c1..a23e2d3071 100644 --- a/src/network/socket/qhttpsocketengine.cpp +++ b/src/network/socket/qhttpsocketengine.cpp @@ -72,9 +72,6 @@ bool QHttpSocketEngine::initialize(QAbstractSocket::SocketType type, QAbstractSo setSocketType(type); d->socket = new QTcpSocket(this); d->reply = new QHttpNetworkReply(QUrl(), this); -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - d->socket->setProperty("_q_networkSession", property("_q_networkSession")); -#endif // Explicitly disable proxying on the proxy socket itself to avoid // unwanted recursion. @@ -866,3 +863,5 @@ QAbstractSocketEngine *QHttpSocketEngineHandler::createSocketEngine(qintptr, QOb QT_END_NAMESPACE #endif // !QT_NO_NETWORKPROXY + +#include "moc_qhttpsocketengine_p.cpp" diff --git a/src/network/socket/qlocalserver_p.h b/src/network/socket/qlocalserver_p.h index 92616e59ce..f331a3f10d 100644 --- a/src/network/socket/qlocalserver_p.h +++ b/src/network/socket/qlocalserver_p.h @@ -99,15 +99,18 @@ public: QMap<quintptr, QTcpSocket*> socketMap; #elif defined(Q_OS_WIN) struct Listener { - HANDLE handle; + Listener() = default; + HANDLE handle = nullptr; OVERLAPPED overlapped; - bool connected; + bool connected = false; + private: + Q_DISABLE_COPY(Listener) }; void setError(const QString &function); bool addListener(); - QList<Listener> listeners; + std::vector<std::unique_ptr<Listener>> listeners; HANDLE eventHandle; QWinEventNotifier *connectionEventNotifier; #else diff --git a/src/network/socket/qlocalserver_win.cpp b/src/network/socket/qlocalserver_win.cpp index 2d71a7e730..6d92ebe93a 100644 --- a/src/network/socket/qlocalserver_win.cpp +++ b/src/network/socket/qlocalserver_win.cpp @@ -62,8 +62,8 @@ bool QLocalServerPrivate::addListener() { // The object must not change its address once the // contained OVERLAPPED struct is passed to Windows. - listeners << Listener(); - Listener &listener = listeners.last(); + listeners.push_back(std::make_unique<Listener>()); + auto &listener = listeners.back(); SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(SECURITY_ATTRIBUTES); @@ -175,7 +175,7 @@ bool QLocalServerPrivate::addListener() sa.lpSecurityDescriptor = pSD.data(); } - listener.handle = CreateNamedPipe( + listener->handle = CreateNamedPipe( reinterpret_cast<const wchar_t *>(fullServerName.utf16()), // pipe name PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, // read/write access PIPE_TYPE_BYTE | // byte type pipe @@ -187,32 +187,32 @@ bool QLocalServerPrivate::addListener() 3000, // client time-out &sa); - if (listener.handle == INVALID_HANDLE_VALUE) { + if (listener->handle == INVALID_HANDLE_VALUE) { setError(QLatin1String("QLocalServerPrivate::addListener")); - listeners.removeLast(); + listeners.pop_back(); return false; } if (worldSID) FreeSid(worldSID); - memset(&listener.overlapped, 0, sizeof(listener.overlapped)); - listener.overlapped.hEvent = eventHandle; + memset(&listener->overlapped, 0, sizeof(OVERLAPPED)); + listener->overlapped.hEvent = eventHandle; // Beware! ConnectNamedPipe will reset the eventHandle to non-signaled. // Callers of addListener must check all listeners for connections. - if (!ConnectNamedPipe(listener.handle, &listener.overlapped)) { + if (!ConnectNamedPipe(listener->handle, &listener->overlapped)) { switch (GetLastError()) { case ERROR_IO_PENDING: - listener.connected = false; + listener->connected = false; break; case ERROR_PIPE_CONNECTED: - listener.connected = true; + listener->connected = true; break; default: - CloseHandle(listener.handle); + CloseHandle(listener->handle); setError(QLatin1String("QLocalServerPrivate::addListener")); - listeners.removeLast(); + listeners.pop_back(); return false; } } else { @@ -284,12 +284,12 @@ void QLocalServerPrivate::_q_onNewConnection() // Testing shows that there is indeed absolutely no guarantee which listener gets // a client connection first, so there is no way around polling all of them. - for (int i = 0; i < listeners.size(); ) { - HANDLE handle = listeners[i].handle; - if (listeners[i].connected - || GetOverlappedResult(handle, &listeners[i].overlapped, &dummy, FALSE)) + for (size_t i = 0; i < listeners.size(); ) { + HANDLE handle = listeners[i]->handle; + if (listeners[i]->connected + || GetOverlappedResult(handle, &listeners[i]->overlapped, &dummy, FALSE)) { - listeners.removeAt(i); + listeners.erase(listeners.begin() + i); addListener(); @@ -319,8 +319,8 @@ void QLocalServerPrivate::closeServer() connectionEventNotifier->deleteLater(); connectionEventNotifier = 0; CloseHandle(eventHandle); - for (int i = 0; i < listeners.size(); ++i) - CloseHandle(listeners[i].handle); + for (size_t i = 0; i < listeners.size(); ++i) + CloseHandle(listeners[i]->handle); listeners.clear(); } diff --git a/src/network/socket/qnativesocketengine.cpp b/src/network/socket/qnativesocketengine.cpp index 31628846dc..ad625b758e 100644 --- a/src/network/socket/qnativesocketengine.cpp +++ b/src/network/socket/qnativesocketengine.cpp @@ -1382,3 +1382,5 @@ void QNativeSocketEngine::setExceptionNotificationEnabled(bool enable) } QT_END_NAMESPACE + +#include "moc_qnativesocketengine_p.cpp" diff --git a/src/network/socket/qsocks5socketengine.cpp b/src/network/socket/qsocks5socketengine.cpp index 4f866e4da0..b1b5621b2a 100644 --- a/src/network/socket/qsocks5socketengine.cpp +++ b/src/network/socket/qsocks5socketengine.cpp @@ -535,9 +535,6 @@ void QSocks5SocketEnginePrivate::initialize(Socks5Mode socks5Mode) udpData = new QSocks5UdpAssociateData; data = udpData; udpData->udpSocket = new QUdpSocket(q); -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - udpData->udpSocket->setProperty("_q_networksession", q->property("_q_networksession")); -#endif udpData->udpSocket->setProxy(QNetworkProxy::NoProxy); QObject::connect(udpData->udpSocket, SIGNAL(readyRead()), q, SLOT(_q_udpSocketReadNotification()), @@ -549,9 +546,6 @@ void QSocks5SocketEnginePrivate::initialize(Socks5Mode socks5Mode) } data->controlSocket = new QTcpSocket(q); -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - data->controlSocket->setProperty("_q_networksession", q->property("_q_networksession")); -#endif data->controlSocket->setProxy(QNetworkProxy::NoProxy); QObject::connect(data->controlSocket, SIGNAL(connected()), q, SLOT(_q_controlSocketConnected()), Qt::DirectConnection); @@ -1927,3 +1921,5 @@ QAbstractSocketEngine *QSocks5SocketEngineHandler::createSocketEngine(qintptr so } QT_END_NAMESPACE + +#include "moc_qsocks5socketengine_p.cpp" diff --git a/src/network/socket/qtcpserver.cpp b/src/network/socket/qtcpserver.cpp index c23b143de3..a404350d98 100644 --- a/src/network/socket/qtcpserver.cpp +++ b/src/network/socket/qtcpserver.cpp @@ -314,10 +314,6 @@ bool QTcpServer::listen(const QHostAddress &address, quint16 port) d->serverSocketErrorString = tr("Operation on socket is not supported"); return false; } -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - //copy network session down to the socket engine (if it has been set) - d->socketEngine->setProperty("_q_networksession", property("_q_networksession")); -#endif if (!d->socketEngine->initialize(d->socketType, proto)) { d->serverSocketError = d->socketEngine->error(); d->serverSocketErrorString = d->socketEngine->errorString(); @@ -436,10 +432,6 @@ bool QTcpServer::setSocketDescriptor(qintptr socketDescriptor) d->serverSocketErrorString = tr("Operation on socket is not supported"); return false; } -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - //copy network session down to the socket engine (if it has been set) - d->socketEngine->setProperty("_q_networksession", property("_q_networksession")); -#endif if (!d->socketEngine->initialize(socketDescriptor, QAbstractSocket::ListeningState)) { d->serverSocketError = d->socketEngine->error(); d->serverSocketErrorString = d->socketEngine->errorString(); diff --git a/src/network/ssl/qocspresponse.cpp b/src/network/ssl/qocspresponse.cpp index bf27bb768b..fbbf8d9708 100644 --- a/src/network/ssl/qocspresponse.cpp +++ b/src/network/ssl/qocspresponse.cpp @@ -232,20 +232,20 @@ Q_NETWORK_EXPORT bool operator==(const QOcspResponse &lhs, const QOcspResponse & */ /*! - \fn uint qHash(const QOcspResponse &response, uint seed) + \fn size_t qHash(const QOcspResponse &response, size_t seed) Returns the hash value for the \a response, using \a seed to seed the calculation. \since 5.13 \relates QHash */ -uint qHash(const QOcspResponse &response, uint seed) noexcept +size_t qHash(const QOcspResponse &response, size_t seed) noexcept { const QOcspResponsePrivate *d = response.d.data(); Q_ASSERT(d); QtPrivate::QHashCombine hasher; - uint hash = hasher(seed, int(d->certificateStatus)); + size_t hash = hasher(seed, int(d->certificateStatus)); hash = hasher(hash, int(d->revocationReason)); if (!d->signerCert.isNull()) hash = hasher(hash, d->signerCert); diff --git a/src/network/ssl/qocspresponse.h b/src/network/ssl/qocspresponse.h index cf6be5a369..1fc3377d58 100644 --- a/src/network/ssl/qocspresponse.h +++ b/src/network/ssl/qocspresponse.h @@ -73,7 +73,7 @@ enum class QOcspRevocationReason }; class QOcspResponse; -Q_NETWORK_EXPORT uint qHash(const QOcspResponse &response, uint seed = 0) noexcept; +Q_NETWORK_EXPORT size_t qHash(const QOcspResponse &response, size_t seed = 0) noexcept; class QOcspResponsePrivate; class Q_NETWORK_EXPORT QOcspResponse @@ -100,7 +100,7 @@ private: friend class QSslSocketBackendPrivate; friend Q_NETWORK_EXPORT bool operator==(const QOcspResponse &lhs, const QOcspResponse &rhs); - friend Q_NETWORK_EXPORT uint qHash(const QOcspResponse &response, uint seed) noexcept; + friend Q_NETWORK_EXPORT size_t qHash(const QOcspResponse &response, size_t seed) noexcept; QSharedDataPointer<QOcspResponsePrivate> d; }; diff --git a/src/network/ssl/qssl.cpp b/src/network/ssl/qssl.cpp index beb03b646a..87b9a1b038 100644 --- a/src/network/ssl/qssl.cpp +++ b/src/network/ssl/qssl.cpp @@ -102,29 +102,16 @@ Q_LOGGING_CATEGORY(lcSsl, "qt.network.ssl"); \value IpAddressEntry An IP address entry; the entry contains an IP address entry that the certificate is valid for, introduced in Qt 5.13. - \note In Qt 4, this enum was called \c {AlternateNameEntryType}. That name - is deprecated in Qt 5. - \sa QSslCertificate::subjectAlternativeNames() */ /*! - \typedef QSsl::AlternateNameEntryType - \obsolete - - Use QSsl::AlternativeNameEntryType instead. -*/ - -/*! \enum QSsl::SslProtocol Describes the protocol of the cipher. - \value SslV3 SSLv3; not supported by QSslSocket. - \value SslV2 SSLv2; not supported by QSslSocket. \value TlsV1_0 TLSv1.0 \value TlsV1_0OrLater TLSv1.0 and later versions. This option is not available when using the WinRT backend due to platform limitations. - \value TlsV1 Obsolete, means the same as TlsV1_0 \value TlsV1_1 TLSv1.1. When using the WinRT backend this option will also enable TLSv1.0. \value TlsV1_1OrLater TLSv1.1 and later versions. This option is not available when using the WinRT backend due to platform limitations. \value TlsV1_2 TLSv1.2. When using the WinRT backend this option will also enable TLSv1.0 and TLSv1.1. @@ -137,7 +124,6 @@ Q_LOGGING_CATEGORY(lcSsl, "qt.network.ssl"); \value TlsV1_3OrLater TLSv1.3 and later versions. (Since Qt 5.12) \value UnknownProtocol The cipher's protocol cannot be determined. \value AnyProtocol Any supported protocol. This value is used by QSslSocket only. - \value TlsV1SslV3 Same as TlsV1_0. This enumerator is deprecated, use TlsV1_0 instead. \value SecureProtocols The default option, using protocols known to be secure. */ diff --git a/src/network/ssl/qssl.h b/src/network/ssl/qssl.h index b28c2a87b9..d0b417f9ed 100644 --- a/src/network/ssl/qssl.h +++ b/src/network/ssl/qssl.h @@ -72,25 +72,11 @@ namespace QSsl { IpAddressEntry }; -#if QT_DEPRECATED_SINCE(5,0) - typedef AlternativeNameEntryType AlternateNameEntryType; -#endif - enum SslProtocol { -#if QT_DEPRECATED_SINCE(5, 15) - SslV3, - SslV2, -#endif TlsV1_0 = 2, -#if QT_DEPRECATED_SINCE(5,0) - TlsV1 = TlsV1_0, -#endif TlsV1_1, TlsV1_2, AnyProtocol, -#if QT_DEPRECATED_SINCE(5, 15) - TlsV1SslV3, -#endif SecureProtocols = AnyProtocol + 2, TlsV1_0OrLater, diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp index 791dc7852f..7539c26ecb 100644 --- a/src/network/ssl/qsslcertificate.cpp +++ b/src/network/ssl/qsslcertificate.cpp @@ -373,15 +373,6 @@ QByteArray QSslCertificate::digest(QCryptographicHash::Algorithm algorithm) cons \sa subjectInfo() */ -#if QT_DEPRECATED_SINCE(5,0) -/*! - \fn QMultiMap<QSsl::AlternateNameEntryType, QString> QSslCertificate::alternateSubjectNames() const - \obsolete - - Use QSslCertificate::subjectAlternativeNames(); -*/ -#endif - /*! \fn QMultiMap<QSsl::AlternativeNameEntryType, QString> QSslCertificate::subjectAlternativeNames() const @@ -464,86 +455,6 @@ QByteArray QSslCertificate::digest(QCryptographicHash::Algorithm algorithm) cons \since 5.0 */ -#if QT_DEPRECATED_SINCE(5,15) -/*! - \obsolete - - Searches all files in the \a path for certificates encoded in the - specified \a format and returns them in a list. \a path must be a file - or a pattern matching one or more files, as specified by \a syntax. - - Example: - - \snippet code/src_network_ssl_qsslcertificate.cpp 0 - - \sa fromData() -*/ -QList<QSslCertificate> QSslCertificate::fromPath(const QString &path, - QSsl::EncodingFormat format, - QRegExp::PatternSyntax syntax) -{ - // $, (,), *, +, ., ?, [, ,], ^, {, | and }. - - // make sure to use the same path separators on Windows and Unix like systems. - QString sourcePath = QDir::fromNativeSeparators(path); - - // Find the path without the filename - QString pathPrefix = sourcePath.left(sourcePath.lastIndexOf(QLatin1Char('/'))); - - // Check if the path contains any special chars - int pos = -1; - if (syntax == QRegExp::Wildcard) - pos = pathPrefix.indexOf(QRegExp(QLatin1String("[*?[]"))); - else if (syntax != QRegExp::FixedString) - pos = sourcePath.indexOf(QRegExp(QLatin1String("[\\$\\(\\)\\*\\+\\.\\?\\[\\]\\^\\{\\}\\|]"))); - if (pos != -1) { - // there was a special char in the path so cut of the part containing that char. - pathPrefix = pathPrefix.left(pos); - const int lastIndexOfSlash = pathPrefix.lastIndexOf(QLatin1Char('/')); - if (lastIndexOfSlash != -1) - pathPrefix = pathPrefix.left(lastIndexOfSlash); - else - pathPrefix.clear(); - } else { - // Check if the path is a file. - if (QFileInfo(sourcePath).isFile()) { - QFile file(sourcePath); - QIODevice::OpenMode openMode = QIODevice::ReadOnly; - if (format == QSsl::Pem) - openMode |= QIODevice::Text; - if (file.open(openMode)) - return QSslCertificate::fromData(file.readAll(), format); - return QList<QSslCertificate>(); - } - } - - // Special case - if the prefix ends up being nothing, use "." instead. - int startIndex = 0; - if (pathPrefix.isEmpty()) { - pathPrefix = QLatin1String("."); - startIndex = 2; - } - - // The path can be a file or directory. - QList<QSslCertificate> certs; - QRegExp pattern(sourcePath, Qt::CaseSensitive, syntax); - QDirIterator it(pathPrefix, QDir::Files, QDirIterator::FollowSymlinks | QDirIterator::Subdirectories); - while (it.hasNext()) { - QString filePath = startIndex == 0 ? it.next() : it.next().mid(startIndex); - if (!pattern.exactMatch(filePath)) - continue; - - QFile file(filePath); - QIODevice::OpenMode openMode = QIODevice::ReadOnly; - if (format == QSsl::Pem) - openMode |= QIODevice::Text; - if (file.open(openMode)) - certs += QSslCertificate::fromData(file.readAll(), format); - } - return certs; -} -#endif // QT_DEPRECATED_SINCE(5,15) - /*! \since 5.15 @@ -616,7 +527,7 @@ QList<QSslCertificate> QSslCertificate::fromPath(const QString &path, #if QT_CONFIG(regularexpression) if (syntax == PatternSyntax::Wildcard) - sourcePath = QRegularExpression::wildcardToRegularExpression(sourcePath); + sourcePath = QRegularExpression::wildcardToRegularExpression(sourcePath, QRegularExpression::UnanchoredWildcardConversion); QRegularExpression pattern(QRegularExpression::anchoredPattern(sourcePath)); #endif @@ -850,7 +761,7 @@ QString QSslCertificate::subjectDisplayName() const } /*! - \fn uint qHash(const QSslCertificate &key, uint seed) + \fn size_t qHash(const QSslCertificate &key, size_t seed) Returns the hash value for the \a key, using \a seed to seed the calculation. \since 5.4 diff --git a/src/network/ssl/qsslcertificate.h b/src/network/ssl/qsslcertificate.h index 147919fa3b..46119ae046 100644 --- a/src/network/ssl/qsslcertificate.h +++ b/src/network/ssl/qsslcertificate.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtNetwork module of the Qt Toolkit. @@ -50,7 +50,6 @@ #include <QtCore/qbytearray.h> #include <QtCore/qcryptographichash.h> #include <QtCore/qdatetime.h> -#include <QtCore/qregexp.h> #include <QtCore/qsharedpointer.h> #include <QtCore/qmap.h> #include <QtNetwork/qssl.h> @@ -66,7 +65,7 @@ class QStringList; class QSslCertificate; // qHash is a friend, but we can't use default arguments for friends (§8.3.6.4) -Q_NETWORK_EXPORT uint qHash(const QSslCertificate &key, uint seed = 0) noexcept; +Q_NETWORK_EXPORT size_t qHash(const QSslCertificate &key, size_t seed = 0) noexcept; class QSslCertificatePrivate; class Q_NETWORK_EXPORT QSslCertificate @@ -130,10 +129,6 @@ public: QList<QByteArray> subjectInfoAttributes() const; QList<QByteArray> issuerInfoAttributes() const; -#if QT_DEPRECATED_SINCE(5,0) - QT_DEPRECATED inline QMultiMap<QSsl::AlternateNameEntryType, QString> - alternateSubjectNames() const { return subjectAlternativeNames(); } -#endif QMultiMap<QSsl::AlternativeNameEntryType, QString> subjectAlternativeNames() const; QDateTime effectiveDate() const; QDateTime expiryDate() const; @@ -146,11 +141,6 @@ public: QByteArray toDer() const; QString toText() const; -#if QT_DEPRECATED_SINCE(5,15) - QT_DEPRECATED_X("Use the overload not using QRegExp") - static QList<QSslCertificate> fromPath(const QString &path, QSsl::EncodingFormat format, - QRegExp::PatternSyntax syntax); -#endif static QList<QSslCertificate> fromPath(const QString &path, QSsl::EncodingFormat format = QSsl::Pem, PatternSyntax syntax = PatternSyntax::FixedString); @@ -180,7 +170,7 @@ private: friend class QSslCertificatePrivate; friend class QSslSocketBackendPrivate; - friend Q_NETWORK_EXPORT uint qHash(const QSslCertificate &key, uint seed) noexcept; + friend Q_NETWORK_EXPORT size_t qHash(const QSslCertificate &key, size_t seed) noexcept; }; Q_DECLARE_SHARED(QSslCertificate) diff --git a/src/network/ssl/qsslcertificate_openssl.cpp b/src/network/ssl/qsslcertificate_openssl.cpp index 6f1fb26add..2bb7c930f2 100644 --- a/src/network/ssl/qsslcertificate_openssl.cpp +++ b/src/network/ssl/qsslcertificate_openssl.cpp @@ -72,7 +72,7 @@ bool QSslCertificate::operator==(const QSslCertificate &other) const return false; } -uint qHash(const QSslCertificate &key, uint seed) noexcept +size_t qHash(const QSslCertificate &key, size_t seed) noexcept { if (X509 * const x509 = key.d->x509) { const EVP_MD *sha1 = q_EVP_sha1(); diff --git a/src/network/ssl/qsslcertificate_qt.cpp b/src/network/ssl/qsslcertificate_qt.cpp index 8b5035ad96..33deaf558f 100644 --- a/src/network/ssl/qsslcertificate_qt.cpp +++ b/src/network/ssl/qsslcertificate_qt.cpp @@ -64,7 +64,7 @@ bool QSslCertificate::operator==(const QSslCertificate &other) const return d->derData == other.d->derData; } -uint qHash(const QSslCertificate &key, uint seed) noexcept +size_t qHash(const QSslCertificate &key, size_t seed) noexcept { // DER is the native encoding here, so toDer() is just "return d->derData": return qHash(key.toDer(), seed); diff --git a/src/network/ssl/qsslconfiguration.cpp b/src/network/ssl/qsslconfiguration.cpp index f5ce02807f..adff0a249f 100644 --- a/src/network/ssl/qsslconfiguration.cpp +++ b/src/network/ssl/qsslconfiguration.cpp @@ -54,7 +54,6 @@ const QSsl::SslOptions QSslConfigurationPrivate::defaultSslOptions = QSsl::SslOp |QSsl::SslOptionDisableSessionPersistence; const char QSslConfiguration::ALPNProtocolHTTP2[] = "h2"; -const char QSslConfiguration::NextProtocolSpdy3_0[] = "spdy/3"; const char QSslConfiguration::NextProtocolHttp1_1[] = "http/1.1"; /*! @@ -134,12 +133,6 @@ const char QSslConfiguration::NextProtocolHttp1_1[] = "http/1.1"; */ /*! - \variable QSslConfiguration::NextProtocolSpdy3_0 - \brief The value used for negotiating SPDY 3.0 during the Next - Protocol Negotiation. -*/ - -/*! \variable QSslConfiguration::NextProtocolHttp1_1 \brief The value used for negotiating HTTP 1.1 during the Next Protocol Negotiation. @@ -229,7 +222,9 @@ bool QSslConfiguration::operator==(const QSslConfiguration &other) const d->nextNegotiatedProtocol == other.d->nextNegotiatedProtocol && d->nextProtocolNegotiationStatus == other.d->nextProtocolNegotiationStatus && d->dtlsCookieEnabled == other.d->dtlsCookieEnabled && - d->ocspStaplingEnabled == other.d->ocspStaplingEnabled; + d->ocspStaplingEnabled == other.d->ocspStaplingEnabled && + d->reportFromCallback == other.d->reportFromCallback && + d->missingCertIsFatal == other.d->missingCertIsFatal; } /*! @@ -274,7 +269,9 @@ bool QSslConfiguration::isNull() const d->nextAllowedProtocols.isEmpty() && d->nextNegotiatedProtocol.isNull() && d->nextProtocolNegotiationStatus == QSslConfiguration::NextProtocolNegotiationNone && - d->ocspStaplingEnabled == false); + d->ocspStaplingEnabled == false && + d->reportFromCallback == false && + d->missingCertIsFatal == false); } /*! @@ -1035,7 +1032,7 @@ QByteArray QSslConfiguration::nextNegotiatedProtocol() const Whether or not the negotiation succeeded can be queried through nextProtocolNegotiationStatus(). - \sa nextNegotiatedProtocol(), nextProtocolNegotiationStatus(), allowedNextProtocols(), QSslConfiguration::NextProtocolSpdy3_0, QSslConfiguration::NextProtocolHttp1_1 + \sa nextNegotiatedProtocol(), nextProtocolNegotiationStatus(), allowedNextProtocols(), QSslConfiguration::NextProtocolHttp1_1 */ #if QT_VERSION >= QT_VERSION_CHECK(6,0,0) void QSslConfiguration::setAllowedNextProtocols(const QList<QByteArray> &protocols) @@ -1053,7 +1050,7 @@ void QSslConfiguration::setAllowedNextProtocols(QList<QByteArray> protocols) server through the Next Protocol Negotiation (NPN) or Application-Layer Protocol Negotiation (ALPN) TLS extension, as set by setAllowedNextProtocols(). - \sa nextNegotiatedProtocol(), nextProtocolNegotiationStatus(), setAllowedNextProtocols(), QSslConfiguration::NextProtocolSpdy3_0, QSslConfiguration::NextProtocolHttp1_1 + \sa nextNegotiatedProtocol(), nextProtocolNegotiationStatus(), setAllowedNextProtocols(), QSslConfiguration::NextProtocolHttp1_1 */ QList<QByteArray> QSslConfiguration::allowedNextProtocols() const { @@ -1199,6 +1196,91 @@ bool QSslConfiguration::ocspStaplingEnabled() const return d->ocspStaplingEnabled; } +/*! + \since 6.0 + + Returns true if a verification callback will emit QSslSocket::handshakeInterruptedOnError() + early, before concluding the handshake. + + \note This function always returns false for all backends but OpenSSL. + + \sa setHandshakeMustInterruptOnError(), QSslSocket::handshakeInterruptedOnError(), QSslSocket::continueInterruptedHandshake() +*/ +bool QSslConfiguration::handshakeMustInterruptOnError() const +{ + return d->reportFromCallback; +} + +/*! + \since 6.0 + + If \a interrupt is true and the underlying backend supports this option, + errors found during certificate verification are reported immediately + by emitting QSslSocket::handshakeInterruptedOnError(). This allows + to stop the unfinished handshake and send a proper alert message to + a peer. No special action is required from the application in this case. + QSslSocket will close the connection after sending the alert message. + If the application after inspecting the error wants to continue the + handshake, it must call QSslSocket::continueInterruptedHandshake() + from its slot function. The signal-slot connection must be direct. + + \note When interrupting handshake is enabled, errors that would otherwise + be reported by QSslSocket::peerVerifyError() are instead only reported by + QSslSocket::handshakeInterruptedOnError(). + \note Even if the handshake was continued, these errors will be + reported when emitting QSslSocket::sslErrors() signal (and thus must + be ignored in the corresponding function slot). + + \sa handshakeMustInterruptOnError(), QSslSocket::handshakeInterruptedOnError(), QSslSocket::continueInterruptedHandshake() +*/ +void QSslConfiguration::setHandshakeMustInterruptOnError(bool interrupt) +{ +#if QT_CONFIG(openssl) + d->reportFromCallback = interrupt; +#else + Q_UNUSED(interrupt); + qCWarning(lcSsl, "This operation requires OpenSSL as TLS backend"); +#endif +} + +/*! + \since 6.0 + + Returns true if errors with code QSslError::NoPeerCertificate + cannot be ignored. + + \note Always returns false for all TLS backends but OpenSSL. + + \sa QSslSocket::ignoreSslErrors(), setMissingCertificateIsFatal() +*/ +bool QSslConfiguration::missingCertificateIsFatal() const +{ + return d->missingCertIsFatal; +} + +/*! + \since 6.0 + + If \a cannotRecover is true, and verification mode in use is + QSslSocket::VerifyPeer or QSslSocket::AutoVerifyPeer (for a + client-side socket), the missing peer's certificate would be + treated as an unrecoverable error that cannot be ignored. A proper + alert message will be sent to the peer before closing the connection. + + \note Only available if Qt was configured and built with OpenSSL backend. + + \sa QSslSocket::ignoreSslErrors(), QSslSocket::PeerVerifyMode, missingCertificateIsFatal() +*/ +void QSslConfiguration::setMissingCertificateIsFatal(bool cannotRecover) +{ +#if QT_CONFIG(openssl) + d->missingCertIsFatal = cannotRecover; +#else + Q_UNUSED(cannotRecover); + qCWarning(lcSsl, "Handling a missing certificate as a fatal error requires an OpenSSL backend"); +#endif // openssl +} + /*! \internal */ bool QSslConfigurationPrivate::peerSessionWasShared(const QSslConfiguration &configuration) { diff --git a/src/network/ssl/qsslconfiguration.h b/src/network/ssl/qsslconfiguration.h index 1c181121f4..1ce01dbee9 100644 --- a/src/network/ssl/qsslconfiguration.h +++ b/src/network/ssl/qsslconfiguration.h @@ -66,7 +66,6 @@ QT_BEGIN_NAMESPACE -template<typename T> class QList; class QSslCertificate; class QSslCipher; class QSslKey; @@ -174,6 +173,12 @@ public: static void setDefaultDtlsConfiguration(const QSslConfiguration &configuration); #endif // dtls + bool handshakeMustInterruptOnError() const; + void setHandshakeMustInterruptOnError(bool interrupt); + + bool missingCertificateIsFatal() const; + void setMissingCertificateIsFatal(bool cannotRecover); + void setOcspStaplingEnabled(bool enable); bool ocspStaplingEnabled() const; @@ -194,7 +199,6 @@ public: NextProtocolNegotiationStatus nextProtocolNegotiationStatus() const; static const char ALPNProtocolHTTP2[]; - static const char NextProtocolSpdy3_0[]; static const char NextProtocolHttp1_1[]; private: diff --git a/src/network/ssl/qsslconfiguration_p.h b/src/network/ssl/qsslconfiguration_p.h index 83126bb9a0..6ee3490df6 100644 --- a/src/network/ssl/qsslconfiguration_p.h +++ b/src/network/ssl/qsslconfiguration_p.h @@ -149,6 +149,14 @@ public: const bool ocspStaplingEnabled = false; #endif +#if QT_CONFIG(openssl) + bool reportFromCallback = false; + bool missingCertIsFatal = false; +#else + const bool reportFromCallback = false; + const bool missingCertIsFatal = false; +#endif // openssl + // in qsslsocket.cpp: static QSslConfiguration defaultConfiguration(); static void setDefaultConfiguration(const QSslConfiguration &configuration); diff --git a/src/network/ssl/qsslcontext_openssl.cpp b/src/network/ssl/qsslcontext_openssl.cpp index 0aa8a4f438..78e37460c8 100644 --- a/src/network/ssl/qsslcontext_openssl.cpp +++ b/src/network/ssl/qsslcontext_openssl.cpp @@ -56,6 +56,7 @@ QT_BEGIN_NAMESPACE // defined in qsslsocket_openssl.cpp: extern int q_X509Callback(int ok, X509_STORE_CTX *ctx); +extern "C" int q_X509CallbackDirect(int ok, X509_STORE_CTX *ctx); extern QString getErrorsFromOpenSsl(); #if QT_CONFIG(dtls) @@ -290,42 +291,31 @@ void QSslContext::initSslContext(QSslContext *sslContext, QSslSocket::SslMode mo bool unsupportedProtocol = false; bool isDtls = false; init_context: - if (sslContext->sslConfiguration.protocol() == QSsl::SslV2) { - // SSL 2 is no longer supported, but chosen deliberately -> error - sslContext->ctx = nullptr; - unsupportedProtocol = true; - } else if (sslContext->sslConfiguration.protocol() == QSsl::SslV3) { - // SSL 3 is no longer supported, but chosen deliberately -> error - sslContext->ctx = nullptr; - unsupportedProtocol = true; - } else { - switch (sslContext->sslConfiguration.protocol()) { - case QSsl::DtlsV1_0: - case QSsl::DtlsV1_0OrLater: - case QSsl::DtlsV1_2: - case QSsl::DtlsV1_2OrLater: + switch (sslContext->sslConfiguration.protocol()) { + case QSsl::DtlsV1_0: + case QSsl::DtlsV1_0OrLater: + case QSsl::DtlsV1_2: + case QSsl::DtlsV1_2OrLater: #if QT_CONFIG(dtls) - isDtls = true; - sslContext->ctx = q_SSL_CTX_new(client ? q_DTLS_client_method() : q_DTLS_server_method()); + isDtls = true; + sslContext->ctx = q_SSL_CTX_new(client ? q_DTLS_client_method() : q_DTLS_server_method()); #else // dtls - sslContext->ctx = nullptr; - unsupportedProtocol = true; - qCWarning(lcSsl, "DTLS protocol requested, but feature 'dtls' is disabled"); - + sslContext->ctx = nullptr; + unsupportedProtocol = true; + qCWarning(lcSsl, "DTLS protocol requested, but feature 'dtls' is disabled"); #endif // dtls - break; - case QSsl::TlsV1_3: - case QSsl::TlsV1_3OrLater: + break; + case QSsl::TlsV1_3: + case QSsl::TlsV1_3OrLater: #if !defined(TLS1_3_VERSION) - qCWarning(lcSsl, "TLS 1.3 is not supported"); - sslContext->ctx = nullptr; - unsupportedProtocol = true; - break; + qCWarning(lcSsl, "TLS 1.3 is not supported"); + sslContext->ctx = nullptr; + unsupportedProtocol = true; + break; #endif // TLS1_3_VERSION - default: - // The ssl options will actually control the supported methods - sslContext->ctx = q_SSL_CTX_new(client ? q_TLS_client_method() : q_TLS_server_method()); - } + default: + // The ssl options will actually control the supported methods + sslContext->ctx = q_SSL_CTX_new(client ? q_TLS_client_method() : q_TLS_server_method()); } if (!sslContext->ctx) { @@ -377,7 +367,6 @@ init_context: #endif // TLS1_3_VERSION break; // Ranges: - case QSsl::TlsV1SslV3: case QSsl::AnyProtocol: case QSsl::SecureProtocols: case QSsl::TlsV1_0OrLater: @@ -419,12 +408,6 @@ init_context: Q_UNREACHABLE(); break; #endif // TLS1_3_VERSION - case QSsl::SslV2: - case QSsl::SslV3: - // These protocols are not supported, and we handle - // them as an error (see the code above). - Q_UNREACHABLE(); - break; case QSsl::UnknownProtocol: break; } @@ -594,11 +577,20 @@ init_context: if (sslContext->sslConfiguration.peerVerifyMode() == QSslSocket::VerifyNone) { q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_NONE, nullptr); } else { - q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_PEER, -#if QT_CONFIG(dtls) - isDtls ? dtlscallbacks::q_X509DtlsCallback : -#endif // dtls - q_X509Callback); + auto verificationCallback = + #if QT_CONFIG(dtls) + isDtls ? dtlscallbacks::q_X509DtlsCallback : + #endif // dtls + q_X509Callback; + + if (!isDtls && configuration.handshakeMustInterruptOnError()) + verificationCallback = q_X509CallbackDirect; + + auto verificationMode = SSL_VERIFY_PEER; + if (!isDtls && sslContext->sslConfiguration.missingCertificateIsFatal()) + verificationMode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; + + q_SSL_CTX_set_verify(sslContext->ctx, verificationMode, verificationCallback); } #ifdef TLS1_3_VERSION diff --git a/src/network/ssl/qssldiffiehellmanparameters.cpp b/src/network/ssl/qssldiffiehellmanparameters.cpp index 7807afaa30..c8f3e564a5 100644 --- a/src/network/ssl/qssldiffiehellmanparameters.cpp +++ b/src/network/ssl/qssldiffiehellmanparameters.cpp @@ -316,7 +316,7 @@ QDebug operator<<(QDebug debug, const QSslDiffieHellmanParameters &dhparam) Returns an hash value for \a dhparam, using \a seed to seed the calculation. */ -uint qHash(const QSslDiffieHellmanParameters &dhparam, uint seed) noexcept +size_t qHash(const QSslDiffieHellmanParameters &dhparam, size_t seed) noexcept { return qHash(dhparam.d->derData, seed); } diff --git a/src/network/ssl/qssldiffiehellmanparameters.h b/src/network/ssl/qssldiffiehellmanparameters.h index f62a3b8f44..6a3cf01ddc 100644 --- a/src/network/ssl/qssldiffiehellmanparameters.h +++ b/src/network/ssl/qssldiffiehellmanparameters.h @@ -56,7 +56,7 @@ class QSslDiffieHellmanParametersPrivate; class QSslDiffieHellmanParameters; // qHash is a friend, but we can't use default arguments for friends (§8.3.6.4) -Q_NETWORK_EXPORT uint qHash(const QSslDiffieHellmanParameters &dhparam, uint seed = 0) noexcept; +Q_NETWORK_EXPORT size_t qHash(const QSslDiffieHellmanParameters &dhparam, size_t seed = 0) noexcept; #ifndef QT_NO_DEBUG_STREAM class QDebug; @@ -106,7 +106,7 @@ private: #ifndef QT_NO_DEBUG_STREAM friend Q_NETWORK_EXPORT QDebug operator<<(QDebug debug, const QSslDiffieHellmanParameters &dhparam); #endif - friend Q_NETWORK_EXPORT uint qHash(const QSslDiffieHellmanParameters &dhparam, uint seed) noexcept; + friend Q_NETWORK_EXPORT size_t qHash(const QSslDiffieHellmanParameters &dhparam, size_t seed) noexcept; }; Q_DECLARE_SHARED(QSslDiffieHellmanParameters) diff --git a/src/network/ssl/qsslellipticcurve.cpp b/src/network/ssl/qsslellipticcurve.cpp index 5608d32fa7..f7faa607bd 100644 --- a/src/network/ssl/qsslellipticcurve.cpp +++ b/src/network/ssl/qsslellipticcurve.cpp @@ -156,7 +156,7 @@ QT_BEGIN_NAMESPACE */ /*! - \fn uint qHash(QSslEllipticCurve curve, uint seed) + \fn size_t qHash(QSslEllipticCurve curve, size_t seed) \since 5.5 \relates QHash diff --git a/src/network/ssl/qsslellipticcurve.h b/src/network/ssl/qsslellipticcurve.h index 28de3a03b4..c63552c680 100644 --- a/src/network/ssl/qsslellipticcurve.h +++ b/src/network/ssl/qsslellipticcurve.h @@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE class QSslEllipticCurve; // qHash is a friend, but we can't use default arguments for friends (§8.3.6.4) -Q_DECL_CONSTEXPR uint qHash(QSslEllipticCurve curve, uint seed = 0) noexcept; +Q_DECL_CONSTEXPR size_t qHash(QSslEllipticCurve curve, size_t seed = 0) noexcept; class QSslEllipticCurve { public: @@ -78,7 +78,7 @@ private: int id; friend Q_DECL_CONSTEXPR bool operator==(QSslEllipticCurve lhs, QSslEllipticCurve rhs) noexcept; - friend Q_DECL_CONSTEXPR uint qHash(QSslEllipticCurve curve, uint seed) noexcept; + friend Q_DECL_CONSTEXPR size_t qHash(QSslEllipticCurve curve, size_t seed) noexcept; friend class QSslContext; friend class QSslSocketPrivate; @@ -87,7 +87,7 @@ private: Q_DECLARE_TYPEINFO(QSslEllipticCurve, Q_PRIMITIVE_TYPE); -Q_DECL_CONSTEXPR inline uint qHash(QSslEllipticCurve curve, uint seed) noexcept +Q_DECL_CONSTEXPR inline size_t qHash(QSslEllipticCurve curve, size_t seed) noexcept { return qHash(curve.id, seed); } Q_DECL_CONSTEXPR inline bool operator==(QSslEllipticCurve lhs, QSslEllipticCurve rhs) noexcept diff --git a/src/network/ssl/qsslerror.cpp b/src/network/ssl/qsslerror.cpp index cdc018a508..5e935adf09 100644 --- a/src/network/ssl/qsslerror.cpp +++ b/src/network/ssl/qsslerror.cpp @@ -362,7 +362,7 @@ QSslCertificate QSslError::certificate() const \since 5.4 \relates QHash */ -uint qHash(const QSslError &key, uint seed) noexcept +size_t qHash(const QSslError &key, size_t seed) noexcept { QtPrivate::QHashCombine hash; seed = hash(seed, key.error()); diff --git a/src/network/ssl/qsslerror.h b/src/network/ssl/qsslerror.h index 28eb1a9ea8..834684cd9d 100644 --- a/src/network/ssl/qsslerror.h +++ b/src/network/ssl/qsslerror.h @@ -124,7 +124,7 @@ private: }; Q_DECLARE_SHARED(QSslError) -Q_NETWORK_EXPORT uint qHash(const QSslError &key, uint seed = 0) noexcept; +Q_NETWORK_EXPORT size_t qHash(const QSslError &key, size_t seed = 0) noexcept; #ifndef QT_NO_DEBUG_STREAM class QDebug; diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index f411732036..5313e97430 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -228,6 +228,74 @@ */ /*! + \enum QAlertLevel + \brief Describes the level of an alert message + \relates QSslSocket + \since 6.0 + + \ingroup network + \ingroup ssl + \inmodule QtNetwork + + This enum describes the level of an alert message that was sent + or received. + + \value Warning Non-fatal alert message + \value Fatal Fatal alert message, the underlying backend will + handle such an alert properly and close the connection. + \value Unknown An alert of unknown level of severity. +*/ + +/*! + \enum QAlertType + \brief Enumerates possible codes that an alert message can have + \relates QSslSocket + \since 6.0 + + \ingroup network + \ingroup ssl + \inmodule QtNetwork + + See \l{https://tools.ietf.org/html/rfc8446#page-85}{RFC 8446, section 6} + for the possible values and their meaning. + + \value CloseNotify, + \value UnexpectedMessage + \value BadRecordMac + \value RecordOverflow + \value DecompressionFailure + \value HandshakeFailure + \value NoCertificate + \value BadCertificate + \value UnsupportedCertificate + \value CertificateRevoked + \value CertificateExpired + \value CertificateUnknown + \value IllegalParameter + \value UnknownCa + \value AccessDenied + \value DecodeError + \value DecryptError + \value ExportRestriction + \value ProtocolVersion + \value InsufficientSecurity + \value InternalError + \value InappropriateFallback + \value UserCancelled + \value NoRenegotiation + \value MissingExtension + \value UnsupportedExtension + \value CertificateUnobtainable + \value UnrecognizedName + \value BadCertificateStatusResponse + \value BadCertificateHashValue + \value UnknownPskIdentity + \value CertificateRequired + \value NoApplicationProtocol + \value UnknownAlertMessage +*/ + +/*! \fn void QSslSocket::encrypted() This signal is emitted when QSslSocket enters encrypted mode. After this @@ -323,6 +391,49 @@ */ /*! + \fn void QSslSocket::alertSent(QAlertLevel level, QAlertType type, const QString &description) + + QSslSocket emits this signal if an alert message was sent to a peer. \a level + describes if it was a warning or a fatal error. \a type gives the code + of the alert message. When a textual description of the alert message is + available, it is supplied in \a description. + + \note This signal is mostly informational and can be used for debugging + purposes, normally it does not require any actions from the application. + \note Not all backends support this functionality. + + \sa alertReceived(), QAlertLevel, QAlertType +*/ + +/*! + \fn void QSslSocket::alertReceived(QAlertLevel level, QAlertType type, const QString &description) + + QSslSocket emits this signal if an alert message was received from a peer. + \a level tells if the alert was fatal or it was a warning. \a type is the + code explaining why the alert was sent. When a textual description of + the alert message is available, it is supplied in \a description. + + \note The signal is mostly for informational and debugging purposes and does not + require any handling in the application. If the alert was fatal, underlying + backend will handle it and close the connection. + \note Not all backends support this functionality. + + \sa alertSent(), QAlertLevel, QAlertType +*/ + +/*! + \fn void QSslSocket::handshakeInterruptedOnError(const QSslError &error) + + QSslSocket emits this signal if a certificate verification error was + found and if early error reporting was enabled in QSslConfiguration. + An application is expected to inspect the \a error and decide if + it wants to continue the handshake, or abort it and send an alert message + to the peer. The signal-slot connection must be direct. + + \sa continueInterruptedHandshake(), sslErrors(), QSslConfiguration::setHandshakeMustInterruptOnError() +*/ + +/*! \fn void QSslSocket::newSessionTicketReceived() \since 5.15 @@ -993,7 +1104,10 @@ void QSslSocket::setSslConfiguration(const QSslConfiguration &configuration) #if QT_CONFIG(ocsp) d->configuration.ocspStaplingEnabled = configuration.ocspStaplingEnabled(); #endif - +#if QT_CONFIG(openssl) + d->configuration.reportFromCallback = configuration.handshakeMustInterruptOnError(); + d->configuration.missingCertIsFatal = configuration.missingCertificateIsFatal(); +#endif // openssl // if the CA certificates were set explicitly (either via // QSslConfiguration::setCaCertificates() or QSslSocket::setCaCertificates(), // we cannot load the certificates on demand @@ -1413,40 +1527,6 @@ QList<QSslCipher> QSslSocket::supportedCiphers() /*! \deprecated - Use QSslConfiguration::addCaCertificates() instead. - - Searches all files in the \a path for certificates encoded in the - specified \a format and adds them to this socket's CA certificate - database. \a path must be a file or a pattern matching one or more - files, as specified by \a syntax. Returns \c true if one or more - certificates are added to the socket's CA certificate database; - otherwise returns \c false. - - The CA certificate database is used by the socket during the - handshake phase to validate the peer's certificate. - - For more precise control, use addCaCertificate(). - - \sa addCaCertificate(), QSslCertificate::fromPath() -*/ -bool QSslSocket::addCaCertificates(const QString &path, QSsl::EncodingFormat format, - QRegExp::PatternSyntax syntax) -{ - Q_D(QSslSocket); -QT_WARNING_PUSH -QT_WARNING_DISABLE_DEPRECATED - QList<QSslCertificate> certs = QSslCertificate::fromPath(path, format, syntax); -QT_WARNING_POP - if (certs.isEmpty()) - return false; - - d->configuration.caCertificates += certs; - return true; -} - -/*! - \deprecated - Use QSslConfiguration::addCaCertificate() instead. Adds the \a certificate to this socket's CA certificate database. @@ -1533,29 +1613,6 @@ QList<QSslCertificate> QSslSocket::caCertificates() const /*! \deprecated - Use QSslConfiguration::addCaCertificates() on the default QSslConfiguration instead. - - Searches all files in the \a path for certificates with the - specified \a encoding and adds them to the default CA certificate - database. \a path can be an explicit file, or it can contain - wildcards in the format specified by \a syntax. Returns \c true if - any CA certificates are added to the default database. - - Each SSL socket's CA certificate database is initialized to the - default CA certificate database. - - \sa QSslConfiguration::caCertificates(), QSslConfiguration::addCaCertificates(), - QSslConfiguration::addCaCertificate() -*/ -bool QSslSocket::addDefaultCaCertificates(const QString &path, QSsl::EncodingFormat encoding, - QRegExp::PatternSyntax syntax) -{ - return QSslSocketPrivate::addDefaultCaCertificates(path, encoding, syntax); -} - -/*! - \deprecated - Use QSslConfiguration::addCaCertificate() on the default QSslConfiguration instead. Adds \a certificate to the default CA certificate database. Each @@ -2083,6 +2140,23 @@ void QSslSocket::ignoreSslErrors(const QList<QSslError> &errors) d->ignoreErrorsList = errors; } + +/*! + \since 6.0 + + If an application wants to conclude a handshake even after receiving + handshakeInterruptedOnError() signal, it must call this function. + This call must be done from a slot function attached to the signal. + The signal-slot connection must be direct. + + \sa handshakeInterruptedOnError(), QSslConfiguration::setHandshakeMustInterruptOnError() +*/ +void QSslSocket::continueInterruptedHandshake() +{ + Q_D(QSslSocket); + d->handshakeInterrupted = false; +} + /*! \internal */ @@ -2257,13 +2331,24 @@ void QSslSocketPrivate::init() */ bool QSslSocketPrivate::verifyProtocolSupported(const char *where) { - if (configuration.protocol == QSsl::SslV2 || configuration.protocol == QSsl::SslV3) { - qCWarning(lcSsl) << where << "Attempted to use an unsupported protocol."; + QLatin1String protocolName("DTLS"); + switch (configuration.protocol) { + case QSsl::UnknownProtocol: + // UnknownProtocol, according to our docs, is for cipher whose protocol is unknown. + // Should not be used when configuring QSslSocket. + protocolName = QLatin1String("UnknownProtocol"); + Q_FALLTHROUGH(); + case QSsl::DtlsV1_0: + case QSsl::DtlsV1_2: + case QSsl::DtlsV1_0OrLater: + case QSsl::DtlsV1_2OrLater: + qCWarning(lcSsl) << where << "QSslConfiguration with unexpected protocol" << protocolName; setErrorAndEmit(QAbstractSocket::SslInvalidUserDataError, QSslSocket::tr("Attempted to use an unsupported protocol.")); return false; + default: + return true; } - return true; } /*! @@ -2376,28 +2461,6 @@ void QSslSocketPrivate::setDefaultCaCertificates(const QList<QSslCertificate> &c /*! \internal */ -bool QSslSocketPrivate::addDefaultCaCertificates(const QString &path, QSsl::EncodingFormat format, - QRegExp::PatternSyntax syntax) -{ - QSslSocketPrivate::ensureInitialized(); -QT_WARNING_PUSH -QT_WARNING_DISABLE_DEPRECATED - QList<QSslCertificate> certs = QSslCertificate::fromPath(path, format, syntax); -QT_WARNING_POP - if (certs.isEmpty()) - return false; - - QMutexLocker locker(&globalData()->mutex); - globalData()->config.detach(); - globalData()->config->caCertificates += certs; - globalData()->dtlsConfig.detach(); - globalData()->dtlsConfig->caCertificates += certs; - return true; -} - -/*! - \internal -*/ void QSslSocketPrivate::addDefaultCaCertificate(const QSslCertificate &cert) { QSslSocketPrivate::ensureInitialized(); @@ -2477,6 +2540,10 @@ void QSslConfigurationPrivate::deepCopyDefaultConfiguration(QSslConfigurationPri #if QT_CONFIG(ocsp) ptr->ocspStaplingEnabled = global->ocspStaplingEnabled; #endif +#if QT_CONFIG(openssl) + ptr->reportFromCallback = global->reportFromCallback; + ptr->missingCertIsFatal = global->missingCertIsFatal; +#endif } /*! @@ -2519,10 +2586,6 @@ void QSslSocketPrivate::createPlainSocket(QIODevice::OpenMode openMode) q->setPeerName(QString()); plainSocket = new QTcpSocket(q); -#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section - //copy network session down to the plain socket (if it has been set) - plainSocket->setProperty("_q_networksession", q->property("_q_networksession")); -#endif q->connect(plainSocket, SIGNAL(connected()), q, SLOT(_q_connectedSlot()), Qt::DirectConnection); diff --git a/src/network/ssl/qsslsocket.h b/src/network/ssl/qsslsocket.h index 298e7aa6c8..7fd2b1cb08 100644 --- a/src/network/ssl/qsslsocket.h +++ b/src/network/ssl/qsslsocket.h @@ -43,7 +43,6 @@ #include <QtNetwork/qtnetworkglobal.h> #include <QtCore/qlist.h> -#include <QtCore/qregexp.h> #include <QtCore/qvector.h> #ifndef QT_NO_SSL # include <QtNetwork/qtcpsocket.h> @@ -63,6 +62,49 @@ class QSslEllipticCurve; class QSslPreSharedKeyAuthenticator; class QOcspResponse; +enum class QAlertLevel { + Warning, + Fatal, + Unknown +}; + +enum class QAlertType { + CloseNotify, + UnexpectedMessage = 10, + BadRecordMac = 20, + RecordOverflow = 22, + DecompressionFailure = 30, // reserved + HandshakeFailure = 40, + NoCertificate = 41, // reserved + BadCertificate = 42, + UnsupportedCertificate = 43, + CertificateRevoked = 44, + CertificateExpired = 45, + CertificateUnknown = 46, + IllegalParameter = 47, + UnknownCa = 48, + AccessDenied = 49, + DecodeError = 50, + DecryptError = 51, + ExportRestriction = 60, // reserved + ProtocolVersion = 70, + InsufficientSecurity = 71, + InternalError = 80, + InappropriateFallback = 86, + UserCancelled = 90, + NoRenegotiation = 100, + MissingExtension = 109, + UnsupportedExtension = 110, + CertificateUnobtainable = 111, // reserved + UnrecognizedName = 112, + BadCertificateStatusResponse = 113, + BadCertificateHashValue = 114, // reserved + UnknownPskIdentity = 115, + CertificateRequired = 116, + NoApplicationProtocol = 120, + UnknownAlertMessage = 255 +}; + class QSslSocketPrivate; class Q_NETWORK_EXPORT QSslSocket : public QTcpSocket { @@ -165,8 +207,6 @@ public: // CA settings. #if QT_DEPRECATED_SINCE(5, 15) - QT_DEPRECATED_X("Use QSslConfiguration::addCaCertificates()") bool addCaCertificates(const QString &path, QSsl::EncodingFormat format = QSsl::Pem, - QRegExp::PatternSyntax syntax = QRegExp::FixedString); QT_DEPRECATED_X("Use QSslConfiguration::addCaCertificate()") void addCaCertificate(const QSslCertificate &certificate); QT_DEPRECATED_X("Use QSslConfiguration::addCaCertificates()") void addCaCertificates(const QList<QSslCertificate> &certificates); #endif // QT_DEPRECATED_SINCE(5, 15) @@ -175,8 +215,6 @@ public: QT_DEPRECATED_X("Use QSslConfiguration::caCertificates()") QList<QSslCertificate> caCertificates() const; #endif // QT_DEPRECATED_SINCE(5, 5) #if QT_DEPRECATED_SINCE(5, 15) - QT_DEPRECATED static bool addDefaultCaCertificates(const QString &path, QSsl::EncodingFormat format = QSsl::Pem, - QRegExp::PatternSyntax syntax = QRegExp::FixedString); QT_DEPRECATED static void addDefaultCaCertificate(const QSslCertificate &certificate); QT_DEPRECATED static void addDefaultCaCertificates(const QList<QSslCertificate> &certificates); #endif // QT_DEPRECATED_SINCE(5, 15) @@ -204,6 +242,7 @@ public: static QString sslLibraryBuildVersionString(); void ignoreSslErrors(const QList<QSslError> &errors); + void continueInterruptedHandshake(); public Q_SLOTS: void startClientEncryption(); @@ -218,6 +257,9 @@ Q_SIGNALS: void encryptedBytesWritten(qint64 totalBytes); void preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator *authenticator); void newSessionTicketReceived(); + void alertSent(QAlertLevel level, QAlertType type, const QString &description); + void alertReceived(QAlertLevel level, QAlertType type, const QString &description); + void handshakeInterruptedOnError(const QSslError &error); protected: qint64 readData(char *data, qint64 maxlen) override; diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp index 77e847e972..1ae32b0330 100644 --- a/src/network/ssl/qsslsocket_mac.cpp +++ b/src/network/ssl/qsslsocket_mac.cpp @@ -496,10 +496,6 @@ QSsl::SslProtocol QSslSocketBackendPrivate::sessionProtocol() const } switch (protocol) { - case kSSLProtocol2: - return QSsl::SslV2; - case kSSLProtocol3: - return QSsl::SslV3; case kTLSProtocol1: return QSsl::TlsV1_0; case kTLSProtocol11: @@ -657,23 +653,6 @@ QSslCipher QSslSocketBackendPrivate::QSslCipher_from_SSLCipherSuite(SSLCipherSui QSslCipher ciph; switch (cipher) { // Sorted as in CipherSuite.h (and groupped by their RFC) - case SSL_RSA_WITH_NULL_MD5: - ciph.d->name = QLatin1String("NULL-MD5"); - ciph.d->protocol = QSsl::SslV3; - break; - case SSL_RSA_WITH_NULL_SHA: - ciph.d->name = QLatin1String("NULL-SHA"); - ciph.d->protocol = QSsl::SslV3; - break; - case SSL_RSA_WITH_RC4_128_MD5: - ciph.d->name = QLatin1String("RC4-MD5"); - ciph.d->protocol = QSsl::SslV3; - break; - case SSL_RSA_WITH_RC4_128_SHA: - ciph.d->name = QLatin1String("RC4-SHA"); - ciph.d->protocol = QSsl::SslV3; - break; - // TLS addenda using AES, per RFC 3268 case TLS_RSA_WITH_AES_128_CBC_SHA: ciph.d->name = QLatin1String("AES128-SHA"); @@ -822,12 +801,8 @@ QSslCipher QSslSocketBackendPrivate::QSslCipher_from_SSLCipherSuite(SSLCipherSui ciph.d->isNull = false; // protocol - if (ciph.d->protocol == QSsl::SslV3) { - ciph.d->protocolString = QLatin1String("SSLv3"); - } else { - ciph.d->protocol = QSsl::TlsV1_2; - ciph.d->protocolString = QLatin1String("TLSv1.2"); - } + ciph.d->protocol = QSsl::TlsV1_2; + ciph.d->protocolString = QLatin1String("TLSv1.2"); const auto bits = ciph.d->name.splitRef(QLatin1Char('-')); if (bits.size() >= 2) { @@ -1106,22 +1081,6 @@ bool QSslSocketBackendPrivate::setSessionProtocol() { Q_ASSERT_X(context, Q_FUNC_INFO, "invalid SSL context (null)"); - // QSsl::SslV2 == kSSLProtocol2 is disabled in Secure Transport and - // always fails with errSSLIllegalParam: - // if (version < MINIMUM_STREAM_VERSION || version > MAXIMUM_STREAM_VERSION) - // return errSSLIllegalParam; - // where MINIMUM_STREAM_VERSION is SSL_Version_3_0, MAXIMUM_STREAM_VERSION is TLS_Version_1_2. - if (configuration.protocol == QSsl::SslV2) { - qCDebug(lcSsl) << "protocol QSsl::SslV2 is disabled"; - return false; - } - - // SslV3 is unsupported. - if (configuration.protocol == QSsl::SslV3) { - qCDebug(lcSsl) << "protocol QSsl::SslV3 is disabled"; - return false; - } - // SecureTransport has kTLSProtocol13 constant and also, kTLSProtocolMaxSupported. // Calling SSLSetProtocolVersionMax/Min with any of these two constants results // in errInvalidParam and a failure to set the protocol version. This means @@ -1162,13 +1121,6 @@ bool QSslSocketBackendPrivate::setSessionProtocol() qCDebug(lcSsl) << plainSocket << "requesting : any"; #endif err = SSLSetProtocolVersionMin(context, kTLSProtocol1); - } else if (configuration.protocol == QSsl::TlsV1SslV3) { - #ifdef QSSLSOCKET_DEBUG - qCDebug(lcSsl) << plainSocket << "requesting : SSLv3 - TLSv1.2"; - #endif - err = SSLSetProtocolVersionMin(context, kTLSProtocol1); - if (err == errSecSuccess) - err = SSLSetProtocolVersionMax(context, kTLSProtocol1); } else if (configuration.protocol == QSsl::SecureProtocols) { #ifdef QSSLSOCKET_DEBUG qCDebug(lcSsl) << plainSocket << "requesting : TLSv1 - TLSv1.2"; @@ -1213,8 +1165,6 @@ bool QSslSocketBackendPrivate::verifySessionProtocol() const bool protocolOk = false; if (configuration.protocol == QSsl::AnyProtocol) protocolOk = true; - else if (configuration.protocol == QSsl::TlsV1SslV3) - protocolOk = (sessionProtocol() == QSsl::TlsV1_0); else if (configuration.protocol == QSsl::SecureProtocols) protocolOk = (sessionProtocol() >= QSsl::TlsV1_0); else if (configuration.protocol == QSsl::TlsV1_0OrLater) diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 859216d097..b6570e2bdd 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -98,6 +98,123 @@ QT_BEGIN_NAMESPACE +namespace { + +QAlertLevel tlsAlertLevel(int value) +{ + if (const char *typeString = q_SSL_alert_type_string(value)) { + // Documented to return 'W' for warning, 'F' for fatal, + // 'U' for unknown. + switch (typeString[0]) { + case 'W': + return QAlertLevel::Warning; + case 'F': + return QAlertLevel::Fatal; + default:; + } + } + + return QAlertLevel::Unknown; +} + +QString tlsAlertDescription(int value) +{ + QString description = QLatin1String(q_SSL_alert_desc_string_long(value)); + if (!description.size()) + description = QLatin1String("no description provided"); + return description; +} + +QAlertType tlsAlertType(int value) +{ + // In case for some reason openssl gives us a value, + // which is not in our enum actually, we leave it to + // an application to handle (supposedly they have + // if or switch-statements). + return QAlertType(value & 0xff); +} + +} // Unnamed namespace + +extern "C" +{ + +void qt_AlertInfoCallback(const SSL *connection, int from, int value) +{ + // Passed to SSL_set_info_callback() + // https://www.openssl.org/docs/man1.1.1/man3/SSL_set_info_callback.html + + if (!connection) { +#ifdef QSSLSOCKET_DEBUG + qCWarning(lcSsl, "Invalid 'connection' parameter (nullptr)"); +#endif // QSSLSOCKET_DEBUG + return; + } + + const auto offset = QSslSocketBackendPrivate::s_indexForSSLExtraData + + QSslSocketBackendPrivate::socketOffsetInExData; + auto privateSocket = + static_cast<QSslSocketBackendPrivate *>(q_SSL_get_ex_data(connection, offset)); + if (!privateSocket) { + // SSL_set_ex_data can fail: +#ifdef QSSLSOCKET_DEBUG + qCWarning(lcSsl, "No external data (socket backend) found for parameter 'connection'"); +#endif // QSSLSOCKET_DEBUG + return; + } + + if (!(from & SSL_CB_ALERT)) { + // We only want to know about alerts (at least for now). + return; + } + + if (from & SSL_CB_WRITE) + privateSocket->alertMessageSent(value); + else + privateSocket->alertMessageReceived(value); +} + +int q_X509CallbackDirect(int ok, X509_STORE_CTX *ctx) +{ + // Passed to SSL_CTX_set_verify() + // https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_verify.html + // Returns 0 to abort verification, 1 to continue. + + // This is a new, experimental verification callback, reporting + // errors immediately and returning 0 or 1 depending on an application + // either ignoring or not ignoring verification errors as they come. + if (!ctx) { + qCWarning(lcSsl, "Invalid store context (nullptr)"); + return 0; + } + + if (!ok) { + // "Whenever a X509_STORE_CTX object is created for the verification of the + // peer's certificate during a handshake, a pointer to the SSL object is + // stored into the X509_STORE_CTX object to identify the connection affected. + // To retrieve this pointer the X509_STORE_CTX_get_ex_data() function can be + // used with the correct index." + SSL *ssl = static_cast<SSL *>(q_X509_STORE_CTX_get_ex_data(ctx, q_SSL_get_ex_data_X509_STORE_CTX_idx())); + if (!ssl) { + qCWarning(lcSsl, "No external data (SSL) found in X509 store object"); + return 0; + } + + const auto offset = QSslSocketBackendPrivate::s_indexForSSLExtraData + + QSslSocketBackendPrivate::socketOffsetInExData; + auto privateSocket = static_cast<QSslSocketBackendPrivate *>(q_SSL_get_ex_data(ssl, offset)); + if (!privateSocket) { + qCWarning(lcSsl, "No external data (QSslSocketBackendPrivate) found in SSL object"); + return 0; + } + + return privateSocket->emitErrorFromCallback(ctx); + } + return 1; +} + +} // extern "C" + Q_GLOBAL_STATIC(QRecursiveMutex, qt_opensslInitMutex) bool QSslSocketPrivate::s_libraryLoaded = false; @@ -266,11 +383,7 @@ QSslCipher QSslSocketBackendPrivate::QSslCipher_from_SSL_CIPHER(const SSL_CIPHER QString protoString = descriptionList.at(1).toString(); ciph.d->protocolString = protoString; ciph.d->protocol = QSsl::UnknownProtocol; - if (protoString == QLatin1String("SSLv3")) - ciph.d->protocol = QSsl::SslV3; - else if (protoString == QLatin1String("SSLv2")) - ciph.d->protocol = QSsl::SslV2; - else if (protoString == QLatin1String("TLSv1")) + if (protoString == QLatin1String("TLSv1")) ciph.d->protocol = QSsl::TlsV1_0; else if (protoString == QLatin1String("TLSv1.1")) ciph.d->protocol = QSsl::TlsV1_1; @@ -425,12 +538,15 @@ int q_X509Callback(int ok, X509_STORE_CTX *ctx) // Not found on store? Try SSL and its external data then. According to the OpenSSL's // documentation: // - // "Whenever a X509_STORE_CTX object is created for the verification of the peers certificate - // during a handshake, a pointer to the SSL object is stored into the X509_STORE_CTX object - // to identify the connection affected. To retrieve this pointer the X509_STORE_CTX_get_ex_data() - // function can be used with the correct index." + // "Whenever a X509_STORE_CTX object is created for the verification of the + // peer's certificate during a handshake, a pointer to the SSL object is + // stored into the X509_STORE_CTX object to identify the connection affected. + // To retrieve this pointer the X509_STORE_CTX_get_ex_data() function can be + // used with the correct index." + const auto offset = QSslSocketBackendPrivate::s_indexForSSLExtraData + + QSslSocketBackendPrivate::errorOffsetInExData; if (SSL *ssl = static_cast<SSL *>(q_X509_STORE_CTX_get_ex_data(ctx, q_SSL_get_ex_data_X509_STORE_CTX_idx()))) - errors = ErrorListPtr(q_SSL_get_ex_data(ssl, QSslSocketBackendPrivate::s_indexForSSLExtraData + 1)); + errors = ErrorListPtr(q_SSL_get_ex_data(ssl, offset)); } if (!errors) { @@ -476,20 +592,23 @@ void q_setDefaultDtlsCiphers(const QList<QSslCipher> &ciphers); long QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions) { long options; - if (protocol == QSsl::TlsV1SslV3) - options = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3; - else if (protocol == QSsl::SecureProtocols) - options = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3; - else if (protocol == QSsl::TlsV1_0OrLater) - options = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3; - else if (protocol == QSsl::TlsV1_1OrLater) - options = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1; - else if (protocol == QSsl::TlsV1_2OrLater) - options = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1; - else if (protocol == QSsl::TlsV1_3OrLater) - options = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1|SSL_OP_NO_TLSv1_2; - else + switch (protocol) { + case QSsl::SecureProtocols: + case QSsl::TlsV1_0OrLater: + options = SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3; + break; + case QSsl::TlsV1_1OrLater: + options = SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1; + break; + case QSsl::TlsV1_2OrLater: + options = SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1; + break; + case QSsl::TlsV1_3OrLater: + options = SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2; + break; + default: options = SSL_OP_ALL; + } // This option is disabled by default, so we need to be able to clear it if (sslOptions & QSsl::SslOptionDisableEmptyFragments) @@ -547,10 +666,7 @@ bool QSslSocketBackendPrivate::initSslContext() return false; } - if (configuration.protocol != QSsl::SslV2 && - configuration.protocol != QSsl::SslV3 && - configuration.protocol != QSsl::UnknownProtocol && - mode == QSslSocket::SslClientMode) { + if (configuration.protocol != QSsl::UnknownProtocol && mode == QSslSocket::SslClientMode) { // Set server hostname on TLS extension. RFC4366 section 3.1 requires it in ACE format. QString tlsHostName = verificationPeerName.isEmpty() ? q->peerName() : verificationPeerName; if (tlsHostName.isEmpty()) @@ -1223,18 +1339,32 @@ bool QSslSocketBackendPrivate::startHandshake() if (inSetAndEmitError) return false; + pendingFatalAlert = false; + errorsReportedFromCallback = false; QVector<QSslErrorEntry> lastErrors; - q_SSL_set_ex_data(ssl, s_indexForSSLExtraData + 1, &lastErrors); + q_SSL_set_ex_data(ssl, s_indexForSSLExtraData + errorOffsetInExData, &lastErrors); + + // SSL_set_ex_data can fail, but see the callback's code - we handle this there. + q_SSL_set_ex_data(ssl, s_indexForSSLExtraData + socketOffsetInExData, this); + q_SSL_set_info_callback(ssl, qt_AlertInfoCallback); + int result = (mode == QSslSocket::SslClientMode) ? q_SSL_connect(ssl) : q_SSL_accept(ssl); - q_SSL_set_ex_data(ssl, s_indexForSSLExtraData + 1, nullptr); + q_SSL_set_ex_data(ssl, s_indexForSSLExtraData + errorOffsetInExData, nullptr); + // Note, unlike errors as external data on SSL object, we do not unset + // a callback/ex-data if alert notifications are enabled: an alert can + // arrive after the handshake, for example, this happens when the server + // does not find a ClientCert or does not like it. - if (!lastErrors.isEmpty()) + if (!lastErrors.isEmpty() || errorsReportedFromCallback) storePeerCertificates(); - for (const auto ¤tError : qAsConst(lastErrors)) { - emit q->peerVerifyError(_q_OpenSSL_to_QSslError(currentError.code, - configuration.peerCertificateChain.value(currentError.depth))); - if (q->state() != QAbstractSocket::ConnectedState) - break; + + if (!errorsReportedFromCallback) { + for (const auto ¤tError : qAsConst(lastErrors)) { + emit q->peerVerifyError(_q_OpenSSL_to_QSslError(currentError.code, + configuration.peerCertificateChain.value(currentError.depth))); + if (q->state() != QAbstractSocket::ConnectedState) + break; + } } errorList << lastErrors; @@ -1258,6 +1388,10 @@ bool QSslSocketBackendPrivate::startHandshake() { const ScopedBool bg(inSetAndEmitError, true); setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError, errorString); + if (pendingFatalAlert) { + trySendFatalAlert(); + pendingFatalAlert = false; + } } q->abort(); } @@ -1781,6 +1915,88 @@ bool QSslSocketBackendPrivate::checkOcspStatus() #endif // ocsp +void QSslSocketBackendPrivate::alertMessageSent(int value) +{ + Q_Q(QSslSocket); + + const auto level = tlsAlertLevel(value); + if (level == QAlertLevel::Fatal && !connectionEncrypted) { + // Note, this logic is handshake-time only: + pendingFatalAlert = true; + } + + emit q->alertSent(level, tlsAlertType(value), tlsAlertDescription(value)); +} + +void QSslSocketBackendPrivate::alertMessageReceived(int value) +{ + Q_Q(QSslSocket); + + emit q->alertReceived(tlsAlertLevel(value), tlsAlertType(value), tlsAlertDescription(value)); +} + +int QSslSocketBackendPrivate::emitErrorFromCallback(X509_STORE_CTX *ctx) +{ + // Returns 0 to abort verification, 1 to continue despite error (as + // OpenSSL expects from the verification callback). + Q_Q(QSslSocket); + + Q_ASSERT(ctx); + + using ScopedBool = QScopedValueRollback<bool>; + // While we are not setting, we are emitting and in general - + // we want to prevent accidental recursive startHandshake() + // calls: + const ScopedBool bg(inSetAndEmitError, true); + + X509 *x509 = q_X509_STORE_CTX_get_current_cert(ctx); + if (!x509) { + qCWarning(lcSsl, "Could not obtain the certificate (that failed to verify)"); + return 0; + } + const QSslCertificate certificate = QSslCertificatePrivate::QSslCertificate_from_X509(x509); + + const auto errorAndDepth = QSslErrorEntry::fromStoreContext(ctx); + const QSslError tlsError = _q_OpenSSL_to_QSslError(errorAndDepth.code, certificate); + + errorsReportedFromCallback = true; + handshakeInterrupted = true; + emit q->handshakeInterruptedOnError(tlsError); + + // Conveniently so, we also can access 'lastErrors' external data set + // in startHandshake, we store it for the case an application later + // wants to check errors (ignored or not): + const auto offset = QSslSocketBackendPrivate::s_indexForSSLExtraData + + QSslSocketBackendPrivate::errorOffsetInExData; + if (auto errorList = static_cast<QVector<QSslErrorEntry>*>(q_SSL_get_ex_data(ssl, offset))) + errorList->append(errorAndDepth); + + // An application is expected to ignore this error (by calling ignoreSslErrors) + // in its directly connected slot: + return !handshakeInterrupted; +} + +void QSslSocketBackendPrivate::trySendFatalAlert() +{ + Q_ASSERT(pendingFatalAlert); + + pendingFatalAlert = false; + QVarLengthArray<char, 4096> data; + int pendingBytes = 0; + while (plainSocket->isValid() && (pendingBytes = q_BIO_pending(writeBio)) > 0 + && plainSocket->openMode() != QIODevice::NotOpen) { + // Read encrypted data from the write BIO into a buffer. + data.resize(pendingBytes); + const int bioReadBytes = q_BIO_read(writeBio, data.data(), pendingBytes); + + // Write encrypted data from the buffer to the socket. + qint64 actualWritten = plainSocket->write(data.constData(), bioReadBytes); + if (actualWritten < 0) + return; + plainSocket->flush(); + } +} + void QSslSocketBackendPrivate::disconnectFromHost() { if (ssl) { @@ -1828,10 +2044,6 @@ QSsl::SslProtocol QSslSocketBackendPrivate::sessionProtocol() const int ver = q_SSL_version(ssl); switch (ver) { - case 0x2: - return QSsl::SslV2; - case 0x300: - return QSsl::SslV3; case 0x301: return QSsl::TlsV1_0; case 0x302: diff --git a/src/network/ssl/qsslsocket_openssl_p.h b/src/network/ssl/qsslsocket_openssl_p.h index 47ccf06e71..6c1ffb7237 100644 --- a/src/network/ssl/qsslsocket_openssl_p.h +++ b/src/network/ssl/qsslsocket_openssl_p.h @@ -131,6 +131,10 @@ public: SSL_SESSION *session; QVector<QSslErrorEntry> errorList; static int s_indexForSSLExtraData; // index used in SSL_get_ex_data to get the matching QSslSocketBackendPrivate + enum ExDataOffset { + errorOffsetInExData = 1, + socketOffsetInExData = 2 + }; bool inSetAndEmitError = false; @@ -158,6 +162,15 @@ public: bool checkOcspStatus(); #endif + void alertMessageSent(int encoded); + void alertMessageReceived(int encoded); + + int emitErrorFromCallback(X509_STORE_CTX *ctx); + void trySendFatalAlert(); + + bool pendingFatalAlert = false; + bool errorsReportedFromCallback = false; + // This decription will go to setErrorAndEmit(SslHandshakeError, ocspErrorDescription) QString ocspErrorDescription; // These will go to sslErrors() diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index 627ae31651..777dc70565 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -156,6 +156,10 @@ DEFINEFUNC(void, OPENSSL_sk_free, OPENSSL_STACK *a, a, return, DUMMYARG) DEFINEFUNC2(void *, OPENSSL_sk_value, OPENSSL_STACK *a, a, int b, b, return nullptr, return) DEFINEFUNC(int, SSL_session_reused, SSL *a, a, return 0, return) DEFINEFUNC2(unsigned long, SSL_CTX_set_options, SSL_CTX *ctx, ctx, unsigned long op, op, return 0, return) +using info_callback = void (*) (const SSL *ssl, int type, int val); +DEFINEFUNC2(void, SSL_set_info_callback, SSL *ssl, ssl, info_callback cb, cb, return, return) +DEFINEFUNC(const char *, SSL_alert_type_string, int value, value, return nullptr, return) +DEFINEFUNC(const char *, SSL_alert_desc_string_long, int value, value, return nullptr, return) #ifdef TLS1_3_VERSION DEFINEFUNC2(int, SSL_CTX_set_ciphersuites, SSL_CTX *ctx, ctx, const char *str, str, return 0, return) DEFINEFUNC2(void, SSL_set_psk_use_session_callback, SSL *ssl, ssl, q_SSL_psk_use_session_cb_func_t callback, callback, return, DUMMYARG) @@ -842,7 +846,9 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(OPENSSL_sk_value) RESOLVEFUNC(DH_get0_pqg) RESOLVEFUNC(SSL_CTX_set_options) - + RESOLVEFUNC(SSL_set_info_callback) + RESOLVEFUNC(SSL_alert_type_string) + RESOLVEFUNC(SSL_alert_desc_string_long) #ifdef TLS1_3_VERSION RESOLVEFUNC(SSL_CTX_set_ciphersuites) RESOLVEFUNC(SSL_set_psk_use_session_callback) diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h index e8f6b7e752..78b097fad6 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols_p.h +++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h @@ -736,6 +736,10 @@ int q_OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b); void *q_CRYPTO_malloc(size_t num, const char *file, int line); #define q_OPENSSL_malloc(num) q_CRYPTO_malloc(num, "", 0) +void q_SSL_set_info_callback(SSL *ssl, void (*cb) (const SSL *ssl, int type, int val)); +const char *q_SSL_alert_type_string(int value); +const char *q_SSL_alert_desc_string_long(int value); + QT_END_NAMESPACE #endif diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h index 87179c8083..25625a1313 100644 --- a/src/network/ssl/qsslsocket_p.h +++ b/src/network/ssl/qsslsocket_p.h @@ -140,8 +140,6 @@ public: static QList<QSslCertificate> defaultCaCertificates(); static QList<QSslCertificate> systemCaCertificates(); static void setDefaultCaCertificates(const QList<QSslCertificate> &certs); - static bool addDefaultCaCertificates(const QString &path, QSsl::EncodingFormat format, - QRegExp::PatternSyntax syntax); static void addDefaultCaCertificate(const QSslCertificate &cert); static void addDefaultCaCertificates(const QList<QSslCertificate> &certs); Q_AUTOTEST_EXPORT static bool isMatchingHostname(const QSslCertificate &cert, @@ -209,6 +207,7 @@ protected: bool flushTriggered; bool systemOrSslErrorDetected = false; QVector<QOcspResponse> ocspResponses; + bool handshakeInterrupted = false; }; #if QT_CONFIG(securetransport) || QT_CONFIG(schannel) diff --git a/src/network/ssl/qsslsocket_schannel.cpp b/src/network/ssl/qsslsocket_schannel.cpp index e47fda17ab..c355abad73 100644 --- a/src/network/ssl/qsslsocket_schannel.cpp +++ b/src/network/ssl/qsslsocket_schannel.cpp @@ -226,12 +226,6 @@ DWORD toSchannelProtocol(QSsl::SslProtocol protocol) protocols = SP_PROT_TLS1_0 | SP_PROT_TLS1_1 | SP_PROT_TLS1_2; // @future Add TLS 1.3 when supported by Windows! break; - case QSsl::SslV2: - case QSsl::SslV3: - return DWORD(-1); // Not supported - case QSsl::TlsV1SslV3: - protocols = SP_PROT_TLS1_0; - break; case QSsl::TlsV1_0: protocols = SP_PROT_TLS1_0; break; diff --git a/src/network/ssl/qsslsocket_winrt.cpp b/src/network/ssl/qsslsocket_winrt.cpp index f3ca3dc257..5f5201fc82 100644 --- a/src/network/ssl/qsslsocket_winrt.cpp +++ b/src/network/ssl/qsslsocket_winrt.cpp @@ -230,13 +230,7 @@ void QSslSocketBackendPrivate::startClientEncryption() QSsl::SslProtocol protocol = q->protocol(); switch (q->protocol()) { - case QSsl::SslV2: - case QSsl::SslV3: - setErrorAndEmit(QAbstractSocket::SslInvalidUserDataError, - QStringLiteral("unsupported protocol")); - return; case QSsl::AnyProtocol: - case QSsl::TlsV1SslV3: protectionLevel = SocketProtectionLevel_Tls10; break; case QSsl::TlsV1_0: @@ -270,7 +264,7 @@ void QSslSocketBackendPrivate::startClientEncryption() } // Sync custom certificates - const QSet<QSslCertificate> caCertificates = configuration.caCertificates.toSet(); + const QSet<QSslCertificate> caCertificates(configuration.caCertificates.constBegin(), configuration.caCertificates.constEnd()); const QSet<QSslCertificate> newCertificates = caCertificates - previousCaCertificates; const QSet<QSslCertificate> oldCertificates = previousCaCertificates - caCertificates; g->syncCaCertificates(newCertificates, oldCertificates); @@ -393,7 +387,7 @@ void QSslSocketBackendPrivate::continueHandshake() hr = control2->get_IgnorableServerCertificateErrors(&ignoreList); Q_ASSERT_SUCCEEDED(hr); - QSet<QSslError> ignoreErrors = ignoreErrorsList.toSet(); + QSet<QSslError> ignoreErrors(ignoreErrorsList.constBegin(), ignoreErrorsList.constEnd()); for (int i = ChainValidationResult_Untrusted; i < ChainValidationResult_OtherErrors + 1; ++i) { // Populate the native ignore list - break to add, continue to skip switch (i) { @@ -596,7 +590,7 @@ HRESULT QSslSocketBackendPrivate::onSslUpgrade(IAsyncAction *action, AsyncStatus } } - sslErrors = errors.toList(); + sslErrors = QList<QSslError>(errors.constBegin(), errors.constEnd()); // Peer validation if (!configuration.peerCertificate.isNull()) { |