| 193 | } |
| 194 | |
| 195 | auto NetRequest::handleRedirect() -> bool |
| 196 | { |
| 197 | QUrl redirect = m_reply->header(QNetworkRequest::LocationHeader).toUrl(); |
| 198 | if (!redirect.isValid()) { |
| 199 | if (!m_reply->hasRawHeader("Location")) { |
| 200 | // no redirect -> it's fine to continue |
| 201 | return false; |
| 202 | } |
| 203 | // there is a Location header, but it's not correct. we need to apply some workarounds... |
| 204 | QByteArray redirectBA = m_reply->rawHeader("Location"); |
| 205 | if (redirectBA.size() == 0) { |
| 206 | // empty, yet present redirect header? WTF? |
| 207 | return false; |
| 208 | } |
| 209 | QString redirectStr = QString::fromUtf8(redirectBA); |
| 210 | |
| 211 | if (redirectStr.startsWith("//")) { |
| 212 | /* |
| 213 | * IF the URL begins with //, we need to insert the URL scheme. |
| 214 | * See: https://bugreports.qt.io/browse/QTBUG-41061 |
| 215 | * See: http://tools.ietf.org/html/rfc3986#section-4.2 |
| 216 | */ |
| 217 | redirectStr = m_reply->url().scheme() + ":" + redirectStr; |
| 218 | } else if (redirectStr.startsWith("/")) { |
| 219 | /* |
| 220 | * IF the URL begins with /, we need to process it as a relative URL |
| 221 | */ |
| 222 | auto url = m_reply->url(); |
| 223 | url.setPath(redirectStr, QUrl::TolerantMode); |
| 224 | redirectStr = url.toString(); |
| 225 | } |
| 226 | |
| 227 | /* |
| 228 | * Next, make sure the URL is parsed in tolerant mode. Qt doesn't parse the location header in tolerant mode, which causes issues. |
| 229 | * FIXME: report Qt bug for this |
| 230 | */ |
| 231 | redirect = QUrl(redirectStr, QUrl::TolerantMode); |
| 232 | if (!redirect.isValid()) { |
| 233 | qCWarning(logCat) << getUid().toString() << "Failed to parse redirect URL:" << redirectStr; |
| 234 | downloadError(QNetworkReply::ProtocolFailure); |
| 235 | return false; |
| 236 | } |
| 237 | qCDebug(logCat) << getUid().toString() << "Fixed location header:" << redirect; |
| 238 | } else { |
| 239 | qCDebug(logCat) << getUid().toString() << "Location header:" << redirect; |
| 240 | } |
| 241 | |
| 242 | m_url = QUrl(redirect.toString()); |
| 243 | qCDebug(logCat) << getUid().toString() << "Following redirect to " << m_url.toString(); |
| 244 | executeTask(); |
| 245 | |
| 246 | return true; |
| 247 | } |
| 248 | |
| 249 | void NetRequest::downloadFinished() |
| 250 | { |