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();
246#ifdef QHTTPTHREADDELEGATE_DEBUG
247 qDebug() <<
"QHttpThreadDelegate::startRequest() thread=" << QThread::currentThreadId();
251 if (!connections.hasLocalData()) {
256 QUrl urlCopy = httpRequest.url();
257 const bool isLocalSocket = urlCopy.scheme().startsWith(
"unix"_L1);
259 urlCopy.setPort(urlCopy.port(
ssl ? 443 : 80));
261 QHttpNetworkConnection::ConnectionType connectionType
262 = httpRequest.isHTTP2Allowed() ? QHttpNetworkConnection::ConnectionTypeHTTP2
263 : QHttpNetworkConnection::ConnectionTypeHTTP;
264 if (httpRequest.isHTTP2Direct()) {
265 Q_ASSERT(!httpRequest.isHTTP2Allowed());
266 connectionType = QHttpNetworkConnection::ConnectionTypeHTTP2Direct;
270 if (!ssl && connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2
271 && !httpRequest.isH2cAllowed()) {
272 connectionType = QHttpNetworkConnection::ConnectionTypeHTTP;
277 Q_ASSERT(!ssl || incomingSslConfiguration);
280 const bool isH2 = httpRequest.isHTTP2Allowed() || httpRequest.isHTTP2Direct();
284 if (!httpRequest.isHTTP2Direct()) {
285 QList<QByteArray> protocols;
286 protocols << QSslConfiguration::ALPNProtocolHTTP2
287 << QSslConfiguration::NextProtocolHttp1_1;
288 incomingSslConfiguration->setAllowedNextProtocols(protocols);
290 urlCopy.setScheme(QStringLiteral(
"h2s"));
295 urlCopy.setScheme(QStringLiteral(
"unix+h2"));
297 urlCopy.setScheme(QStringLiteral(
"h2"));
301 QString extraData = httpRequest.peerVerifyName();
303 if (QString path = httpRequest.fullLocalServerName(); !path.isEmpty())
307#ifndef QT_NO_NETWORKPROXY
308 if (transparentProxy.type() != QNetworkProxy::NoProxy)
309 cacheKey = makeCacheKey(urlCopy, &transparentProxy, httpRequest.peerVerifyName());
310 else if (cacheProxy.type() != QNetworkProxy::NoProxy)
311 cacheKey = makeCacheKey(urlCopy, &cacheProxy, httpRequest.peerVerifyName());
314 cacheKey = makeCacheKey(urlCopy,
nullptr, httpRequest.peerVerifyName());
317 if (connectionCacheExpiryTimeoutSeconds.value_or(0) >= 0)
319 connections.localData()->requestEntryNow(cacheKey));
323 QString host = urlCopy.host();
326 if (QString path = httpRequest.fullLocalServerName(); !path.isEmpty())
332 httpConnection =
new QNetworkAccessCachedHttpConnection(
333 http1Parameters.numberOfConnectionsPerHost(), host, urlCopy.port(), ssl,
334 isLocalSocket, connectionType);
335 if (connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2
336 || connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2Direct) {
340 httpConnection->setTcpKeepAliveParameters(tcpKeepAliveParameters);
347#ifndef QT_NO_NETWORKPROXY
353 if (connectionCacheExpiryTimeoutSeconds.value_or(0) >= 0)
355 connectionCacheExpiryTimeoutSeconds);
357 if (httpRequest.withCredentials()) {
359 if (!credential.user.isEmpty() && !credential.password.isEmpty()) {
361 auth.setUser(credential.user);
362 auth.setPassword(credential.password);
376 connect(
httpReply,SIGNAL(finishedWithError(QNetworkReply::NetworkError,QString)),
377 this, SLOT(synchronousFinishedWithErrorSlot(QNetworkReply::NetworkError,QString)));
379 connect(
httpReply, SIGNAL(authenticationRequired(QHttpNetworkRequest,QAuthenticator*)),
381#ifndef QT_NO_NETWORKPROXY
392 connect(
httpReply,SIGNAL(finishedWithError(QNetworkReply::NetworkError,QString)),
393 this, SLOT(finishedWithErrorSlot(QNetworkReply::NetworkError,QString)));
395 connect(
httpReply,SIGNAL(readyRead()),
this, SLOT(readyReadSlot()));
396 connect(
httpReply,SIGNAL(dataReadProgress(qint64,qint64)),
this, SLOT(dataReadProgressSlot(qint64,qint64)));
399 connect(
httpReply,SIGNAL(sslErrors(QList<QSslError>)),
this, SLOT(sslErrorsSlot(QList<QSslError>)));
400 connect(
httpReply,SIGNAL(preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator*)),
401 this, SLOT(preSharedKeyAuthenticationRequiredSlot(QSslPreSharedKeyAuthenticator*)));
406 connect(
httpReply, SIGNAL(authenticationRequired(QHttpNetworkRequest,QAuthenticator*)),
407 this, SIGNAL(authenticationRequired(QHttpNetworkRequest,QAuthenticator*)));
408#ifndef QT_NO_NETWORKPROXY
414 connect(
httpReply, SIGNAL(cacheCredentials(QHttpNetworkRequest,QAuthenticator*)),
416 if (httpReply->errorCode() != QNetworkReply::NoError) {
418 synchronousFinishedWithErrorSlot(httpReply->errorCode(), httpReply->errorString());
420 finishedWithErrorSlot(httpReply->errorCode(), httpReply->errorString());