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();
240#ifdef QHTTPTHREADDELEGATE_DEBUG
241 qDebug() <<
"QHttpThreadDelegate::startRequest() thread=" << QThread::currentThreadId();
245 if (!connections.hasLocalData()) {
250 QUrl urlCopy = httpRequest.url();
251 const bool isLocalSocket = urlCopy.scheme().startsWith(
"unix"_L1);
253 urlCopy.setPort(urlCopy.port(
ssl ? 443 : 80));
255 QHttpNetworkConnection::ConnectionType connectionType
256 = httpRequest.isHTTP2Allowed() ? QHttpNetworkConnection::ConnectionTypeHTTP2
257 : QHttpNetworkConnection::ConnectionTypeHTTP;
258 if (httpRequest.isHTTP2Direct()) {
259 Q_ASSERT(!httpRequest.isHTTP2Allowed());
260 connectionType = QHttpNetworkConnection::ConnectionTypeHTTP2Direct;
264 if (!ssl && connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2
265 && !httpRequest.isH2cAllowed()) {
266 connectionType = QHttpNetworkConnection::ConnectionTypeHTTP;
271 Q_ASSERT(!ssl || incomingSslConfiguration);
274 const bool isH2 = httpRequest.isHTTP2Allowed() || httpRequest.isHTTP2Direct();
278 if (!httpRequest.isHTTP2Direct()) {
279 QList<QByteArray> protocols;
280 protocols << QSslConfiguration::ALPNProtocolHTTP2
281 << QSslConfiguration::NextProtocolHttp1_1;
282 incomingSslConfiguration->setAllowedNextProtocols(protocols);
284 urlCopy.setScheme(QStringLiteral(
"h2s"));
289 urlCopy.setScheme(QStringLiteral(
"unix+h2"));
291 urlCopy.setScheme(QStringLiteral(
"h2"));
295 QString extraData = httpRequest.peerVerifyName();
297 if (QString path = httpRequest.fullLocalServerName(); !path.isEmpty())
301#ifndef QT_NO_NETWORKPROXY
302 if (transparentProxy.type() != QNetworkProxy::NoProxy)
303 cacheKey = makeCacheKey(urlCopy, &transparentProxy, httpRequest.peerVerifyName());
304 else if (cacheProxy.type() != QNetworkProxy::NoProxy)
305 cacheKey = makeCacheKey(urlCopy, &cacheProxy, httpRequest.peerVerifyName());
308 cacheKey = makeCacheKey(urlCopy,
nullptr, httpRequest.peerVerifyName());
314 QString host = urlCopy.host();
317 if (QString path = httpRequest.fullLocalServerName(); !path.isEmpty())
323 httpConnection =
new QNetworkAccessCachedHttpConnection(
324 http1Parameters.numberOfConnectionsPerHost(), host, urlCopy.port(), ssl,
325 isLocalSocket, connectionType);
326 if (connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2
327 || connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2Direct) {
331 httpConnection->setTcpKeepAliveParameters(tcpKeepAliveParameters);
338#ifndef QT_NO_NETWORKPROXY
344 connections.localData()->addEntry(cacheKey,
httpConnection, connectionCacheExpiryTimeoutSeconds);
346 if (httpRequest.withCredentials()) {
348 if (!credential.user.isEmpty() && !credential.password.isEmpty()) {
350 auth.setUser(credential.user);
351 auth.setPassword(credential.password);
365 connect(
httpReply,SIGNAL(finishedWithError(QNetworkReply::NetworkError,QString)),
366 this, SLOT(synchronousFinishedWithErrorSlot(QNetworkReply::NetworkError,QString)));
368 connect(
httpReply, SIGNAL(authenticationRequired(QHttpNetworkRequest,QAuthenticator*)),
370#ifndef QT_NO_NETWORKPROXY
381 connect(
httpReply,SIGNAL(finishedWithError(QNetworkReply::NetworkError,QString)),
382 this, SLOT(finishedWithErrorSlot(QNetworkReply::NetworkError,QString)));
384 connect(
httpReply,SIGNAL(readyRead()),
this, SLOT(readyReadSlot()));
385 connect(
httpReply,SIGNAL(dataReadProgress(qint64,qint64)),
this, SLOT(dataReadProgressSlot(qint64,qint64)));
388 connect(
httpReply,SIGNAL(sslErrors(QList<QSslError>)),
this, SLOT(sslErrorsSlot(QList<QSslError>)));
389 connect(
httpReply,SIGNAL(preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator*)),
390 this, SLOT(preSharedKeyAuthenticationRequiredSlot(QSslPreSharedKeyAuthenticator*)));
395 connect(
httpReply, SIGNAL(authenticationRequired(QHttpNetworkRequest,QAuthenticator*)),
396 this, SIGNAL(authenticationRequired(QHttpNetworkRequest,QAuthenticator*)));
397#ifndef QT_NO_NETWORKPROXY
403 connect(
httpReply, SIGNAL(cacheCredentials(QHttpNetworkRequest,QAuthenticator*)),
405 if (httpReply->errorCode() != QNetworkReply::NoError) {
407 synchronousFinishedWithErrorSlot(httpReply->errorCode(), httpReply->errorString());
409 finishedWithErrorSlot(httpReply->errorCode(), httpReply->errorString());