Qt 4.8
qnetworkaccessauthenticationmanager.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtNetwork module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qnetworkaccessmanager.h"
45 
46 #include "QtCore/qbuffer.h"
47 #include "QtCore/qurl.h"
48 #include "QtCore/qvector.h"
49 #include "QtCore/QMutexLocker"
50 #include "QtNetwork/qauthenticator.h"
51 
53 
54 
55 
56 
57 class QNetworkAuthenticationCache: private QVector<QNetworkAuthenticationCredential>,
59 {
60 public:
62  {
63  setExpires(false);
64  setShareable(true);
65  reserve(1);
66  }
67 
69  {
70  iterator it = qLowerBound(begin(), end(), domain);
71  if (it == end() && !isEmpty())
72  --it;
73  if (it == end() || !domain.startsWith(it->domain))
74  return 0;
75  return &*it;
76  }
77 
78  void insert(const QString &domain, const QString &user, const QString &password)
79  {
81  if (closestMatch && closestMatch->domain == domain) {
82  // we're overriding the current credentials
83  closestMatch->user = user;
84  closestMatch->password = password;
85  } else {
87  newCredential.domain = domain;
88  newCredential.user = user;
89  newCredential.password = password;
90 
91  if (closestMatch)
92  QVector<QNetworkAuthenticationCredential>::insert(++closestMatch, newCredential);
93  else
95  }
96  }
97 
98  virtual void dispose() { delete this; }
99 };
100 
101 #ifndef QT_NO_NETWORKPROXY
102 static QByteArray proxyAuthenticationKey(const QNetworkProxy &proxy, const QString &realm)
103 {
104  QUrl key;
105 
106  switch (proxy.type()) {
108  key.setScheme(QLatin1String("proxy-socks5"));
109  break;
110 
113  key.setScheme(QLatin1String("proxy-http"));
114  break;
115 
117  key.setScheme(QLatin1String("proxy-ftp"));
118  break;
119 
122  // shouldn't happen
123  return QByteArray();
124 
125  // no default:
126  // let there be errors if a new proxy type is added in the future
127  }
128 
129  if (key.scheme().isEmpty())
130  // proxy type not handled
131  return QByteArray();
132 
133  key.setUserName(proxy.user());
134  key.setHost(proxy.hostName());
135  key.setPort(proxy.port());
136  key.setFragment(realm);
137  return "auth:" + key.toEncoded();
138 }
139 #endif
140 
141 static inline QByteArray authenticationKey(const QUrl &url, const QString &realm)
142 {
143  QUrl copy = url;
144  copy.setFragment(realm);
146 }
147 
148 
149 #ifndef QT_NO_NETWORKPROXY
151  const QAuthenticator *authenticator)
152 {
153  Q_ASSERT(authenticator);
156 
157  QMutexLocker mutexLocker(&mutex);
158 
159  QString realm = authenticator->realm();
160  QNetworkProxy proxy = p;
161  proxy.setUser(authenticator->user());
162 
163  // don't cache null passwords, empty password may be valid though
164  if (authenticator->password().isNull())
165  return;
166 
167  // Set two credentials: one with the username and one without
168  do {
169  // Set two credentials actually: one with and one without the realm
170  do {
172  if (cacheKey.isEmpty())
173  return; // should not happen
174 
176  auth->insert(QString(), authenticator->user(), authenticator->password());
177  authenticationCache.addEntry(cacheKey, auth); // replace the existing one, if there's any
178 
179  if (realm.isEmpty()) {
180  break;
181  } else {
182  realm.clear();
183  }
184  } while (true);
185 
186  if (proxy.user().isEmpty())
187  break;
188  else
189  proxy.setUser(QString());
190  } while (true);
191 }
192 
195  const QAuthenticator *authenticator)
196 {
197  QNetworkProxy proxy = p;
198  if (proxy.type() == QNetworkProxy::DefaultProxy) {
200  }
201  if (!proxy.password().isEmpty())
202  return QNetworkAuthenticationCredential(); // no need to set credentials if it already has them
203 
204  QString realm;
205  if (authenticator)
206  realm = authenticator->realm();
207 
208  QMutexLocker mutexLocker(&mutex);
210  if (cacheKey.isEmpty())
212  if (!authenticationCache.hasEntry(cacheKey))
214 
216  static_cast<QNetworkAuthenticationCache *>(authenticationCache.requestEntryNow(cacheKey));
218  authenticationCache.releaseEntry(cacheKey);
219 
220  // proxy cache credentials always have exactly one item
221  Q_ASSERT_X(!cred.isNull(), "QNetworkAccessManager",
222  "Internal inconsistency: found a cache key for a proxy, but it's empty");
223  return cred;
224 }
225 
226 #endif
227 
229  const QAuthenticator *authenticator)
230 {
231  Q_ASSERT(authenticator);
232  QString domain = QString::fromLatin1("/"); // FIXME: make QAuthenticator return the domain
233  QString realm = authenticator->realm();
234 
235  QMutexLocker mutexLocker(&mutex);
236 
237  // Set two credentials actually: one with and one without the username in the URL
238  QUrl copy = url;
239  copy.setUserName(authenticator->user());
240  do {
241  QByteArray cacheKey = authenticationKey(copy, realm);
242  if (authenticationCache.hasEntry(cacheKey)) {
244  static_cast<QNetworkAuthenticationCache *>(authenticationCache.requestEntryNow(cacheKey));
245  auth->insert(domain, authenticator->user(), authenticator->password());
246  authenticationCache.releaseEntry(cacheKey);
247  } else {
249  auth->insert(domain, authenticator->user(), authenticator->password());
250  authenticationCache.addEntry(cacheKey, auth);
251  }
252 
253  if (copy.userName().isEmpty()) {
254  break;
255  } else {
256  copy.setUserName(QString());
257  }
258  } while (true);
259 }
260 
274  const QAuthenticator *authentication)
275 {
276  if (!url.password().isEmpty())
277  return QNetworkAuthenticationCredential(); // no need to set credentials if it already has them
278 
279  QString realm;
280  if (authentication)
281  realm = authentication->realm();
282 
283  QByteArray cacheKey = authenticationKey(url, realm);
284 
285  QMutexLocker mutexLocker(&mutex);
286  if (!authenticationCache.hasEntry(cacheKey))
288 
290  static_cast<QNetworkAuthenticationCache *>(authenticationCache.requestEntryNow(cacheKey));
293  if (cred)
294  ret = *cred;
295  authenticationCache.releaseEntry(cacheKey);
296  return ret;
297 }
298 
300 {
301  authenticationCache.clear();
302 }
303 
305 
QNetworkProxy::ProxyType type() const
Returns the proxy type for this instance.
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
static QByteArray authenticationKey(const QUrl &url, const QString &realm)
#define it(className, varName)
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
static QByteArray proxyAuthenticationKey(const QNetworkProxy &proxy, const QString &realm)
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
Definition: qstring.cpp:3734
QNetworkAuthenticationCredential * findClosestMatch(const QString &domain)
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
void setUser(const QString &userName)
Sets the user name for proxy authentication to be user.
The QUrl class provides a convenient interface for working with URLs.
Definition: qurl.h:61
The QString class provides a Unicode character string.
Definition: qstring.h:83
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
The QVector class is a template class that provides a dynamic array.
Definition: qdatastream.h:64
void setHost(const QString &host)
Sets the host of the URL to host.
Definition: qurl.cpp:4821
void insert(const QString &domain, const QString &user, const QString &password)
QString path() const
Returns the path of the URL.
Definition: qurl.cpp:4977
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the vector...
Definition: qvector.h:250
static QNetworkProxy applicationProxy()
Returns the application level network proxying.
The QNetworkProxy class provides a network layer proxy.
QNetworkAuthenticationCredential fetchCachedCredentials(const QUrl &url, const QAuthenticator *auth=0)
Fetch the credential data from the credential cache.
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
void setFragment(const QString &fragment)
Sets the fragment of the URL to fragment.
Definition: qurl.cpp:5669
The QAuthenticator class provides an authentication object.
QByteArray toEncoded(FormattingOptions options=None) const
Returns the encoded representation of the URL if it&#39;s valid; otherwise an empty QByteArray is returne...
Definition: qurl.cpp:5949
bool isNull() const
Returns true if this string is null; otherwise returns false.
Definition: qstring.h:505
void insert(int i, const T &t)
Inserts value at index position i in the vector.
Definition: qvector.h:362
Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
Definition: qalgorithms.h:227
QString userName() const
Returns the user name of the URL if it is defined; otherwise an empty string is returned.
Definition: qurl.cpp:4667
QString scheme() const
Returns the scheme of the URL.
Definition: qurl.cpp:4550
#define Q_ASSERT_X(cond, where, what)
Definition: qglobal.h:1837
The QMutexLocker class is a convenience class that simplifies locking and unlocking mutexes...
Definition: qmutex.h:101
void setPort(int port)
Sets the port of the URL to port.
Definition: qurl.cpp:4897
iterator begin()
Returns an STL-style iterator pointing to the first item in the vector.
Definition: qvector.h:247
void clear()
Clears the contents of the string and makes it empty.
Definition: qstring.h:723
static QString fromLatin1(const char *, int size=-1)
Returns a QString initialized with the first size characters of the Latin-1 string str...
Definition: qstring.cpp:4188
QString user() const
returns the user used for authentication.
quint16 port() const
Returns the port of the proxy host.
static int closestMatch(QRgb pixel, const QVector< QRgb > &clut)
Definition: qimage.cpp:4015
void setScheme(const QString &scheme)
Sets the scheme of the URL to scheme.
Definition: qurl.cpp:4533
QString password() const
Returns the password used for authentication.
void cacheProxyCredentials(const QNetworkProxy &proxy, const QAuthenticator *auth)
bool isEmpty() const
Returns true if the byte array has size 0; otherwise returns false.
Definition: qbytearray.h:421
void cacheCredentials(const QUrl &url, const QAuthenticator *auth)
bool isEmpty() const
Returns true if the vector has size 0; otherwise returns false.
Definition: qvector.h:139
void reserve(int size)
Attempts to allocate memory for at least size elements.
Definition: qvector.h:339
QNetworkAuthenticationCredential fetchCachedProxyCredentials(const QNetworkProxy &proxy, const QAuthenticator *auth=0)
QString password() const
returns the password used for authentication.
QString user() const
Returns the user name used for authentication.
void setUserName(const QString &userName)
Sets the URL&#39;s user name to userName.
Definition: qurl.cpp:4648
QString password() const
Returns the password of the URL if it is defined; otherwise an empty string is returned.
Definition: qurl.cpp:4754
QString realm() const
returns the realm requiring authentication.
QString hostName() const
Returns the host name of the proxy host.