Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qhttpthreaddelegate.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
4//#define QHTTPTHREADDELEGATE_DEBUG
6
7#include <QThread>
8#include <QTimer>
9#include <QAuthenticator>
10#include <QEventLoop>
11#include <QCryptographicHash>
12
13#include "private/qhttpnetworkreply_p.h"
14#include "private/qnetworkaccesscache_p.h"
15#include "private/qnoncontiguousbytedevice_p.h"
16
18
19using namespace Qt::StringLiterals;
20
21static QNetworkReply::NetworkError statusCodeFromHttp(int httpStatusCode, const QUrl &url)
22{
24 // we've got an error
25 switch (httpStatusCode) {
26 case 400: // Bad Request
28 break;
29
30 case 401: // Authorization required
32 break;
33
34 case 403: // Access denied
36 break;
37
38 case 404: // Not Found
40 break;
41
42 case 405: // Method Not Allowed
44 break;
45
46 case 407:
48 break;
49
50 case 409: // Resource Conflict
52 break;
53
54 case 410: // Content no longer available
56 break;
57
58 case 418: // I'm a teapot
60 break;
61
62 case 500: // Internal Server Error
64 break;
65
66 case 501: // Server does not support this functionality
68 break;
69
70 case 503: // Service unavailable
72 break;
73
74 default:
75 if (httpStatusCode > 500) {
76 // some kind of server error
78 } else if (httpStatusCode >= 400) {
79 // content error we did not handle above
81 } else {
82 qWarning("QNetworkAccess: got HTTP status code %d which is not expected from url: \"%s\"",
83 httpStatusCode, qPrintable(url.toString()));
85 }
86 }
87
88 return code;
89}
90
91
92static QByteArray makeCacheKey(QUrl &url, QNetworkProxy *proxy, const QString &peerVerifyName)
93{
95 QUrl copy = url;
96 QString scheme = copy.scheme();
97 bool isEncrypted = scheme == "https"_L1 || scheme == "preconnect-https"_L1;
98 const bool isLocalSocket = scheme.startsWith("unix"_L1);
99 if (!isLocalSocket)
100 copy.setPort(copy.port(isEncrypted ? 443 : 80));
101 if (scheme == "preconnect-http"_L1)
102 copy.setScheme("http"_L1);
103 else if (scheme == "preconnect-https"_L1)
104 copy.setScheme("https"_L1);
107
108#ifndef QT_NO_NETWORKPROXY
109 if (proxy && proxy->type() != QNetworkProxy::NoProxy) {
110 QUrl key;
111
112 switch (proxy->type()) {
114 key.setScheme("proxy-socks5"_L1);
115 break;
116
119 key.setScheme("proxy-http"_L1);
120 break;
121
122 default:
123 break;
124 }
125
126 if (!key.scheme().isEmpty()) {
127 const QByteArray obfuscatedPassword = QCryptographicHash::hash(proxy->password().toUtf8(),
129 key.setUserName(proxy->user());
130 key.setPassword(QString::fromUtf8(obfuscatedPassword));
131 key.setHost(proxy->hostName());
132 key.setPort(proxy->port());
133 key.setQuery(result);
134 result = key.toString(QUrl::FullyEncoded);
135 }
136 }
137#else
139#endif
140 if (!peerVerifyName.isEmpty())
141 result += u':' + peerVerifyName;
142 return "http-connection:" + std::move(result).toLatin1();
143}
144
147{
148 // Q_OBJECT
149public:
150 QNetworkAccessCachedHttpConnection(quint16 connectionCount, const QString &hostName, quint16 port, bool encrypt, bool isLocalSocket,
152 : QHttpNetworkConnection(connectionCount, hostName, port, encrypt, isLocalSocket, /*parent=*/nullptr, connectionType)
153 {
154 setExpires(true);
155 setShareable(true);
156 }
157
158 virtual void dispose() override
159 {
160#if 0 // sample code; do this right with the API
161 Q_ASSERT(!isWorking());
162#endif
163 delete this;
164 }
165};
166
167
168QThreadStorage<QNetworkAccessCache *> QHttpThreadDelegate::connections;
169
170
172{
173 // It could be that the main thread has asked us to shut down, so we need to delete the HTTP reply
174 if (httpReply) {
175 delete httpReply;
176 }
177
178 // Get the object cache that stores our QHttpNetworkConnection objects
179 // and release the entry for this QHttpNetworkConnection
180 if (connections.hasLocalData() && !cacheKey.isEmpty()) {
181 connections.localData()->releaseEntry(cacheKey);
182 }
183}
184
185
187 QObject(parent)
188 , ssl(false)
189 , downloadBufferMaximumSize(0)
190 , readBufferMaxSize(0)
191 , bytesEmitted(0)
192 , pendingDownloadData()
193 , pendingDownloadProgress()
194 , synchronous(false)
195 , connectionCacheExpiryTimeoutSeconds(-1)
196 , incomingStatusCode(0)
197 , isPipeliningUsed(false)
198 , isHttp2Used(false)
199 , incomingContentLength(-1)
200 , removedContentLength(-1)
201 , incomingErrorCode(QNetworkReply::NoError)
202 , downloadBuffer()
203 , httpConnection(nullptr)
204 , httpReply(nullptr)
205 , synchronousRequestLoop(nullptr)
206{
207}
208
209// This is invoked as BlockingQueuedConnection from QNetworkAccessHttpBackend in the user thread
211{
212#ifdef QHTTPTHREADDELEGATE_DEBUG
213 qDebug() << "QHttpThreadDelegate::startRequestSynchronously() thread=" << QThread::currentThreadId();
214#endif
215 synchronous = true;
216
218 this->synchronousRequestLoop = &synchronousRequestLoop;
219
220 // Worst case timeout
221 QTimer::singleShot(30*1000, this, SLOT(abortRequest()));
222
223 QMetaObject::invokeMethod(this, "startRequest", Qt::QueuedConnection);
225
226 connections.localData()->releaseEntry(cacheKey);
227 connections.setLocalData(nullptr);
228
229#ifdef QHTTPTHREADDELEGATE_DEBUG
230 qDebug() << "QHttpThreadDelegate::startRequestSynchronously() thread=" << QThread::currentThreadId() << "finished";
231#endif
232}
233
234
235// This is invoked as QueuedConnection from QNetworkAccessHttpBackend in the user thread
237{
238#ifdef QHTTPTHREADDELEGATE_DEBUG
239 qDebug() << "QHttpThreadDelegate::startRequest() thread=" << QThread::currentThreadId();
240#endif
241 // Check QThreadStorage for the QNetworkAccessCache
242 // If not there, create this connection cache
243 if (!connections.hasLocalData()) {
244 connections.setLocalData(new QNetworkAccessCache());
245 }
246
247 // check if we have an open connection to this host
248 QUrl urlCopy = httpRequest.url();
249 const bool isLocalSocket = urlCopy.scheme().startsWith("unix"_L1);
250 if (!isLocalSocket)
251 urlCopy.setPort(urlCopy.port(ssl ? 443 : 80));
252
259 }
260
261 // Use HTTP/1.1 if h2c is not allowed and we would otherwise choose to use it
262 if (!ssl && connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2
265 }
266
267#if QT_CONFIG(ssl)
268 // See qnetworkreplyhttpimpl, delegate's initialization code.
270#endif // QT_CONFIG(ssl)
271
272 const bool isH2 = httpRequest.isHTTP2Allowed() || httpRequest.isHTTP2Direct();
273 if (isH2) {
274#if QT_CONFIG(ssl)
275 if (ssl) {
276 if (!httpRequest.isHTTP2Direct()) {
277 QList<QByteArray> protocols;
281 }
282 urlCopy.setScheme(QStringLiteral("h2s"));
283 } else
284#endif // QT_CONFIG(ssl)
285 {
286 if (isLocalSocket)
287 urlCopy.setScheme(QStringLiteral("unix+h2"));
288 else
289 urlCopy.setScheme(QStringLiteral("h2"));
290 }
291 }
292
293 QString extraData = httpRequest.peerVerifyName();
294 if (isLocalSocket) {
295 if (QString path = httpRequest.fullLocalServerName(); !path.isEmpty())
296 extraData = path;
297 }
298
299#ifndef QT_NO_NETWORKPROXY
304 else
305#endif
306 cacheKey = makeCacheKey(urlCopy, nullptr, httpRequest.peerVerifyName());
307
308 // the http object is actually a QHttpNetworkConnection
309 httpConnection = static_cast<QNetworkAccessCachedHttpConnection *>(connections.localData()->requestEntryNow(cacheKey));
310 if (!httpConnection) {
311
312 QString host = urlCopy.host();
313 // Update the host if a unix socket path or named pipe is used:
314 if (isLocalSocket) {
316 host = path;
317 }
318
319 // no entry in cache; create an object
320 // the http object is actually a QHttpNetworkConnection
322 http1Parameters.numberOfConnectionsPerHost(), host, urlCopy.port(), ssl,
323 isLocalSocket, connectionType);
327 }
328#ifndef QT_NO_SSL
329 // Set the QSslConfiguration from this QNetworkRequest.
330 if (ssl)
332#endif
333
334#ifndef QT_NO_NETWORKPROXY
337#endif
339 // cache the QHttpNetworkConnection corresponding to this cache key
341 } else {
343 QNetworkAuthenticationCredential credential = authenticationManager->fetchCachedCredentials(httpRequest.url(), nullptr);
344 if (!credential.user.isEmpty() && !credential.password.isEmpty()) {
345 QAuthenticator auth;
346 auth.setUser(credential.user);
347 auth.setPassword(credential.password);
348 httpConnection->d_func()->copyCredentials(-1, &auth, false);
349 }
350 }
351 }
352
353 // Send the request to the connection
355 httpReply->setParent(this);
356
357 // Connect the reply signals that we need to handle and then forward
358 if (synchronous) {
359 connect(httpReply,SIGNAL(headerChanged()), this, SLOT(synchronousHeaderChangedSlot()));
360 connect(httpReply,SIGNAL(finished()), this, SLOT(synchronousFinishedSlot()));
363
366#ifndef QT_NO_NETWORKPROXY
369#endif
370
371 // Don't care about ignored SSL errors for now in the synchronous HTTP case.
372 } else if (!synchronous) {
375 connect(httpReply,SIGNAL(headerChanged()), this, SLOT(headerChangedSlot()));
376 connect(httpReply,SIGNAL(finished()), this, SLOT(finishedSlot()));
379 // some signals are only interesting when normal asynchronous style is used
380 connect(httpReply,SIGNAL(readyRead()), this, SLOT(readyReadSlot()));
382#ifndef QT_NO_SSL
384 connect(httpReply,SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(sslErrorsSlot(QList<QSslError>)));
387#endif
388
389 // In the asynchronous HTTP case we can just forward those signals
390 // Connect the reply signals that we can directly forward
393#ifndef QT_NO_NETWORKPROXY
396#endif
397 }
398
402 if (synchronous)
404 else
406 }
407}
408
409// This gets called from the user thread or by the synchronous HTTP timeout timer
411{
412#ifdef QHTTPTHREADDELEGATE_DEBUG
413 qDebug() << "QHttpThreadDelegate::abortRequest() thread=" << QThread::currentThreadId() << "sync=" << synchronous;
414#endif
415 if (httpReply) {
416 httpReply->abort();
417 delete httpReply;
418 httpReply = nullptr;
419 }
420
421 // Got aborted by the timeout timer
422 if (synchronous) {
425 } else {
426 //only delete this for asynchronous mode or QNetworkAccessHttpBackend will crash - see QNetworkAccessHttpBackend::postRequest()
427 this->deleteLater();
428 }
429}
430
432{
433#ifdef QHTTPTHREADDELEGATE_DEBUG
434 qDebug() << "QHttpThreadDelegate::readBufferSizeChanged() size " << size;
435#endif
436 if (httpReply) {
440 }
441}
442
451
453{
454 if (!httpReply)
455 return;
456
457 // Don't do in zerocopy case
458 if (!downloadBuffer.isNull())
459 return;
460
461 if (readBufferMaxSize) {
463 qint64 sizeEmitted = 0;
464 while (httpReply->readAnyAvailable() && (sizeEmitted < (readBufferMaxSize-bytesEmitted))) {
466 sizeEmitted = readBufferMaxSize-bytesEmitted;
467 bytesEmitted += sizeEmitted;
468 pendingDownloadData->fetchAndAddRelease(1);
469 emit downloadData(httpReply->read(sizeEmitted));
470 } else {
471 sizeEmitted = httpReply->sizeNextBlock();
472 bytesEmitted += sizeEmitted;
473 pendingDownloadData->fetchAndAddRelease(1);
475 }
476 }
477 } else {
478 // We need to wait until we empty data from the read buffer in the reply.
479 }
480
481 } else {
482 while (httpReply->readAnyAvailable()) {
483 pendingDownloadData->fetchAndAddRelease(1);
485 }
486 }
487}
488
490{
491 if (!httpReply)
492 return;
493
494#ifdef QHTTPTHREADDELEGATE_DEBUG
495 qDebug() << "QHttpThreadDelegate::finishedSlot() thread=" << QThread::currentThreadId() << "result=" << httpReply->statusCode();
496#endif
497
498 // If there is still some data left emit that now
499 while (httpReply->readAnyAvailable()) {
500 pendingDownloadData->fetchAndAddRelease(1);
502 }
503
504#ifndef QT_NO_SSL
505 if (ssl)
507#endif
508
509 if (httpReply->statusCode() >= 400) {
510 // it's an error reply
511 QString msg = QLatin1StringView(QT_TRANSLATE_NOOP("QNetworkReply",
512 "Error transferring %1 - server replied: %2"));
515 }
516
519
521
524 httpReply = nullptr;
525}
526
528{
529 if (!httpReply)
530 return;
531
532#ifdef QHTTPTHREADDELEGATE_DEBUG
533 qDebug() << "QHttpThreadDelegate::synchronousFinishedSlot() thread=" << QThread::currentThreadId() << "result=" << httpReply->statusCode();
534#endif
535 if (httpReply->statusCode() >= 400) {
536 // it's an error reply
537 QString msg = QLatin1StringView(QT_TRANSLATE_NOOP("QNetworkReply",
538 "Error transferring %1 - server replied: %2"));
541 }
542
545
548 httpReply = nullptr;
549}
550
552{
553 if (!httpReply)
554 return;
555
556#ifdef QHTTPTHREADDELEGATE_DEBUG
557 qDebug() << "QHttpThreadDelegate::finishedWithErrorSlot() thread=" << QThread::currentThreadId() << "error=" << errorCode << detail;
558#endif
559
560#ifndef QT_NO_SSL
561 if (ssl)
563#endif
564 emit error(errorCode,detail);
566
567
570 httpReply = nullptr;
571}
572
573
575{
576 if (!httpReply)
577 return;
578
579#ifdef QHTTPTHREADDELEGATE_DEBUG
580 qDebug() << "QHttpThreadDelegate::synchronousFinishedWithErrorSlot() thread=" << QThread::currentThreadId() << "error=" << errorCode << detail;
581#endif
582 incomingErrorCode = errorCode;
584
586
589 httpReply = nullptr;
590}
591
593{
594 if (!httpReply)
595 return;
596
597#ifdef QHTTPTHREADDELEGATE_DEBUG
598 qDebug() << "QHttpThreadDelegate::headerChangedSlot() thread=" << QThread::currentThreadId();
599#endif
600
601#ifndef QT_NO_SSL
602 if (ssl)
604#endif
605
606 // Is using a zerocopy buffer allowed by user and possible with this reply?
609 char *buf = new (std::nothrow) char[httpReply->contentLength()];
610 // in out of memory situations, don't use downloadBuffer.
611 if (buf) {
612 downloadBuffer = QSharedPointer<char>(buf, [](auto p) { delete[] p; });
614 }
615 }
616
617 // We fetch this into our own
626
636}
637
639{
640 if (!httpReply)
641 return;
642
643#ifdef QHTTPTHREADDELEGATE_DEBUG
644 qDebug() << "QHttpThreadDelegate::synchronousHeaderChangedSlot() thread=" << QThread::currentThreadId();
645#endif
646 // Store the information we need in this object, the QNetworkAccessHttpBackend will later read it
653}
654
655
657{
658 // If we don't have a download buffer don't attempt to go this codepath
659 // It is not used by QNetworkAccessHttpBackend
661 return;
662
663 pendingDownloadProgress->fetchAndAddRelease(1);
664 emit downloadProgress(done, total);
665}
666
668{
669 authenticationManager->cacheCredentials(request.url(), authenticator);
670}
671
672
673#ifndef QT_NO_SSL
682
683void QHttpThreadDelegate::sslErrorsSlot(const QList<QSslError> &errors)
684{
685 if (!httpReply)
686 return;
687
689
690 bool ignoreAll = false;
691 QList<QSslError> specificErrors;
692 emit sslErrors(errors, &ignoreAll, &specificErrors);
693 if (ignoreAll)
695 if (!specificErrors.isEmpty())
696 httpReply->ignoreSslErrors(specificErrors);
697}
698
706#endif
707
709{
710 if (!httpReply)
711 return;
712
714#ifdef QHTTPTHREADDELEGATE_DEBUG
715 qDebug() << "QHttpThreadDelegate::synchronousAuthenticationRequiredSlot() thread=" << QThread::currentThreadId();
716#endif
717
718 // Ask the credential cache
719 QNetworkAuthenticationCredential credential = authenticationManager->fetchCachedCredentials(httpRequest.url(), a);
720 if (!credential.isNull()) {
721 a->setUser(credential.user);
722 a->setPassword(credential.password);
723 }
724
725 // Disconnect this connection now since we only want to ask the authentication cache once.
728}
729
730#ifndef QT_NO_NETWORKPROXY
732{
733 if (!httpReply)
734 return;
735
736#ifdef QHTTPTHREADDELEGATE_DEBUG
737 qDebug() << "QHttpThreadDelegate::synchronousProxyAuthenticationRequiredSlot() thread=" << QThread::currentThreadId();
738#endif
739 // Ask the credential cache
740 QNetworkAuthenticationCredential credential = authenticationManager->fetchCachedProxyCredentials(p, a);
741 if (!credential.isNull()) {
742 a->setUser(credential.user);
743 a->setPassword(credential.password);
744 }
745
746#ifndef QT_NO_NETWORKPROXY
747 // Disconnect this connection now since we only want to ask the authentication cache once.
750#endif
751}
752
753#endif
754
756
757#include "moc_qhttpthreaddelegate_p.cpp"
The QAuthenticator class provides an authentication object.
void setUser(const QString &user)
Sets the user used for authentication.
\inmodule QtCore
Definition qbytearray.h:57
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
Definition qbytearray.h:107
static QByteArray hash(QByteArrayView data, Algorithm method)
Returns the hash of data using method.
\inmodule QtCore
Definition qeventloop.h:16
int exec(ProcessEventsFlags flags=AllEvents)
Enters the main event loop and waits until exit() is called.
Q_NETWORK_EXPORT qsizetype numberOfConnectionsPerHost() const
Returns the number of connections used per http(s) {host}:{port} combination.
QHttpNetworkReply * sendRequest(const QHttpNetworkRequest &request)
void setCacheProxy(const QNetworkProxy &networkProxy)
void setPeerVerifyName(const QString &peerName)
ConnectionType connectionType() const
void setTransparentProxy(const QNetworkProxy &networkProxy)
void setHttp2Parameters(const QHttp2Configuration &params)
void setSslConfiguration(const QSslConfiguration &config)
QHttpHeaders header() const override
QString errorString() const
bool readAnyAvailable() const
qint64 removedContentLength() const
QByteArray read(qint64 amount)
bool isPipeliningUsed() const
void setUserProvidedDownloadBuffer(char *)
void setReadBufferSize(qint64 size)
QNetworkReply::NetworkError errorCode() const
bool supportsUserProvidedDownloadBuffer()
void setDownstreamLimited(bool t)
QString reasonPhrase() const
qint64 contentLength() const override
QSslConfiguration sslConfiguration() const
QHttpNetworkRequest request() const
QUrl url() const override
QString fullLocalServerName() const
void cacheCredentialsSlot(const QHttpNetworkRequest &request, QAuthenticator *authenticator)
QSharedPointer< char > downloadBuffer
QHttpNetworkReply * httpReply
void readBufferSizeChanged(qint64 size)
void synchronousAuthenticationRequiredSlot(const QHttpNetworkRequest &request, QAuthenticator *)
void synchronousFinishedWithErrorSlot(QNetworkReply::NetworkError errorCode, const QString &detail=QString())
void socketStartedConnecting()
QScopedPointer< QSslConfiguration > incomingSslConfiguration
std::shared_ptr< QAtomicInt > pendingDownloadData
void sslErrorsSlot(const QList< QSslError > &errors)
QNetworkAccessCachedHttpConnection * httpConnection
void redirected(const QUrl &url, int httpStatus, int maxRedirectsRemainig)
void downloadMetaData(const QHttpHeaders &, int, const QString &, bool, QSharedPointer< char >, qint64, qint64, bool, bool)
void downloadProgress(qint64, qint64)
QHttpNetworkRequest httpRequest
void preSharedKeyAuthenticationRequiredSlot(QSslPreSharedKeyAuthenticator *authenticator)
QHttp1Configuration http1Parameters
QHttpThreadDelegate(QObject *parent=nullptr)
void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *)
void sslErrors(const QList< QSslError > &, bool *, QList< QSslError > *)
void synchronousProxyAuthenticationRequiredSlot(const QNetworkProxy &, QAuthenticator *)
void finishedWithErrorSlot(QNetworkReply::NetworkError errorCode, const QString &detail=QString())
void authenticationRequired(const QHttpNetworkRequest &request, QAuthenticator *)
void readBufferFreed(qint64 size)
QHttp2Configuration http2Parameters
static QThreadStorage< QNetworkAccessCache * > connections
std::shared_ptr< QAtomicInt > pendingDownloadProgress
QNetworkReply::NetworkError incomingErrorCode
void downloadData(const QByteArray &)
std::shared_ptr< QNetworkAccessAuthenticationManager > authenticationManager
void dataReadProgressSlot(qint64 done, qint64 total)
void preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator *)
void sslConfigurationChanged(const QSslConfiguration &)
QNetworkAccessCachedHttpConnection(quint16 connectionCount, const QString &hostName, quint16 port, bool encrypt, bool isLocalSocket, QHttpNetworkConnection::ConnectionType connectionType)
The QNetworkProxy class provides a network layer proxy.
QString user() const
Returns the user name used for authentication.
QNetworkProxy::ProxyType type() const
Returns the proxy type for this instance.
QString password() const
Returns the password used for authentication.
QString hostName() const
Returns the host name of the proxy host.
quint16 port() const
Returns the port of the proxy host.
The QNetworkReply class contains the data and headers for a request sent with QNetworkAccessManager.
NetworkError
Indicates all possible error conditions found during the processing of the request.
@ ContentOperationNotPermittedError
@ OperationNotImplementedError
@ ProtocolInvalidOperationError
@ ProxyAuthenticationRequiredError
@ AuthenticationRequiredError
QUrl url() const
Returns the URL this network request is referring to.
\inmodule QtCore
Definition qobject.h:103
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
void setParent(QObject *parent)
Makes the object a child of parent.
Definition qobject.cpp:2195
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
\threadsafe
Definition qobject.cpp:3236
void deleteLater()
\threadsafe
Definition qobject.cpp:2435
T * data() const noexcept
Returns the value of the pointer referenced by this object.
bool isNull() const noexcept
Returns true if this object refers to \nullptr.
static const char ALPNProtocolHTTP2[]
void setAllowedNextProtocols(const QList< QByteArray > &protocols)
static const char NextProtocolHttp1_1[]
The QSslPreSharedKeyAuthenticator class provides authentication data for pre shared keys (PSK) cipher...
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
QByteArray toLatin1() const &
Definition qstring.h:630
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:5465
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:6028
QString arg(qlonglong a, int fieldwidth=0, int base=10, QChar fillChar=u' ') const
Definition qstring.cpp:8881
QByteArray toUtf8() const &
Definition qstring.h:634
static Qt::HANDLE currentThreadId() noexcept Q_DECL_PURE_FUNCTION
Definition qthread.h:149
bool singleShot
whether the timer is a single-shot timer
Definition qtimer.h:22
\inmodule QtCore
Definition qurl.h:94
QString scheme() const
Returns the scheme of the URL.
Definition qurl.cpp:1991
@ RemoveFragment
Definition qurl.h:112
@ RemoveQuery
Definition qurl.h:111
@ RemovePath
Definition qurl.h:110
@ RemoveUserInfo
Definition qurl.h:107
@ FullyEncoded
Definition qurl.h:129
QString toString(FormattingOptions options=FormattingOptions(PrettyDecoded)) const
Returns a string representation of the URL.
Definition qurl.cpp:2831
Combined button and popup list for selecting options.
@ QueuedConnection
static jboolean copy(JNIEnv *, jobject)
DBusConnection const char DBusError * error
EGLOutputPortEXT port
static QNetworkReply::NetworkError statusCodeFromHttp(int httpStatusCode, const QUrl &url)
static QByteArray makeCacheKey(QUrl &url, QNetworkProxy *proxy, const QString &peerVerifyName)
#define qDebug
[1]
Definition qlogging.h:165
#define qWarning
Definition qlogging.h:167
static bool isEncrypted(const my_mach_header *header)
#define SLOT(a)
Definition qobjectdefs.h:52
#define SIGNAL(a)
Definition qobjectdefs.h:53
GLuint64 key
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLuint GLenum GLsizei const GLchar * buf
GLsizei const GLchar *const * path
GLuint64EXT * result
[6]
GLfloat GLfloat p
[1]
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define qPrintable(string)
Definition qstring.h:1531
#define QStringLiteral(str)
@ NoError
Definition main.cpp:34
static bool ignoreAll
#define emit
#define Q_UNUSED(x)
#define QT_TRANSLATE_NOOP(scope, x)
unsigned short quint16
Definition qtypes.h:48
long long qint64
Definition qtypes.h:60
QUrl url("example.com")
[constructor-url-reference]
QObject::connect nullptr
QNetworkRequest request(url)
QNetworkProxy proxy
[0]
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(nullptr), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
\threadsafe This is an overloaded member function, provided for convenience. It differs from the abov...