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 QString token = QString::fromUtf8(rawToken).trimmed();
33
34 // A lone "*" bypasses every host, which suffix matching cannot express.
35 if (token == "*"_L1)
36 return true;
37
38 // A leading "*" is redundant once the rest is matched as a suffix.
39 if (token.startsWith(u'*'))
40 token = token.mid(1);
41
42 // Harmonize trailing dot notation
43 if (token.endsWith(u'.') && !host.endsWith(u'.'))
44 token = token.chopped(1);
45
46 if (token.startsWith(u'.')) // leading dot is implied
47 token = token.mid(1);
48
49 // QUrl hands back a canonical host, so put the entry in that form.
50 if (const QByteArray ace = QUrl::toAce(token); !ace.isEmpty())
51 token = QUrl::fromAce(ace);
52
53 if (host.endsWith(token)) {
54
55 // Make sure that when we have a suffix match,
56 // we don't match "donotmatch.com" with "match.com"
57
58 if (host.size() == token.size()) // iow: host == token
59 return true;
60 if (host[host.size() - token.size() - 1] == u'.') // match follows a dot
61 return true;
62 }
63 }
64
65 return false;
66}
67
68QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkProxyQuery &query)
69{
70 QList<QNetworkProxy> proxyList;
71
72 if (ignoreProxyFor(query))
73 return proxyList << QNetworkProxy::NoProxy;
74
75 // No need to care about casing here, QUrl lowercases values already
76 const QString queryProtocol = query.protocolTag();
77 QByteArray proxy_env;
78
79 if (queryProtocol == "http"_L1)
80 proxy_env = qgetenv("http_proxy");
81 else if (queryProtocol == "https"_L1)
82 proxy_env = qgetenv("https_proxy");
83 else if (queryProtocol == "ftp"_L1)
84 proxy_env = qgetenv("ftp_proxy");
85 else
86 proxy_env = qgetenv("all_proxy");
87
88 // Fallback to http_proxy is no protocol specific proxy was found
89 if (proxy_env.isEmpty())
90 proxy_env = qgetenv("http_proxy");
91
92 if (!proxy_env.isEmpty()) {
93 QUrl url = QUrl(QString::fromLocal8Bit(proxy_env));
94 const QString scheme = url.scheme();
95 if (scheme == "socks5"_L1 || scheme == "socks5h"_L1) {
96 QNetworkProxy proxy(QNetworkProxy::Socks5Proxy, url.host(),
97 url.port() ? url.port() : 1080, url.userName(), url.password());
98 proxyList << proxy;
99 } else if ((scheme.isEmpty() || scheme == "http"_L1)
100 && query.queryType() != QNetworkProxyQuery::UdpSocket
101 && query.queryType() != QNetworkProxyQuery::TcpServer) {
102 QNetworkProxy proxy(QNetworkProxy::HttpProxy, url.host(),
103 url.port() ? url.port() : 8080, url.userName(), url.password());
104 proxyList << proxy;
105 }
106 }
107 if (proxyList.isEmpty())
108 proxyList << QNetworkProxy::NoProxy;
109
110 return proxyList;
111}
112
113QT_END_NAMESPACE
114
115#endif
static bool ignoreProxyFor(const QNetworkProxyQuery &query)