Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qnetworkproxy_generic.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:critical reason:data-parser
4
6
7#include <QtCore/QByteArray>
8#include <QtCore/QUrl>
9
10#ifndef QT_NO_NETWORKPROXY
11
12/*
13 * Construct a proxy from the environment variables http_proxy and no_proxy.
14 * Or no system proxy. Just return a list with NoProxy.
15 */
16
17QT_BEGIN_NAMESPACE
18
19using namespace Qt::StringLiterals;
20
21static bool ignoreProxyFor(const QNetworkProxyQuery &query)
22{
23 const QByteArray noProxy = qgetenv("no_proxy").trimmed();
24 if (noProxy.isEmpty())
25 return false;
26
27 const QString host = query.peerHostName();
28
29 const QList<QByteArray> noProxyTokens = noProxy.split(',');
30
31 for (const QByteArray &rawToken : noProxyTokens) {
32 auto token = QLatin1StringView(rawToken).trimmed();
33
34 // Since we use suffix matching, "*" is our 'default' behaviour
35 if (token.startsWith(u'*'))
36 token = token.mid(1);
37
38 // Harmonize trailing dot notation
39 if (token.endsWith(u'.') && !host.endsWith(u'.'))
40 token = token.chopped(1);
41
42 if (token.startsWith(u'.')) // leading dot is implied
43 token = token.mid(1);
44
45 if (host.endsWith(token)) {
46
47 // Make sure that when we have a suffix match,
48 // we don't match "donotmatch.com" with "match.com"
49
50 if (host.size() == token.size()) // iow: host == token
51 return true;
52 if (host[host.size() - token.size() - 1] == u'.') // match follows a dot
53 return true;
54 }
55 }
56
57 return false;
58}
59
60QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkProxyQuery &query)
61{
62 QList<QNetworkProxy> proxyList;
63
64 if (ignoreProxyFor(query))
65 return proxyList << QNetworkProxy::NoProxy;
66
67 // No need to care about casing here, QUrl lowercases values already
68 const QString queryProtocol = query.protocolTag();
69 QByteArray proxy_env;
70
71 if (queryProtocol == "http"_L1)
72 proxy_env = qgetenv("http_proxy");
73 else if (queryProtocol == "https"_L1)
74 proxy_env = qgetenv("https_proxy");
75 else if (queryProtocol == "ftp"_L1)
76 proxy_env = qgetenv("ftp_proxy");
77 else
78 proxy_env = qgetenv("all_proxy");
79
80 // Fallback to http_proxy is no protocol specific proxy was found
81 if (proxy_env.isEmpty())
82 proxy_env = qgetenv("http_proxy");
83
84 if (!proxy_env.isEmpty()) {
85 QUrl url = QUrl(QString::fromLocal8Bit(proxy_env));
86 const QString scheme = url.scheme();
87 if (scheme == "socks5"_L1) {
88 QNetworkProxy proxy(QNetworkProxy::Socks5Proxy, url.host(),
89 url.port() ? url.port() : 1080, url.userName(), url.password());
90 proxyList << proxy;
91 } else if (scheme == "socks5h"_L1) {
92 QNetworkProxy proxy(QNetworkProxy::Socks5Proxy, url.host(),
93 url.port() ? url.port() : 1080, url.userName(), url.password());
94 proxy.setCapabilities(QNetworkProxy::HostNameLookupCapability);
95 proxyList << proxy;
96 } else if ((scheme.isEmpty() || scheme == "http"_L1)
97 && query.queryType() != QNetworkProxyQuery::UdpSocket
98 && query.queryType() != QNetworkProxyQuery::TcpServer) {
99 QNetworkProxy proxy(QNetworkProxy::HttpProxy, url.host(),
100 url.port() ? url.port() : 8080, url.userName(), url.password());
101 proxyList << proxy;
102 }
103 }
104 if (proxyList.isEmpty())
105 proxyList << QNetworkProxy::NoProxy;
106
107 return proxyList;
108}
109
110QT_END_NAMESPACE
111
112#endif
static bool ignoreProxyFor(const QNetworkProxyQuery &query)