25 QNetworkReply::NetworkError code;
27 switch (httpStatusCode) {
29 code = QNetworkReply::ProtocolInvalidOperationError;
33 code = QNetworkReply::AuthenticationRequiredError;
37 code = QNetworkReply::ContentAccessDenied;
41 code = QNetworkReply::ContentNotFoundError;
45 code = QNetworkReply::ContentOperationNotPermittedError;
49 code = QNetworkReply::ProxyAuthenticationRequiredError;
53 code = QNetworkReply::ContentConflictError;
57 code = QNetworkReply::ContentGoneError;
61 code = QNetworkReply::ProtocolInvalidOperationError;
65 code = QNetworkReply::InternalServerError;
69 code = QNetworkReply::OperationNotImplementedError;
73 code = QNetworkReply::ServiceUnavailableError;
77 if (httpStatusCode > 500) {
79 code = QNetworkReply::UnknownServerError;
80 }
else if (httpStatusCode >= 400) {
82 code = QNetworkReply::UnknownContentError;
84 qWarning(
"QNetworkAccess: got HTTP status code %d which is not expected from url: \"%s\"",
85 httpStatusCode, qPrintable(url.toString()));
86 code = QNetworkReply::ProtocolFailure;
98 QString scheme = copy.scheme();
99 bool isEncrypted = scheme ==
"https"_L1 || scheme ==
"preconnect-https"_L1;
100 const bool isLocalSocket = scheme.startsWith(
"unix"_L1);
102 copy.setPort(copy.port(isEncrypted ? 443 : 80));
103 if (scheme ==
"preconnect-http"_L1)
104 copy.setScheme(
"http"_L1);
105 else if (scheme ==
"preconnect-https"_L1)
106 copy.setScheme(
"https"_L1);
107 result = copy.toString(QUrl::RemoveUserInfo | QUrl::RemovePath |
108 QUrl::RemoveQuery | QUrl::RemoveFragment | QUrl::FullyEncoded);
110#ifndef QT_NO_NETWORKPROXY
111 if (proxy && proxy->type() != QNetworkProxy::NoProxy) {
114 switch (proxy->type()) {
115 case QNetworkProxy::Socks5Proxy:
116 key.setScheme(
"proxy-socks5"_L1);
119 case QNetworkProxy::HttpProxy:
120 case QNetworkProxy::HttpCachingProxy:
121 key.setScheme(
"proxy-http"_L1);
128 if (!key.scheme().isEmpty()) {
129 const QByteArray obfuscatedPassword = QCryptographicHash::hash(proxy->password().toUtf8(),
130 QCryptographicHash::Sha1).toHex();
131 key.setUserName(proxy->user());
132 key.setPassword(QString::fromUtf8(obfuscatedPassword));
133 key.setHost(proxy->hostName());
134 key.setPort(proxy->port());
135 key.setQuery(result);
136 result = key.toString(QUrl::FullyEncoded);
142 if (!peerVerifyName.isEmpty())
143 result += u':' + peerVerifyName;
144 return "http-connection:" +
std::move(result).toLatin1();
241#ifdef QHTTPTHREADDELEGATE_DEBUG
242 qDebug() <<
"QHttpThreadDelegate::startRequest() thread=" << QThread::currentThreadId();
246 if (!connections.hasLocalData()) {
251 QUrl urlCopy = httpRequest.url();
252 const bool isLocalSocket = urlCopy.scheme().startsWith(
"unix"_L1);
254 urlCopy.setPort(urlCopy.port(
ssl ? 443 : 80));
256 QHttpNetworkConnection::ConnectionType connectionType
257 = httpRequest.isHTTP2Allowed() ? QHttpNetworkConnection::ConnectionTypeHTTP2
258 : QHttpNetworkConnection::ConnectionTypeHTTP;
259 if (httpRequest.isHTTP2Direct()) {
260 Q_ASSERT(!httpRequest.isHTTP2Allowed());
261 connectionType = QHttpNetworkConnection::ConnectionTypeHTTP2Direct;
265 if (!ssl && connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2
266 && !httpRequest.isH2cAllowed()) {
267 connectionType = QHttpNetworkConnection::ConnectionTypeHTTP;
272 Q_ASSERT(!ssl || incomingSslConfiguration);
275 const bool isH2 = httpRequest.isHTTP2Allowed() || httpRequest.isHTTP2Direct();
279 if (!httpRequest.isHTTP2Direct()) {
280 QList<QByteArray> protocols;
281 protocols << QSslConfiguration::ALPNProtocolHTTP2
282 << QSslConfiguration::NextProtocolHttp1_1;
283 incomingSslConfiguration->setAllowedNextProtocols(protocols);
285 urlCopy.setScheme(QStringLiteral(
"h2s"));
290 urlCopy.setScheme(QStringLiteral(
"unix+h2"));
292 urlCopy.setScheme(QStringLiteral(
"h2"));
296 QString extraData = httpRequest.peerVerifyName();
298 if (QString path = httpRequest.fullLocalServerName(); !path.isEmpty())
302#ifndef QT_NO_NETWORKPROXY
303 if (transparentProxy.type() != QNetworkProxy::NoProxy)
304 cacheKey = makeCacheKey(urlCopy, &transparentProxy, httpRequest.peerVerifyName());
305 else if (cacheProxy.type() != QNetworkProxy::NoProxy)
306 cacheKey = makeCacheKey(urlCopy, &cacheProxy, httpRequest.peerVerifyName());
309 cacheKey = makeCacheKey(urlCopy,
nullptr, httpRequest.peerVerifyName());
312 if (connectionCacheExpiryTimeoutSeconds.value_or(0) >= 0)
314 connections.localData()->requestEntryNow(cacheKey));
318 QString host = urlCopy.host();
321 if (QString path = httpRequest.fullLocalServerName(); !path.isEmpty())
327 httpConnection =
new QNetworkAccessCachedHttpConnection(
328 http1Parameters.numberOfConnectionsPerHost(), host, urlCopy.port(), ssl,
329 isLocalSocket, connectionType);
330 if (connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2
331 || connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2Direct) {
335 httpConnection->setTcpKeepAliveParameters(tcpKeepAliveParameters);
342#ifndef QT_NO_NETWORKPROXY
348 if (connectionCacheExpiryTimeoutSeconds.value_or(0) >= 0)
350 connectionCacheExpiryTimeoutSeconds);
352 if (httpRequest.withCredentials()) {
354 if (!credential.user.isEmpty() && !credential.password.isEmpty()) {
356 auth.setUser(credential.user);
357 auth.setPassword(credential.password);
371 connect(
httpReply,SIGNAL(finishedWithError(QNetworkReply::NetworkError,QString)),
372 this, SLOT(synchronousFinishedWithErrorSlot(QNetworkReply::NetworkError,QString)));
374 connect(
httpReply, SIGNAL(authenticationRequired(QHttpNetworkRequest,QAuthenticator*)),
376#ifndef QT_NO_NETWORKPROXY
387 connect(
httpReply,SIGNAL(finishedWithError(QNetworkReply::NetworkError,QString)),
388 this, SLOT(finishedWithErrorSlot(QNetworkReply::NetworkError,QString)));
390 connect(
httpReply,SIGNAL(readyRead()),
this, SLOT(readyReadSlot()));
391 connect(
httpReply,SIGNAL(dataReadProgress(qint64,qint64)),
this, SLOT(dataReadProgressSlot(qint64,qint64)));
394 connect(
httpReply,SIGNAL(sslErrors(QList<QSslError>)),
this, SLOT(sslErrorsSlot(QList<QSslError>)));
395 connect(
httpReply,SIGNAL(preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator*)),
396 this, SLOT(preSharedKeyAuthenticationRequiredSlot(QSslPreSharedKeyAuthenticator*)));
401 connect(
httpReply, SIGNAL(authenticationRequired(QHttpNetworkRequest,QAuthenticator*)),
402 this, SIGNAL(authenticationRequired(QHttpNetworkRequest,QAuthenticator*)));
403#ifndef QT_NO_NETWORKPROXY
409 connect(
httpReply, SIGNAL(cacheCredentials(QHttpNetworkRequest,QAuthenticator*)),
411 if (httpReply->errorCode() != QNetworkReply::NoError) {
413 synchronousFinishedWithErrorSlot(httpReply->errorCode(), httpReply->errorString());
415 finishedWithErrorSlot(httpReply->errorCode(), httpReply->errorString());