6#ifndef QT_NO_NETWORKPROXY
8#include <CFNetwork/CFNetwork.h>
9#include <CoreFoundation/CoreFoundation.h>
10#include <SystemConfiguration/SystemConfiguration.h>
12#include <QtCore/QRegularExpression>
13#include <QtCore/QStringList>
15#include <QtCore/qendian.h>
16#include <QtCore/qstringlist.h>
17#include <QtCore/qsystemdetection.h>
18#include "private/qcore_mac_p.h"
60 CFNumberRef excludeSimples;
62 (excludeSimples = (CFNumberRef)CFDictionaryGetValue(dict, kCFNetworkProxiesExcludeSimpleHostnames))) {
64 if (CFNumberGetValue(excludeSimples, kCFNumberIntType, &
enabled) &&
enabled)
73 CFArrayRef exclusionList = (CFArrayRef)CFDictionaryGetValue(dict, kCFNetworkProxiesExceptionsList);
77 CFIndex
size = CFArrayGetCount(exclusionList);
78 for (CFIndex
i = 0;
i <
size; ++
i) {
79 CFStringRef cfentry = (CFStringRef)CFArrayGetValueAtIndex(exclusionList,
i);
87 if (
rx.match(host).hasMatch())
99 CFStringRef enableKey, CFStringRef hostKey,
102 CFNumberRef protoEnabled;
103 CFNumberRef protoPort;
104 CFStringRef protoHost;
106 && (protoEnabled = (CFNumberRef)CFDictionaryGetValue(dict, enableKey))
107 && (protoHost = (CFStringRef)CFDictionaryGetValue(dict, hostKey))
108 && (protoPort = (CFNumberRef)CFDictionaryGetValue(dict, portKey))) {
110 if (CFNumberGetValue(protoEnabled, kCFNumberIntType, &
enabled) &&
enabled) {
111 QString host = QString::fromCFString(protoHost);
114 CFNumberGetValue(protoPort, kCFNumberIntType, &
port);
132 CFStringRef cfProxyType = (CFStringRef)CFDictionaryGetValue(dict, kCFProxyTypeKey);
133 if (CFStringCompare(cfProxyType, kCFProxyTypeNone, 0) == kCFCompareEqualTo) {
135 }
else if (CFStringCompare(cfProxyType, kCFProxyTypeFTP, 0) == kCFCompareEqualTo) {
137 }
else if (CFStringCompare(cfProxyType, kCFProxyTypeHTTP, 0) == kCFCompareEqualTo) {
139 }
else if (CFStringCompare(cfProxyType, kCFProxyTypeHTTPS, 0) == kCFCompareEqualTo) {
141 }
else if (CFStringCompare(cfProxyType, kCFProxyTypeSOCKS, 0) == kCFCompareEqualTo) {
145 hostName = QString::fromCFString((CFStringRef)CFDictionaryGetValue(dict, kCFProxyHostNameKey));
146 user = QString::fromCFString((CFStringRef)CFDictionaryGetValue(dict, kCFProxyUsernameKey));
147 password = QString::fromCFString((CFStringRef)CFDictionaryGetValue(dict, kCFProxyPasswordKey));
149 CFNumberRef portNumber = (CFNumberRef)CFDictionaryGetValue(dict, kCFProxyPortNumberKey);
151 CFNumberGetValue(portNumber, kCFNumberSInt16Type, &
port);
164void proxyAutoConfigCallback(
void *client, CFArrayRef proxylist, CFErrorRef
error)
168 PACInfo *
info =
static_cast<PACInfo *
>(client);
177 info->proxies = proxylist;
184 const auto qtPath = QString::fromCFString(originalPath);
186 return escaped.toCFString();
199 const auto count = CFArrayGetCount(proxies);
203 for (CFIndex
i = 0;
i <
count; ++
i) {
204 const void *
obj = CFArrayGetValueAtIndex(proxies,
i);
205 if (CFGetTypeID(
obj) != CFDictionaryGetTypeID())
225 qWarning(
"QNetworkProxyFactory::systemProxyForQuery: CFNetworkCopySystemProxySettings returned nullptr");
233 CFNumberRef pacEnabled;
234 if ((pacEnabled = (CFNumberRef)CFDictionaryGetValue(dict, kCFNetworkProxiesProxyAutoConfigEnable))) {
236 if (CFNumberGetValue(pacEnabled, kCFNumberIntType, &
enabled) &&
enabled) {
240 CFStringRef pacLocationSetting = (CFStringRef)CFDictionaryGetValue(dict, kCFNetworkProxiesProxyAutoConfigURLString);
241 auto cfPacLocation = stringByAddingPercentEscapes(pacLocationSetting);
243 QCFType<CFURLRef> pacUrl = CFURLCreateWithString(kCFAllocatorDefault, cfPacLocation, NULL);
254 QCFType<CFURLRef> targetURL = CFURLCreateWithBytes(kCFAllocatorDefault, (UInt8*)encodedURL.
data(), encodedURL.
size(), kCFStringEncodingUTF8, NULL);
259 CFStreamClientContext pacCtx;
262 pacCtx.info = &pacInfo;
263 pacCtx.retain = NULL;
264 pacCtx.release = NULL;
265 pacCtx.copyDescription = NULL;
267 static CFStringRef pacRunLoopMode = CFSTR(
"qtPACRunLoopMode");
269 QCFType<CFRunLoopSourceRef> pacRunLoopSource = CFNetworkExecuteProxyAutoConfigurationURL(pacUrl, targetURL, &proxyAutoConfigCallback, &pacCtx);
270 CFRunLoopAddSource(CFRunLoopGetCurrent(), pacRunLoopSource, pacRunLoopMode);
271 while (!pacInfo.done)
272 CFRunLoopRunInMode(pacRunLoopMode, 1000,
true);
274 if (!pacInfo.proxies) {
275 QString pacLocation = QString::fromCFString(cfPacLocation);
277 qWarning(
"Execution of PAC script at \"%s\" failed: %s",
qPrintable(pacLocation),
qPrintable(QString::fromCFString(pacErrorDescription)));
281 CFIndex
size = CFArrayGetCount(pacInfo.proxies);
282 for (CFIndex
i = 0;
i <
size; ++
i) {
283 CFDictionaryRef
proxy = (CFDictionaryRef)CFArrayGetValueAtIndex(pacInfo.proxies,
i);
294 if (protocol ==
"http"_L1) {
295 protocolSpecificProxy =
297 kCFNetworkProxiesHTTPEnable,
298 kCFNetworkProxiesHTTPProxy,
299 kCFNetworkProxiesHTTPPort);
308 result << protocolSpecificProxy;
314 const auto proxiesForUrl = proxiesForQueryUrl(dict,
query.url());
315 for (
const auto &
proxy : proxiesForUrl) {
320 bool isHttps =
false;
321 if (protocol ==
"ftp"_L1) {
322 protocolSpecificProxy =
324 kCFNetworkProxiesFTPEnable,
325 kCFNetworkProxiesFTPProxy,
326 kCFNetworkProxiesFTPPort);
327 }
else if (protocol ==
"https"_L1) {
329 protocolSpecificProxy =
331 kCFNetworkProxiesHTTPSEnable,
332 kCFNetworkProxiesHTTPSProxy,
333 kCFNetworkProxiesHTTPSPort);
337 result << protocolSpecificProxy;
341 kCFNetworkProxiesSOCKSEnable,
342 kCFNetworkProxiesSOCKSProxy,
343 kCFNetworkProxiesSOCKSPort);
352 kCFNetworkProxiesHTTPSEnable,
353 kCFNetworkProxiesHTTPSProxy,
354 kCFNetworkProxiesHTTPSPort);
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
The QHostAddress class provides an IP address.
bool isInSubnet(const QHostAddress &subnet, int netmask) const
void setAddress(quint32 ip4Addr)
Set the IPv4 address specified by ip4Addr.
static QPair< QHostAddress, int > parseSubnet(const QString &subnet)
static QList< QNetworkProxy > systemProxyForQuery(const QNetworkProxyQuery &query=QNetworkProxyQuery())
This function takes the query request, query, examines the details of the type of socket or request a...
The QNetworkProxyQuery class is used to query the proxy settings for a socket.
The QNetworkProxy class provides a network layer proxy.
ProxyType
This enum describes the types of network proxying provided in Qt.
QNetworkProxy::ProxyType type() const
Returns the proxy type for this instance.
static QRegularExpression fromWildcard(QStringView pattern, Qt::CaseSensitivity cs=Qt::CaseInsensitive, WildcardConversionOptions options=DefaultWildcardConversion)
\macro QT_RESTRICTED_CAST_FROM_ASCII
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
QString toLower() const &
bool contains(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Combined button and popup list for selecting options.
DBusConnection const char DBusError * error
static bool isHostExcluded(CFDictionaryRef dict, const QString &host)
static QNetworkProxy proxyFromDictionary(CFDictionaryRef dict, QNetworkProxy::ProxyType type, CFStringRef enableKey, CFStringRef hostKey, CFStringRef portKey)
QList< QNetworkProxy > macQueryInternal(const QNetworkProxyQuery &query)
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLenum GLsizei count
GLenum GLenum GLsizei const GLuint GLboolean enabled
#define qPrintable(string)
QFileInfo info(fileName)
[8]
QUrl url("example.com")
[constructor-url-reference]